λ λ CS 251 Fall 2019 CS 251 Fall 2019 Principles of Programming Languages Principles of Programming Languages Ben Wood Ben Wood Lexical Scope and Function Closures https://cs.wellesley.edu/~cs251/f19/ 1 Lexical Scope and Function Closures
Topics • Lexical vs dynamic scope • Closures implement lexical scope. • Design considerations: why lexical scope? • Relevant design dimensions Lexical Scope and Function Closures 2
A question of scope (warmup) (define x 1) (define f (lambda (y) (+ x y))) (define z (let ([x 2] [y 3]) (f (+ x y)) )) What is the argument value passed to this function application? Lexical Scope and Function Closures 3
A question of scope (define x 1) (define f (lambda (y) (+ x y))) (define z (let ([x 2] [y 3]) (f (+ x y)) )) What is the value of x when this function body is evaluated for this function application? Lexical Scope and Function Closures 4
A question of free variables free in an expression, e , if x is referenced in e A variable, x , is fr outside the scope of any binding of x within e . x is a free variable of the lambda expression. (define x 1) (define f (lambda (y) (+ x y))) (define z (let ([x 2] [y 3]) (f (+ x y)) )) To what bindings do free variables of a function refer when the function is applied? Lexical Scope and Function Closures 5
Answer 1: lexical (static) scope free in an expression, e , if x is referenced in e A variable, x , is fr outside the scope of any binding of x within e . x is a free variable of the lambda expression. (define x 1) (define f (lambda (y) (+ x y))) (define z (let ([x 2] [y 3]) (f (+ x y)))) Free variables of a function refer to bindings in the environment where the function is de defined , regardless of where it is applied. Lexical Scope and Function Closures 6
Answer 2: dynamic scope free in an expression, e , if x is referenced in e A variable, x , is fr outside the scope of any binding of x within e . x is a free variable of the lambda expression. (define x 1) (define f (lambda (y) (+ x y))) (define z (let ([ x 2] [y 3]) (f (+ x y)) )) Free variables of a function refer to bindings in the environment where the function is ap applied , regardless of where it is defined. Lexical Scope and Function Closures 7
Answer 2: dynamic scope free in an expression, e , if x is referenced in e A variable, x , is fr outside the scope of any binding of x within e . x is a free variable of the lambda expression. (define x 1) (define f (lambda (y) (+ x y))) (define z (let ([x 2] [y 3]) (f (+ x y)))) Free variables of a function refer to bindings in the environment where the function is ap applied , regardless of where it is defined. Lexical Scope and Function Closures 8
Closures implement lexical scope. Closures allow functions to use any binding in the environment where the function is defined, regardless of where it is applied. Lexical Scope and Function Closures 9
Anonymous function definition expressions Week 1 Sy Syntax : ( lambda ( x1 … xn ) e ) – pa parameters: x1 through xn are identifiers – bo body: e is any expression Ev Evaluation : closure , ⟨ E, (lambda (x1 … xn) e) ⟩ , 1. The result is a fu function c holding the current environment, E , and the function. [closure] E ⊢ (lambda (x1 … xn) e) ↓ ⟨ E, (lambda (x1 … xn) e) ⟩ Note: – An anonymous function definition is an expression. – A function closure is a new kind of value. Closures are not expressions. – This is a de definition , not a call . . The body, e , is no not evaluated now. lambda from the λ -ca – calcu culus . Lexical Scope and Function Closures 10
Function application (call) Week 1 Syntax : ( e0 e1 ... en ) Sy Ev Evalu luati tion : 1. Under the current dynamic environment, E , evaluate e0 through en to values v0, …, vn. 2. If v0 is a function closure of n arguments, ⟨ E', (lambda (x1 … xn) e) ⟩ then The result is the result of evaluating the closure body, e , under the closure environment, E' , extended with argument bindings: x1 ⟼ v1, …, xn ⟼ vn . Otherwise, there is a type error. Functions 11
Function application (call) Week 1 Sy Synta ntax : ( e0 e1 … en ) Ev Evaluation : E ⊢ e0 ↓ ⟨ E', (lambda (x1 … xn) e) ⟩ E ⊢ e1 ↓ v1 … E ⊢ en ↓ vn x1 ⟼ v1, …, xn ⟼ vn, E' ⊢ e ↓ v [apply] E ⊢ (e0 e1 … en) ↓ v Functions 12
Example: env pointer shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value def de (define x 1) def Current evaluation step: de (define (f y) (let ([x (+ y 1)]) Current environment: (lambda (z) (+ x y z)) ) (define z (let ([x 3] [g (f 4)] [y 5]) (g 6) )) Lexical Scope and Function Closures 13
Example: env pointer shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value 1 (define x 1) x def de (define (f y) def de (let ([x (+ y 1)]) (lambda (z) (+ x y z)) ) (define z (let ([x 3] [g (f 4)] [y 5]) (g 6) )) Lexical Scope and Function Closures 14
Example: env pointer shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value 1 (define x 1) x (define (f y) (lambda (y) f def env de (let ([x (+ y 1)]) (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) (+ x y z)) ) (define z (let ([x 3] [g (f 4)] def de [y 5]) (g 6) )) Lexical Scope and Function Closures 15
Example: env pointer shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value 1 (define x 1) x (define (f y) (lambda (y) f def env de (let ([x (+ y 1)]) (lambda (z) (let ([x (+ y 1)]) let (+ x y z)) ) ) le (lambda (z) (+ x y z)) ) (define z (let ([x 3] [g (f 4)] def let de le [y 5]) (g 6) )) Lexical Scope and Function Closures 16
Example: env pointer shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value 1 (define x 1) x (define (f y) (lambda (y) f def env de (let ([x (+ y 1)]) (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) (+ x y z)) ) 3 x let le (define z (let ([x 3] [g (f 4)] def de [y 5]) let le (g 6) )) Lexical Scope and Function Closures 17
Example: env pointer shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value 1 (define x 1) x app app (define (f y) (lambda (y) app app f def env de (let ([x (+ y 1)]) (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) app app 4 y (+ x y z)) ) 3 x let le (define z (let ([x 3] [g (f 4)] def de [y 5]) let le (g 6) )) Lexical Scope and Function Closures 18
Example: env pointer shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value 1 (define x 1) x (define (f y) (lambda (y) f def env de (let ([x (+ y 1)]) (lambda (z) (let ([x (+ y 1)]) p p p p (+ x y z)) ) ) a a (lambda (z) p p 4 p p a a y (+ x y z)) ) 3 x let le (define z (let ([x 3] 5 x app app [g (f 4)] def de [y 5]) let le (g 6) )) Lexical Scope and Function Closures 19
Example: env pointer shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value 1 (define x 1) x (define (f y) (lambda (y) f def env de (let ([x (+ y 1)]) (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) app app 4 y (+ x y z)) ) 3 x let le app app (define z (let ([x 3] 5 x app app [g (f 4)] def de [y 5]) (lambda (z) let le env (+ x y z)) (g 6) )) Lexical Scope and Function Closures 20
Example: env pointer shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value 1 (define x 1) x (define (f y) (lambda (y) f def env de (let ([x (+ y 1)]) (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) 4 y (+ x y z)) ) 3 x (define z (let ([x 3] 5 x [g (f 4)] def g de let le [y 5]) (lambda (z) env (+ x y z)) let le (g 6) )) Lexical Scope and Function Closures 21
Example: env pointer shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value 1 (define x 1) x (define (f y) (lambda (y) f def env de (let ([x (+ y 1)]) (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) 4 y (+ x y z)) ) 3 x (define z (let ([x 3] 5 x [g (f 4)] def g de [y 5]) (lambda (z) env (+ x y z)) 5 (g 6) )) y let le let le Lexical Scope and Function Closures 22
Example: env pointer shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value 1 (define x 1) x (define (f y) (lambda (y) f def env de (let ([x (+ y 1)]) (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) 4 y (+ x y z)) ) p p p p a a 3 x (define z (let ([x 3] 5 x [g (f 4)] def g de [y 5]) (lambda (z) env (+ x y z)) p p p p a a 5 (g 6) )) y let le 6 z app app let le Lexical Scope and Function Closures 23
Recommend
More recommend