Top Banner
1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can be utilized to gain further improvements that cannot be achieved using the substitution model (The analyzer/compiler) model evaluator: Motivation
25

1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

Dec 24, 2015

Download

Documents

Hilary Pierce
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: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

1

• Saves repeated renaming and substitution: explicit substitution is replaced by variable

bindings using new data structures (frame, environment).

• Can be utilized to gain further improvements that cannot be achieved using the

substitution model (The analyzer/compiler)

Env. model evaluator: Motivation

Page 2: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

Env. model evaluator: Structure and implementation

Data Structures:

• New data structures: frame, environment

• Additional procedures are added to handle the new ADTs

• A closure keeps the Env in which it was created.

• Renaming and substitution are no longer needed!

ASPASP

Derived expressions

Derived expressions

TestTest

Data structuresData structures

UtilsA racket lib

UtilsA racket lib

• Proc / Primitive-Proc.• Global Environment.

• Op. semantics(evaluation rules)• Special forms

• ADT per expressions• An abstraction barrier• Used by all evaluators

<Scheme-expression>

ParserParser

<AST>

substitutionsubstitution

valuesvalues

CoreCore

Page 3: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

Env. model evaluator: Structure and implementation

ASPASP

Derived expressions

Derived expressions

TestTest

Data structuresData structures

UtilsA racket lib

UtilsA racket lib

• Proc / Primitive-Proc.• Global Environment.

• Op. semantics(evaluation rules)• Special forms

• ADT per expressions• An abstraction barrier• Used by all evaluators

<Scheme-expression>

ParserParser

<AST>

substitutionsubstitution

valuesvalues

CoreCore

Core:• Procedure application (apply procedure) and evaluation of

expressions are done with respect to a certain environment.

Tests:

• Updated accordingly.

Page 4: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

4

Env. model evaluator: Structure and implementation

Box, unbox:

• The global environment may change (E.g., by definitions).

• Values that may change should be boxed (similar to pointers).

#<primitive:+>+Binding: implemented as a Pair

• A correspondence between a variable and its value.

‘((x foo) (4 <procedure (x) x>))

• A substitution from variables to values. Each variable is bound to a single value.

Frame: Implemented as a substitution

Page 5: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

5

Environment: Implemented as a list of boxed frames

• A finite sequence of frames in which the last frames is the-global-environment.

Env. model evaluator: Structure and implementation

E1

box-pointer diagram:

frame

t-g-e

‘((foo …) ( ))

‘((+ - …) (prim+ prim- …))

box box

proc params body

frame

E2

E3

Page 6: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

6

Env. model evaluator: Evaluation examples

