30
From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti [email protected]

From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 1: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

From Lambda Calculus to LISPFunctional Programming

Academic Year 2005-2006Alessandro Cimatti

[email protected]

Page 2: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro 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

Page 3: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 4: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

LISP Expressions

> (+ (* 3 5) (- 10 6))19> (+ (* 3 (+ (* 2 4) (+ 3 5))) (+ (- 10 7) 6))33

Page 5: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 6: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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)

Page 7: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

Evaluating Combinations

> (* (+ 2 (* 4 6)) (+ 3 5 7))

390

1524

+

26

64* 3 5 7+ 2*

Page 8: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

Compound Functions> (defun square (x) (* x x))square> (square 21)441> (square (+ 2 5))49> (square (square 3))81> (defun <name> ( <params> ) <body> )

Page 9: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 10: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 11: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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.

Page 12: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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…

Page 13: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 14: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

Conditional Expressions

> (cond ( <p1> <e1> ) ( <p2> <e2> ) ... ( <pn> <en> ))

> (if <p1> <e1> <e2> )

Page 15: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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))

Page 16: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

Exercise• Define a procedure that takes three numbers as

arguments and returns the sum of the squares of the two larger numbers

Page 17: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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)))))

Page 18: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 19: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 20: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 21: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

Comparison• Linear recursive • Stack needed• Conceptually simpler

• Iterative• Does not need stack• State is finite• Powerful compilation

technique

Page 22: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 23: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 24: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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, ...

Page 25: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 26: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

Exercise

• Exponentiation– bn = 1, if n = 0– bn = b * bn-1, otherwise

• Exponentiation in LISP– using linear recursion– using linear iteration

Page 27: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

Exponentiation

> (defun expt (b n) (if (= n 0) 1 (* b (expt b (- n 1)))))expt

Page 28: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 29: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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

Page 30: From Lambda Calculus to LISP Functional Programming Academic Year 2005-2006 Alessandro Cimatti

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