Cs784(Prasad)L10Rec1 Implementing Recursion. cs784(Prasad)L10Rec2 let insufficient for recursion ( (let((fact(lambda (n) (if (zero? n) 1 (* n (fact (-

Slides:



Advertisements
Similar presentations
Plt /7/ Data Abstraction Programming Language Essentials 2nd edition Chapter 2.2 An Abstraction for Inductive Data Types.
Advertisements

Closures & Environments CS153: Compilers Greg Morrisett.
Semantics of PLs via Interpreters: Getting Started CS784: Programming Languages Prabhaker Mateti.
1 Programming Languages (CS 550) Mini Language Interpreter Jeremy R. Johnson.
Type Checking, Inference, & Elaboration CS153: Compilers Greg Morrisett.
Letrec fact(n) = if zero?(n) then 1 else *(n, (fact sub1(n))) 4.4 Type Inference Type declarations aren't always necessary. In our toy typed language,
Scheme in Scheme. Why implement Scheme in Scheme  Implementing a language is a good way to learn more about programming languages  Interpreters are.
Assignments and Procs w/Params EOPL3 Chapter 4. Expressible vs. Denotable values Expressible Values –the language can express and compute these –represented.
1 How to transform an analyzer into a verifier. 2 OUTLINE OF THE LECTURE a verification technique which combines abstract interpretation and Park’s fixpoint.
Tim Sheard Oregon Graduate Institute Lecture 8: Operational Semantics of MetaML CSE 510 Section FSC Winter 2005 Winter 2005.
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.
3.6 Interpreter: Recursion Recall Scheme's letrec (recursive let ): > (letrec ((fact (lambda (x) (if (zero? x) 1 (* x (fact (- x 1))))) (fact 6)) 720 Question:
Metacircular Evaluation SICP Chapter 4 Mark Boady.
Cs784(TK)1 Semantics of Procedures and Scopes. Kinds of Scope Static or Lexical scope –determined by structure of program –Scheme, C++, Java, and many.
1 Scheme Scheme is a functional language. Scheme is based on lambda calculus. lambda abstraction = function definition In Scheme, a function is defined.
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.
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.
EOPL3: Section 3.3 PROC and App B: SLLGEN
Cs784(tk)1 Implementing Recursion. Recap: Goals Experimenting with PL design alternatives Scoping, parameter passing, arrays,... Runnable prototype of.
Cs7100(Prasad)L8Proc1 Procedures. cs7100(Prasad)L8Proc2 Primitive procedures  etc User-defined procedures –Naming a sequence of operations.
Plt /12/ Data Abstraction Programming Language Essentials 2nd edition Chapter 2.3 Representation Strategies for Data Types.
3.5 Procedures Recall procedures (functions) in Scheme: (let ((f (lambda(y z) (+ y (- z 5))) (f 2 28)) We would like something similar in our toy language:
SICP Interpretation Parts of an interpreter Arithmetic calculator Names Conditionals and if Storing procedures in the environment Environment as.
Plt /17/ Environment-Passing Interpreters Programming Language Essentials 2nd edition Chapter 3.8 Parameter-Passing Variations.
1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10.
Eight languages Eight weeks How I designed and implemented a teaching OO language in 4 days.
Cs784 (Prasad)L6AST1 Abstract Syntax. cs784 (Prasad)L6AST2 Language of -expressions ::= | (lambda ( ) ) | ( ) E.g., concrete syntax Scheme S-expressions.
SICP Interpretation part 2 Store operators in the environment Environment as explicit parameter Defining new procedures.
Operational Semantics of Scheme
Abstract Syntax cs7100 (Prasad) L7AST.
6.001 SICP Variations on a Scheme
The interpreter.
Interpreters Study Semantics of Programming Languages through interpreters (Executable Specifications) cs7100(Prasad) L8Interp.
September 4, 1997 Programming Languages (CS 550) Lecture 6 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts.
Implementing Recursion
Env. Model Implementation
Original material by Eric Grimson
5.4.1: Implementation Method Invocation
2.3 Representation Strategies for Data Types
Semantics of PLs via Interpreters: Getting Started
The Metacircular Evaluator
Abstract Syntax Prabhaker Mateti 1.
Dynamic Scoping Lazy Evaluation
The Metacircular Evaluator
Procedures App B: SLLGEN 1.
3.7 Variable Assignment Recall instance variables in Python:
3.4 Local Binding Recall Scheme's let: > (let ((x 5)‏ (y 6))
The Metacircular Evaluator (Continued)
Chapter 1 Review: BNF Grammar for lists:
Streams, Delayed Evaluation and a Normal Order Interpreter
Abstract Syntax cs7100 (Prasad) L7AST.
2.2.2 Abstract Syntax Recall BNF definition of l-calculus expressions:
6.001 SICP Explicit-control evaluator
3.6 Interpreter: Recursion
6.001 SICP Explicit-control evaluator
6.001 SICP Variations on a Scheme
2.2.2 Abstract Syntax Recall BNF definition of l-calculus expressions:
Chapter 3: Environment-Passing Interpreters
Assignments cs7100(Prasad) L13Assg.
6.001 SICP Interpretation Parts of an interpreter
Assignments and Procs w/Params
topics interpreters meta-linguistic abstraction eval and apply
Recursive Procedures and Scopes
Rehearsal: Lazy Evaluation Infinite Streams in our lazy evaluator
Inductively Defined Data Concrete and Abstract syntax
Presentation transcript:

cs784(Prasad)L10Rec1 Implementing Recursion

cs784(Prasad)L10Rec2 let insufficient for recursion ( (let((fact(lambda (n) (if (zero? n) 1 (* n (fact (- n 1))) ) ) )) (fact 6) ) Problem : The closure to be formed must freeze the environment containing the “correct” binding for fact which is the closure itself!

cs784(Prasad)L10Rec3 “Correct” Environment : Circularity Old approach

cs784(Prasad)L10Rec4 Concrete syntax ::= letrec * in ::= () | ( {, }*) ::= = Abstract Syntax letrec-exp (proc-names idss bodies letrec-body)

cs784(Prasad)L10Rec5 Example letrec even(x) = if zero?(x) then 1 else (odd sub1(x)) odd(x) = if zero?(x) then 0 else (even sub1(x)) in (odd 13);

cs784(Prasad)L10Rec6 Potential Approaches Delay the creation of the closure until a suitable environment has been formed. Create the environment and then change what one of its procedure binding points to. Simulate letrec using let and assignment in the object language, or alternatively, using assignment in the meta- language. Create the closure with a “hole” and then “install” the final environment, when available, later. Refer to EOPL (1st Ed., Chapter 7)

cs784(Prasad)L10Rec7 Delayed Closure Creation (New Env.) So far, each procedure definition is translated as a closure ( ), and the environment binds a closure to proc name. To handle (mutually) recursive procedures, the creation of the closure is delayed until the binding for the proc name is required (using apply-env ), prior to carrying out apply-proc.

cs784(Prasad)L10Rec8 (define eval-expression (lambda (exp env) (cases expression exp... (primapp-exp (prim rands) … ) (app-exp (rator rands) (let ((proc (eval-expression rator env)) (args (eval-rands rands env))) (if (procval? proc) (apply-procval proc args) (eopl:error 'eval-expression “Applying non-procedure ~s" proc)) (proc-exp (ids body) (closure ids body env)) (let-exp (ids rands body) (let ((args (eval-rands rands env))) (eval-expression body (extend-env ids args env))) ) (letrec-exp (proc-names idss bodies letrec-body) (eval-expression letrec-body (extend-env-recursively proc-names idss bodies env))) )))

cs784(Prasad)L10Rec9 (define-datatype environment environment? (empty-env-record) (extended-env-record (syms (list-of symbol?)) (vals vector?) (env environment?)) (recursively-extended-env-record (proc-names (list-of symbol?)) (idss (list-of (list-of symbol?))) (bodies (list-of expression?)) (env environment?)) ) Extended Recursive Environments

cs784(Prasad)L10Rec10 (define (empty-env) (empty-env-record)) (define (extend-env syms vals env) (extended-env-record syms (list->vector vals) env)) (define (extend-env-recursively proc-names idss bodies old-env) (recursively-extended-env-record proc-names idss bodies old-env)) (cont’d)

cs784(Prasad)L10Rec11 (define (apply-env env sym) (cases environment env (empty-env-record () (eopl:error 'empty-env “Unbound ~s" sym)) (extended-env-record (syms vals old-env) (let ((pos (rib-find-position sym syms))) (if (number? pos) (vector-ref vals pos) (apply-env old-env sym)))) (recursively-extended-env-record (proc-names idss bodies old-env) (let ((pos (rib-find-position sym proc- names))) (if (number? pos) (closure (list-ref idss pos) (list-ref bodies pos) env) (apply-env old-env sym)))) )) (cont’d)

cs784(Prasad)L10Rec12 Example let x = 6 in let y = 8 in letrec p = D1 q = D2 in let z = 10 in (p) INIT-ENV : [] EXT-ENV: [x = 6,[]] EXT-ENV: [y=8, [x = 6,[]]] REC-EXT-ENV: [{p=D1,q=D2}+[y=8, [x = 6,[]]] EXT-ENV: [z=10, [{p=D1,q=D2}+[y=8, [x = 6,[]]] ] Closure: D1%[{p=D1,q=D2}+[y=8, [x = 6,[]]]

cs784(Prasad)L10Rec13 Another Implementation (based on procedures) (define environment? procedure?) (define (apply-env env sym) (env sym)) (define (empty-env) (lambda (sym) (eopl:error 'empty-env “Unbound ~s" sym))) (define (extend-env ids vals env) (lambda (sym) (let ((pos (rib-find-position sym ids))) (if (number? pos) (list-ref vals pos) (apply-env env sym))) ))

cs784(Prasad)L10Rec14 (cont’d) (define (extend-env-recursively proc-names idss bodies old-env) (letrec ((rec-env (lambda (sym) (let((pos( rib-find-position sym proc-names ))) (if (number? pos) (closure (list-ref idss pos) (list-ref bodies pos) rec-env) (apply-env old-env sym)))) )) rec-env) )

cs784(Prasad)L10Rec15 Simulating letrec using let and assignment (letrec ((var1 exp1) (var2 exp2)) exp ) (* exp1 and exp2 are lambda -forms *) (let ((var1 ’*) (var2 ’*)) (set! var1 exp1) (set! var2 exp2) exp )

cs784(Prasad)L10Rec16 Yet Another Implementation (based on assignment) (define (extend-env-recursively proc-names idss bodies old-env) (let ((len (length proc-names))) (let ((vec (make-vector len))) (let ((env (extended-env-record proc-names vec old-env))) (for-each (lambda (pos ids body) (vector-set! vec pos (closure ids body env))) (iota len) idss bodies) env))))

cs784(Prasad)L10Rec17 (cont’d) (define apply-env (lambda (env sym) (cases environment env (empty-env-record () (eopl:error 'empty-env “Unbound ~s" sym)) (extended-env-record (syms vals old-env) (let ((pos (rib-find-position sym syms))) (if (number? pos) (vector-ref vals pos) (apply-env old-env sym)))) )))