(define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env)) ((application? exp) (apply-procedure (env-eval (operator exp) env) (list-of-values (operands exp) env))) (else (error 'eval "unknown expression type: ~s" exp)))))

Reminder: env-eval (interpreter-core.rkt)

Page 7: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

7

Env. model evaluator: Evaluation examples

1. Evaluating a definition expression:

(define eval-special-form (lambda (exp env) (cond ... ((definition? exp) (if (not (eq? env t-g-e)) (error 'eval "non global definition: ~s" exp) (eval-definition exp))) ...)))

(define eval-definition (lambda (exp) (add-binding! (make-binding (definition-variable exp)

(env-eval (definition-value exp) t-g-e))) 'ok))

(define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env)) ...)))

> (env-eval (derive '(define f (lambda (x) (lambda (y) (+ x y))))) t-g-e)

Page 8: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

8

Env. model evaluator: Evaluation examples

(define eval-special-form (lambda (exp env) (cond ... ((lambda? exp) (eval-lambda exp env)) ...)))

> (env-eval (derive '(define f (lambda (x) (lambda (y) (+ x y))))) t-g-e)

(define eval-lambda (lambda (exp env) (make-procedure (lambda-parameters exp) (lambda-body exp) env)))

(define make-procedure (lambda (parameters body env) (attach-tag (list parameters body env) 'procedure)))

(make-procedure '(x) '(lambda (y) (+ x y)) t-g-e)

P: xB: (lambda (y) (+ x y))

t-g-e

1. Evaluating a definition expression:

Textual annotation:<procedure (x) (lambda (y) (+ x y))>@t-g-e

Page 9: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

9

Env. model evaluator: Evaluation examples

> (env-eval (derive '(define f (lambda (x) (lambda (y) (+ x y))))) t-g-e)

(add-binding! (make-binding ‘f <procedure (x) (lambda (y) (+ x y))>@t-g-e))

1. Evaluating a definition expression:

(define eval-special-form (lambda (exp env) (cond ... ((definition? exp) (if (not (eq? env t-g-e)) (error 'eval "non global definition: ~s" exp) (eval-definition exp))) ...)))

(define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env)) ...)))

(define eval-definition (lambda (exp) (add-binding! (make-binding (definition-variable exp)

(env-eval (definition-value exp) t-g-e))) 'ok)) Done!

Page 10: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

10

Env. model evaluator: Evaluation examples

2. Evaluating a user procedure:

(define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env)) ...)))

> (derive-eval 'f)

(define eval-atomic (lambda (exp env) (if (or (number? exp) (boolean? exp) (null? exp)) exp (lookup-variable-value exp env))))

> <procedure (x) (lambda (y) (+ x y))>@t-g-e

Page 11: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

x: 1

GE

11

Env. model evaluator: Evaluation examples

3. Evaluating an application of a user procedure:

> (derive-eval '(define g (f 1)) )

(apply-procedure <procedure (x) (lambda (y) (+ x y))>@t-g-e (1))

Create a new frame where x maps to 1(make-frame ‘(x) ‘(1))

Extend the environment(extend-env new-frame t-g-e)

Evaluate the body(eval-sequence body new-env)

Page 12: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

12

• Can be regarded as a nested let expression.

• Similar to let, but each defined variable can be used in subsequent definitions.

> (let ((a 1) (c (* a 2))) (+ a c))

> (define a 10)

Env. model evaluator: Supporting let*

Reminder: What is a let* expression?

Example:

> (let* ((a 1) (c (* a 2))) (+ a c))

> (let ((a 1)) (let ((c (* a 2))) (+ a c)))

> ((λ (a) ((λ (c) (+ a c)) (* a 2)) 1)

> 3

= =

> 21

Page 13: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

13

An expression (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm),

with respect to environment E0, is defined as follows:

E1 E0 * make-frame [(v1),(env-eval e1 E0)]E2 E1 * make-frame [(v2),(env-eval e2 E1)]...En En-1* make-frame [(vn),(env-eval en En-1)]

(env-eval b1 En) ... (env-eval bm-1 En)

Return (env-eval bm En)

Q: How would the evaluation rule for let look like?

A: e1…en will be evaluated with respect to E0. A new frame mapping (v1…vn) to (e1…en)

will extend E0, creating a new environment, E1.

Evaluation rule for a let* expression:

Env. model evaluator: Supporting let*

Page 14: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

14

Env. model evaluator: Supporting let* - as a derived expression

1. Add the required ADT procedures to the ASP

(let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

ASPASP

Derived expressions

Derived expressions

CoreCoreData structures

Data structures

(define let*? (lambda (exp) (tagged-by? exp 'let*)))

(define let*-initial-values (lambda (exp) (map cadr (let*-bindings exp))))

(define let*-bindings (lambda (exp) (car (get-content exp))))(define let*-body (lambda (exp) (cdr (get-content exp))))(define let*-variables (lambda (exp) (map car (let*-bindings exp))))

(define make-let* (lambda (bindings body) (attach-tag (cons bindings body) 'let*)))(define (let*-first-variable exp) (caar (let*-bindings exp)))

(define (let*-first-initial-value exp) (cadar (let*-bindings exp)))

(define (make-let*-bindings vars vals) (map list vars vals))

Page 15: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

15

Env. model evaluator: Supporting let* - as a derived expression

2. Modify the procedure derived?(define (derived? exp) (or (cond? exp) (function-definition? exp) (let? exp) (let*? exp)))

(define (shallow-derive exp) (cond ((cond? exp) (cond->if exp)) ... ((let*? exp) (let*->nested-let exp)) (else (error "Unhandled " exp))))

3. Modify the procedure shallow-derive

(let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

ASPASP

Derived expressions

Derived expressions

CoreCoreData structures

Data structures

Page 16: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

16

Env. model evaluator: Supporting let* - as a derived expression

Q: The result is a let exp. Shouldn’t it be further derived?

A: Nah, derive recursively calls itself until the result exp does not change.

Q: What about the let* expression created by make-let*?

A: Nope. derive is recursively called for all sub expressions.

Q: When the if-condition does not hold, we wrap the body parameter in a list. Why?

A: Since the body of a let expression may consist of several expressions.

4. Add a translation procedure let*->nested-let (define (let*->nested-let exp) (let ((bindings (let*-bindings exp)) (body (let*-body exp))) (if (null? bindings) (make-lambda '() body) (if (null? (cdr bindings)) (make-let bindings body) ;dit (make-let ;dif (make-let*-bindings (list (let*-first-variable exp)) (list (let*-first-initial-value exp))) (list (make-let* (cdr bindings) body)) )))))(let*->nested-let

(derive

Page 17: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

17

Env. model evaluator: Supporting let* - as a special form

1. Add the required ADT procedures to the ASP

(let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

ASPASP

Derived expressions

Derived expressions

CoreCoreData structures

Data structures

DONE

Page 18: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

18

(define (special-form? exp) (or (quoted? exp) (lambda? exp) (definition? exp) (if? exp) (begin? exp) (let*? exp)))

(define (eval-special-form exp env) (cond ((quoted? exp) (text-of-quotation exp)) ((lambda? exp) (eval-lambda exp env)) … ((let*? exp) (eval-let* exp env))))

(let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

ASPASP

Derived expressions

Derived expressions

CoreCoreData structures

Data structures

Env. model evaluator: Supporting let* - as a special form

2. Modify the procedure special-form?

3. Modify eval-special-form

Page 19: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

19

(define (eval-let* exp env) (let ((vars (let*-variables exp)) (vals (let*-initial-values exp)) (body (let*-body exp))) (letrec ((helper

(lambda (vars-lst vals-lst env) (if (null? vars-lst) (eval-sequence body env) (helper (cdr vars-lst) (cdr vals-lst) (extend-env

(make-frame (list (car vars-lst)) (list (env-eval (car vals-lst) env)))

env)))))) (helper vars vals env))))

Env. model evaluator: Supporting let* - as a special form

4. Add the procedure eval-let*, direct approach:

• Extend the environment with a new frame per variable.

• When no variables remain, evaluate the body.

Page 20: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

20

(define (eval-let* exp env) (let ((body (let*-body exp))) (if (null? (let*-bindings exp)) (eval-sequence body env) (let ((first-var (let*-first-variable exp)) (first-val (let*-first-initial-value exp)) (rest-bindings (let*-rest-bindings exp))) (eval-let* (make-let* rest-bindings body) (extend-env (make-frame (list first-var) (list (env-eval first-val env))) env) )))))

Env. model evaluator: Supporting let* - as a special form

4. Add the procedure eval-let*, code generation approach:

Page 21: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

21

Env. model Compiler: Motivation

(define length (lambda (lst) (if (null? lst) 0 (* 1 (length (cdr lst))))))

Special form?

What is ? *

What’s fact?

Each time fact is called, the interpreter:

• Uses the ASP to identify the body as an if exp,

• Extracts the required components for evaluation,

• Looks-up variables, etc.

To avoid repeated analysis, the compiler:

• Analyzes a given expression in static (compilation) time.

• Returns a procedure that awaits an environment argument.

• Once applied, it evaluates the analyzed expression with respect to the given environment.

• No further Analysis is performed!

Page 22: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

22

• Using the compiler, we distinguish analysis from evaluation.

• The compiler returns a procedure ready for execution.

• Given an env, the procedure will compute the analyzed code with respect to that env.

• No analysis is performed during computation.

(define env-eval (lambda (exp env) <body>))

(define analyze (lambda (exp) (lambda (env) <analyzed -body>)))

Env. model Compiler: Introduction

env-eval:

[Exp*Env->Scheme-

Type]

compiler:

[Exp->[Env->Scheme-

Type]

Interpreter vs Compiler:

Page 23: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

(define (analyze exp) (cond ((atomic? exp) (analyze-atomic exp)) ((special-form? exp) (analyze-special-form exp)) ((application? exp) (analyze-application exp)) (else

(error "Unknown expression type -- EVAL“ exp))))

Env. model Compiler: Comparing with env-eval

The analyze procedure:

Handling an if expression:(define eval-if (lambda (exp env) (if (true? (env-eval (if-predicate exp) env)) (env-eval (if-consequent exp) env) (env-eval (if-alternative exp) env))))

(define analyze-if (lambda (exp) (let ((pred (analyze (if-predicate exp))) (consequent (analyze (if-consequent exp))) (alternative (analyze (if-alternative exp)))) (lambda (env) (if (true? (pred env)) (consequent env) (alternative env))))))

Evaluator

Analyzer

Page 24: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

24

(define (analyze-special-form exp) (cond ((quoted? exp) (analyze-quoted exp)) ((lambda? exp) (analyze-lambda exp)) … ((let*? exp) (analyze-let* exp))))

As a derived expression? Already done in the ASP!

1. Add the required ADT procedures to the ASP

2. identify a let* expression as a special form

3. Modify the procedure analyze-special-form:

Env. model Compiler: Supporting let*

As a special form?

Page 25: 1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.

25

Env. model Compiler: Supporting let*

(define (analyze-let* exp) (let ((vars (let*-variables exp)) (vals (map analyze (let*-initial-values exp))) (body (analyze-sequence (let*-body exp)))) (letrec ((fold (lambda (vars-lst vals-lst env) (if (null? vars-lst) (body env) (fold (cdr vars-lst) (cdr vals-lst) (extend-env (make-frame (list (car vars-lst)) (list ((car vals-lst) env))) env)))))) (lambda (env) (fold vars vals env)))))

4. Add the procedure analyze-let*:

“Translate” eval-let*, to an analyzer procedure: • Curry the env parameter. • Inductively analyze all sub expressions.