Top Banner
בבבב בבבבב בבבבב בבבבב בבבבScheme בבבבב14
67

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

Jan 20, 2016

Download

Documents

Erik

מבוא מורחב למדעי המחשב בשפת 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
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: מבוא מורחב למדעי המחשב בשפת  Scheme

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

14תרגול

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

Metacircular Evaluator

4.1, pages 362-398

definitions file on web

2

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

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

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

4

Evaluator: a program that

determines meaning of expressions

in a programming language.

Metacircular: written in the same language that it evaluates

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

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

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

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

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

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

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

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

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

Change definition

from (define x 7)

to (x := 7)

and

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

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

9

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

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

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

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

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

Adding let, let*

Rearranging as another expression

12

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

let

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

is equivalent to

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

add a syntactic transformationlet->combination

13

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

let - case in eval

((let? exp)

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

(define (let? exp)

(tagged-list? exp ‘let))

let - predicate

14

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

let - constructors

(define (make-combination

function expressions)

(cons function expressions))

15

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

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

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

let - evaluation

(define (let->combination exp)

(make-combination

(make-lambda

(let-variables exp)

(let-body exp))

(let-expressions exp)))

17

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

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

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

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

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

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

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

let* - case in eval

((let*? exp)

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

21

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

let* - constructors

(define (make-let bindings body)

(cons ‘let (cons bindings body)))

(define (make-let* bindings body)

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

22

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

let* - predicates

(define (let*? exp)

(tagged-list exp ‘let*))

(define (no-bindings? bindings)

(null? bindings))

23

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

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

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

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

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

Special forms: and, or

Direct evaluation

26

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Abstraction of frame scanning

Exercise 4.12

34

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

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)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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<

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

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

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

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

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

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

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

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

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

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)

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

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)

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

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

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

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

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

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)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

65

eval-this-env

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

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

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)

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

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)