The Metacircular Evaluator

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.
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.
Metacircular Evaluation SICP Chapter 4 Mark Boady.
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.
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.
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 The Evaluator. 2 Compiler vs. Interpreter Command Processing Unit The Computer Program in Low Level Machine Language Program in High Level Language.
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 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.
Scheme in Scheme 2. What’s next  Adding set!  Dynamic vs. lexical variable scope  Extending mcscheme v1 with libraries  Can mcscheme execute mcscheme?
CS61A Lecture Colleen Lewis 1. Clicker poll Are you in a two person group for project 4? A)Yes – I have my partner B)No – I plan to work.
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.
SICP Interpretation part 2 Store operators in the environment Environment as explicit parameter Defining new procedures.
(Thunking about Thunks)
Scheme in Scheme 1.
Operational Semantics of Scheme
Functional Programming
Lecture 4: Metacircles Eval Apply David Evans
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.
Interpreters Study Semantics of Programming Languages through interpreters (Executable Specifications) cs7100(Prasad) L8Interp.
The role of abstractions
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
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
Lecture 25: Metalinguistics > (meval '((lambda (x) (* x x)) 4)
The Metacircular Evaluator (Continued)
Lecture 27: In Praise of Idleness CS200: Computer Science
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 Explicit-control evaluator
6.001 SICP Explicit-control evaluator
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
Introduction to the Lab
topics interpreters meta-linguistic abstraction eval and apply
Rehearsal: Lazy Evaluation Infinite Streams in our lazy evaluator
*Lecture based on notes from SICP
Lecture 25: The Metacircular Evaluator Eval Apply
Presentation transcript:

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. http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-26.html

High level to Low-level reduction The Programmer The Computer Transformation Command Processing Unit T Program in High Level Language Program in Low Level Machine Language

C A Compiler Inputs High Level Machine Level Program Program The Compiler turns the high level program instructions to Instructions understood by the machine. CPU Outputs

I An Interpreter Inputs High Level Program CPU Outputs The Interpreter is a machine level program, which interprets and executes the high level program line after line…

The Metacircular Evaluator Inputs Scheme Program ME CPU It might seem circular to think about evaluating Scheme programs in Scheme, but the idea is since we have throughout the course used Scheme as our way of describing processes, and the evaluator is a process, then its only natural that we describe it too using Scheme. Outputs The Metacircular Evaluator is an Interpreter for Scheme on a machine whose machine language is Scheme.

The Environment Evaluation Model To evaluate a combination (a compound expression other than a special form), evaluate the subexpressions and then apply the value of the operator subexpression to the values of the operand subexpressions. To apply a compound procedure to a set of arguments, evaluate the body of the procedure in a new environment. To construct this environment, extend the environment part of the procedure object by a frame in which the formal parameters of the procedure are bound to the arguments to which the procedure is applied.

The Eval/Apply Cycle

The Meta-Circular Evaluator: Eval (define (eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((quoted? exp) (text-of-quotation exp)) ((assignment? exp) (eval-assignment exp env)) ((definition? exp) (eval-definition exp env)) ((if? exp) (eval-if exp env)) ((lambda? exp) (make-procedure (lambda-parameters exp) (lambda-body exp) env)) ((begin? exp) (eval-sequence (begin-actions exp) env)) ((cond? exp) (eval (cond->if exp) env)) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression type -- EVAL" exp)))) Special forms This is a top down, modular piece of software, built correctly with many layers of abstraction. However, since you havn’t built an interpreter before, we will not start directly a top down review of the process but rather first give a simplified example. Note that the use of a high level description in the main eval loop allows easy modification For possible changes to the language, but also makes it harder to add new constructs since they must Be added by changing this main eveal loop.

The Meta-Circular Evaluator: Apply (define (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 "Unknown procedure type" procedure))))

How the Environment Works manipulation 3. How the Environment Works E2 x: 10 plus: (procedure ...) E1 Abstractly – in our environment diagrams: Concretely – our implementation (as in SICP) list of values enclosing- environment list of variables frame x plus 10 E2 procedure

Extending the Environment plus: (procedure ...) E3 x: 4 y: 5 Abstractly (extend-environment '(x y) (list 4 5) E2) Concretely E2 list of values list of variables frame x y 4 E3 5 E1

Extending the environment (define (extend-environment vars vals base-env) (if (= (length vars) (length vals)) (cons (make-frame vars vals) base-env) (if (< (length vars) (length vals)) (error "Too many arguments supplied" vars vals) (error "Too few arguments supplied" vars vals))))

"Scanning" the environment Look for a variable in the environment... Look for a variable in a frame... loop through the list of vars and list of vals in parallel detect if the variable is found in the frame If not found in frame (out of variables in the frame), look in enclosing environment

Scanning the environment (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)) (define (enclosing-environment env) (cdr env)) (define (frame-variables frame) (car frame)) (define (frame-values frame) (cdr frame))

If predicate (define (eval-if exp) (if (true? (eval (if-predicate exp))) (eval (if-consequent exp)) (eval (if-alternative exp)))) (define (if-predicate exp) (cadr exp)) (define (if-consequent exp) (caddr exp)) (define (if-alternative exp) (if (not (null? (cdddr exp))) (cadddr exp) 'false)) (define (true? x) (not (eq? x #f))) (define (false? x) (eq? x #f))  

Eval-definition (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)))) (define (eval-definition exp env) (let ((name (cadr exp)) (defined-to-be (eval (caddr exp) env))) (define-variable! name defined-to-be env) ‘undefined))

