מבוא מורחב למדעי המחשב
Download
1 / 29

???? ????? ????? ????? ????? 13 - PowerPoint PPT Presentation


  • 143 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
13

מבוא מורחב למדעי המחשבתרגול 13

Lazy Evaluation


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


13

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