Download presentation
Presentation is loading. Please wait.
Published byCalvin McDowell Modified over 9 years ago
1
PS4 #6: if you got points off because you didn’t do an intersect with accessible and the start states, submit a re- grade. Today: let, let*, letrec in the env. model side-effecting lists (set-car!, set-cdr!) Tomorrow: more on side-effecting data structures (e.g., chains)
2
To evaluate a lambda in environment E, build a closure. To evaluate a (non-special form) combination: (f a1... an) in E: evaluate f in E and get a closure c evaluate each argument ai in E to get a value vi apply the closure c to the values v1... vn To apply a closure c to values v1... vn: build a new frame, binding closure formal parameters to actual parameters v1... vn link the frame into the environment of the closure to yield a new environment evaluate the body of the closure in the new environment
3
To evaluate: (let ((x1 e1) (x2 e2)... (xn en)) e) in environment E: 1. evaluate e1, e2,..., en in environment E producing values v1, v2,..., vn. 2. build a new frame that binds x1 to v1, x2 to v2,..., xn to vn. 3. link the new frame into E to yield a new environment. 4. evaluate the body of the let, e, in the new environment.
4
(let ((x 1) (y 2)) (* x y)) *: {mult} 1. evaluate 1 and 2 in the current env.
5
(let ((x 1) (y 2)) (* x y)) *: {mult} x: 1 y: 2 2. build new frame with bindings 3. link it in to the env.
6
(let ((x 1) (y 2)) (* x y)) *: {mult} x: 1 y: 2 4. evaluate body of let in new env.
7
(let ((x 3) (y (* x x))) (* x y)) *: {mult} 1. evaluate 1 in environment to get 1...
8
(let ((x 3) (y (* x x))) (* x y)) *: {mult}...but evaluating (* x x) fails! (no binding for x in the environment!)
9
Alternative: (let ((x1 e1) (x2 e2)... (xn en)) e) in environment E, evaluate: ((lambda (x1 x2... xn) e) e1 e2... en)
10
(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) *: {mult}
11
(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) *: {mult}
12
(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) args: (x y) body: (* x y) env : *: {mult}
13
(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) args: (x y) body: (* x y) env : *: {mult} Now apply the closure to 1 and 2...
14
(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) args: (x y) body: (* x y) env : *: {mult} x: 1 y: 2...and we get 2.
15
(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) args: (x y) body: (* x y) env : *: {mult} x: 1 y: 2 afterwards, we continue evaluating in the top-level environment...
16
(let ((x 1) (y 2)) => ((lambda (x y) (* x y)) 1 2) (* x y)) args: (x y) body: (* x y) env : *: {mult} x: 1 y: 2 and the intermediate closure and frame are garbage collected
17
To evaluate: (let* ((x1 e1) (x2 e2)... (xn en)) e) in environment E: 1. evaluate e1 in E to v1 2. add a new frame mapping x1 to v1, yielding E2 3. evaluate e2 in E2 to v2 4. add a new frame mapping x2 to v2, yielding E3... 2n-1. evaluate en in En to vn 2n. add a new frame mapping xn to vn, yielding E’ 2n+1. evaluate the body e in E’
18
(let* ((x 3) (y (* x x))) (* x y)) *: {mult}
19
(let* ((x 3) (y (* x x))) (* x y)) *: {mult} x:3
20
(let* ((x 3) (y (* x x))) (* x y)) *: {mult} x:3 The (* x x) yields 9...
21
(let* ((x 3) (y (* x x))) (* x y)) *: {mult} x:3 y:9
22
(let* ((x 3) (y (* x x))) (* x y)) *: {mult} x:3 y:9 The (* x y) yields 3*9 = 27
23
Alternative: (let* ((x1 e1) (x2 e2)... (xn en)) e) in environment E, evaluate: (let ((x1 e1)) (((...(lambda (x1) (let ((x2 e2)) ((lambda (x2)... =>... (let ((xn en)) ((lambda (xn) e)...)) e))) e1) e2)... en)
24
(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult}
25
(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} args: x body: env:
26
(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} args: x body: env: x:3
27
(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} args: x body: env: x:3
28
(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} x:3
29
(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} x:3 args: y body: (* x y) env:
30
(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} x:3 args: y body: (* x y) env: And then we apply the closure to 9...
31
(let* ((x 3) (let ((x 3)) (y (* x x))) => (let ((y (* x x)) => (* x y)) (* x y))) ((lambda (x) ((lambda (y) (* x y)) (* x x))) 3) *: {mult} x:3 args: y body: (* x y) env: y:9...and as before get 27 as the result.
32
To evaluate: (letrec ((x1 e1) (x2 e2)... (xn en)) e) in environment E: 1. build a new frame mapping each xi to *void* looking up *void* should be an error... 2. link the frame into E yielding a new environment E’ 3. evaluate each ei in the new environment E’ to a value vi 4. set! the bindings in the frame so that xi maps to vi 5. evaluate the body e in E’
33
(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 1. create a new frame mapping f to *void*
34
(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 1. create a new frame mapping f to *void* 2. link it in to the environment f: *void*
35
(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 3. evaluate the expression in the new environment to get a value v. f: *void*
36
(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 3. evaluate the expression in the new environment to get a value v. f: *void* args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env :
37
(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 4. set! the binding in the frame so that f maps to v f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env :
38
(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} 5. now evaluate the body of the letrec in the new environment. f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env :
39
(letrec ((f (lambda (x) (if (= 1 x) 1 (* x (f (- 1 x))))))) (f 3)) *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3
40
(if (= 1 x) 1 (* x (f (- 1 x)))) => (if (= 1 3) 1 (* x (f (- 1 x)))) => (if #f 1 (* x (f (- 1 x)))) => (* x (f (- 1 x))) => (* 3 (f (- 1 x))) => (* 3 (f 2)) *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3
41
(if (= 1 x) 1 (* x (f (- 1 x)))) => (if (= 1 2) 1 (* x (f (- 1 x)))) => (if #f 1 (* x (f (- 1 x)))) => (* x (f (- 1 x))) => (* 2 (f (- 1 x))) => (* 2 (f 1)) *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3 x: 2
42
(if (= 1 x) 1 (* x (f (- 1 x)))) => (if (= 1 1) 1 (* x (f (- 1 x)))) => (if #t 1 (* x (f (- 1 x)))) => 1 *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3 x: 2 x: 1
43
(if (= 1 x) 1 (* x (f (- 1 x)))) => (* 2 (f 1)) => (* 2 1) => 2 *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3 x: 2
44
(if (= 1 x) 1 (* x (f (- 1 x)))) => (* 3 (f 2)) => (* 3 2) => 6 *: {mult} +: {add} =: {equal} -: {sub} f: args: x body: (if (= 1 x) 1 (* x (f (- 1 x)))) env : x: 3
45
(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0))
46
(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: *void* g: *void*
47
(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: *void* g: *void*
48
(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: *void* g: *void* args: x body: (g x) env :
49
(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: *void* g: *void* args: x body: (g x) env :
50
args: y body: (f y) env : (letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: *void* g: *void* args: x body: (g x) env :
51
(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: g: args: x body: (g x) env : args: y body: (f y) env :
52
(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: g: args: x body: (g x) env : args: y body: (f y) env :
53
(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: g: args: x body: (g x) env : args: y body: (f y) env : x: 0
54
(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) f: g: args: x body: (g x) env : args: y body: (f y) env : x: 0 y: 0
55
Alternative: to evaluate (letrec ((x1 e1)... (xn en)) e) in environment E, evaluate? (let ((x1 ‘void) ; define place-holders... (xn ‘void)) (let ((v1 e1) ; evaluate e1,...,en... ; and save values as v1,...,vn (vn en)) (set! x1 v1) ; set x1,...,xn to v1,...,vn... (set! xn vn) e))
56
(letrec ((f (lambda (x) (g x))) (g (lambda (y) (f y)))) (f 0)) => (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))
57
(let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0))) f: ‘void g: ‘void
58
f: ‘void g: ‘void args: x body: (g x) env : (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))
59
f: ‘void g: ‘void args: x body: (g x) env : args: y body: (f y) env : (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))
60
f: ‘void g: ‘void args: x body: (g x) env : args: y body: (f y) env : v1: v2: (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))
61
f: g: ‘void args: x body: (g x) env : args: y body: (f y) env : v1: v2: (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))
62
f: g: args: x body: (g x) env : args: y body: (f y) env : v1: v2: (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))
63
f: g: args: x body: (g x) env : args: y body: (f y) env : v1: v2: (let ((f ‘void) (g ‘void)) (let ((v1 (lambda (x) (g x))) (v2 (lambda (y) (f y)))) (set! f v1) (set! g v2) (f 0)))
64
Mutable Data (define mylist (list 1 2 3)) (let ((new (list 4))) (set! (tail new) (tail mylist)) (set! (tail mylist) new)) 1 2 3 () mylist
65
4 () new Mutable Data (define mylist (list 1 2 3)) (let ((new (list 4))) (set! (tail new) (tail mylist)) (set! (tail mylist) new)) mylist 1 2 3 ()
66
new Mutable Data (define mylist (list 1 2 3)) (let ((new (list 4))) (set! (tail new) (tail mylist)) (set! (tail mylist) new)) mylist 4 1 2 3 ()
67
new Mutable Data (define mylist (list 1 2 3)) (let ((new (list 4))) (set! (tail new) (tail mylist)) (set! (tail mylist) new)) mylist 4 1 2 3 () X
68
Mutable Data (define mylist (list 1 2 3)) (let ((new (list 4))) (set! (tail new) (tail mylist)) (set! (tail mylist) new)) new mylist 4 1 2 3 ()
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.