330 likes | 345 Views
מבוא מורחב למדעי המחשב בשפת Scheme. תרגול 2 1. Overview. 1. Dynamic Binding 2. Lazy Evaluation 3. More MC-Eval. 2. Dynamic vs. Static Binding. ( define (factorial n) (if (= n 1) 1 (* n (factorial (- n 1))))) Draw environments in static and dynamic binding for (factorial 5)
E N D
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 21
Overview • 1. Dynamic Binding • 2. Lazy Evaluation • 3. More MC-Eval 2
Dynamic vs. Static Binding • (define (factorial n) • (if (= n 1) 1 • (* n (factorial (- n 1))))) • Draw environments in static and dynamic binding for (factorial 5) • What is the maximal number of environments that the ‘*’ operator is looked for (in one search)? • (Appeared on a final exam)
Variations on a Scheme: dynamic MCE Lexical (static) binding Free variables are searched in the surrounding lexical environment Dynamic binding Free variables are searched in calling procedures.
GE factorial: n:5 n:4 n:3 n:2 n:1 p: n b: (if (= n 1) 1…) Static binding
GE factorial: n:5 n:4 n:3 p: n b: (if (= n 1) 1…) n:2 n:1 Dynamic binding
Example: if>=< • Format: (if>=< exp1exp2 if> if= if<) • exp1 and exp2 evaluate to numerical values • if exp1>exp2 evaluate and return if> • if exp1=exp2 evaluate and return if= • otherwise, evaluate and return if<
Predicate and Selectors • (define (if>=<? exp) • (tagged-list? exp ‘if>=<)) • (define (if>=<exp1 exp) (cadr exp)) • (define (if>=<exp2 exp) (caddr exp)) • (define (if> exp) (cadddr exp)) • (define (if= exp) (list-ref exp 4)) • (define (if< exp) (list-ref exp 5))
mc-eval implementation • (define (eval-if>=< exp env) • (let ((exp1 (mc-eval (if>=<exp1 exp) env)) • (exp2 (mc-eval (if>=<exp2 exp) env)) • (cond ((> exp1 exp2) • (mc-eval (if> exp) env)) • ((= exp1 exp2) • (mc-eval (if= exp) env)) • (else (mc-eval (if< exp) env)))))
Lazy Evaluation • Normal order - delay operands (only) • Special forms and compound procedures may return delayed objects • Primitives must receive the actual value • Print-on-screen is actual value • (l-eval exp env) may return delayed value • (actual-value exp env) returns real value • We use actual-value only if we have to, otherwise we use l-eval
delayed if>=< • (define (eval-if>=< exp env) • (let ((exp1 (actual-value (if>=<exp1 exp) env)) • (exp2 (actual-value (if>=<exp2 exp) env)) • (cond ((> exp1 exp2) • (l-eval (if> exp) env)) • ((= exp1 exp2) • (l-eval (if= exp) env)) • (else (l-eval (if< exp) env)))))
Example • In mc-eval • (define count 0) • (define (id x) (set! count (+ count 1)) x) • (define w (id (id 10))) • count • w • count 2 10 2
Example (cont.) In l-eval (define count 0) (define (id x) (set! count (+ count 1)) x) (define w (id (id 10))) count w count 1 10 2
delay and memoization • (define (square x) (* x x)) • (define count 0) • (define (id x) (set! count (+ count 1)) x) • (square (id 10)) ? • count ?
Practice Question • When a procedure with no parameters is applied, an empty frame is opened • Change the MCE code such that parameter-less procedures will be applied in the parent environment • Is the modified evaluator equivalent to the original one? Explain or give a contradicting example
Modification to apply • (define (mc-apply procedure arguments) • (cond ((primitive-procedure? procedure) • (apply-primitive-procedure procedure arguments)) • ((compound-procedure? procedure) • (eval-sequence • (procedure-body procedure) • (extend-environment • (procedure-parameters procedure) • arguments • (procedure-environment procedure)))) • (else (error ….)))) (if (null? (procedure-parameters procedure)) (eval-sequence (procedure-body procedure) (procedure-environment procedure)) )
Practice Question • Suppose we can manipulate environments as if they were data types, using the following imaginary special forms: • (this-env) • (get-env proc) • (set-env! proc env)
GE x:2 f: make-env p: y b: (+ x y) p: x b: (this-env) Example (define x 2) (define (f y) (+ x y)) (define (make-env x) (this-env))
GE x:2 f: env1 make-env E1 x:3 p: y b: (+ x y) p: x b: (this-env) Example (cont.) (define env1 (make-env 3))
GE x:2 f: env1 make-env p: y b: (+ x y) p: x b: (this-env) Example (cont.) E1 x:3 (set-env! f env1)
Section A • What will evaluating the following code return? • Apply changes to the env. diagram. • (f 5) • (define (mystery g) • (define (aux x y) • (set-env! g (this-env))) • (aux 1 4)) • (mystery f) • (f 5)
GE x:2 f: env1 make-env E1 x:3 p: y b: (+ x y) p: x b: (this-env) Solution E2 y:5 (f 5)
E3 g: aux: E4 x:1 y:4 Solution (cont.) GE x:2 f: env1 make-env mystery: E1 x:3 E2 y:5 (mystery f)
E3 g: aux: E4 x:1 y:4 Solution (cont.) GE x:2 f: env1 make-env mystery: E1 x:3 E2 y:5 (f 5) E5 y:5
Section B • Complete(call-from-env proc vars env) • which applies proc on vars from environment env, instead of proc’s original environment • When returning, proc’s environment is restored to its original environment
Code • (define (call-from-env proc vars env • (let ((original-env )) • ? • (let ((result )) • ? • ?))) (get-env proc) (set-env! proc env) (apply proc vars) (set-env! proc original-env) result
Section C,D,E • Add support for this-env, get-env and set-env! in the mc-eval • The representation of an environment is the interior data structure inside the evaluator • Relaxation: In set-env! you may assume that the proc operand is evaluated to a compound (not primitive) procedure
mc-eval additions • Add in mc-eval: • ((this-env? exp) (eval-this-env exp env)) • ((get-env? exp) (eval-get-env exp env)) • ((set-env? exp) (eval-set-env exp env))
Predicates • (define (this-env? exp) • ) • (define (get-env? exp) • ) • (define (set-env? exp) • ) (tagged-list? exp ‘this-env) (tagged-list? exp ‘get-env) (tagged-list? exp ‘set-env!)
Selectors • (this-env) • no selectors • (get-env proc) • (define (get-env-proc exp) (cadr exp)) • (set-env! proc env) • (define (set-env-proc exp) (cadr exp)) • (define (set-env-env exp) (caddr exp))
eval-this-env • eval-this-env is simply: • (define (eval-this-env exp env) env)
eval-get-env • (define (eval-get-env exp env) • (let ((proc _______________________________)) • (if (primitive-procedure? proc) • _______________________________ • _______________________________ ))) (mc-eval (get-env-proc exp) env) the-global-environment (procedure-environment proc)
eval-set-env • (define (eval-set-env exp env) • (let ((proc • ________________________________ ) • (new-env • ________________________________ )) • __________________________________ )) • Reminder: a compound procedure is represented by: • (list ‘procedure parameters body env) (mc-eval (set-env-proc exp) env) (mc-eval (set-env-env exp) env) (set-car! (cdddr proc) new-env)