PPL Lecture 4 Slides by Yaron Gonen based
PPL Lecture 4 Slides by Yaron Gonen, based on slides by Daniel Deutch and lecture notes by Prof. Mira Balaban
Midterm 2010 (define foo (let((f (lambda(x ) (+ 1 x)))) (lambda(x) (f x)))) anonymous lambda- לביטוי ה let- • תרגמו את ביטוי ה ? שיווצרו closure- • מהו מס' ה
A note about notation… • Until now we used the term ‘procedure’ for the value of lambda expression. • We can call them closures. • (To be precise closure is a procedure with environment – more on that later in the course)
Today: High-Order Procedures (continued) • Closures as returned values • Delayed computation 5
Closures as Returned Values Number (+ x y y) [Num -> Num] (lambda (x) (+ x y y)) [Num -> Num]] (lambda (y) (lambda (x) (+ x y y))) [Num -> Num] ((lambda (y) (lambda (x) (+ x y y))) 2) Number (((lambda (y) (lambda (x) (+ x y y))) 2) 5)
Example: derive ; Signature: deriv(f) ; Type: [[Number -> Number] -> [Number -> Number]] ; Example: for f(x)=x^3, the derivative is the function 3 x^2, ; whose value at x=5 is 75. ; Tests: ((deriv cube) 5) ==> ~75 (define deriv (lambda (f) (lambda (x) (/ (- (f (+ x dx)) (f x)) dx))))
Example: derive (define dx 0. 001) (define deriv (lambda (f) (lambda (x) (/ (- (f (+ x dx)) (f x)) dx)))) >deriv #<proc(f)> >(deriv (lambda (x) (* x x x))) #<proc(x)> >((deriv (lambda (x) (* x x x))) 5) 75. 015
Compile Time vs. Runtime • More a question of ‘is it a closure already? Or do we need to evaluate this lambda expression? ’ • When a closure depends on other closures, it is preferred that these auxiliary closures are created at compile time
Compile Time vs Runtime (define sqr (lambda (x) (* x x))) C (sqr 5) ompile time ((lambda (x) (* x x)) Ru ntime 5)
Example: nth deriv (define nth-deriv (lambda (f n) (lambda (x) (if (= n 0) (f x) ((nth-deriv (deriv f) (- n 1)) x))))) reminde r (define dx 0. 00 1) (define deriv (lambda (f) (lambda (x) (/ ((f (+ x dx)) (f x)) dx))))
(define nth-deriv (lambda (f n) (lambda (x) (if (= n 0) (f x) ((nth-deriv (deriv f) (- n 1)) x))))) (define nth-deriv (lambda (f n) (if (= n 0) f (lambda (x) ((nth-deriv (deriv f) (- n 1)) x))))) (define nth-deriv (lambda (f n) (if (= n 0) f (nth-deriv (deriv f) (- n 1))))) (define nth-deriv (lambda (f n) (if (= n 0) f (deriv (nth-deriv f (- n 1)))))) >(define five-exp (lambda (x) (* x x x))) >(define fourth-deriv-of-five-exp (nth-deriv five-exp 4)) > fourth-deriv-of-five-exp #<proc(x)>
Compile time vs Runtime • We will always prefer compile-time, but sometimes its not possile (remember f_helper ? )
Delayed Computation • With lambda we can delay the computation. • We can abuse it to solve hard problems in an elegant way.
and or special forms • (and <e 1>. . . <en>) • (or <e 1>. . . <en>)
Example (if condition consequence alternative) ==> (or (and condition consequence) alternative)
Example > (define x 0) > (define y 6) > (or (and (zero? x) 100000) (/ y x)) 100000 But what about > (if (zero? x) #f #t) #f > (or (and (zero? x) #f) #t
Example • The fixed version: (if condition consequence alternative) ==> ((or (and condition (lambda () consequence)) (lambda () alternative)))
Delayed Computation for obtaining Iterative Process • Reminder: recursion stores future computation • New method for making iteration of recursion using high-order procedures
Recursive Factorial (define fact (lambda (n) (if (= n 0) 1 (* (fact (- n 1)) n))))
Iterative Factorial (define fact-iter (lambda (n prod) (if (= n 0) prod (fact-iter (- n 1) (* n prod)))))
Iterative Factorial with Delayed Computation (define fact$ (lambda (n cont) (if (= n 0) (cont 1) (fact$ (- n 1) (lambda (res) (cont (* n res)))))))
(fact$ 2 (lambda (x) x)) (fact$ 1 (lambda (res) ((lambda (x) x) (* 2 res)))) (fact$ 0 (lambda (res) ((lambda (x) x) (* 2 res))) (* 1 res)))) ((lambda (res) ((lambda (x) x) (* 2 res))) (* 1 res))) 1) ((lambda (res) ((lambda (x) x) (* 2 res))) 1) ((lambda (x) x) 2) 2
- Slides: 24