Upload
garey-turner
View
216
Download
1
Embed Size (px)
Citation preview
PPL
Lecture 3
Slides by Yaron Gonen, based on slides by Daniel Deutch and lecture notes by Prof. Mira Balaban
Warm-up
Is this recursive or iterative?(define sum (lambda (n) (if (= n 0) 0 (+ (/ 1 (pow 2 n)) (sum (- n 1))))))
The Iterative Version
(define sum-iter (lambda (n prod) (if (= n 0) prod (sum-iter (- n 1) (+ prod (/ 1 (pow 2 n)))))))
Today: High-Order Procedures(or procedures that manipulate procedures)
In functional programming (hence, in Racket) procedures have a first class status:
• Can be a value of a variable• Pass procedures as arguments• Return procedures as values• Create them at runtime• Can be included in data structures
5
Motivation Example: sum-integers;Signature: sum-integers(a,b);Purpose: to compute the sum of integers in the interval [a,b].;Type: [Number*Number -> Number];Post-conditions: result = a + (a+1) + ... + b.;Example: (sum-integers 1 5) should produce 15(define sum-integers (lambda (a b) (if (> a b) 0 (+ a (sum-integers (+ a 1) b)))))
Motivation Example: sum-cubes;Signature: sum-cubes(a,b);Purpose: to compute the sum of cubic powers of;integers in the interval [a,b].;Type: [Number*Number -> Number];Post-conditions: result = a^3 + (a+1)^3 + ... + b^3.;Example: (sum-cubes 1 3) should produce 36(define sum-cubes (lambda (a b) (if (> a b) 0 (+ (cube a) (sum-cubes (+ a 1) b)))))
(define cube (la
mbda (x) (* x x
x)))
Motivation Example: pi-sum
(define pi-sum(lambda (a b) (if (> a b) 0 (+
(/ 1 (* a (+ a 2))) (pi-sum (+ a 4) b)))))
Same Pattern
(define <name> (lambda (a b) (if (> a b) 0 (+ (<term> a) (<name> (<next> a) b)))))
Abstraction;Signature: sum(term,a,next,b);Purpose: to compute the sum of terms, defined by <term>;in predefined gaps, defined by <next>, in the interval [a,b].;Type: [[Num -> Num] * Num * [Num -> Num] * Num -> Num];Post-conditions: result = (term a) + (term (next a)) + ... (term n),;where n = (next (next ...(next a))) =< b,;(next n) > b.;Example: (sum identity 1 add1 3) should produce 6,;where ’identity’ is (lambda (x) x) and add1 is (lambda (x) (+ 1 x))(define sum (lambda (term a next b) (if (> a b) 0 (+ (term a) (sum term (next a) next b)))))
Using the Abstracted Form(define id (λ (x) x))
(define add1 (λ (x) (+ x 1)))(define pi-term (λ (x) (/ 1 (* x (+ x 2)))))(define pi-next (λ (x) (+ x 4)))
(define sum-integers (λ (a b) (sum id a add1 b)))
(define sum-cubes (λ (a b) (sum cube a add1 b)))
(define pi-sum (λ (a b) (sum pi-term a pi-next b)))
Advantages
• Code reuse– Easier maintenance, understanding, debugging…
• General interface– Expresses a well-defined concept (in this case:
sum)
Another Example: Integral(define dx 0.005)(define add-dx (λ (x) (+ x dx)))
(define integral (λ (f a b) (* (sum f (+ a (/ dx 2)) add-dx b) dx)))
> (integral cube 0 1)0.2499875> (integral cube 0 1)0.249999875
More Abstraction: Sequence Operations;Signature: …
;Type: [[Number*Number -> Number]*Number*Number*Number -> Number];…;Example: (sequence-operation * 1 3 5) is 60;Tests: (sequence-operation + 0 2 2) ==> 2
(define sequence-operation (λ (operation start a b) (if (> a b) start (operation a (sequence-operation operation start (+ a 1) b)))))
Example of Sequence Operations
> (sequence-operation * 1 3 5)60> (sequence-operation + 0 2 7)27> (sequence-operation - 0 3 5)4> (sequence-operation expt 1 2 4)2417851639229258349412352> (expt 2 (expt 3 4))2417851639229258349412352
Anonymous Procedures
From Greek: ἀνωνυμία, anonymia, meaning "without a name" or "namelessness"
Anonymous Procedures
• λ forms evaluated during computation (no define)
• Useful in many cases.
(define pi-sum (lambda (a b) (sum (lambda (x) (/ 1 (* x (+ x 2)))) a (lambda (x) (+ x 4)) b)))
Anonymous Procedures
• Disadvantage: careless use may cause the same λ to reevaluate:
(define sum-squares-iter (lambda (n sum) (if (= n 0) sum (sum-squares-iter (- n 1) (+ sum ((lambda (x) (* x x)) n))))))
Scope and Binding
• In a λ form every parameter has– Binding (declaration)– Occurrence– Scope: lexical scoping
• In nested λ, things are a little tricky.• An occurrence without binding is called free• define is also declaration. Its scope is
universal.
Scope and Binding
(lambda (f a b dx) (* (sum f (+ a (/ dx 2.0)) (lambda (x) (+ x dx)) b) dx))
Local Variables
• Essential programming technique: mostly used for saving repeated computation.
• Can we use scoping to define local variables? Yes we can!
Local Variables
Consider the function:
It is useful to define 2 local variables:a = 1+xyb = 1-y
Local Variables
Local Variables
(define f (lambda (x y) ((lambda (a b) (+ (* x (square a)) (* y b) (* a b))) (+ 1 (* x y)) (- 1 y)) ))
Let
(define f (lambda ( x y) (let ((a (+ 1 (* x y))) (b (- 1 y))) (+ (* x (square a)) (* y b) (* a b)))))
Let
(let ( (<var1> <exp1>)
(<var2> <exp2>)
... (<varn> <expn>) )
<body> )
Let vs. Anonymous Lambda
Let(define f (lambda ( x y) (let ((a (+ 1 (* x y))) (b (- 1 y))) (+ (* x (square a)) (* y b) (* a b)))))
Lambda(define f (lambda (x y) ((lambda (a b) (+ (* x (square a)) (* y b) (* a b))) (+ 1 (* x y)) (- 1 y)) ))
Notes about Let
• let provides variables (declaration and scope)
• <expi> are in outer scope.• <body> is the scope.• Let variables are the bindings.
From Midterm 2008
( scopesסמן את כל הבלוקים הלקסיקליים )•בקטע הבא.
מהו הערך המוחזר?•(let ((x 2)) (let ( (x 3) (y x) ) ((lambda (x y +) (+ x y)) (- x y) x *)))