מבוא מורחב למדעי המחשב בשפת Scheme

Post on 20-Jan-2016

52 views 0 download

Tags:

description

מבוא מורחב למדעי המחשב בשפת Scheme. תרגול 14. Metacircular Evaluator. 4.1, pages 362-398 definitions file on web. 2. Overview. 1. Eval, apply 2. Change definition 3. Add let, let* 4. Add special forms and, or 5. Abstraction of frame scanning 6. More examples. 3. - PowerPoint PPT Presentation

transcript

מבוא מורחב למדעי המחשב Scheme בשפת

14תרגול

Metacircular Evaluator

4.1, pages 362-398

definitions file on web

2

Overview

1. Eval, apply

2. Change definition

3. Add let, let*

4. Add special forms and, or

5. Abstraction of frame scanning

6. More examples3

4

Evaluator: a program that

determines meaning of expressions

in a programming language.

Metacircular: written in the same language that it evaluates

Read-Eval-Print Loop

(define (driver-loop)1. PRINT PROMPT (prompt-for-input input-prompt)2. READ INPUT EXPRESSION (let ((input (read))) 3. EVALUATE EXPRESSION (let ((output (mc-eval input the-global-environment)))

…4. PRINT RESULT (user-print output)5. LOOP (driver-loop))))))

5

Eval-Apply

Mutual recursion between eval and apply

To evaluate a compound expression means to evaluate the sub-expressions recursively, then apply the operator to the arguments.

To apply a function to arguments means to evaluate the body of the function in a new environment.

6

Eval

Evaluate expression in given environment

