Presentation is loading. Please wait.

Presentation is loading. Please wait.

Evaluators for Functional Programming 1. How to describe (specify) a programming language? 1.Syntax: atoms, primitives, combination and abstraction means.

Similar presentations


Presentation on theme: "Evaluators for Functional Programming 1. How to describe (specify) a programming language? 1.Syntax: atoms, primitives, combination and abstraction means."— Presentation transcript:

1 Evaluators for Functional Programming 1

2 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

3 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

4 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

5 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

6 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

7 evaluator structure Evaluators for Functional Programming7 Scheme expression Value (Global) Environment evaluator Code in: Racket-Evaluators\substitution-interpreter\

8 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

9 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

10 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

11 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

12 Tagged-data interface and impl. 12Evaluators for Functional Programming

13 Tagged-data interface and impl. 13Evaluators for Functional Programming

14 Parser procedures - atomic exp. 14Evaluators for Functional Programming

15 Parser procedures - compound exp. 15Evaluators for Functional Programming

16 Parser procedures - compound exp. 16Evaluators for Functional Programming

17 Parser procedures - compound exp. 17Evaluators for Functional Programming

18 Parser procedures - compound exp. 18Evaluators for Functional Programming

19 Parser procedures - compound exp. 19Evaluators for Functional Programming

20 Parser procedures - compound exp. 20Evaluators for Functional Programming

21 Parser procedures - compound exp. 21Evaluators for Functional Programming

22 Parser procedures - compound exp. 22Evaluators for Functional Programming letrec - similar functions...

23 Parser procedures - compound exp. Evaluators for Functional Programming23

24 Parser procedures - application The application expression is special compound expression: It does not have a tag. 24Evaluators for Functional Programming

25 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

26 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

27 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

28 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

29 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

30 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

31 Evaluators for Functional Programming31

32 Evaluators for Functional Programming32

33 evaluator structure Evaluators for Functional Programming33 Scheme expression Value (Global) Environment evaluator Code in: Racket-Evaluators\substitution-interpreter\

34 Applicative-Eval Evaluator Core data structures: 1. Evaluated values 2. The global environment – managing "global" variable-value bindings. 34Evaluators for Functional Programming

35 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

36 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

37 Primitive procedure - Impl. Evaluators for Functional Programming37

38 Procedure - Impl. Evaluators for Functional Programming38

39 evaluator structure Evaluators for Functional Programming39 Scheme expression Value (Global) Environment evaluator Code in: Racket-Evaluators\substitution-interpreter\

40 The global environment GE procedures: 40Evaluators for Functional Programming

41 The global environment mutable binding management. mapping from "global" variables to values. make-binding binding-variable Binding-value 41Evaluators for Functional Programming

42 evaluator structure Evaluators for Functional Programming42 Scheme expression Value (Global) Environment evaluator Code in: Racket-Evaluators\substitution-interpreter\

43 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

44 Applicative-Eval Evaluator - core 44Evaluators for Functional Programming

45 Applicative-Eval Evaluator - core 45Evaluators for Functional Programming

46 Applicative-Eval Evaluator - core 46Evaluators for Functional Programming

47 Applicative-Eval Evaluator - core atomic exp. 47Evaluators for Functional Programming

48 Applicative-Eval Evaluator - core special forms 48Evaluators for Functional Programming

49 Applicative-Eval Evaluator - core special forms 49Evaluators for Functional Programming

50 Applicative-Eval Evaluator - core special forms 50Evaluators for Functional Programming

51 Applicative-Eval Evaluator - core application 51Evaluators for Functional Programming

52 Applicative-Eval Evaluator - core primitive procedure application 52Evaluators for Functional Programming

53 Applicative-Eval Evaluator - core substitution 53Evaluators for Functional Programming

54 evaluator structure Evaluators for Functional Programming54 Scheme expression Value (Global) Environment evaluator Code in: Racket-Evaluators\substitution-interpreter\

55 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))

56 The environment-based operational semantics 56

57 Why Substitute? Because we needed the values of the variables. 57

58 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

59 New Way to get the Value of a Variable: The Environment Model 59

60 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 61 The Environments Model Name Value Environment Table 23 score Substitution model: a single global environment Environments model: many environments.

62 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 15 2 1 x: 15 A y:

63 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 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

65 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

66 Operations on environments and frames: 66

67 Operations on environments and frames: 67

68 Operations on environments and frames: 68

69 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

70 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 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)

72 The Environment Model Evaluation Algorithm 72

73 The Environment Model Evaluation Algorithm - continued 73

74 74 The Environment Model Evaluation Algorithm - continued

75 75 The Environment Model Evaluation Algorithm - continued

76 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

77 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.

78 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

79 Example 4.5. 79

80 Example 4.6. 80

81 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

82 dynamic-env-eval 82

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

84 Example 4.10. >(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

85 Example 4.12. >(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

86 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

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

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

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

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

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

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

93 4.4.2.2 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

94 4.4.2.2 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 …)))))

95 4.4.2.2 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)

96 96 4.4.2.2 Global environment construction

97 97

98 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 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 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)))))

101 4.4.1.1 Main evaluator loop: 101

102 102

103 103

104 104 4.4.1.2 Evaluation of atomic expressions

105 105

106 106

107 107

108 4.4.1.4 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)))))

109 Primitive procedure application 109

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

111 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

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

113 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

114 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.

115 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

116 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

117 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

118 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

119 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

120 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

121 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

122 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

123 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

124 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

125 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

126 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

127 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

128 | | |(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

129 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

130 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


Download ppt "Evaluators for Functional Programming 1. How to describe (specify) a programming language? 1.Syntax: atoms, primitives, combination and abstraction means."

Similar presentations


Ads by Google