Evaluators for Functional Programming 1
How to describe (specify) a programming language? 1.Syntax: atoms, primitives, combination and abstraction means. 2.Semantics: values, types. 3.Operational semantics: evaluation rules, evaluator algorithm. Evaluators for Functional Programming2
Evaluator for Functional Programming meta-circular : – Interpreted language = our flavor of Scheme – (embedding) language = Scheme We will see three evaluators for FP: 1. Substitution evaluator (impl. applicative- eval) 2. Environment-based evaluator (uses an environment data structure) 3. Environment-based compiler 3Evaluators for Functional Programming
Evaluator Structure Evaluators for Functional Programming4 program in interpreted language Value from interpreted language values (Global) Environment evaluator eval substitute - reduce written in Implementation (embedding) language
common evaluator structure Evaluators for Functional Programming5 abstract syntax parser program in interpreted language Value from interpreted language values (Global) Environment evaluator parsed expression (parse tree) eval substitute - reduce
basic compiler structure Evaluators for Functional Programming6 abstract syntax parser program in interpreted language Value from target language values Global Environment compiler parsed expression (parse tree) compilation program in target language execution/ evaluation
evaluator structure Evaluators for Functional Programming7 Scheme expression Value (Global) Environment evaluator Code in: Racket-Evaluators\substitution-interpreter\
Input Input: a scheme expression or an already evaluated scheme expression (in case of repeated evaluation). (lambda (lst) (car (car lst)) Input is accepted in the form of constant lists. '(lambda (lst) (car (car lst))) (list 'lambda (list 'lst) (list 'car (list 'car 'lst)) uniformity of Scheme expressions and the printed form of lists. 8Evaluators for Functional Programming
Input > (derive-eval '(+ 1 2) ) 3 > (derive-eval (list 'lambda (list 'lst) (list 'car (list 'car 'lst)) )) (procedure (lst) ((car (car lst)))) > (derive-eval '(lambda (lst) (car (car 'lst))) ) (procedure (lst) ((car (car lst)))) > (derive-eval (lambda (lst) (car (car lst)) )).. ASP.scm:247:31: car: expects argument of type ; given # Evaluators for Functional Programming9
Abstract Syntax Parser (ASP) A tool that 1.Identifies the kind of an input expression (atomic, lambda, application, etc) 2.Select the components of a Scheme expression 3.Construct a Scheme expression from its components Impl. an interface for Scheme Expression, according to Abstract Syntax of Scheme: ADT! 10Evaluators for Functional Programming
Derived Expressions Language expression have two classes: Kernel (core knows what to do with them) Derived (rewritten using kernel expressions – more on that later) Evaluators for Functional Programming11
Tagged-data interface and impl. 12Evaluators for Functional Programming
Tagged-data interface and impl. 13Evaluators for Functional Programming
Parser procedures - atomic exp. 14Evaluators for Functional Programming
Parser procedures - compound exp. 15Evaluators for Functional Programming
Parser procedures - compound exp. 16Evaluators for Functional Programming
Parser procedures - compound exp. 17Evaluators for Functional Programming
Parser procedures - compound exp. 18Evaluators for Functional Programming
Parser procedures - compound exp. 19Evaluators for Functional Programming
Parser procedures - compound exp. 20Evaluators for Functional Programming
Parser procedures - compound exp. 21Evaluators for Functional Programming
Parser procedures - compound exp. 22Evaluators for Functional Programming letrec - similar functions...
Parser procedures - compound exp. Evaluators for Functional Programming23
Parser procedures - application The application expression is special compound expression: It does not have a tag. 24Evaluators for Functional Programming
ASP - Derived Expressions 'derived' expression are translated into 'core' expressions (according to syntactic sugar/macro rule), before being evaluated. Derivation procedures are part of the ASP ; Signature: derive(exp) ; Type: [Scheme-exp -> Scheme-exp] 25Evaluators for Functional Programming
ASP - Derived Expressions (define let->combination (lambda (exp) (let ((vars (let-variables exp)) (body (let-body exp)) (initial-vals (let-initial-values exp))) (make-application (make-lambda vars body) initial-vals)))) (let ((x (+ y 2)) (y (- x 3))) (* x y)) ((lambda (x y) (* x y)) (+ y 2) (- x 3)) 26Evaluators for Functional Programming
ASP - Derived Expressions (define (f x y) (display x) (+ x y)) (define f (lambda (x y) (display x) (+ x y))) (define function-define->define (lambda (exp) (let ((var (function-definition-variable exp)) (params (function-definition-parameters exp)) (body (function-definition-body exp))) (make-definition var (make-lambda params body))))) 27Evaluators for Functional Programming
ASP - Derived Expressions cond->if (cond ((> x 0) x) ((= x 0) (display ’zero) 0) (else (- x))) (if (> x 0) x (if (= x 0) (begin (display ’zero) 0) (- x))) 28Evaluators for Functional Programming
ASP - Derived expressions (cond ((> x 0) x) (else (cond ((= x 0) 0) (else (- x)))))) (if (> x 0) x (cond ((= x 0) 0) (else (- x)))) 29Evaluators for Functional Programming (if (> x 0) x (if(= x 0) 0 (- x))) shallow derivation deep (recursive) derivation
ASP - Derived expressions (let*((x 10) (y (+ x 2)) (+ x y)) (let((x 10)) (let ((y (+ x 2))) (+ x y))) 30Evaluators for Functional Programming ((lambda(x) (let ((y....)) 10) shallow derivation recursive derivation until fixed point achieved
Evaluators for Functional Programming31
Evaluators for Functional Programming32
evaluator structure Evaluators for Functional Programming33 Scheme expression Value (Global) Environment evaluator Code in: Racket-Evaluators\substitution-interpreter\
Applicative-Eval Evaluator Core data structures: 1. Evaluated values 2. The global environment – managing "global" variable-value bindings. 34Evaluators for Functional Programming
Evaluated Values Repeated evaluation of compound values: applicative-eval[((λ (lst)(car lst)) (list 1 2 3))] applicative-eval[(λ (lst)(car lst))] applicative-eval[(list 1 2 3)] <== (1 2 3)// evaluated value of list applicative-eval[ (car (1 2 3)) ] ==> applicative-eval[car] <== Code of car. applicative-eval[(1 2 3)] <== "error: 1 is not a procedure" Same problem for values of lambda, quote (and other possible compound values) and primitive procedures. Need to identify (tag), evaluated values. 35 Evaluators for Functional Programming
Evaluated values ADTs Primitive-proceduremake-primitive-procedure [T -> Primitive-procedure] primitive-procedure? [T –> Boolean] primitive-implementation [Primitive-procedure –> T] Procedure make-procedure [LIST(Symbol)*LIST –> Procedure] compound-procedure? procedure-parameters [Procedure –> LIST(Symbol)] procedure-body [Procedure –> LIST] Othermake-value value? value-content 36Evaluators for Functional Programming
Primitive procedure - Impl. Evaluators for Functional Programming37
Procedure - Impl. Evaluators for Functional Programming38
evaluator structure Evaluators for Functional Programming39 Scheme expression Value (Global) Environment evaluator Code in: Racket-Evaluators\substitution-interpreter\
The global environment GE procedures: 40Evaluators for Functional Programming
The global environment mutable binding management. mapping from "global" variables to values. make-binding binding-variable Binding-value 41Evaluators for Functional Programming
evaluator structure Evaluators for Functional Programming42 Scheme expression Value (Global) Environment evaluator Code in: Racket-Evaluators\substitution-interpreter\
Applicative-Eval Evaluator - core Implementation of applicative eval algorithm. Derives expressions Special form/Atomic/Application Application: Eval-substitute-reduce (recursive). Has 'rename' and 'substitute' sub-routines Uses: ASP (parser), GE packages Creates Evaluated Values and returns them. 43Evaluators for Functional Programming
Applicative-Eval Evaluator - core 44Evaluators for Functional Programming
Applicative-Eval Evaluator - core 45Evaluators for Functional Programming
Applicative-Eval Evaluator - core 46Evaluators for Functional Programming
Applicative-Eval Evaluator - core atomic exp. 47Evaluators for Functional Programming
Applicative-Eval Evaluator - core special forms 48Evaluators for Functional Programming
Applicative-Eval Evaluator - core special forms 49Evaluators for Functional Programming
Applicative-Eval Evaluator - core special forms 50Evaluators for Functional Programming
Applicative-Eval Evaluator - core application 51Evaluators for Functional Programming
Applicative-Eval Evaluator - core primitive procedure application 52Evaluators for Functional Programming
Applicative-Eval Evaluator - core substitution 53Evaluators for Functional Programming
evaluator structure Evaluators for Functional Programming54 Scheme expression Value (Global) Environment evaluator Code in: Racket-Evaluators\substitution-interpreter\
55Evaluators for Functional Programming Applicative-Eval Evaluator - tests > (derive-eval '(* 3 4)) '(value 12) > (derive-eval '((lambda (f) (f 2 1)) +)) '(value 3) Regression tests: (test (derive-eval '(* 3 4)) => '(value 12)) (test (derive-eval '(cons 3 (cons 4 (list)))) => '(value (3 4))) (test (derive-eval '((lambda (f) (f 2 1)) +)) => '(value 3)) (test (derive-eval '(begin 1 2 3)) => '(value 3)) (test (derive-eval '(define x 2)) => 'ok) (test (derive-eval '(define (f x) (+ x x))) => 'ok) (test (derive-eval 'x) => '(value 2)) (test (derive-eval '(f x)) => '(value 4)) (test (derive '(let ((x 1)) (+ x 1))) => '( (lambda (x)(+ x 1)) 1))
The environment-based operational semantics 56
Why Substitute? Because we needed the values of the variables. 57
Ok, So What’s Wrong with Substitution? On every application we have to: – Rename – Substitute – Analyze the body (ask what kind of expression it is etc) Mixed value/expression. Evaluator value distinction required 58
New Way to get the Value of a Variable: The Environment Model 59
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. 60
61 The Environments Model Name Value Environment Table 23 score Substitution model: a single global environment Environments model: many environments.
62 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:
63 Environment: a finite 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
64 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=. 65 environment diagram
Operations on environments and frames: 66
Operations on environments and frames: 67
Operations on environments and frames: 68
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. 69
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. 70 B2B2 B1B1
71 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 72
The Environment Model Evaluation Algorithm - continued 73
74 The Environment Model Evaluation Algorithm - continued
75 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` 76
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) 77 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) 78
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 81
dynamic-env-eval 82
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 84
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 85
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))) 86
evaluator structure Chapter 4 - Evaluators for Functional Programming 87 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 88
4.4.2 Data Structures Package Procedure ADTs and their implementation Primitive procedure: same as in applicative-eval. 89
4.4.2 Data Structures Package Procedure ADTs and their implementation A Closure (procedure value) - contains an environment in which is was created 90
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 91
Environment related ADTs and their implementations: 92 The interpreter holds a "DrRacket" variable the-global-environment * Bindings, Frames, Environments.
Environment related ADTs and their implementations: The Binding ADT and its implementation : 93 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: 94 (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. 95 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
97
98 (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)))))
99 (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)))))
100 ; 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: 101
102
103
Evaluation of atomic expressions
105
106
107
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 109
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) 110
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. 111
Files Racket-Evaluators\env-functional-interpreter-compiler>dir analyzer-core.rkt analyzer-tests.rkt env-ds.rkt interpreter-core.rkt interpreter-tests.rkt 112
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. 113
analyzer structure Chapter 4 - Evaluators for Functional Programming 114 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. 115
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. 116
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 'eval "unknown expression type: ~s" exp))))) 117
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))))) 118
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)))))) 119
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)))) 120
Environment-based compiler (define analyze-sequence (lambda (exps) (let ((procs (map analyze exps))) (lambda (env) (let ((vals (map (lambda (proc) (proc env)) procs))) (last vals)))))) relies on the order of map in the underlining (implementation) Scheme. 121
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)) 122
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)))))) 123
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)))))) 124
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... ))))) 125
Compiler - evaluation of analyzed operator on extended environment (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))) (body new-env))) (else (error 'apply "unknown procedure type: ~s" procedure))))) 126
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) 127
| | |(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) | | | # | | |# // returned from analyze '( * (factorial... | | # // returned from analyze '(if... | |# // returned from analyze '(lambda... | # // returned from analyze '(define...) |ok // returned from application on the-global-environment 128
No repeated analysis - example > (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!! 129
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. 130