Review: Dynamic Scoping - PowerPoint PPT Presentation

1 / 35
About This Presentation
Title:

Review: Dynamic Scoping

Description:

Review: Dynamic Scoping. Today: Lazy Evaluation (4.2.1, 4.2.2) 2. Last lecture: Lexical Scoping ... (define (first-variable var-decls) (car var-decls) ... – PowerPoint PPT presentation

Number of Views:80
Avg rating:3.0/5.0
Slides: 36
Provided by: duaneb3
Category:

less

Transcript and Presenter's Notes

Title: Review: Dynamic Scoping


1
Lecture 20
  • Review Dynamic Scoping
  • Today Lazy Evaluation (4.2.1, 4.2.2)

2
Last lecture Lexical Scoping
Free variables in an application of procedure f
get their values from the procedure where f was
defined (by the appropriate lambda special
form). Also called static binding
3
Lexical Scoping Environment Diagram
(define (foo x y) (lambda (z) ( x y z)))
Will always evaluate ( x y z) in a new
environment inside the surrounding lexical
environment.
(define bar (foo 1 2))
(bar 3)
4
Alternative Model Dynamic Scoping
  • Dynamic scope
  • Look up free variables in the caller's
    environment rather than the surrounding lexical
    environment
  • Example
  • (define x 11)
  • (define bear (lambda (y)
  • ( x y)))
  • (define (p x)
  • (bear 20))
  • (p 9) gt 29

5
Dynamic Scoping Environment Diagram
(define x 11)
(define (p x) (bear 20))
Will evaluate ( x y) in an environment that
extendsthe caller's environment.
(define (bear y) ( x y))
(p 9)
x11
( x y) E2gt 29
6
A "Dynamic" Version of Scheme
  • (define (d-eval exp env)
  • (cond
  • ((self-evaluating? exp) exp)
  • ((variable? exp) (lookup-variable-value exp
    env))
  • ...
  • ((lambda? exp)
  • (make-procedure (lambda-parameters exp)
  • (lambda-body exp)
  • 'no-environment)) CHANGE no env
  • ...
  • ((application? exp)
  • (d-apply (d-eval (operator exp) env)
  • (list-of-values (operands exp) env)
  • env)) CHANGE add env
  • (else (error "Unknown expression -- M-EVAL"
    exp))))

7
A "Dynamic" Scheme d-apply
  • (define (d-apply procedure arguments calling-env)
  • (cond ((primitive-procedure? procedure)
  • (apply-primitive-procedure procedure
  • arguments))
  • ((compound-procedure? procedure)
  • (eval-sequence
  • (procedure-body procedure)
  • (extend-environment
  • (procedure-parameters procedure)
  • arguments
  • calling-env))) CHANGE use calling
    env
  • (else (error "Unknown procedure"
    procedure))))

8
Implement lazy evaluation
  • Beyond Scheme designing language variants
  • Lazy evaluation
  • Complete conversion normal order evaluator
  • Upward compatible extension lazy, lazy-memo

9
Normal Order (Lazy) Evaluation
  • Alternative models for computation
  • Applicative Order
  • evaluate all arguments, then apply operator
  • Normal Order
  • go ahead and apply operator with unevaluated
    argument subexpressions
  • evaluate a subexpression only when value is
    needed
  • to print
  • by primitive procedure

10
Limitations of Applicative Order Evaluation
  • Suppose we wanted to create
  • (define (unless condition usual-value
    exceptional-value)
  • (if condition exceptional-value
    usual-value))
  • Which can be used in expressions such as
  • (unless ( b 0)
  • (/ a b)
  • (begin (display "exception returning 0")
  • 0))
  • This won't work in an applicative-order language!
  • But Will work with Lazy Evaluation!

11
Strict vs. Non-Strict Arguments
  • If the body of a procedure is entered before an
    argument has been evaluated we say that the
    procedure is non-strict in that argument.
  • If the argument is evaluated before the body of
    the procedure is entered we say that the
    procedure is strict in that argument.
  • Applicative order strict in all arguments.
  • Normal order strict in arguments only in
  • primitive procedures.

12
How to Implement Lazy Evaluation
(define (foo x y)( x y))
Eval will not evaluate the parameters passed to
apply!
(foo ( 1 2) ( 3 4))
How are these delayed parameters passed? Via the
binding in the extended environment E1!
13
How can we implement lazy evaluation?
  • (define (l-apply procedure arguments env)
    changed
  • (cond ((primitive-procedure? procedure)
  • (apply-primitive-procedure
  • procedure
  • (list-of-arg-values arguments env)))
  • ((compound-procedure? procedure)
  • (l-eval-sequence
  • (procedure-body procedure)
  • (extend-environment
  • (procedure-parameters procedure)
  • (list-of-delayed-args arguments env)
  • (procedure-environment procedure))))
  • (else (error "Unknown proc" procedure))))

14
Lazy Evaluation l-eval
  • Most of the work is in l-apply need to call it
    with
  • actual value for the operator
  • just expressions for the operands
  • the environment...
  • (define (l-eval exp env)
  • (cond ((self-evaluating? exp) exp)
  • ...
  • ((application? exp
  • (l-apply (actual-value (operator exp)
    env)
  • (operands exp)
  • env))
  • (else (error "Unknown expression" exp))))

15
Actual vs. Delayed Values
  • (define (actual-value exp env)
  • (force-it (l-eval exp env)))

(define (list-of-arg-values exps env) (if
(no-operands? exps) '() (cons (actual-value
(first-operand exps) env)
(list-of-arg-values (rest-operands exps)
env))))
(define (list-of-delayed-args exps env) (if
(no-operands? exps) '() (cons (delay-it
(first-operand exps) env)
(list-of-delayed-args (rest-operands exps)
env))))
16
Representing Thunks
  • Abstractly a thunk is a "promise" to return a
    value when later needed ("forced")

