{add} y:20 z:30 x

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: