170 likes | 184 Views
6001 structure & interpretation of computer programs recitation 10/ october 22, 1997. overview. today’s ideas environments & encapsulation. basic notions. an environment is a sequence of frames a frame is a table of bindings a binding is a variable and its associated value constraints
E N D
6001structure & interpretation of computer programsrecitation 10/ october 22, 1997
overview • today’s ideas • environments & encapsulation
basic notions • an environment is • a sequence of frames • a frame is • a table of bindings • a binding is • a variable and its associated value • constraints • every frame (except the global frame) points to another one • each frame has at most one binding for a variable a binding a frame x : 1y : 2 x :2z : 3 E1 E2 an environment, includes both frames
interpretation of variables • evaluation • every expression is evaluated in an environment • a variable is evaluated by looking up its value in that environment • start with the first frame, and move thru the frames until a binding is found • a variable’s value in one frame may not be accessible because • that frame is not within the current environment • the variable is shadowed by a binding for the same variable in an earlier frame • examples • in env E1, (+ x y z) evals to 7 • in env E2, (+ x y z) does not eval • in env E2, (+ x z) evals to 6 • in env E2, (+ x z) evals to 5 • in E1, E2’s x is shadowed • in E2, E1’s x is not accessible x : 1y : 3 x : 2z : 4 E1 E2
modifying environments • an environment is • a mutable data structure! • special forms • (define v e) • evaluate e to some value E • add a fresh binding that associates the variable v with the value E • (set! v e) • evaluate e to some value E • change v’s binding to that v is now associated with E • notes • a redefinition is actually a set! • (set! v e) fails if v is not bound • example • (define x 100) • x ==> 100 • (set! x 99) • x ==> 99
failure of the substitution model • consider • (define x 100) • (define (down i) (begin (set! x (- x i)) x)) • (down 1) ==> 99 • (down 1) ==> 98 • loss of referential transparency • so far, evaluation of the same expression always gave the same result • this is referential transparency • no longer true • can’t use substitution model • suppose we substituted 100 for x in the definition of down: • (define down (begin (set! 100 99) 100)) • makes no sense at all • not enough just to track values associated with variables: need notion of place
a new notion of procedure • when a procedure is evaluated • we need to know what environment it might modify • scheme obeys the rule of lexical scoping: • the procedure body is evaluated in the environment • in which the procedure was created • a procedure is a pair • the code (params and body) • the environment in which it was created • example • (define x 100) • results in a new binding in top-level env • (define (down i) (begin (set! x (- x i)) x)) • results in a new binding in the top-level env: • down is associated with the pair • code: param i, body (begin (set! x (- x 1)) x)) • environment: pointer to top-level environment itself x : 100down : param ibody (begin (set! x (- x 1)) x))
application rule • to apply a procedure • create a new frame for its arguments • bind the arguments to their values in this frame • make the new frame point to the procedure’s environment • now evaluate the body in the environment that starts with the new frame • example • consider application (down 1) • create a new frame that binds i to 1 • lin k to the top-level env E1 (because this is the environment in which down was created) • now evaluate the body in this environment E2 • x refers to the x in the frame that is the sole frame of environment E1
diagram for evaluation of an application x : 100down : i : 1 (begin (set! x (- x 1)) x)) param ibody (begin (set! x (- x 1)) x))
encapsulation • compare these • procedure that modifies global var • (define down1 (lambda (i) (set! x (- x i)) x)) • procedure that modifies local var • (define down2 (let ((x 100)) (lambda (i) (set! x (- x i)) x))) • what does this interaction produce when down is down1 down2? • (define x 100) • (down 5) 95 95 • x 95 100 • (down 5) 90 90 • (set! x 100) • (down 5) 95 85 • note • down2’s x cannot be accessed (read or write!) at the top level, except by executing down2 • that x is said to be encapsulated
benefits of encapsulation • namespace • can pick local name without worrying about name clashes • modularity • can reason about a small set of procedures that manipulate the encapsulated data • representation independence • can make sure that clients have no accidental dependence on thechoice of representation
environment model explanation • to make sense of down2, carefully evaluate its definition • let is short for lambda • so we evaluate in the top-level environment • ((lambda (x) )) (lambda (i) (set! x (- x i)) x)) ) 100) • create a fresh frame for the argument x • the inner lambda evaluates to itself, since it’s not applied here • resulting value is bound to down2 in top-level env • now when down2 is applied, evaluation of body is in the environment EB x : 100down1 :down2 : EB x : 100 param ibody (begin (set! x (- x 1)) x)) param ibody (begin (set! x (- x 1)) x))
bank account example (1) • one bank account with one operation, initial deposit always $100 • (define withdraw (define bal 100) (lambda (i) (set! bal (- bal i)) bal)) • (withdraw 10) ==> 90 • (withdraw 10) ==> 80 • puzzle • can i replace (set! bal (- bal i)) by a procedure call (reduce bal i)? • construct environment diagram to see why not
bank account example (2) • many bank accounts, one operation • (define (make-withdraw bal) (lambda (i) (set! bal (- bal i)) bal)) • (define w1 (make-withdraw 100)) • (define w2 (make-withdraw 100)) • (w1 10) ==> 90 • (w1 10) ==> 80 • (w2 10) ==> 90 • note • w1 and w2 are different procedures: same code but different environments!
bank account example (3) • many bank accounts, many operations • procedure that makes accounts: • (define (make-account bal)(define (withdraw amt) (set! bal (- bal amt)) bal)(define (deposit amt) (set! bal (+ bal amt)) bal)(define (dispatch m) (cond ((eq? m ‘withdraw) withdraw) ((eq? m ‘deposit) deposit)))dispatch) • example of use • (define a1 (make-account 50)) • ((a1 ‘deposit) 40) • ((a1 ‘withdraw) 60)
another variant • one bank account, many operations • (define withdraw ‘unimplemented) • (define deposit ‘unimplemented) • (define (make-account bal) (begin (set! withdraw (lambda (amt) (set! bal (- bal amt)) bal)) (set! deposit (lambda (amt) (set! bal (+ bal amt)) bal)))) • example of use • (make-account 50) • (deposit 40) ==>90 • (withdraw 60) ==> 30 • notes • this coding style is a dangerous: must apply make-account before using ops • used in problem set code
puzzle for student presentation • define a procedure • called prev • that returns the value it was called with last time • on first invocation, returns ‘first-call