The Environment Model • an extension of the substitution model • more "operational" • fully explains static scoping and the process by which variable names are resolved in Scheme An expression only has a value with respect to an environment Binding identifier : value Frame unordered set of bindings Environment ordered list of frames x:10 y:20 z:30 +:{add} x:() w:foobar x:oh y:(list of stuff) global environment (top level frame) The Lookup Rule • the value of an identifier x is the value associated with x in the first (lowest) frame containing a binding for x • undefined if there aren't any Top-Level Define rule To evaluate (define ident expr): • evaluate expr in the current environment • add a binding to the top-level frame (the global environment) • NOTE: this is only applicable for top-level defines Set! rule To evaluate (set! ident expr): • evaluate expr in the current environment • look up ident using lookup rule • change that binding to value of expr (define d (+ 5 7)) x:10 y:20 z:30 +:{add} x:() w:foobar x:oh y:(list of stuff) (define d (+ 5 7)) x:10 y:20 z:30 +:{add} d:12 x:() w:foobar x:oh y:(list of stuff) (set! x 'my) x:10 y:20 z:30 +:{add} x:() w:foobar x:oh y:(list of stuff) (set! x 'my) x:10 y:20 z:30 +:{add} x:() w:foobar x:my y:(list of stuff) Lambda rule To evaluate (lambda (params) body) in environment env: create a function object consisting of • params • body (unevaluated) • env Example: value of (lambda (x y) (sqrt (+ (* x x) (* y y)))) in environment env is params: (x y) body: (sqrt (+ (* x x) (* y y))) env: env Eval rule To evaluate (f a1 ... an) in environment e: • evaluate f,a1,...,an in e • apply f to arguments a1,...,an Apply rule To apply f to arguments a1,...,an: • f should be a closure: list of args, body, and pointer to environment e’ • create a new frame with parameters of f bound to arguments a1,...,an • append that frame to the bottom of environment e’ in the closure of f to get e’’ • evaluate body of f in environment e’’ (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} y:200 z:300 (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} y:200 z:300 (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} y:200 z:300 x:10 (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} y:200 z:300 x:10 (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} y:200 z:300 x:10 params: (y) body: x env: (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} y:200 z:300 x:10 foo: params: (y) body: x env: (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} x:10 y:200 foo: z:300 params: (y) body: x env: (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} x:10 y:200 foo: z:300 x: 15 params: (y) body: x env: (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} x:10 y:200 foo: z:300 x: 15 params: (y) body: x env: (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} x:10 y:200 foo: z:300 x: 15 params: (y) body: x env: (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} x:10 y:200 foo: z:300 y: 20 x: 15 params: (y) body: x env: (define x 10) (define foo (lambda (y) x)) (let ((x 15)) (foo 20)) => 10 +:{add} x:10 y:200 foo: z:300 y: 20 x: 15 params: (y) body: x env:
© Copyright 2025 Paperzz