Transcript Lecture 5

Lecture 5
Higher-order procedures
5 ‫ שיעור‬- ‫מבוא מורחב‬
1
Types so far
• Numbers: 1, 7, 1.2
• Boolean: #t , #f
• Strings: “this is a string”
• Procedures:
+
 (lambda (x) (if (< x 0)
“x is negative”
“x is not negative”))
5 ‫ שיעור‬- ‫מבוא מורחב‬
2
Procedures have types
A procedure
• may have requirements regarding the
number of its arguments,
• may expect each argument to be of a certain type.
The procedure + expects numbers as its arguments.
Cannot be applied to strings.
(+ “abc” “xyz”)
5 ‫ שיעור‬- ‫מבוא מורחב‬
3
Procedures have types
The type of a procedure is (part of) a contract:
• If the operands have the specified types,
the procedure will result in a value of the specified type
• otherwise, its behavior is undefined
– maybe an error, maybe random behavior
A contract between the caller and the procedure.
• caller responsible for argument number and types
• procedure responsible to deliver correct result
5 ‫ שיעור‬- ‫מבוא מורחב‬
4
Example
The type of the procedure add:
(define (add x y) (+ x y))
is:
number × number 
two arguments,
both numbers
(+ 7 “xx”)
number
result value of number addition
is a number
- causes an error.
5 ‫ שיעור‬- ‫מבוא מורחב‬
5
Your turn
The following expressions evaluate to values of what type?
(lambda (a b c) (if (> a 0) (+ b c) (- b c)))
number × number × number
number
(lambda (p) (if p "hi" "bye"))
Boolean
string
(* 3.14 (* 2 5))
number
(lambda (p) (if p "hi" 0))
5 ‫ שיעור‬- ‫מבוא מורחב‬
??
6
Types (summary)
• type: a set of possible values and operations
• every value has a type
• procedure types (types which include ) indicate
• number of arguments required
• type of each argument
• type of result of the procedure
5 ‫ שיעור‬- ‫מבוא מורחב‬
7
Can procedures get and return procedures?
In scheme a procedure can:
• Return a procedure as its return value,
• Receive procedures as arguments.
Why is this useful?
5 ‫ שיעור‬- ‫מבוא מורחב‬
8
Consider the following three sums
•1 + 2 + … + 100 = (100 * 101)/2
•1 + 4 + 9 + … + 1002 = (100 * 101 * 102)/6
•1 + 1/32 + 1/52 + … + 1/1012 ~ p2/8
100
k
k 1
100
k
2
k 1
In mathematics they are all captured
by the notion of a sum:
5 ‫ שיעור‬- ‫מבוא מורחב‬
101
k
2
k 1,odd
9
Let’s have a look at the three programs
(define (sum-integers a b)
(if (> a b)
k

0
k 1
(+ a (sum-integers (+ 1 a) b))))
100
(define (sum term a next b)
100
k
2
k 1
(define (sum-squares a b)
(if (> a b)
(if (> a b)
0
0
(+ (square a)
(sum-squares (+ 1 a) b)))) (+ (term a)
(sum term (next a) next b))))
101
k
k 1,odd
2
(define (pi-sum a b)
(if (> a b)
0
(+ (/ 1 (square a))
(pi-sum (+ a 2) b))))
5 ‫ שיעור‬- ‫מבוא מורחב‬
10
Let’s check this new procedure out!
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
What is the type of this procedure?
((number  number) × number × (number number) × number)  number
procedure
procedure
procedure
5 ‫ שיעור‬- ‫מבוא מורחב‬
11
Higher-order procedures
(define (sum term a next b)
(if (> a b)
A higher-order procedure:
takes one or more procedures as arguments and/or
0
returns one as a value
(+ (term a)
(sum term (next a) next b))))
Examples of use:
1. (define (sum-integers1 a b)
(sum (lambda (x) x) a (lambda (x) (+ x 1)) b))
2. (define (sum-squares1 a b)
(sum square a (lambda (x) (+ x 1)) b))
3. (define (pi-sum1 a b)
(sum (lambda (x) (/ 1 (square x))) a (lambda (x) (+ x 2)) b))
5 ‫ שיעור‬- ‫מבוא מורחב‬
12
How does it work?
(define (sum term a next b)
(if (> a b) 0
(+ (term a) (sum term (next a) next b))))
100
(sum square 1 (lambda (x) (+ x 1)) 100)
k
2
k 1
(+ (square 1)
(sum square ((lambda (x) (+ x 1)) 1) (lambda (x) (+ x 1)) 100))
(+ 1 (sum square 2 (lambda (x) (+ x 1)) 100))
(+ 1 (+ (square 2) (sum square 3 (lambda (x) (+ x 1)) 100)))
(+ 1 (+ 4 (sum square 3 (lambda (x) (+ x 1)) 100)))
(+ 1 (+ 4 (+ 9 (sum square 4 (lambda (x) (+ x 1)) 100)))
…
5 ‫ שיעור‬- ‫מבוא מורחב‬
13
Integration as a procedure
Integration under a curve f is approximated by
dx (f(a) + f(a + dx) + f(a + 2dx) + … + f(b))
f
a
dx
b
(define (integral f a b)
(define dx 1.0e-3)
(* (sum f a (lambda (x) (+ x dx)) b) dx))
a
arctan(a) = ∫(1/(1+y2))dy
0
(define atan (lambda (a)
(integral (lambda (y) (/ 1 (+ 1 (square y)))) 0 a)))
5 ‫ שיעור‬- ‫מבוא מורחב‬
14
The derivative.
We want to write a procedure with:
• Argument: a function f: number  number
• Result: the function f’: number  number
deriv: (number  number)  (number  number)
(define (deriv f)
(lambda (x)
(define dx 0.001)
(/ (- (f (+ x dx)) (f x)) dx)))
> ((deriv square) 3)
6.000999999999479
5 ‫ שיעור‬- ‫מבוא מורחב‬
15
We will soon see more examples
of higher-order procedures
Before that, LET us have an intermezzo
5 ‫ שיעור‬- ‫מבוא מורחב‬
16
The syntactic sugar “Let”
Suppose we wish to implement the function
f(x,y) = x(1+x*y)2 + y(1-y) + (1+x*y)(1-y)
a
b
a
b
We can also express this as
a = 1+x*y
b = 1-y
f(x,y) = xa2 + yb + ab
5 ‫ שיעור‬- ‫מבוא מורחב‬
17
The syntactic sugar “Let”
(define (f x y)
(define (f-helper a b)
(+ (* x (square a))
(* y b)
(* a b)))
(f-helper (+ 1 (* x y))
(- 1 y)))
(define (f x y)
((lambda (a b)
(+ (* x (square a))
(* y b)
(* a b)))
(+ 1 (* x y))
(- 1 y)))
(define (f x y)
(let ((a (+ 1 (* x y)))
(b (- 1 y)))
(+ (* x (square a))
(* y b)
(* a b))))
5 ‫ שיעור‬- ‫מבוא מורחב‬
18
The syntactic sugar “Let”
(Let ((<var1> <exp1>)
(<var2> <exp2>)
..
bindings
(<varn> <expn>))
<body>)
Is defined to be equivalent to:
((lambda (<var1> ….. <varn>)
<body>)
<exp1>
<exp2>
…
<expn>)
5 ‫ שיעור‬- ‫מבוא מורחב‬
19
More Procedural Abstraction… Fixed Points
x0 is a fixed point of F(x) if F(x0) = x0
Example:
x0 = a
is a fixed point of F(x) = a/x
20
Finding fixed points for f(x)
Start with an arbitrary first guess x1
Each time:
• try the guess, f(x) ~ x ??
• If it’s not a good guess try the next guess xi+1 = f(xi)
(define (fixed-point f first-guess)
(define tolerance 0.00001)
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(define (try guess)
(let ((next (f guess)))
(if (close-enough? guess next)
guess
(try next))))
(try first-guess))
5 ‫ שיעור‬- ‫מבוא מורחב‬
21
An example: f(x) = 1+1/x
(define (f x) (+ 1 (/ 1 x)))
(fixed-point f 1.0)
X1 = 1.0
X2 = f(x1) = 2
X3 = f(x2) = 1.5
X4 = f(x3) = 1.666666666..
X5 = f(x4) = 1.6
X6 = f(x5) = 1.625
X7 = f(x6) = 1.6153846…
Note how odd guesses
underestimate
And even guesses
Overestimate.
Exact fixed-point: 1.6180339…
5 ‫ שיעור‬- ‫מבוא מורחב‬
22
Another example: f(x) = 2/x
(define (f x) (/ 2 x))
(fixed-point f 1.0)
x1 = 1.0
x2 = f(x1) = 2
x3 = f(x2) = 1
x4 = f(x3) = 2
x5 = f(x4) = 1
x6 = f(x5) = 2
x7 = f(x6) = 1
Exact fixed-point: 1.414213562…
5 ‫ שיעור‬- ‫מבוא מורחב‬
23
How do we deal with oscillation?
Consider f(x)=2/x.
If guess is a number such that guess < sqrt(2) then
2/guess > sqrt(2)
So the average of guess and 2/guess is always an even
Better guess.
So, we will try to find a fixed point of g(x)= (x + f(x))/2
Notice that g(x) = (x +f(x)) /2 has the same fixed
points as f.
For f(x)=2/x this gives: g(x)= (x + 2/x)/2
5 ‫ שיעור‬- ‫מבוא מורחב‬
24
Example :
x for x  2.
To find an approximation of x:
• Make a guess G
• Improve the guess by averaging G and x/G
• Keep improving the guess until it is good enough
X=2
G=1
X/G = 2
X/G = 4/3
G = ½ (1+ 2) = 1.5
G = ½ (3/2 + 4/3) = 17/12 = 1.416666
X/G = 24/17 G = ½ (17/12 + 24/17) = 577/408 = 1.4142156
5 ‫ שיעור‬- ‫מבוא מורחב‬
25
Extracting the common pattern: average-damp
(define (average-damp f) ;outputs g(x)=(x+f(x))/2
(lambda (x) (average x (f x))))
average-damp: (number  number)  (number  number)
((average-damp square) 10)
((lambda (x) (average x (square x))) 10)
(average 10 (square 10))
55
5 ‫ שיעור‬- ‫מבוא מורחב‬
26
… which gives us a clean version of sqrt
(define (sqrt x)
(fixed-point
(average-damp
(lambda (y) (/ x y)))
1))
• Compare this to our previous implementation of sqrt – same process.
For the cubic root of x, fixed point of f(y) = x/y2
(define (cubert x)
(fixed-point
(average-damp (lambda (y) (/ x (square y))))
1))
5 ‫ שיעור‬- ‫מבוא מורחב‬
27
Further abstraction
(define (osc-fixed-point f first-guess)
(fixed-point (average-damp f)
first-guess))
(define (sqrt x)
(osc-fixed-point (lambda (y) (/ x y))
1.0)
(define (cubert x)
(osc-fixed-point (lambda (y) (/ x (square y)))
1.0)
5 ‫ שיעור‬- ‫מבוא מורחב‬
28
Newton’s method
A solution to the equation: F(x) = 0
is a fixed point of: G(x) = x - F(x)/F’(x)
(define (newton-transform f)
(lambda (x) (- x
(/ (f x)
((deriv f) x)))))
(define (newton-method f guess)
(fixed-point (newton-transform f) guess))
(define (sqrt x)
(newton-method (lambda (y) (- (square y) x))
1.0))
5 ‫ שיעור‬- ‫מבוא מורחב‬
29
Further abstraction
(define (fixed-point-of-transform f transform guess)
(fixed-point (transform f) guess))
(define (osc-fixed-point f guess)
(fixed-point-of-transform f
average-damp
guess))
(define (newton-method f guess)
(fixed-point-of-transform f
newton-transform
guess))
5 ‫ שיעור‬- ‫מבוא מורחב‬
30