modvadon for local bindings
play

MoDvaDon for local bindings We want local bindings = a way to name - PowerPoint PPT Presentation

MoDvaDon for local bindings We want local bindings = a way to name things locally in Local Bindings and Scope funcDons and other expressions. Why? These slides borrow heavily from Ben Woods Fall 15 slides, some of which are For style


  1. MoDvaDon for local bindings We want local bindings = a way to name things locally in Local Bindings and Scope funcDons and other expressions. Why? These slides borrow heavily from Ben Wood’s Fall ‘15 slides, some of which are – For style and convenience in turn based on Dan Grossman’s material from the University of Washington. – Avoiding duplicate computaDons – A big but natural idea: nested funcDon bindings CS251 Programming – Improving algorithmic efficiency ( not “just a liQle faster”) Languages Fall 2018, Lyn Turbak Department of Computer Science Wellesley College Local Bindings & Scope 2 let in the let expressions: Example quadraDc formula > ( let {[a (+ 1 2)] [b (* 3 4)]} (list a b)) (define (quadratic-roots a b c) '(3 12) (let {[-b (- b)] [sqrt-discriminant Pre$y printed form (sqrt (- (* b b) (* 4 a c)))] [2a (* 2 a)]} > ( let {[a (+ 1 2)] (list (/ (+ -b sqrt-discriminant) 2a) [b (* 3 4)]} (/ (- -b sqrt-discriminant) 2a)))) (list a b)) '(3 12) Local Bindings & Scope 3 Local Bindings & Scope 4

  2. Parens vs. Braces vs. Brackets Formalizing let expressions As matched pairs, they are interchangeable. Differences can be used to enhance readability. 2 quesDons: a new keyword! > (let {[ a (+ 1 2) ] [ b (* 3 4) ]} (list a b)) • Syntax: (let {[ Id1 E1 ] ... [ Idn En ]} Ebody ) '(3 12) – Each Idi is any identiier, and Ebody and each Ei are any expressions > (let (( a (+ 1 2) ) ( b (* 3 4) )) (list a b)) '(3 12) • Evaluation: > (let [[ a (+ 1 2) ] [ b (* 3 4) ]] (list a b)) – Evaluate each expression Ei to value Vi in the current dynamic environment. '(3 12) – Evaluate Ebody[V1,…Vn/Id1,…,Idn] in the current > (let [{ a (+ 1 2) } ( b (* 3 4) )] (list a b)) dynamic environment. '(3 12) Result of whole let expression is result of evaluating Ebody . Local Bindings & Scope 5 Local Bindings & Scope 6 let is an expression let is just syntactic sugar! A let-expression is just an expression , so we can use it ( let {[ Id1 E1 ] … [ Idn En ]} Ebody ) anywhere an expression can go. Silly example: desugars to (( lambda ( Id1 … Idn ) Ebody ) E1 … En ) (+ (let {[x 1]} x) (let {[y 2] Example: [z 4]} (- z y))) (let {[ a (+ 1 2) ] [ b (* 3 4) ]} (list a b)) desugars to ((lambda (a b) (list a b)) (+ 1 2) (* 3 4)) Local Bindings & Scope 7 Local Bindings & Scope 8

  3. ( if (> (first xs) Avoid repeated recursion Fast vs. unusable ( bad-maxlist (rest xs))) (first xs) ( bad-maxlist (rest xs))) Consider this code and the recursive calls it makes (bad-maxlist (range 50 0 -1)) – Don’t worry about calls to first , rest , and null? because they do a small constant amount of work bm 50,… bm 49,… bm 48,… bm 1 (bad-maxlist (range 1 51)) (define ( bad-maxlist xs) ( if (null? xs) bm 1,… bm 2,… bm 3,… bm 50 -inf.0 ( if (> (first xs) ( bad-maxlist (rest xs))) bm 3,… (first xs) 2 50 … ( bad-maxlist (rest xs))))) times bm 2,… bm 3,… bm 3,… bm 50 Local Bindings & Scope 9 Local Bindings & Scope 10 Some calculaDons Efficient maxlist Suppose one bad-maxlist call’s if logic and calls to null? , first? , rest take 10 -7 seconds total (define ( good-maxlist xs) – Then ( bad-maxlist (list 50 49 … 1)) takes 50 x 10 -7 sec ( if (null? xs) – And ( bad-maxlist (list 1 2 … 50)) -inf.0 takes (1 + 2 + 2 2 + 2 3 + … + 2 49 ) x 10 -7 ( let {[rest-max ( good-maxlist (rest xs))]} = (2 50 - 1) x 10 -7 = 1.12 x 10 8 sec = over 3.5 years ( if (> (first xs) rest-max) – And ( bad-maxlist (list 1 2 … 55)) (first xs) takes over 114 years rest-max)))) – And ( bad-maxlist (list 1 2 … 100)) takes over 4 x 10 15 years . (Our sun is predicted to die in about 5 x 10 9 years) – Buying a faster computer won’t help much J gm 50,… gm 49,… gm 48,… gm 1 The key is not to do repeated work! gm 1,… gm 2,… gm 3,… gm 50 – Saving recursive results in local bindings is essential … Local Bindings & Scope 11 Local Bindings & Scope 12

  4. Transforming good-maxlist Your turn: sumProdList (define ( good-maxlist xs) ( if (null? xs) Given a list of numbers, sumProdList returns a pair of -inf.0 (1) the sum of the numbers in the list and ( let {[rest-max ( good-maxlist (rest xs))]} ( if (> (first xs) rest-max) (2) The product of the numbers in the list (first xs) rest-max)))) (sumProdList '(5 2 4 3)) –> (14 . 120) (define ( good-maxlist xs) (sumProdList '()) –> (0 . 1) ( if (null? xs) -inf.0 Define sumProdList . Why is it a good idea to use let (( � (fst rest-max) ; name fst too! in your definiDon? ( if (> fst rest-max) fst rest-max)) (first xs) ( good-maxlist (rest xs))))) (define ( good-maxlist xs) (define ( max a b) ( if (null? xs) ( if (> a b) a b)) -inf.0 ( max (first xs) ( good-maxlist (rest xs))))) Local Bindings & Scope 13 Local Bindings & Scope 14 Scope and Lexical Contours and and or sugar scope = area of program where declared name can be used. (and) desugars to #t Show scope in Racket via lexical contours in scope diagrams . (and E1 ) desugars to E1 (and E1 …) desugars to (if E1 (and …) #f) (define add-n ( λ ( x ) (+ n x )) ) (or) desugars to #f (define add-2n ( λ ( y ) (add-n (add-n y )))) (or E1 ) desugars to E1 (or E1 …) desugars to (define n 17) (let (( Id1 E1 )) (define f ( λ ( z ) (if Id1 Id1 (or …)) where Id1 must be fresh – i.e., not used elsewhere in (let {[ c (add-2n z ) ] the program. [ d (- z 3) ]} • Why is let needed in or desugaring but not and ? (+ z (* c d ))) ) ) • Why must Id1 be fresh? Local Bindings & Scope 15 Local Bindings & Scope 16

  5. DeclaraDons vs. References Scope and Define Sugar A declara7on introduces an idenDfier (variable) into a scope. (define (add-n x ) (+ n x ) ) A reference is a use of an idenDfier (variable) within a scope. (define (add-2n y ) (add-n (add-n y )) ) We can box declaraDons, circle references, and draw a line (define n 17) from each reference to its declaraDon. Dr. Racket does this (define (f z ) for us (except it puts ovals around both declaraDons and references). (let {[ c (add-2n z ) ] An idenDfier (variable) reference is unbound if there is no [ d (- z 3) ]} declaraDon to which it refers. (+ z (* c d ))) ) ) Local Bindings & Scope 17 Local Bindings & Scope 18 Shadowing Alpha-renaming An inner declaraDon of a name shadows uses of outer declaraDons Can consistently rename idenDfiers as long as it doesn’t change the of the same name. “wiring diagram” between uses and declaraDons. (define (f w z) (define (f c d) (let {[x 2]} OK (* w (* c (let {[c (add-2n z)] (let {[b (add-2n d)] (- (let {[x (* x x)]} [d (- z 3)]} [c (- d 3)]} Can’t refer to (+ x 3)) (+ z (* c d)))))) (+ d (* b c)))))) outer x here. Not OK x )) (define (f x y) (* x (let {[x (add-2n y)] [y (- y 3)]} (+ y (* x y)))))) Local Bindings & Scope 19 Local Bindings & Scope 20

  6. Scope, Free Variables, and Higher-order FuncDons Compare the Values of the Following In a lexical contour, an idenDfier is a free variable if it is not (let {[a (+ 2 3)] [b (* 3 4)]} defined by a declaraDon within that contour. (list a Scope diagrams are especially helpful for understanding the (let {[a (- b a)] meaning of free variables in higher order funcDons. [b (* a a)]} (list a b)) b)) (define (make-sub n ) ( λ ( x ) (- x n )) ) (let {[a (+ 2 3)] [b (* 3 4)]} (list a (let {[a (- b a)]} (let {[b (* a a)]} (define (map-scale factor ns ) (list a b))) b)) (map ( λ ( num ) (* factor num )) ns) ) Local Bindings & Scope 21 Local Bindings & Scope 22 More sugar: let* Local funcDon bindings with let (let* {} Ebody ) desugars to Ebody • Silly example: (let* {[ Id1 E1 ] …} Ebody ) (define (quad x) (let ([square (lambda (x) (* x x))]) desugars to (let {[ Id1 E1 ]} (square (square x)))) (let* {…} Ebody )) • Private helper functions bound locally = good style. Example (same as 2 nd example on previous slide) • But can’t use let for local recursion. Why not? (let {[a (+ 2 3)] [b (* 3 4)]} ? (define (up-to-broken x) (list a (let {[between (lambda (from to) (let* {[a (- b a)] (if (> from to) [b (* a a)]} null (cons from (list a b)) (between (+ from 1) to))))]} b)) (between 1 x))) Local Bindings & Scope 23 Local Bindings & Scope 24

Recommend


More recommend