Lexical Scope and Function Closures +Closures.Rkt
Total Page:16
File Type:pdf, Size:1020Kb
CS 251 SpringFall 2019 2020 Principles of of Programming Programming Languages Languages λ Ben Wood Lexical Scope and Function Closures +closures.rkt https://cs.wellesley.edu/~cs251/s20/ Lexical Scope and Function Closures 1 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 A variable, x, is free in an expression, e, if x is referenced in e outside the scope of any binding of x within e. x is a free variable (define x 1) of the lambda expression. (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 A variable, x, is free in an expression, e, if x is referenced in e outside the scope of any binding of x within e. x is a free variable (define x 1) of the lambda expression. (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 defined, regardless of where it is applied. Lexical Scope and Function Closures 6 Answer 2: dynamic scope A variable, x, is free in an expression, e, if x is referenced in e outside the scope of any binding of x within e. x is a free variable (define x 1) of the lambda expression. (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 applied, regardless of where it is defined. Lexical Scope and Function Closures 7 Answer 2: dynamic scope A variable, x, is free in an expression, e, if x is referenced in e outside the scope of any binding of x within e. x is a free variable (define x 1) of the lambda expression. (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 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 Syntax: (lambda (x1 … xn) e) Week 1 – parameters: x1 through xn are identifiers – body: e is any expression Evaluation: 1. The result is a function closure, ⟨E, (lambda (x1 … xn) e)⟩, 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 definition, not a call. The body, e, is not evaluated now. – lambda from the λ-calculus. Lexical Scope and Function Closures 10 Function application (call) Syntax: (e0 e1 ... en) Week 1 Evaluation: 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 Syntax: (e0 e1 … en) 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 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value def (define x 1) Current evaluation step: (definedef (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 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 def (define (f y) (letdef ([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 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 (define (f y) (lambda (y) f env (let ([x (+ y 1)]) def (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) (+ x y z)) ) (define z (let ([x 3] [g (f 4)] [y 5]) def (g 6) )) Lexical Scope and Function Closures 15 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 (define (f y) (lambda (y) f env (let ([x (+ y 1)]) def (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) let (lambda (z) (+ x y z)) ) (define z (let ([x 3] [g (f 4)] [y 5]) def let (g 6) )) Lexical Scope and Function Closures 16 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 (define (f y) (lambda (y) f env (let ([x (+ y 1)]) def (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) (+ x y z)) ) x 3 (define z (let ([x 3] let [g (f 4)] [y 5]) def let (g 6) )) Lexical Scope and Function Closures 17 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 app (define (f y) (lambda (y) app f env (let ([x (+ y 1)]) def (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) (+ x y z)) ) app y 4 x 3 (define z (let ([x 3] let [g (f 4)] [y 5]) def let (g 6) )) Lexical Scope and Function Closures 18 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 (define (f y) (lambda (y) f env (let ([x (+ y 1)]) def (lambda (z) (let ([x (+ y 1)]) app (+ x y z)) ) ) (lambda (z) app (+ x y z)) ) y 4 x 3 let (define z (let ([x 3] x 5 [g (f 4)] app [y 5]) def let (g 6) )) Lexical Scope and Function Closures 19 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 (define (f y) (lambda (y) f env (let ([x (+ y 1)]) def (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) y 4 (+ x y z)) ) app x 3 let (define z (let ([x 3] x 5 [g (f 4)] app app [y 5]) def (lambda (z) env let (+ x y z)) (g 6) )) Lexical Scope and Function Closures 20 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 (define (f y) (lambda (y) f env (let ([x (+ y 1)]) def (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) (+ x y z)) ) y 4 x 3 (define z (let ([x 3] x 5 [g (f 4)] [y 5]) g def let (lambda (z) env (+ x y z)) (g 6) )) let Lexical Scope and Function Closures 21 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 (define (f y) (lambda (y) f env (let ([x (+ y 1)]) def (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) (+ x y z)) ) y 4 x 3 (define z (let ([x 3] x 5 [g (f 4)] [y 5]) g def (lambda (z) env (+ x y z)) (g 6) )) y 5 let let Lexical Scope and Function Closures 22 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 (define (f y) (lambda (y) f env (let ([x (+ y 1)]) def (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) (+ x y z)) ) y 4 app x 3 (define z (let ([x 3] x 5 [g (f 4)] [y 5]) g def (lambda (z) env (+ x y z)) (g 6) )) y 5 app let z 6 app let Lexical Scope and Function Closures 23 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 (define (f y) (lambda (y) f env (let ([x (+ y 1)]) def (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) (+ x y z)) ) y 4 x 3 (define z (let ([x 3] x 5 [g (f 4)]app [y 5]) g def (lambda (z) env (+ x y z)) (g 6) )) y 5 let z 6 app app let 15 Lexical Scope and Function Closures 24 env pointer Example: shows env structure, by pointing to “rest of environment” returning a function binding maps variable name to value (define x 1) x 1 (define (f y) (lambda (y) f env (let ([x (+ y 1)]) (lambda (z) (let ([x (+ y 1)]) (+ x y z)) ) ) (lambda (z) (+ x y z)) ) y 4 x 3 (define z (let ([x 3] x 5 [g (f 4)] g [y 5]) (lambda (z) env (+ x y z)) def (g 6) )) y 5 z 6 z 15 def Lexical Scope and Function Closures 25 Debrief 1.