The environment-based operational semantics Chapter 4.3 1.

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.
מבוא מורחב למדעי המחשב תרגול 13 Lazy Evaluation. Lazy Evaluation Implementation Two types of values – Delayed Values – Actual Values Introduce two functions.
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).
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.
1 The metacircular evaluator (Cont.) Defining new procedures (define (lambda? e) (tag-check e 'lambda)) (define (eval exp env) (cond ((number? exp)
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.
1 The Evaluator. 2 Compiler vs. Interpreter Command Processing Unit The Computer Program in Low Level Machine Language Program in High Level Language.
1 Lecture 20 Lazy Evaluation Continued (4.2.1, 4.2.2) MC-eval examples from exams (Time permitting)
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 Lecture 14: Assignment and the Environment Model (EM)
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 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10.
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.
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
6.001 SICP Object Oriented Programming
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
The Metacircular Evaluator
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 12: Message passing The Environment Model
Lecture 13 - Assignment and the environments model Chapter 3
6.001 SICP Environment model
6.001 SICP Variations on a Scheme
6.001 SICP Interpretation Parts of an interpreter
6.001 SICP Environment model
topics interpreters meta-linguistic abstraction eval and apply
Lecture 25: The Metacircular Evaluator Eval Apply
Presentation transcript:

The environment-based operational semantics Chapter 4.3 1

What’s Wrong with Substitution? On every application we have to: – Rename and substitute: heavy operations – Analyze the body (ask what kind of expression it is etc) mixed value/expression. Evaluator value distinction required 2

The Environment Based Operational Semantics Replace local variable management Substitution with A hierarchical environment structure. The env-eval algorithm evaluates an expression with respect to an environment. Advantage: – Directly access local variables (procedures are pure code, no need for evaluator value distinction. – Later: Body of procedure may be analyzed once. 3

4 The Environments Model Name Value Environment Table 23 score Substitution model: a single global environment Environments model: many environments.

5 Binding: a pairing of a name and a value Frame: a table of bindings Example: x is bound to 15 in frame A y is bound to (1 2) in frame A the value of the variable x in frame A is x: 15 A y:

6 Environment: a sequence of frames Environment E1 consists of frames A and B Environment E2 consists of frame B only (A frame may be shared by multiple environments) z: 10 B E1 E2 x: 15 A 2 1 y: this arrow is called the enclosing environment pointer

7 Evaluation in the environment model All evaluations occur with respect to an environment The current environment changes when the interpreter applies a procedure The top environment is called the global environment (GE) Only the GE has no enclosing environment

The environment data structure frame is a list of bindings, a variable-value mapping: Variable –> Scheme-type. environment is a finite sequence of frames E=. 8 environment diagram

Operations on environments and frames: 9

10

Operations on environments and frames: 11

The closure data structure The closure is the value of a lambda expression.. The components of a closure cl are denoted cl parameters, cl body, cl environment. The closure carries the environment it was constructed in. this enables the evaluator algorithm to have a lexical scoping policy. 12

The closure data structure A closure carries an environment - the one containing all local variables defined when it was created. >(define f (let ((x 3)) (lambda(y) (+ x y))) >(f 1) The interpreter need to know that: x=3 when evaluating B 1. This local variable binding needs to be saved for future use of the closure corresponding to (lambda(y) (+ x y)). Procedure application involves an extension of that environment. 13 B2B2 B1B1

14 Double bubble: how to draw a procedure (lambda (x) (* x x)) eval lambda-rule A compound proc that squares its argument #[proc-...] print Environment pointer Code pointer parameters: x body: (* x x)

The Environment Model Evaluation Algorithm 15

The Environment Model Evaluation Algorithm - continued 16

17 The Environment Model Evaluation Algorithm - continued

18 The Environment Model Evaluation Algorithm - continued

Notes The recursive algorithm passes an 'env' parameter env-eval consults or modify the environment structure in the following steps: (a) Creation of a compound procedure (closure): Evaluation of a 'lambda' expression (and 'let'). (b) Application of a compound procedure (closure) – the only way to add a frame (also 'let'). (c) Evaluation of 'define' expression – adds a binding to the global environment. (d) Evaluation of a variable. De-allocation of frames: garbage collection... An environment corresponds to a lexical scope 19

Example 4.7. >(define member (lambda (x list) (cond ((null list) (list)) ((eq? x (car list)) list) (else (member x (cdr list))))) >(define a (list ’a ’b ’c)) >(member ’b a) 20 Drawing environment diagrams is a way to represent the computation of the env-eval algorithm.

Example 4.8. Try a "curried" version of member: >(define c_member (lambda (list) (lambda (el) (cond ((null list) (list)) ((eq? el (car list)) list) (else ((c_member (cdr list)) el)))))) >(define a (list ’a ’b ’c)) >(define search-a (c_member a)) >(search-a 'b) 21

Example

Example

Static (Lexical) vs. Dynamic Scoping Policies (Section 4.3.3) Policies for interpreting variables (variable scoping) in a program. applicative-eval, normal-eval and env-eval algorithms have a Static (lexical) scoping policy. The nesting of lexical blocks determines the variable binding at run- time In dynamic scoping, a variable occurrences is bound by the most recent declaration of that variable. In dynamic scoping: the access link is defined by the control link and closures do not carry an environment. Do not confuse static scoping with static type-inference algorithms! => languages with static scoping policies allow for static type inference 24

dynamic-env-eval 25

Example Not all evaluation algorithms are equivalent! dynamic-eval != env-eval (compute the same function, have the same domain)

Example >(define f (lambda (x) (a x x))) >(define g (lambda (a x) (f x))) >(define a +) >(g * 3) env-eval[(g*3),GE] ==> 6 dynamic-env-eval[(g*3),GE] ==> 9 27

Example >(define init 0) >(define 1+ (lambda(x)(+ x 1))) >(define f (lambda (f1) (let ((f2 (lambda () (f1 init)))) (let ((f1 1+) (init 1)) (f2) )))) >(f (lambda (x) (* x x))) env-eval[(f (lambda (x) (* x x)))] ==> 0 dynamic-env-eval[(f (lambda (x) (* x x)))] ==> 2 28

4.4 The env-eval Evaluator Implementation 1. Abstract Syntax Parser (same as "applicative-eval" implementation) 2. Data structures - environment hierarchy, closures. 3. Core ("env-eval" algorithm implementation) ; Type: [ -> Scheme-type] (define derive-eval (lambda (exp) (env-eval (derive exp) the-global-environment))) 29

evaluator structure Chapter 4 - Evaluators for Functional Programming 30 Scheme expression Value evaluator (Global) Environment

Files Racket-Evaluators\env-functional-interpreter-compiler>dir analyzer-core.rkt analyzer-tests.rkt env-ds.rkt interpreter-core.rkt interpreter-tests.rkt 31

4.4.2 Data Structures Package Procedure ADTs and their implementation Primitive procedure: same as in applicative-eval. 32

4.4.2 Data Structures Package Procedure ADTs and their implementation A Closure (procedure value) - contains an environment in which is was created 33

4.4.2 Data Structures Package Procedure ADTs and their implementation A Closure (procedure value) - contains an environment in which is was created Identify procedures in general 34

Environment related ADTs and their implementations: 35 The interpreter holds a "DrRacket" variable the-global-environment * Bindings, Frames, Environments.

Environment related ADTs and their implementations: The Binding ADT and its implementation : 36 Alternative definition: (define make-binding cons) (define binding-variable car) (define binding-value cdr) What is the difference? varval binding

Environment related ADTs and their implementations: The Frame ADT and its implementation: 37 (define make-frame (lambda (variables values) (make-sub variables values))) (define make-sub (lambda (variables values) (let ((sub (list variables values))) (if (sub? sub) sub (error …)))))

Environment implementation An environment is implemented as a list of boxed (mutable) frames. 38 environment frame substitution * in implementation language box variable->value lookup function Racket box operations box(x) unbox(b) set-box!(b, y)

Global environment construction

40

41 (define lookup-variable-value (lambda (env var) (letrec ((defined-in-env (lambda (var env) (if (empty-env? env) env (let ((b (get-value-of-variable (first-frame env) var))) (if (eq? b '_not-found) (defined-in-env var (enclosing-env env)) b)))))) (let ((b (defined-in-env var env))) (if (empty? b) (error 'lookup "variable not found: ~s\n env = ~s" var env) b)))))

42 (define get-value-of-variable (lambda (sub var) (letrec ((lookup (lambda (vars vals) (cond ((or (empty-sub? sub) (not (member var vars))) '_not-found) ((eq? var (car vars)) (car vals)) (else (lookup (cdr vars) (cdr vals))))))) (lookup (get-variables sub) (get-values sub)))))

43 ; Global environment mutator: ADT type is [Binding -> Unit] ; Type: [PAIR(Symbol,T) -> Unit] ; Note: Mutation is enabled only for the global environment (define add-binding! (lambda (binding) (let ((frame (first-frame the-global-environment))) (set-box! (first-boxed-frame the-global-environment) (extend-frame binding frame)))))

Main evaluator loop: 44

45

46

Evaluation of atomic expressions

48

49

50

Evaluation of applications ; Type: [Evaluator-procedure*LIST -> Scheme-type] (define apply-procedure (lambda (procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (let* ((parameters (procedure-parameters procedure)) (body (procedure-body procedure)) (env (procedure-environment procedure)) (new-env (extend-env (make-frame parameters arguments) env))) (eval-sequence body new-env))) (else (error 'apply "unknown procedure type: ~s" procedure)))))

Primitive procedure application 52

Testing (define (app-lambda-tests) (test (derive-eval '((lambda (x) x) 12)) => 12) (test (derive-eval '((lambda (x y z) (+ x y z)) )) => 39)... ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Invoking tests ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (app-lambda-tests) 53

The Analyzer So far, no distinction between syntax analysis and evaluation For example: the kind of an expression (special form, application etc) can be decided statically. 54

Files Racket-Evaluators\env-functional-interpreter-compiler>dir analyzer-core.rkt analyzer-tests.rkt env-ds.rkt interpreter-core.rkt interpreter-tests.rkt 55

4.5.1 The Analyzer Compile time (static time): Things performed first, once if possible. – static syntax analysis Run time (dynamic time): Things performed later, as needed – data-structure (environments and closures) related Compile time is less expensive than run time. Analyzing a procedure body once, independently from its application, means compiling its code into something more efficient/optimal, which is ready for evaluation. 56

analyzer structure Chapter 4 - Evaluators for Functional Programming 57 Scheme expression Value (Global) Environment syntax-analysis (compilation) run-time evaluation Program in target language code in the implementation language.

4.5 An Environment-based FP Meta-Circular Compiler The analyzer avoid repetition of syntax-analysis in every procedure application. Idea: separate static syntax analysis (syntax parsing) from run-time evaluation (closure/environment data- structure manipulation). means: curried function style. 58

An Environment-based FP Meta-Circular Compiler The analyzer Use currying Interpreter:Compiler: (lambda (exp env) (lambda (exp) syntax analysis+ syntax analysis run-time evaluation (performed once) returns (lambda(env) run-time evaluation [Expression*Env->T][Expression->[Env->T]] Compiler output is code in the implementation language. 59

Environment-based compiler (define derive-analyze-eval (lambda(exp) ((analyze (derive exp)) the-global-environment)) (define analyze (lambda (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) )))) 60

Environment-based compiler Interpreter: (define eval-atomic (lambda (exp env) (if (or (number? exp) (boolean? exp) (null? exp)) exp (lookup-variable-value exp env)))) Compiler: (define analyze-atomic (lambda (exp) (if (or (number? exp) (boolean? exp) (null? exp)) (lambda (env) exp) (lambda (env) (lookup-variable-value exp env))))) 61

Environment-based compiler Interpreter: (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)))) Compiler: (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)))))) 62

Environment-based compiler Interpreter (define eval-lambda (lambda (exp env) (make-procedure (lambda-parameters exp) (lambda-body exp) env))) Compiler - body is analyzed once! (define analyze-lambda (lambda (exp) (let ((parameters (lambda-parameters exp)) (body (analyze-sequence (lambda-body exp)))) (lambda (env) (make-procedure parameters body env)))) 63

Environment-based compiler (define analyze-sequence (lambda (exps) (let ((procs (map analyze exps)) (last-in-list (lambda (lst) (car (reverse lst))))) (if (null? procs) (error "Empty sequence -- ANALYZE")) (lambda (env) (let ((vals (map (lambda (proc)(proc env)) procs))) (last-in-list vals))))) relies on the order of map in the underlining (implementation) Scheme. 64

Environment-based compiler Interpreter (define eval-special-form (lambda (exp env) (cond... ((definition? exp) (if (not (eq? env the-global-environment)) (error "Non global definition" exp) (eval-definition exp)))... (define eval-definition (lambda (exp) (add-binding! (make-binding (definition-variable exp) (env-eval (definition-value exp) the-global-environment))) ’ok)) 65

Environment-based compiler Compiler: (define (analyze-definition (lambda (exp) (let ((var (definition-variable exp)) (val (analyze (definition-value exp)))) (lambda (env) (if (not (eq? env the-global-environment)) (error "Non global definition" exp) (begin (add-binding! (make-binding var (val the-global-environment))) ’ok)))))) 66

Interpreter: (define env-eval (lambda (exp env) (cond... ((application? exp) (apply-procedure (env-eval (operator exp) env) (list-of-values (operands exp) env)))... Compiler: (define analyze (lambda (exp) (cond... ((application? exp) (analyze-application exp))... (define analyze-application (lambda (exp) (let((application-operator (analyze (operator exp))) (application-operands (map analyze (operands exp)))) (lambda (env) (apply-procedure (application-operator env) (map (lambda (operand) (operand env)) application-operands)))))) 67

Interpreter: (define apply-procedure (lambda (procedure args) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure args)) ((compound-procedure? procedure) (let ((proc-params (procedure-parameters procedure)) (proc-body (procedure-body procedure)) (proc-env (procedure-environment procedure))) (eval-sequence proc-body (extend-env (make-frame proc-params args) proc-env)) (else (error... ))))) 68

Compiler - evaluation of analyzed operator on extended environment (define apply-procedure (lambda (procedure args) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure args)) ((compound-procedure? procedure) (let ((proc-params (procedure-parameters procedure))) (proc-abody (procedure-body procedure)) (proc-env (procedure-environment procedure))) (proc-abody (extend-env (make-frame proc-params args) proc-env)) (else (error... ))))) 69

No repeated analysis - Tracing example > (require racket/trace) > (trace analyze) > (derive-analyze-eval ’(define (factorial n) (if (= n 1) 1 (* (factorial (- n 1)) n))) | (analyze (define factorial (lambda(n) (if (= n 1) 1 (* (factorial (- n 1)) n)))) | |(analyze (lambda (n) (if (= n 1) 1 (* (factorial (- n 1)) n)))) | | (analyze (if (= n 1) 1 (* (factorial (- n 1)) n))) | | |(analyze (= n 1)) | | | (analyze =) | | | # | | | (analyze n) | | | # | | | (analyze 1) | | | # | | |# // returned from analyze '(= n 1) 70

| | |(analyze 1) | | |# | | |(analyze (* (factorial (- n 1)) n)) | | | (analyze *) | | | # | | | (analyze (factorial (- n 1))) | | | |(analyze factorial) | | | |# | | | |(analyze (- n 1)) | | | | (analyze -) | | | | # | | | | (analyze n) | | | | # | | | | (analyze 1) | | | | # | | | |# // returned from analyze '(- n 1) | | | # // returned from analyze '(factorial (- n 1)) | | | (analyze n) 71

No repeated analysis - example | | | # | | |# // returned from analyze '( * (factorial... | | # // returned from analyze '(if... | |# // returned from analyze '(lambda... | # // returned from analyze '(define...) |ok // returned from application on the-global-environment > (derive-analyze-eval ’(factorial 4)) |( (analyze (factorial 4)) the-global-environment) | (analyze (factorial 4)) | |(analyze factorial) | |# // returned from analyze 'factorial | |(analyze 4) | |# // returned from analyze 4 | # // returned from analyze '(factorial 4) |24// returned from application on the-global-environment // no recursive analysis when recursive analyzed procedure is applied!! 72

Chapter 4 Summary Interpreter algorithms that have a static scoping policy: applicative-eval, env-eval and normal-eval are functionally equivalent (on the domain conjunction). An interpreter algorithm that has a dynamic scoping policy. dynamic-env-eval Implementations for applicative-eval, env-eval : use ASP (incl. handling expression derivation), Data structures (environments, procedure and other values), have test modules. Analyzer optimization for the environment based interpreter. 73