1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10.

Slides:



Advertisements
Similar presentations
Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is a good way to learn more about programming languages  Interpreters are.
Advertisements

1 Programming Languages (CS 550) Lecture Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
Scheme in Scheme?!? …the metacircular evaluator….
1 The metacircular evaluator Names Extend the calculator to store intermediate results as named values (define x (+ 4 5)) store result as x (+ x.
Imperative Programming: Mutable data (local state, letrec, set!) Example 1: counter (define counter (let ((count 0)) (lambda () (set! count (+ count 1))
1 Programming Languages (CS 550) Operational Semantics of Scheme using Substitution and the Lambda Calculus Jeremy R. Johnson TexPoint fonts used in EMF.
Metacircular Evaluation SICP Chapter 4 Mark Boady.
Evaluators for Functional Programming Chapter 4 1 Chapter 4 - Evaluators for Functional Programming.
Imperative Programming: Mutable data (local state, letrec, set!) Example 1: counter (define counter (let ((count 0)) (lambda () (set! count (+ count 1))
Imperative Programming Chapter 6 1. Local State Real world software like: Banks Course grading system Are state systems. i.e. they change along time:
1 Programming Languages (CS 550) Lecture 7 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts used in EMF. Read.
1 The Metacircular Evaluator Chapter 4 Section 4.1 We will not cover every little detail in the lectures, so you MUST read Section 4.1 in full.
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 11. Metacircular Evaluator 4.1, pages definitions file on web 2.
(define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((list-form? exp) (eval-list.
1 Lecture 18 Continue Evaluator. 2 z9 true#t + twice Representing procedures (eval '(define twice (lambda (x) (+ x x))) GE) symbol primitive scheme procedure.
Functional programming: LISP Originally developed for symbolic computing Main motivation: include recursion (see McCarthy biographical excerpt on web site).
SICP Interpretation part 1 Parts of an interpreter Arithmetic calculator Names Conditionals and if Store procedures in the environment.
6.001 SICP SICP – Evaluation I Recitation 11/19/2004 Eval review Evaluation examples define lambda apply New language elements.
SICP Variations on a Scheme Scheme Evaluator – A Grand Tour Techniques for language design: Interpretation: eval/apply Semantics vs. syntax Syntactic.
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
Scheme More MCE examples. Q1 new special form which defines global variables (static ) search the global environment – Variable exists: does nothing,
The environment model evaluator and compiler 1 The env model evaluator Motivation In one word: Efficiency Saves repeated renaming and substitution: Using.
1 Saves repeated renaming and substitution: explicit substitution is replaced by variable bindings using new data structures (frame, environment). Can.
1 Continue Evaluator. 2 z9 true#t + twice Representing procedures (eval '(define twice (lambda (x) (+ x x))) GE) symbol primitive scheme procedure + symbol.
Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is aa good way to learn more about programming languages  Interpreters are.
1 The metacircular evaluator (Cont.) Defining new procedures (define (lambda? e) (tag-check e 'lambda)) (define (eval exp env) (cond ((number? exp)
Functional Programming Universitatea Politehnica Bucuresti Adina Magda Florea
CS220 Programming Principles 프로그래밍의 이해 2002 가을학기 Class 15: Meta-Circular Evaluator 한 태숙.
SICP Interpretation Parts of an interpreter Arithmetic calculator Names Conditionals and if Storing procedures in the environment Environment as.
1 Subt. model interpreter: Structure of the interpreter ASP Derived expressions Core Test Data structures Utils A racket lib Proc / Primitive-Proc. Global.
Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is a good way to learn more about programming languages  Interpreters are.
SICP Explicit-control evaluator Big ideas: how to connect evaluator to machine instructions how to achieve tail recursion Obfuscation: tightly.
1 The Evaluator. 2 Compiler vs. Interpreter Command Processing Unit The Computer Program in Low Level Machine Language Program in High Level Language.
The environment-based operational semantics Chapter
1 Read-Eval-Print Loop (define (driver-loop) (prompt-for-input input-prompt) (let ((input (read))) (let ((output (eval input the-global-env))) (announce-output.
1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)
Example 1: counter (set! vs set-box!) 1 Imperative Programming: Mutable data and local state (define counter (let ((count 0)) (lambda () (set! count (+
Example 1: counter (set! vs set-box!) 1 Imperative Programming: Mutable data and local state (define counter (let ((count 0)) (lambda () (set! count (+
Imperative Programming Chapter 6 1. Local State Real world software like: Banks Course grading system Are state systems. i.e. they change along time:
1 Programming Languages (CS 550) Lecture 4 Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
1 Lecture 19 Dynamic Scoping Lazy Evaluation (4.2.1, 4.2.2)
1/ SICP Variations on a Scheme Scheme Evaluator – A Grand Tour Making the environment model concrete Defining eval defines the language –Provides.
David Evans CS200: Computer Science University of Virginia Computer Science Lecture 27: Types of Types “It would appear.
1 Vectors, binary search, and sorting. 2 We know about lists O(n) time to get the n-th item. Consecutive cons cell are not necessarily consecutive in.
1 The Evaluator. 2 Compiler vs. Interpreter Command Processing Unit The Computer Program in Low Level Machine Language Program in High Level Language.
Evaluators for Functional Programming 1. How to describe (specify) a programming language? 1.Syntax: atoms, primitives, combination and abstraction means.
SICP Interpretation part 2 Store operators in the environment Environment as explicit parameter Defining new procedures.
Operational Semantics of Scheme
Edited by Original material by Eric Grimson
6.001 SICP Variations on a Scheme
The interpreter.
September 4, 1997 Programming Languages (CS 550) Lecture 6 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts.
Env. Model Implementation
Original material by Eric Grimson
Nondeterministic Evaluation
The Metacircular Evaluator
Dynamic Scoping Lazy Evaluation
The Metacircular Evaluator
The Metacircular Evaluator (Continued)
Lecture 26: The Metacircular Evaluator Eval Apply
6.001 SICP Further Variations on a Scheme
Streams, Delayed Evaluation and a Normal Order Interpreter
Lecture 12: Message passing The Environment Model
Lecture 13 - Assignment and the environments model Chapter 3
6.001 SICP Variations on a Scheme
6.001 SICP Interpretation Parts of an interpreter
Rehearsal: Lazy Evaluation Infinite Streams in our lazy evaluator
More Scheme CS 331.
Lecture 25: The Metacircular Evaluator Eval Apply
Presentation transcript:

1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10

2 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) Efficiency: Env. model evaluator: Introduction

Env. model evaluator: Structure and implementation ASP Derived expressions Core Test Data structures Utils (a racket lib) Input text Data structures: New data structures: frame, environment A closure keeps the Env in which it has been created renaming and substitution functions are no longer needed

Env. model evaluator: Structure and implementation ASP Derived expressions Test Utils (a racket lib) Input text Core: Procedure application and evaluation of expressions is done with respect to a certain environment. Core Data structures ASP: No changes here!

5 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). '( (x foo) (4 ) ) A variable-value mapping. Each variable is bound to a single value only. Frame: Implemented as a substitution, i.e: as a list of 2 lists

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 … … E1E1 '((+ - …) (prim+ prim- …)) '((foo …) ( … )) t-g-e box-pointer diagram: box frame box 'procparamsbody E2E2 E3E3

7 Env. model evaluator: Evaluation example (1) Evaluating a definition expression: (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env))...))) (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) (define eval-special-form (lambda (exp env) (cond... ((lambda? exp) (eval-lambda exp env)) ((definition? exp) (if (not (eq? env t-g-e)) (error 'eval "non global definition: ~s" exp) (eval-definition exp)))...))) (define eval-special-form (lambda (exp env) (cond... ((lambda? exp) (eval-lambda exp env)) ((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 eval-definition (lambda (exp) (add-binding! (make-binding (definition-variable exp) (env-eval (definition-value exp) t-g-e))) 'ok))

8 Env. model evaluator: Evaluation example (1) Evaluating a definition expression: (define eval-special-form (lambda (exp env) (cond... ((lambda? exp) (eval-lambda exp env))...))) (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 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))) (define make-procedure (lambda (parameters body env) (attach-tag (list parameters body env) 'procedure))) (attach-tag (list '(x) '(lambda (y) (+ x y)) t-g-e)) 'procedure)

9 Env. model evaluator: Evaluation example (1) Evaluating a definition expression: (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env))...))) (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) (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-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 eval-definition (lambda (exp) (add-binding! (make-binding (definition-variable exp) (env-eval (definition-value exp) t-g-e))) 'ok)) Done! (add-binding! (make-binding f (list 'procedure '(x) '(lambda (y) (+ x y)) t-g-e)) )

10 Env. model evaluator: Evaluation example (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))...))) (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)))) (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) The result is our representation of a procedure.

Create a new frame where x maps to 1 GE x: 1 11 Extend the environment Evaluate the body Env. model evaluator: Evaluation example (3) Evaluating an application of a user procedure: > (env-eval '(define g (f 1) )) (apply-procedure (‘ procedure (x) ((lambda (y) (+ x y))) t-g-e ) (1)) (make-frame ‘(x) ‘(1)) (extend-env new-frame t-g-e) (eval-sequence body new-env)

12 Can be regarded as a nested let expression. Similar to let, but defined variable can be used in the following 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) (c (* a 2))) (+ a c)) > (let ((a 1)) (let ((c (* a 2))) (+ a c))) > (let ((a 1)) (let ((c (* a 2))) (+ a c))) > ((λ (a) ((λ (c) (+ a c)) (* a 2)) 1) > ((λ (a) ((λ (c) (+ a c)) (* a 2)) 1) > 3 = = > 21

13 An expression (let* ((v 1 e 1 ) (v 2 e 2 ) … (v n e n )) b 1 b 2 … b m ), with respect to environment E0, is defined as follows: E 1 E 0 * make-frame [(v 1 ),(env-eval e 1 E 0 )] E 2 E 1 * make-frame [(v 2 ),(env-eval e 2 E 1 )]... E n E n-1 * make-frame [(v n ),(env-eval e n E n-1 )] (env-eval b 1 E n )... (env-eval b m-1 E n ) Return (env-eval b m E n ) Q: How would the evaluation rule for let look like? Evaluation rule for a let* expression: Env. model evaluator: Supporting let*

14 (define (let*? exp) (tagged-list? exp 'let*)) (define (let*? exp) (tagged-list? exp 'let*)) (define let*-bindings cadr) (define let*-body cddr) (define (let*-variables exp) (map car (let*-bindings exp))) (define (let*-variables exp) (map car (let*-bindings exp))) (define (let*-initial-values exp) (map cadr (let*-bindings exp))) (define (let*-initial-values exp) (map cadr (let*-bindings exp))) (define (let*-first-variable exp) (caar (let*-bindings exp))) (define (let*-first-variable exp) (caar (let*-bindings exp))) (define (let*-first-initial-value exp) (cadar (let*-bindings exp))) (define (let*-first-initial-value exp) (cadar (let*-bindings exp))) (define (make-let*-bindings vars vals) (map list vars vals)) (define (make-let*-bindings vars vals) (map list vars vals)) (define (make-let* bindings body) (append (list 'let* bindings) body)) (define (make-let* bindings body) (append (list 'let* bindings) body)) Env. model evaluator: Supporting let* - as a derived expression 1. Add the required ADT procedures to the ASP (let* ((v 1 e 1 ) (v 2 e 2 ) … (v n e n )) b 1 b 2 … b m ) ASP Derived expressions Core Data structures

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 (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 "Unhandled derivision" exp))) (define (shallow-derive exp) (cond ((cond? exp) (cond->if exp))... ((let*? exp) (let*->nested-let exp)) (else "Unhandled derivision" exp))) 3. Modify the procedure shallow-derive (let* ((v 1 e 1 ) (v 2 e 2 ) … (v n e n )) b 1 b 2 … b m ) ASP Derived expressions Core Data structures

16 Env. model evaluator: Supporting let* - as a derived expression 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-let '() body) (if (null? (cdr bindings)) (make-let bindings body) ;do-if-true (make-let ;do-if-false (make-let-bindings (list (let*-first-variable exp)) (list (let*-first-initial-value exp))) (list (make-let* (cdr bindings) body)) ))))) (define (let*->nested-let exp) (let ((bindings (let*-bindings exp)) (body (let*-body exp))) (if (null? bindings) (make-let '() body) (if (null? (cdr bindings)) (make-let bindings body) ;do-if-true (make-let ;do-if-false (make-let-bindings (list (let*-first-variable exp)) (list (let*-first-initial-value exp))) (list (make-let* (cdr bindings) body)) ))))) (let* ((v 1 e 1 ) (v 2 e 2 ) … (v n e n )) b 1 b 2 … b m ) ASP Derived expressions Core Data structures No changes to the core!

17 Env. model evaluator: Supporting let* - as a derived expression 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-let '() 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)) ))))) (define (let*->nested-let exp) (let ((bindings (let*-bindings exp)) (body (let*-body exp))) (if (null? bindings) (make-let '() 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)) ))))) Q: The result is a let exp. Shouldn’t it be further derived? Q: What about the let* expression created by make-let*? Q: When the if-condition does not hold, we wrap the body parameter in a list. Why? (let*->nested-let (derive

18 Env. model evaluator: Supporting let* - as a derived expression 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-let '() 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)) ))))) (define (let*->nested-let exp) (let ((bindings (let*-bindings exp)) (body (let*-body exp))) (if (null? bindings) (make-let '() 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)) ))))) Q: The result is a let exp. Shouldn’t it be further derived? A: Nah.. This is done by derive which calls itself until the result exp is not changed. 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 may consist of several expressions. (let*->nested-let (derive

19 Env. model evaluator: Supporting let* - as a special form 1. Add the required ADT procedures to the ASP (let* ((v 1 e 1 ) (v 2 e 2 ) … (v n e n )) b 1 b 2 … b m ) ASP Derived expressions Core Data structures DONE

20 (define (special-form? exp) (or (quoted? exp) (lambda? exp) (definition? exp) (if? exp) (begin? exp) (let*? exp))) (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)))) (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* ((v 1 e 1 ) (v 2 e 2 ) … (v n e n )) b 1 b 2 … b m ) ASP Derived expressions Core Data structures Env. model evaluator: Supporting let* - as a special form 2. Modify the procedure special-form? 3. Modify eval-special-form

