Env. Model Implementation

Slides:



Advertisements
Similar presentations
1 Programming Languages (CS 550) Mini Language Interpreter Jeremy R. Johnson.
Advertisements

Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is a good way to learn more about programming languages  Interpreters are.
1 Programming Languages (CS 550) Lecture Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
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))
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))
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.
(define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((list-form? exp) (eval-list.
6.001 SICP SICP – October environment Trevor Darrell 32-D512 Office Hour: W web page:
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.
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.
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.
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
Milos Hauskrecht (PDF) Hieu D. Vu (PPT) LISP PROGARMMING LANGUAGE.
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 (+
1 Programming Languages (CS 550) Lecture 4 Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10.
Scheme in Scheme 2. What’s next  Adding set!  Dynamic vs. lexical variable scope  Extending mcscheme v1 with libraries  Can mcscheme execute mcscheme?
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
6.001 SICP Object Oriented Programming
6.001 SICP Compilation Context: special purpose vs. universal machines
The interpreter.
Introduction to Scheme
September 4, 1997 Programming Languages (CS 550) Lecture 6 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts.
Original material by Eric Grimson
Nondeterministic Evaluation
The Metacircular Evaluator
Lecture 23 Pages : Separating Syntactic Analysis from Execution. We omit many details so you have to read the section in the book. The halting.
Dynamic Scoping Lazy Evaluation
The Metacircular Evaluator
6.001 SICP Environment model
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 #9 מבוא מורחב.
Lecture 12: Message passing The Environment Model
Lecture 13 - Assignment and the environments model Chapter 3
Data Mutation Primitive and compound data mutators set! for names
6.001 SICP Environment model
6.001 SICP Variations on a Scheme
6.001 SICP Data Mutation Primitive and Compound Data Mutators
Lecture 14: The environment model (cont
6.001 SICP Interpretation Parts of an interpreter
6.001 SICP Environment model
topics interpreters meta-linguistic abstraction eval and apply
Recursive Procedures and Scopes
Rehearsal: Lazy Evaluation Infinite Streams in our lazy evaluator
More Scheme CS 331.
Lecture 25: The Metacircular Evaluator Eval Apply
Presentation transcript:

Env. Model Implementation & Analyzer Practice Session #11

Env. model evaluator: Introduction Efficiency: 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: Structure and implementation Input text ASP Data structures Core Derived expressions Utils (a racket lib) Test Data structures: New data structures: frame, environment A closure keeps the Env in which it has been created Additional procedures are added to handle new ADTs Renaming and Substitution are no longer needed

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

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 <procedure(x) x>) ) 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

Env. model evaluator: Structure and implementation Environment: Implemented as a list of boxed frames A finite sequence of frames in which the last frames is the-global-environment. … E1 '((+ - …) (prim+ prim- …)) '((foo …) ( … )) t-g-e box-pointer diagram: box frame 'proc params body E2 E3

Env. model evaluator: Evaluation example (1) Evaluating a definition expression: > (env-eval (derive '(define f (lambda (x) (lambda (y) (+ x y))))) t-g-e) (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form exp env)) ...))) (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))

שאלה Env. model evaluator: Evaluation example (1) Evaluating a definition expression: > (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)) ...))) (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))) שאלה (attach-tag (list '(x) '(lambda (y) (+ x y)) t-g-e)) 'procedure) P: x B: (lambda (y) (+ x y)) t-g-e

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

Env. model evaluator: Evaluation example (2) Evaluating a user procedure: > (derive-eval 'f t-g-e) (define env-eval (lambda (exp env) (cond ((atomic? exp) (eval-atomic exp env)) ((special-form? exp) (eval-special-form 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) We look up f in the given env. The result is our representation of a procedure.

Env. model evaluator: Evaluation example (3) Evaluating an application of a user procedure: > (env-eval '(define g (f 1) ) t-g-e) (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) GE x: 1

Env. model evaluator: Supporting let* Reminder: What is a let* expression? Can be regarded as a nested let expression. Similar to let, but defined variable can be used in the following definitions. Example: > (define a 10) > (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 > (let ((a 1) (c (* a 2))) (+ a c)) > 21

Env. model evaluator: Supporting let* Evaluation rule for a let* expression: 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 to creating a new environment, E1.

Env. model evaluator: Supporting let* - as a derived expression 1. Add the required ADT procedures to the ASP (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*-initial-values exp) (map cadr (let*-bindings exp))) (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)) (define (make-let* bindings body) (append (list 'let* bindings) body)) Data structures Core ASP Derived expressions (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

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))) 3. Modify the procedure shallow-derive (define (shallow-derive exp) (cond ((cond? exp) (cond->if exp)) ... ((let*? exp) (let*->nested-let exp)) (else "Unhandled derivision" exp))) Data structures Core ASP Derived expressions (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

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)) ))))) No changes to the core! Data structures Core ASP Derived expressions (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

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-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)) ))))) (derive (let*->nested-let 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.

DONE Env. model evaluator: Supporting let* - as a special form 1. Add the required ADT procedures to the ASP DONE Data structures Core ASP Derived expressions (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

Env. model evaluator: Supporting let* - as a special form 2. Modify the procedure special-form? (define (special-form? exp) (or (quoted? exp) (lambda? exp) (definition? exp) (if? exp) (begin? exp) (let*? exp))) 3. Modify eval-special-form (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)))) Data structures Core ASP Derived expressions (let* ((v1 e1) (v2 e2) … (vn en)) b1 b2 … bm)

Env. model evaluator: Supporting let* - as a special form 4. Add the procedure eval-let* (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)))) Extend the Env with new frames for each variable. When no variables remain, evaluate the body.

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

Env. model Compiler: Introduction Interpreter vs Compiler: 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) <body>)) (define analyze (lambda (exp) (lambda (env) <analyzed -body>))) env-eval: [Exp*Env->Scheme-Type] compiler: [Exp->[Env->Scheme-Type]]

Env. model Compiler: Comparing with env-eval The analyze procedure: (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)))) 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))) Evaluator (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))))) Analyzer

Env. model Compiler: Supporting let* As a derived expression? Same as already done with the evaluator! As a special form? 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: (define (analyze-special-form exp) (cond ((quoted? exp) (analyze-quoted exp)) ((lambda? exp) (analyze-lambda exp)) … ((let*? exp) (analyze-let* exp))))

Env. model evaluator: Supporting let* - as a special form 4. Add the procedure eval-let* (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 Compiler: Supporting let* 4. Add the procedure analyze-let*: We “translate” the evaluator procedure, eval-let*, to an analyzer procedure: First, Curry the env parameter. Next, inductively apply analyze to all sub expressions. (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)))))