170 likes | 184 Views
Explore the basic concepts of environments and encapsulation in computer programs, including variable interpretation and modifying environments. Understand the failure points of the substitution model and the benefits of encapsulation. Gain insights into the environment model explanation and encapsulation benefits.
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