21 (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)))) (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* Extend the Env with new frames for each variable. When no variables remain, evaluate the body.

22 Env. model Compiler: Motivation (define length (lambda (lst) (if (null? lst) 0 (+ 1 (length (cdr lst)))))) (define length (lambda (lst) (if (null? lst) 0 (+ 1 (length (cdr lst)))))) Special form? Each time length is called, the interpreter: Uses the ASP to identify the body as an if exp. Extracts the required components for evaluation. 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.

23 Using the compiler, we distinguish analysis from evaluation. The compiler produces a procedure ready for execution, given an environment. The procedure returns the evaluation of the analyzed code with respect to the env. No analysis is performed during evaluation. (define env-eval (lambda (exp env) )) (define env-eval (lambda (exp env) )) (define analyze (lambda (exp) (lambda (env) ))) (define analyze (lambda (exp) (lambda (env) ))) Env. model Compiler: Introduction env-eval: [Exp*Env->Scheme-Type] compiler: [Exp->[Env->Scheme-Type]] Interpreter vs Compiler:

(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)))) (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 exp env) (if (true? (env-eval (if-predicate exp) env)) (env-eval (if-consequent exp) env) (env-eval (if-alternative exp) env))) (define (eval-if 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 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))))) (define (analyze-if 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

25 (define (analyze-special-form exp) (cond ((quoted? exp) (analyze-quoted exp)) ((lambda? exp) (analyze-lambda exp)) … ((let*? exp) (analyze-let* exp)))) (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? Same as already done with the evaluator! 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?

26 (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)))) (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*

27 4. Add the procedure analyze-let*: We “translate” the evaluator procedure, eval-let*, to an analyzer procedure: Inductively apply analyze to all sub expressions. Curry the env parameter. 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 ((helper (lambda (vars-lst vals-lst env) (if (null? vars-lst) (body env) (helper (cdr vars-lst) (cdr vals-lst) (extend-env (make-frame (list (car vars-lst)) (list ((car vals-lst) env))) env)))))) (lambda (env) ;letrc body – Currying (helper vars vals env))))) (define (analyze-let* exp) (let ((vars (let*-variables exp)) (vals (map analyze (let*-initial-values exp))) (body (analyze-sequence (let*-body exp)))) (letrec ((helper (lambda (vars-lst vals-lst env) (if (null? vars-lst) (body env) (helper (cdr vars-lst) (cdr vals-lst) (extend-env (make-frame (list (car vars-lst)) (list ((car vals-lst) env))) env)))))) (lambda (env) ;letrc body – Currying (helper vars vals env)))))