slide1
Download
Skip this Video
Download Presentation
מבוא מורחב למדעי המחשב תרגול 13

Loading in 2 Seconds...

play fullscreen
1 / 29

מבוא מורחב למדעי המחשב תרגול 13 - PowerPoint PPT Presentation


  • 142 Views
  • Uploaded on

מבוא מורחב למדעי המחשב תרגול 13. Lazy Evaluation. Lazy Evaluation Implementation. Two types of values Delayed Values Actual Values Introduce two functions (actual-value exp env ) returns real value (delay-it exp env ) returns a “ thunk ”. Lazy Evaluation.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' מבוא מורחב למדעי המחשב תרגול 13' - manchu


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
lazy evaluation implementation
Lazy Evaluation Implementation
  • Two types of values
    • Delayed Values
    • Actual Values
  • Introduce two functions
    • (actual-value exp env)returns real value
    • (delay-it exp env)returns a “thunk”
lazy evaluation
Lazy Evaluation
  • Normal order - delay operands (only)
  • Special forms and compound procedures may return delayed objects
  • (l-eval exp env) may return delayed value
  • We use actual-value only if we have to, otherwise we use l-eval
  • Primitives must receive the actual value
  • Print-on-screen is actual value
lazy evaluation l eval
Lazy Evaluation – l-eval

(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))))

Compare with mc-eval:

((application? exp)

(mc-apply (mc-eval (operator exp) env)

(list-of-values (operands exp) env)))

lazy evaluation l apply
Lazy Evaluation – l-apply

(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))))

actual vs delayed values
Actual vs. Delayed Values

(define (actual-value exp env)

(force-it (l-eval exp env)))

(define (list-of-arg-values expsenv)

(if (no-operands? exps) \'()

(cons (actual-value (first-operand exps) env)

(list-of-arg-values (rest-operands exps)

env))))

(define (list-of-delayed-argsexpsenv)

(if (no-operands? exps) \'()

(cons (delay-it (first-operand exps) env)

(list-of-delayed-args (rest-operands exps)

env))))

representing thunks

thunk

exp

env

Representing Thunks
  • In our implementation we represent “Thunks” using a tagged list:
thunks abstraction
Thunks – abstraction

Constructor:

(define (delay-it exp env) (list \'thunk exp env))

Selectors:

(define (thunk? obj) (tagged-list? obj \'thunk))

(define (thunk-exp thunk) (cadrthunk))

(define (thunk-envthunk) (caddrthunk))

(define (force-it obj)

(cond ((thunk? obj)

(actual-value (thunk-exp obj)

(thunk-envobj)))

(else obj)))

lazy evaluation other changes needed
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)))

Might return

delayed values

  • 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)

No change relative to

mc-eval version!

lazy evaluation more changes
Lazy Evaluation – more changes

(define input-prompt ";;; L-Eval input:")

(define output-prompt ";;; L-Eval value:")

(define (driver-loop)

(prompt-for-input input-prompt)

(let ((input (read)))

(let ((output (actual-value

input

the-global-environment)))

(cond ((eq? output exit-object)

\'done)

(else

(announce-output output-prompt)

(user-print output)

(driver-loop))))))

lazy evaluation example
Lazy Evaluation - Example
  • What happens when this code is executed using mc-eval?
  • Can we add “unless” to the metacircular evaluator?

(define (unless condition usual exceptional)

(if condition exceptional usual))

(define (factorial n)

(unless (= n 1)

(* n (factorial (- n 1)))

1))

memoizing thunks

thunk

exp

env

evaluated-thunk

result

MemoizingThunks
  • Only evaluate Thunks once
  • Mutate our data structure when the thunk is first evaluated
thunks memoizing implementation
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-envobj))))

(set-car! obj \'evaluated-thunk)

(set-car! (cdrobj) result)

(set-cdr! (cdrobj) \'())

result))

((evaluated-thunk? obj) (thunk-value obj))

(else obj)))

timing comparison
Timing Comparison
  • How would the different implementations (mc-eval, lazy, lazy + memoization) compute the following:

(define (square x) (* x x))

(square (fib 100))

example
Example
  • What is the result of (func 1)?
  • Is it similar to evaluation with mc-eval?

(define (func x)

(define (p e)

e

x)

(p (set! x (cons x \'(2)))))

lazy and lazy memo
lazy and lazy-memo
  • We want to extend the original mc-eval:

(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.
controllably memo izing thunks

when

forced

evaluated-thunk

result

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

exp

env

a new version of delay it
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))))

changes to force it
Changes 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)))

changes to l apply
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-argsparamsarguments env)

(procedure-environment procedure)))))

(else (error "Unknown proc" procedure))))

deciding when to evaluate an argument
Deciding when to evaluate an argument...
  • Process each variable declaration together with application subexpressions – delay as necessary:

(define (list-of-delayed-argsvar-declsexpsenv)

(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))))

syntax extensions parameter declarations
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))))

exam question
Exam Question
  • Assume we have the following special form:
    • (static <variable> <value>)
  • Evaluation
    • If <variable> exists in the global environment, do nothing
    • Otherwise evaluate <value> in the current environmentand bind <variable> to the result of the evaluation in the global environment
slide24

> (define (f) (static x 1) x)

> (define (g x) (static x (* 2 2)) x)

> (g 7)

> (f)

> (set! x (+ x 1))

> (f)

7

4

5

how would the code evaluate
How would the code evaluate?

(define (id x)

(static counter 0)

(set! counter (+ counter 1))

x)

(define (foobar counter)

(id (begin (static counter 5)

(id counter))))

(foobar 10)

counter

mc eval static binding
mc-eval, static binding

GE

id:

foobar:

counter:5

/6

/7

E3

E2

E1

counter:10

x:10

p:xb:…

p:counterb:…

x:10

(foobar 10)

10

counter

7

l eval static binding
l-eval, static binding

GE

id:

foobar:

counter:0

/1

/2

E3

E1

E2

counter:10

thunk

x:

p:xb:…

p:counterb:…

(begin…)

x:10

(foobar 10)

10

counter

2

In (driver-loop):

(let ((output (actual-value

input

the-global-environment)))

mc eval dynamic binding
mc-eval, dynamic binding

GE

id:

foobar:

counter:5

E1

E2

E3

XX 11

XX 12

counter:10

x:10

x:10

p:xb:…

p:counterb:…

(foobar 10)

10

counter

5

l eval dynamic binding
l-eval, dynamic binding

GE

id:

foobar:

counter:0

E1

E2

E3

XX 11

XX 12

counter:10

thunk

x:

x:11

p:xb:…

p:counterb:…

(begin…)

(foobar 10)

11

In (driver-loop):

(let ((output (actual-value

input

the-global-environment)))

counter

0

ad