(define (mc-eval exp env) (cond ((self-evaluating? exp) exp)… ((application? exp) (mc-apply (mc-eval (operator exp) env) (list-of-values (operands exp) env)))

The name mc-eval is used to differ from the primitive eval

7

Apply

Apply procedure to list of arguments

(define (mc-apply procedure arguments)…(eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments (procedure-environment procedure))))

The name mc-apply is used to differ from the primitive apply

8

Change definition

from (define x 7)

to (x := 7)

and

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

to ((square x) := (* x x))

9

Change eval case

from:(define (definition? exp) (tagged-list? exp 'define))

(define (tagged-list? exp tag) (if (pair? exp) (eq? (car exp) tag) false))to:(define (definition? exp) (and (pair? exp) (pair? (cdr exp)) (eq? (cadr exp) ':=)))

10

Change selectors

(define (definition-variable exp) (if (symbol? (cadr exp)) (cadr exp) (caadr exp)))

(define (definition-value exp) (if (symbol? (cadr exp)) (caddr exp) (make-lambda (cdadr exp) (cddr exp))))

(car(car

(car

(caar

(cdar

11

Adding let, let*

Rearranging as another expression

12

let

(let ((<var1> <exp1>) … (<varn> <expn>)) <body>)

is equivalent to

((lambda (<var1> … <varn>) <body>) <exp1> … <expn>)

add a syntactic transformationlet->combination

13

let - case in eval

((let? exp)

(mc-eval (let->combination exp) env))

(define (let? exp)

(tagged-list? exp ‘let))

let - predicate

14

let - constructors

(define (make-combination

function expressions)

(cons function expressions))

15

let - selectors

(define (let-bindings exp) (cadr exp))

(define (let-body exp) (cddr exp))

(define (let-variables exp) (map car (let-bindings exp)))

(define (let-expressions exp) (map cadr (let-bindings exp)))

16

let - evaluation

(define (let->combination exp)

(make-combination

(make-lambda

(let-variables exp)

(let-body exp))

(let-expressions exp)))

17

let*

The bindings of are performed sequentially.

Each binding is made in an environment inwhich all of the preceding bindings arevisible.

(let* ((x 3) (y (+ x 2)) (z (+ x y 5))) (* x z))> 39

18

let*

(let* ((<var1> <exp1>)…(<varn> <expn>))

<body>)

is equivalent to

(let ((<var1> <exp1>)) (let* ((<var2> <exp2>)… (<varn> <expn>)) <body>))

add a syntactic transformationlet*->nested-let

19

let* - example(let* ((<var1> <exp1>) (<var2> <exp2>)) <body>)=(let ((<var1> <exp1>)) (let* (<var2> <exp2>)) <body>))=(let ((<var1> <exp1>)) (let ((<var2> <exp2>)) (let* () <body>)))=(let ((<var1> <exp1>)) (let ((<var2> <exp2>)) (let () <body>)))

20

let* - case in eval

((let*? exp)

(mc-eval (let*->nested-let exp) env))

21

let* - constructors

(define (make-let bindings body)

(cons ‘let (cons bindings body)))

(define (make-let* bindings body)

(cons ‘let* (cons bindings body)))

22

let* - predicates

(define (let*? exp)

(tagged-list exp ‘let*))

(define (no-bindings? bindings)

(null? bindings))

23

let* - selectors

(define (let*-bindings exp) (cadr exp))

(define (let*-body exp) (cddr exp))

(define (let*-first-binding bindings)

(car bindings))

(define (let*-rest-bindings bindings)

(cdr bindings))

24

let* - evaluation

(define (let*->nested-let exp)

(if (no-bindings? (let*-bindings exp))

(make-let

(let*-bindings exp)

(let*-body exp))

(make-let

(list (let*-first-binding

(let*-bindings exp)) ; ((v1 e1))

(make-let*

(let*-rest-bindings (let*-bindings exp))

(let*-body exp))))

25

Special forms: and, or

Direct evaluation

26

and, or - cases in eval

(define (mc-eval exp env) (cond ((self-evaluating? exp) exp)…((and? exp) (eval-and (and-exps exp) env))((or? exp) (eval-or (or-exps exp) env))

((application? exp) (mc-apply (mc-eval (operator exp) env) (list-of-values (operands exp) env)))

27

and, or - predicates

(define (and? exp) (tagged-list? exp ‘and))

(define (or? exp) (tagged-list? exp ‘or))

(define (no-exps? exps) (null? exps))

(define (last-exp? exps) (null? (cdr exps)))

28

and, or - selectors

(define (and-exps exp) (cdr exp))

(define (or-exps exp) (cdr exp))

(define (first-exp exps) (car exps))

(define (rest-exps exps) (cdr exps))

29

and - evaluation

from left to right

Evaluation Return value

Any expression evaluates to false

false

All expressions evaluate to true

value of last expression

No expressions true

and - evaluation

(define (eval-and exps env) (if (no-exps? exps) true (let ((first (mc-eval (first-exp exps) env)))

(if (false? first) false (if (last-exp? exps) first (eval-and (rest-exps exps) env)))))

31

or - evaluation

from left to right

32

Evaluation Return value

Any expression evaluates to true

value of last expression

All expressions evaluate to false

false

No expressions false

or - evaluation

(define (eval-or exps env) (if (no-exps? exps) false (let ((first (mc-eval (first-exp exps) env)))

(if (true? first) first ;(if (last-exp? exps) false (eval-or (rest-exps exps) env)))))

33

Abstraction of frame scanning

Exercise 4.12

34

35

Frames

A frame is a set of bindings, represented as a pair of two lists: variables and values

Constructor(make-frame variables values)Selectors(frame-variables frame)(frame-values frame)Mutator(add-binding-to-frame! var val frame)

36

EnvironmentsAn environment consists of its first frame and an enclosing

environment

Constructor(extend-environment vars vals base-env)Selectors (first-frame env)(enclosing-environment env)Predefined environmentsthe-global-environmentthe-empty-environment

37

Frame Scanning

Performed by:• lookup-variable-value

invoked when evaluating names• set-variable-value!

invoked when evaluating set! expressions• define-value!

invoked when evaluating definitions

38

lookup-variable-value(define (lookup-variable-value var env) (define (env-loop env) (define (scan vars vals) (cond ((null? vars) (env-loop (enclosing-environment env))) ((eq? var (car vars)) (car vals)) (else (scan (cdr vars) (cdr vals))))) (if (eq? env the-empty-environment) (error "Unbound variable" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env))

39

set-variable-value!(define (set-variable-value! var val env) (define (env-loop env) (define (scan vars vals) (cond ((null? vars) (env-loop (enclosing-environment env))) ((eq? var (car vars)) (set-car! vals val)) (else (scan (cdr vars) (cdr vals))))) (if (eq? env the-empty-environment) (error "Unbound variable -- SET!" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env))

40

define-variable!(define (define-variable! var val env) (let ((frame (first-frame env))) (define (scan vars vals) (cond ((null? vars) (add-binding-to-frame! var val frame)) ((eq? var (car vars)) (set-car! vals val)) (else (scan (cdr vars) (cdr vals))))) (scan (frame-variables frame) (frame-values frame))))

41

All procedures are alike!

• Scan the frame for the variable’s name– If found, success operation

(return value / set value)– If not in frame, failure operation

(continue to next frame / add binding)

• Error on empty environment (if this can happen)

• We can get better abstraction– Capturing common patterns– Hiding frame scanning / mutation

42

Generic frame scan

(define (scan-first-frame var env succeed fail)

(define (scan vars vals)

(cond ((null? vars)

(fail))

((eq? var (car vars))

(succeed vals))

(else (scan (cdr vars) (cdr vals)))))

(if (eq? env the-empty-environment)

(error "Unbound variable" var)

(let ((frame (first-frame env)))

(scan (frame-variables frame)

(frame-values frame)))))

43

lookup-variable-value

(define (lookup-variable-value var env)

(define (succeed vals)

(get-binding-value vals))

(define (fail)

(scan-first-frame

var (enclosing-environment env) succeed fail))

(scan-first-frame var env succeed fail))

(define (get-binding-value vals)

(car vals))

44

set-variable-value!

(define (set-variable-value! var val env)

(define (succeed vals)

(set-binding-value! vals val))

(define (fail)

(scan-first-frame

var (enclosing-environment env) succeed fail))

(scan-first-frame var env succeed fail))

(define (set-binding-value! vals val)

(set-car! vals val))

45

define-variable!

(define (define-variable! var val env)

(define (succeed vals)

(set-binding-value! vals val))

(define (fail)

(add-binding-to-frame! var val (first-frame env))) (scan-first-frame var env succeed fail))

46

Example: if>=<

Format: (if>=< exp1 exp2 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<

47

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

48

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

49

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

50

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

51

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)

52

Example

(define x 2)

(define (f y) (+ x y))

(define (make-env x) (this-env))

GE

x:2

f: make-env

p: y

b: (+ x y)

p: x

b: (this-env)

53

(define env1 (make-env 3))

GE

x:2

f: env1 make-env

p: y

b: (+ x y)

p: x

b: (this-env)

E1

x:3

Example (cont.)

54

(set-env! f env1)

GE

x:2

f: env1 make-env

p: y

b: (+ x y)

p: x

b: (this-env)

E1

x:3

Example (cont.)

55

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)

56

(f 5)

GE

x:2

f: env1 make-env

p: y

b: (+ x y)

p: x

b: (this-env)

E1

x:3

E2

y:5

Solution

57

(mystery f)

GE

x:2

f: env1 make-env mystery:

E1

x:3

E2

y:5

E3

g:

aux:E4

x:1

y:4

Solution (cont.)

58

(f 5)

GE

x:2

f: env1 make-env mystery:

E1

x:3

E2

y:5

E3

g:

aux:E4

x:1

y:4E5

y:5

Solution (cont.)

59

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

60

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

61

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

62

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

63

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

64

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

65

eval-this-env

eval-this-env is simply:(define (eval-this-env exp env) env)

66

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)

67

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)