17
Thunks delay-it and force-it
  • (define (delay-it exp env) (list 'thunk exp env))
  • (define (thunk? obj) (tagged-list? obj 'thunk))
  • (define (thunk-exp thunk) (cadr thunk))
  • (define (thunk-env thunk) (caddr thunk))

(define (force-it obj) (cond ((thunk? obj)
(actual-value (thunk-exp obj)
(thunk-env obj))) (else obj)))
(define (actual-value exp env) (force-it
(l-eval exp env)))
18
Lazy Evaluation other changes needed
  • Example need actual predicate value in
    conditional if...
  • (define (l-eval-if exp env)
  • (if (true? (actual-value (if-predicate exp)
    env))
  • (l-eval (if-consequent exp) env)
  • (l-eval (if-alternative exp) env)))
  • Example don't need actual value in
    assignment...
  • (define (l-eval-assignment exp env)
  • (set-variable-value!
  • (assignment-variable exp)
  • (l-eval (assignment-value exp) env)
  • env)
  • 'ok)

19
(l-eval ((lambda (x) ( x x) ) ( 1 1))
GE) (l-apply (actual-value (lambda (x) ( x x))
GE) ((1 1 )) GE) (force-it (l-eval (lambda
(x) ( x x)) GE)) (procedure (x) (( x x))
GE) (l-apply (procedure (x) ( x x) GE) ((1
1 )) GE) (l-eval ( x x) E1)
(l-apply (actual-value E1) (x x) E1) (l-apply
(primitive add) (x x) E1) (apply-primitive-pr
ocedure (primitive add)
(actual-value x E1)(actual-value x E1)
) (force-it (l-eval x E1)) (force-it (thunk
( 1 1) GE)) (actual-value ( 1 1)
GE) (force-it (l-eval ( 1 1) GE)) gt 2
20
(l-eval (define f (lambda (x y) x))
GE) (eval-definition (define f (lambda (x y) x))
GE) (define-variable! f (l-eval (lambda (x y)
x) GE) GE)
21
(l-eval (f 1 1) GE) (l-apply (actual-value f
GE) (1 1) GE) (force-it (l-eval f GE)) gt
(procedure (x y) (x) GE) (l-apply (procedure
(x y) (x) GE) (1 1) GE) (l-eval x E1)
gt (thunk 1 GE)
22
(l-eval (f (f 1 1) 1) GE) (l-apply
(actual-value f GE) ((f 1 1) 1)
GE) (force-it (l-eval f GE)) (procedure (x y)
(x) GE) (l-apply (procedure (x y) (x) GE)
((f 1 1) 1) GE) (l-eval x E1)
gt (thunk (f 1 1) GE)
Lets force this thunk ..
23
(force-it (thunk (f 1 1) GE)) (actual-value (f
1 1) GE) (force-it (l-eval (f 1 1) GE))
(force-it (l-apply (actual-value f GE)
(1 1) GE)) (force-it (thunk 1
GE)) (actual-value 1 GE) (force-it (l-eval 1
GE)) gt 1
24
Memo-izing Thunks
  • Idea once thunk exp has been evaluated, remember
    it
  • If value is needed again, just return it rather
    than recompute
  • Concretely mutate a thunk into an
    evaluated-thunk

25
Thunks Memoizing Implementation
  • (define (evaluated-thunk? obj)
  • (tagged-list? obj 'evaluated-thunk))
  • (define (thunk-value evaluated-thunk)
  • (cadr evaluated-thunk))

(define (force-it obj) (cond ((thunk? obj)
(let ((result (actual-value (thunk-exp obj)
(thunk-env
obj)))) (set-car! obj
'evaluated-thunk) (set-car! (cdr obj)
result) (set-cdr! (cdr obj) '())
result)) ((evaluated-thunk? obj)
(thunk-value obj)) (else obj)))
26
Laziness and Language Design
  • We have a dilemma with lazy evaluation
  • Advantage only do work when value actually
    needed
  • Disadvantages
  • not sure when expression will be evaluated can
    be very big issue in a language with side effects
  • may evaluate same expression more than once
  • Memoization doesn't fully resolve our dilemma
  • Advantage Evaluate expression at most once
  • Disadvantage What if we want evaluation on each
    use?
  • Alternative approach give programmer control!

27
Variable Declarations lazy and lazy-memo
  • We want to extend the language as follows
  • (lambda (a (b lazy) c (d lazy-memo)) ...)
  • "a", "c" are strict variables (evaluated before
    procedure application
  • "b" is lazy it gets (re)-evaluated each time its
    value is actually needed
  • "d" is lazy-memo it gets evaluated the first
    time its value is needed, and then that value is
    returned again any other time it is needed again.

28
Controllably Memo-izing Thunks
  • thunk never gets memoized
  • thunk-memo first eval is remembered
  • evaluated-thunk memoized-thunk that has
    already been evaluated

Thunk Memo
env
exp
29
A new version of delay-it
  • Look at the variable declaration to do the right
    thing...
  • (define (delay-it decl exp env)
  • (cond ((not (declaration? decl))
  • (l-eval exp env))
  • ((lazy? decl)
  • (list 'thunk exp env))
  • ((memo? decl)
  • (list 'thunk-memo exp env))
  • (else (error "unknown declaration" decl))))

30
Change to force-it
  • (define (force-it obj)
  • (cond ((thunk? obj) eval, but don't remember
    it
  • (actual-value (thunk-exp obj)
  • (thunk-env obj)))
  • ((memoized-thunk? obj) eval and remember
  • (let ((result
  • (actual-value (thunk-exp obj)
  • (thunk-env obj))))
  • (set-car! obj 'evaluated-thunk)
  • (set-car! (cdr obj) result)
  • (set-cdr! (cdr obj) '())
  • result))
  • ((evaluated-thunk? obj) (thunk-value obj))
  • (else obj)))

31
Changes to l-apply
  • Key in l-apply, only delay "lazy" or "lazy-memo"
    params
  • make thunks for "lazy" parameters
  • make memoized-thunks for "lazy-memo" parameters

(define (l-apply procedure arguments env) (cond
((primitive-procedure? procedure) ...)
as before apply on list-of-arg-values
((compound-procedure? procedure)
(l-eval-sequence (procedure-body
procedure) (let ((params (procedure-parameters
procedure))) (extend-environment
(map parameter-name params)
(list-of-delayed-args params arguments env)
(procedure-environment procedure)))))
(else (error "Unknown proc" procedure))))
32
Deciding when to evaluate an argument...
  • Process each variable declaration together with
    application subexpressions delay as necessary
  • (define (list-of-delayed-args var-decls exps env)
  • (if (no-operands? exps)
  • '()
  • (cons (delay-it (first-variable var-decls)
  • (first-operand exps)
  • env)
  • (list-of-delayed-args
  • (rest-variables var-decls)
  • (rest-operands exps)
    env))))

33
Syntax Extensions Parameter Declarations
  • (define (first-variable var-decls) (car
    var-decls))
  • (define (rest-variables var-decls) (cdr
    var-decls))
  • (define declaration? pair?)
  • (define (parameter-name var-decl)
  • (if (pair? var-decl) (car var-decl) var-decl))
  • (define (lazy? var-decl)
  • (and (pair? var-decl) (eq? 'lazy (cadr
    var-decl))))
  • (define (memo? var-decl)
  • (and (pair? var-decl)
  • (eq? 'lazy-memo (cadr var-decl))))

34
Summary
  • Lazy evaluation control over evaluation models
  • Convert entire language to normal order
  • Upward compatible extension
  • lazy lazy-memo parameter declarations

35
How do we use this new lazy evaluation?
  • Our users could implement a stream abstraction
  • (define (cons-stream x (y lazy-memo))
  • (lambda (msg)
  • (cond ((eq? msg 'stream-car) x)
  • ((eq? msg 'stream-cdr) y)
  • (else (error "unknown stream msg"
    msg)))))
  • (define (stream-car s) (s 'stream-car))
  • (define (stream-cdr s) (s 'stream-cdr))
Write a Comment
User Comments (0)
About PowerShow.com