Defining New Procedures Want to add new procedures For example, a scheme program: (define twice (lambda (x) (+ x x))) (twice 4) (define (lambda? exp) (tag-check exp 'lambda))   (define (eval exp env) (cond … ((lambda? exp) (eval-lambda exp env)) … (else (error "unknown expression " exp))))

Lambda expression (define (make-procedure parameters body env)    (define (eval-lambda exp env) (make-procedure (lambda-parameters exp) (lambda-body exp) env)) (define (lambda-parameters exp) (cadr exp)) (define (lambda-body exp) (cddr exp)) (define (make-procedure parameters body env) (list 'procedure parameters body env))

Implementation of lambda (eval '(define twice (lambda (x) (+ x x))) GE) (eval '(lambda (x) (+ x x)) GE) (eval-lambda '(lambda (x) (+ x x)) GE) (make-procedure '(x) ’((+ x x)) GE) (list ’procedure '(x) ’((+ x x)) GE) GE This data structure is a procedure! symbol procedure symbol + symbol x

Naming the procedure (eval '(define twice (lambda (x) (+ x x))) GE) z 9 true #t + twice symbol primitive scheme procedure + symbol procedure symbol + symbol x

Selctors for procedure type   (define (compound-procedure? exp) (tag-check exp ‘procedure)) (define (procedure-parameters compound) (cadr compound)) (define (procedure-body compound) (caddr compound)) (define (procedure-env compound) (cadddr compound))

Eval sequence (define (eval-sequence exps env) (cond ((last-exp? exps) (eval (first-exp exps) env)) (else (eval (first-exp exps) env) (eval-sequence (rest-exps exps) env)))) (define (last-exp? seq) (null? (cdr seq))) (define (first-exp seq) (car seq)) (define (rest-exps seq) (cdr seq))

The Meta-Circular Evaluator: Apply (define (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 "Unknown procedure type" procedure))))

Implementation of apply (1) (eval '(twice 4) GE) (apply (eval 'twice GE) (map (lambda (e) (eval e GE)) '(4))) (apply (list 'procedure '(x) ’((+ x x)) GE) '(4)) (eval-seq ’((+ x x)) (extend-environment '(x) '(4) GE)) (eval '(+ x x) E1) GE E1 A names values 4 x

Implementation of apply (2) (eval '(+ x x) E1) (apply (eval + E1) (map (lambda (e) (eval e E1)) '(x x))) (apply '(primitive #[add]) (list (eval 'x E1) (eval 'x E1))) (apply '(primitive #[add]) '(4 4)) (scheme-apply #[add] '(4 4)) 8 GE E1 A names values 4 x

We Implemented Lexical Scoping Free variables in an application of procedure f get their values from the procedure where f was defined (by the appropriate lambda special form). Also called static binding (define (foo x y) (lambda (z) (+ x y z))) (define bar (foo 1 2)) (bar 3) bar : (lambda (z) (+ 1 2 z))

Lexical Scoping Environment Diagram (define (foo x y) (lambda (z) (+ x y z))) Will always evaluate (+ x y z) in a new environment inside the surrounding lexical environment. (define bar (foo 1 2)) (bar 3) GE p: x y body: (l (z) (+ x y z)) foo: bar: E1 x: 1 y: 2 p: z body: (+ x y z) (+ x y z) | E2 => 6 z: 3 E2

Alternative Model: Dynamic Scoping Dynamic scope: Look up free variables in the caller's environment rather than the surrounding lexical environment Example: (define x 11) (define (pooh x) (bear 20)) (define bear (lambda (y) (+ x y))) (pooh 9) => 29

Dynamic Scoping Environment Diagram (define x 11) (define (pooh x) (bear 20)) Will evaluate (+ x y) in an environment that extends the caller's environment. (define (bear y) (+ x y)) (pooh 9) GE x:11 p: x body: (bear 20) pooh: bear: p: y body: (+ x y) x: 9 E1 y: 20 E2 (+ x y) | E2 => 29

A "Dynamic" Version of Scheme (define (d-eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ... ((lambda? exp) (make-procedure (lambda-parameters exp) (lambda-body exp) '*no-environment*)) ;CHANGE: no env ((application? exp) (d-apply (d-eval (operator exp) env) (list-of-values (operands exp) env) env)) ;CHANGE: add env (else (error "Unknown expression -- M-EVAL" exp))))

A "Dynamic" Scheme – d-apply (define (d-apply procedure arguments calling-env) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence (procedure-body procedure) (extend-environment (procedure-parameters procedure) arguments calling-env))) ;CHANGE: use calling env (else (error "Unknown procedure" procedure))))