Dynamic Assignment
Quiz:
Lexical scope: What is the output?
When p is applied, free vars in p are
bound in p's creation environment
(let ([a 3])
(let ([p (proc (x) ( + x a))]
[a 5])
(* a (p 2))))
Dynamic Scope:
When p is applied, free vars in p are
bound in p's application environment
This is DYNAMIC BINDING
A dynamic binding is extant during the evaluation
of the body associaed with the binding form.
References to a dynamically-bound variable refer
to the MOST RECENT extant binding of that variable
EASIER to IMPLEMENT
MORE DIFFICULT to REASON ABOUT
Dynamic Binding: What is the output?
(let ([a 3])
(let ([p (proc (x) ( + x a))]
[a 5])
(* a (p 2))))
(define eval-exp
(lambda (exp env)
(variant-case exp
(lit (datum) datum)
(varref (var)
(cell-ref (apply-env env var)))
(app (rator rands)
(let ((proc (eval-exp rator env))
(args (eval-rands rands env)))
(apply-proc proc args env)))
(if (test-exp then-exp else-exp)
(if (true-value?
(eval-exp test-exp env))
(eval-exp then-exp env)
(eval-exp else-exp env)))
(proc (formals body) exp)
(varassign (var exp)
(cell-set!
(apply-env env var)
(eval-exp exp env)))
(else
(error "Invalid abstract syntax:" exp)))))
(define apply-proc
(lambda (proc args current-env)
(variant-case proc
(prim-proc (prim-op)
(apply-prim-op prim-op args))
(proc (formals body)
(eval-exp body
(extend-env formals
(map make-cell args) current-env)))
(else
(error "Invalid procedure:" proc)))))
With dynamic scope, when a binding is added
to an environment, it remains in effect
(is extant) until all subsequent bindings are
removed.
This is
LIFO or stack behavior. Therefore:
instead of carrying the environment around all the
time by passing it as an argument, let's use a
global stack.
(define eval-exp
(lambda (exp)
(variant-case exp
(lit (datum) datum)
(varref (var)
(cell-ref (lookup-in-env var)))
(app (rator rands)
(let ((proc (eval-exp rator))
(args (eval-rands rands)))
(apply-proc proc args)))
(if (test-exp then-exp else-exp)
(if (true-value?
(eval-exp test-exp))
(eval-exp then-exp)
(eval-exp else-exp)))
(proc (formals body) exp)
(varassign (var exp)
(cell-set!
(lookup-in-env var) (eval-exp exp)))
(else
(error "Invalid abstract syntax:" exp)))))
(define eval-rands
(lambda (rands)
(map (lambda (exp) (eval-exp exp))
rands)))
(define apply-proc
(lambda (proc args)
(variant-case proc
(prim-proc (prim-op)
(apply-prim-op prim-op args))
(proc (formals body)
(push-env!
formals
(map make-cell args))
(let ((value (eval-exp body)))
(pop-env!)
value))
(else (error
"Invalid procedure:" proc)))))
Recursive procedures may be bound by let! no
special handling needed for recursive procedures.
However, NFL
How deep is a variable binding in the stack?
No way to tell in advance. This single stack
approach is called DEEP BINDING.
Variable referencing is inefficient with deep
binding.
Alternative:
A separate stack for each variable name?
Shallow binding.
Top binding is always the one you want. Constant
Access time.
However, when procedures have several arguments,
pushing and popping a NUMBER of stacks is less
efficient
So many tradeoffs......
With dynamic binding:
1. alpha, beta, and neta conversions
are not valid
2. Binding variables with dynamic scope has GLOBAL
effect; lexical scope has LOCAL effect
DYNAMIC ASSIGNMENT
Consider:
Assignment statements, with dynamic extent
to bindings that have lexical scope!!
(letDynamic ([var1 exp1]
[var2 exp2]
...
[varn expn])
;;;;during
body)
These assignments are valid during the evaluation
of body.
for example,
(letdynamic ([standardoutput port])
;; during
(p 1 2))
You don't have to pass procedure p the output
stream/port
In fact, you don't have to pass the output
stream/port to
procedure p OR ANY OTHER PROCEDURES THAT p MAY
CALL
Very convenient.
After all the programmer does not even need to
know if p calls any procedures that do output.
dynamic assignment is also perfect for
implementing exception handling
For example:
DURING execution of procedure foo
we would like to have an exception handler
handle divide by zero by returning a LARGE number,
the rest of the time, we want the program to
abort.
Dynamic assignment is perfect for this.
Sushil Louis
Last modified: Fri Dec 10 16:23:25 PST 1999