Upload
juliet-cain
View
229
Download
0
Embed Size (px)
DESCRIPTION
LISP Expressions > > ( ) 531 > ( ) 666 > (* 5 99) 495 > (/ 10 5) 2 > (/ 10 6) > ( ) 12.7 > ( ) 75 > (* ) 1200 The operator is always the leftmost element Parentheses rule out ambiguities
Citation preview
From Lambda Calculus to LISPFunctional Programming
Academic Year 2005-2006Alessandro Cimatti
The LISP Language• Proposed by John McCarthy in the late 1950s• Based on Lambda Calculus• Key concepts
– Interpreted language– Dynamic data structures– LISP Procedures as LISP data
• Basic notions– primitive expressions– combination of simple into compound expressions– abstraction, compound objects are named and
manipulated as units
LISP Expressions> 486486> (+ 137 394)531> (- 1000 334)666> (* 5 99)495> (/ 10 5)2> (/ 10 6)1.666667
> (+ 2.7 10)12.7> (+ 21 35 12 7)75> (* 25 4 12)1200
The operator is always the leftmost element
Parentheses rule out ambiguities
LISP Expressions
> (+ (* 3 5) (- 10 6))19> (+ (* 3 (+ (* 2 4) (+ 3 5))) (+ (- 10 7) 6))33
Naming the Environment
> (setq size 2)2> (setq pi 3.14159)3.14159> (* pi (* radius radius))314.519> (setq circumference (* 2 pi radius))62.8318
Evaluating Combinations
> (* (+ 2 (* 4 6)) (+ 3 5 7)); (* (+ 2 24 ) (+ 3 5 7)); (* (+ 2 24 ) 15 ); (* 26 15 )390
Any evaluation order is ok (in this simple example)
Evaluating Combinations
> (* (+ 2 (* 4 6)) (+ 3 5 7))
390
1524
+
26
64* 3 5 7+ 2*
Compound Functions> (defun square (x) (* x x))square> (square 21)441> (square (+ 2 5))49> (square (square 3))81> (defun <name> ( <params> ) <body> )
Compound Functions> (defun sum-of-squares (x y) (+ (square x) (square y)))sum-of-squares> (sum-of-squares 3 4)25> (defun f (a) (sum-of-squares (+ a 1) (* a 2)))f> (f 5)136
Procedure Application> (f 5) ((λ a.(sum-of-squares (+ a 1) (* a 2)) 5) (sum-of-squares (+ 5 1) (* 5 2)) (sum-of-squares 6 10 ) ((λ x y.(+ (square x) (square y))) 6 10) (+ (square 6) (square 10)) (+ ((λ x.(* x x)) 6) ((λ x.(* x x)) 10)) (+ (* 6 6) (* 10 10)) (+ 36 100)136
Procedure Application> (f 5) (sum-of-squares (+ 5 1) (* 5 2)) (+ (square (+ 5 1)) (square (* 5 2))) (+ (* (+ 5 1) (+ 5 1)) (* (* 5 2) (* 5 2))) (+ (* 6 6 ) (* 10 10)) (+ 36 100)136
The result is the same, but the evaluation process is different!Notice that (+ 5 1) and (* 5 2) are evaluated twice.
Reduction Methods• Normal-order evaluation
– fully expand body, and then reduce• Applicative-order evaluation
– evaluate the arguments and then apply– additional efficiency, reduced evaluations
• More to come…
Conditional Expressions> (defun abs (x) (cond ((> x 0) x) ((= x 0) 0) ((< x 0) (- x))))abs> (defun abs (x) (cond ((< x 0) (- x)) (else x)))abs> (defun abs (x) (if (< x 0) (- x) x))abs
Conditional Expressions
> (cond ( <p1> <e1> ) ( <p2> <e2> ) ... ( <pn> <en> ))
> (if <p1> <e1> <e2> )
Logical Operators> (and <p1> <p2> ... <pn>)> (or <p1> <p2> ... <pn>)> (not <p1>)
> (and (> x 5) (< x 10))> (defun >= (x y) (or (= x y) (> x y)))> (defun >= (x y) (not (< x y))
Exercise• Define a procedure that takes three numbers as
arguments and returns the sum of the squares of the two larger numbers
A Solution
> (defun sos-greatest (x y z) (cond ((and (< x y) (< x z)) (sum-of-squares y z)) ((and (< y x) (< y z)) (sum-of-squares x z)) (else (sum-of-squares x y)))))
Recursion> (defun factorial (n) (if (= n 1) 1 (* n (factorial (- n 1))))factorial
> (factorial 6) (* 6 (factorial 5)) (* 6 (* 5 (factorial 4))) (* 6 (* 5 (* 4 (factorial 3)))) (* 6 (* 5 (* 4 (* 3 (factorial 2))))) (* 6 (* 5 (* 4 (* 3 (* 2 (factorial 1)))))) (* 6 (* 5 (* 4 (* 3 (* 2 1))))) (* 6 (* 5 (* 4 (* 3 2)))) (* 6 (* 5 (* 4 6))) (* 6 (* 5 24)) (* 6 120)720
Recursion> (defun factorial (n) (f-iter 1 1 n))factorial
> (defun f-iter (res cnt max) (if (> cnt max) res (f-iter (* cnt res) (+ cnt 1) max)))f-iter
Recursion> (factorial 6) (f-iter 1 1 6) (f-iter 1 2 6) (f-iter 2 3 6) (f-iter 6 4 6) (f-iter 24 5 6) (f-iter 120 6 6) (f-iter 720 7 6)720
Comparison• Linear recursive • Stack needed• Conceptually simpler
• Iterative• Does not need stack• State is finite• Powerful compilation
technique
Fibonacci Numbers• The sequence of Fibonacci
– Fib(n) = 0 if n = 0, else– Fib(n) = 1 if n = 1, else– Fib(n) = Fib(n – 1) + Fib(n – 2)
• 0, 1, 1, 2, 3, 5, 8, 13, 21, ...
> (defun fib (n) (cond ((= n 0) 0) ((= n 1) 1) (else (+ (fib (- n 1)) (fib (- n 2)))))fib
Fibonacci: Computation> (fib 5) (+ (fib 4) (fib 3)) (+ (fib 4) (+ (fib 2) (fib 1))) (+ (fib 4) (+ (+ (fib 1)(fib 0)) 1)) (+ (fib 4) (+ (+ 1 0) 1)) (+ (+ (fib 3) (fib 2)) 2) ... ... (+ (+ (fib 3) (+ (fib 1) (fib 0))) 2) ... ... (+ (+ (fib 3) (+ 1 0)) 2) (+ (+ 2 1) 2)5
Exercise• Tree recursion
– Can be very expensive• Can we define linear iteration for Fibonacci numbers?• Hint
– identify the state: we need only the two previous values of the series, say a an b
– Initially, a is 1 and b is 0– At each step,
• a becomes a + b• b becomes a
a 1, 1, 2, 3, 5, 8, 13, 21, 34, ...b 0, 1, 1, 2, 3, 5, 8, 13, 21, ...
Linear Iteration for Fibonacci> (defun fib (n) (fib-iter 1 0 n))fib> (defun fib-iter (a b cnt) (if (= cnt 0) b (fib-iter (+ a b) a (- cnt 1))))fib-iter
Exercise
• Exponentiation– bn = 1, if n = 0– bn = b * bn-1, otherwise
• Exponentiation in LISP– using linear recursion– using linear iteration
Exponentiation
> (defun expt (b n) (if (= n 0) 1 (* b (expt b (- n 1)))))expt
Iterative Exponentiation> (defun expt (b n) (expt-iter b n 1)expt
> (defun expt-iter (b cnt res) (if (= cnt 0) res (expt-iter b (- cnt 1) (* b res))))expt-iter
Iterative Squaring
• We have seen– linear recursion– linear iteration
• Can we do better?– E.g. use only a logarithmic number of steps?
• Exponentiation also follows these rules– b2n = (bn)2
– b2n+1 = b * b2n
Iterative Squaring
> (defun fast-exp (b n) (cond ((= n 0) 1) ((even? n) (square (fast-exp b (/ n 2))) (else (* b (fast-exp b (- n 1)))))fast-exp