This preview shows pages 1–3. Sign up to view the full content.
This preview has intentionally blurred sections. Sign up to view the full version.View Full Document
Unformatted text preview: 5/11/2009 1 COMPUTER SCIENCE 51 Spring 2009 cs51.seas.harvard.edu Prof. Greg Morrisett Prof. Ramin Zabih Notes Midterm good job! will go over in sections see Profs if you struggled This week: mutation & side effects see VII of HTDP, 4.9 & 5.8 of PLT Guide key concepts of OO programming see 5.3 & 13 of PLT Guide Side Effects So far, weve been working with the purely functional subset of Scheme. principle of substitution : you can always * replace an expression e with its value (and vice versa) without affecting the output of a program. sometimes known as referential transparency. results in a very simple evaluation model to evaluate (e 1 e 2 ... e n ) : evaluate e i to a value v i . e1 should evaluate to a ( (x 2 ... x n ) e) substitute v i for x i in e . evaluate the resulting expression. * wel, almost always... Substitution in Action Consider these two sets of definitions: ( define x (factorial 4)) ( define y (factorial 4)) ( define x 24) ( define y x) Are these equivalent? That is, can I write a function that tells which set of definitions I used for x & y ? No! A good thing... From a compilers standpoint, the substitution principle is great . It can replace computations over constants with their value (constant folding) (fact 4) ==> 24 It can factor out common sub-expressions: (* (length x) (length x)) ==> ( let ([n (length x)]) (* n n)) Side Effects A side effect breaks the substitution principle. For example, diverging computations are a side effect: ( define x (car (cons 3 (f)))) Is not equivalent to: (define x 3) because (f) could run forever. 5/11/2009 2 Sliding Scale of Effects expressions that diverge or throw an exception: Because the expression may not have a value! But substitution holds when they do have values. So these are more benign than other effects. local variable assignment Breaks substitution -- variable has different values at different times. But doesnt suffer from sharing (alias) problems. Can almost always eliminate. shared data structure mutation, input & output Non-local, subtle effects due to sharing Bad interactions with multi-threading But to be fair, these are crucial facilities! Local Variable Assignment Two new forms: ( set! x e) Modifies the variable x to have the value of e , and returns #<void> . ( begin e 1 e 2 ... e n ) Execute e 1 , then e 2 , then ... then e n , and return the value of e n . set! Example ( define x 0) x ==> 0 ( set! x (+ 1 x)) x ==> 1 ( define (incx) ( begin ( set! x (+ 1 x)) x))) (incx) ==> 2 (incx) ==> 3 (+ (incx) (incx)) ==> ? Consider: ( define (counter n) ( () ( begin (set! n (+ 1 n)) n))) ( define c1 (counter 0)) ( define c2 (counter 0)) (c1) ==> 1 (c1) ==> 2 (c2) ==> 1 (c2) ==> 2 (+ (c1) (c2)) ==> 6 Encapsulation The general pattern: (let ([x init]) (lambda (...) ...(set! x ...)...)) gives us a variable x that is local to a function....
View Full Document
- Spring '09