Cs784(tk)1 Implementing Recursion. Recap: Goals Experimenting with PL design alternatives Scoping, parameter passing, arrays,... Runnable prototype of.

Slides:



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

1 Programming Languages (CS 550) Mini Language Interpreter Jeremy R. Johnson.
Chapter 5: Abstraction, parameterization, and qualification Xinming (Simon) Ou CIS 505: Programming Languages Kansas State University Fall
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.
Recap 1.Programmer enters expression 2.ML checks if expression is “well-typed” Using a precise set of rules, ML tries to find a unique type for the expression.
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.
Cs7100(Prasad)L8Interp1 Interpreters Study Semantics of Programming Languages through interpreters (Executable Specifications)
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.
Functional programming: LISP Originally developed for symbolic computing Main motivation: include recursion (see McCarthy biographical excerpt on web site).
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
SchemeCOP Introduction to Scheme. SchemeCOP Scheme Meta-language for coding interpreters –“ clean ” semantics Scheme = LISP + ALGOL –simple.
PPL Syntax & Formal Semantics Lecture Notes: Chapter 2.
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
Environment: Data type associating symbols with values { a: 4s:'foof: x.x } Interface: (empty-env) = [ Ø ] (apply-env [f] s ) = f(s) (extend-env '( s 1...
PrasadL145OOL1 Managing Environments An Exercise in the Design, Analysis, Specification, and Implementation of the Core of an OOP Language. Object-Oriented.
5.4.1: Implementation Method Invocation (define eval-expression (lambda (exp env) (cases expression exp... (method-app-exp (obj-exp method-name rands)
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:
4.2 Type Checking (type-of-expression > tenv ) = bool (type-of-expression > tenv ) = x ( type-of-expression if > tenv ) = x Recall type of if statement:
1 Objects and types Typed languages = define a set of types in the language and assign a type to each expression in the program Type checking = how can.
Plt /17/ Environment-Passing Interpreters Programming Language Essentials 2nd edition Chapter 3.8 Parameter-Passing Variations.
Plt /19/ Environment-Passing Interpreters Programming Language Essentials 2nd edition Chapter 3.1 A Simple Interpreter.
1 Env. Model Implementation & Analyzer Practice Session #10 Env. Model Implementation & Analyzer Practice Session #10.
1 Programming Languages (CS 550) Lecture 2 Summary Mini Language Interpreter Jeremy R. Johnson.
Scheme in Scheme 2. What’s next  Adding set!  Dynamic vs. lexical variable scope  Extending mcscheme v1 with libraries  Can mcscheme execute mcscheme?
Compiler (javac) vs. Interpreter (drscheme): Chapter 3: Environment-Passing Interpreters Front End Interpreter program textsyntax tree answer > ((lambda.
Inductively Defined Data Concrete and Abstract syntax Karl Lieberherr.
Objects and Classes Gul Agha CS 421 Spring /11/2001CS 322 Fall Characteristics of OOP Object-based  encapsulate state  provide interface.
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.
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.
Implementing Recursion
Env. Model Implementation
Original material by Eric Grimson
5.4.1: Implementation Method Invocation
2.3 Representation Strategies for Data Types
Mini Language Interpreter Programming Languages (CS 550)
The Metacircular Evaluator
Abstract Syntax Prabhaker Mateti 1.
Dynamic Scoping Lazy Evaluation
The Metacircular Evaluator
And more store-passing interpreters
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)
Abstract Syntax cs7100 (Prasad) L7AST.
2.2.2 Abstract Syntax Recall BNF definition of l-calculus expressions:
3.6 Interpreter: Recursion
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
Inductively Defined Data Concrete and Abstract syntax
Presentation transcript:

cs784(tk)1 Implementing Recursion

Recap: Goals Experimenting with PL design alternatives Scoping, parameter passing, arrays,... Runnable prototype of reference implementation. – Cf. Informal description of a programming problem with an example executable for reference. cs784(tk)2

Recap: closure procedure definition –bind a closure to proc name. closure == (formals, body, creation- environment) cs784(tk)3

4 let insufficient for recursion Consider, in the defined language ( (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(tk)5 “Correct” Environment : Circularity Old approach

Adding LETREC Concrete syntax ::= letrec { }* in ::= () | ( {, }*) ::= = Abstract Syntax letrec-exp (proc-names idss bodies letrec-body) cs784(tk)6

letrec 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(tk)7

8 Three Potential Approaches 1.Delay the creation of the closure until a suitable environment has been formed. 2.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. 3.Create the closure with a “hole” and then “install” the final environment, when available, later. –Refer to EOPL (1st Ed., Chapter 7)

cs784(tk)9 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(tk)10 (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))) )))

Extended recursive environment TBD A list of the variables in the procdecls that is created by mapping the selector function for variables from a procdecl onto the list of procedure declarations. A vector containing procedure records (not closures) created from the formals and body of each procedure in the procedure declarations. The active environment. cs784(tk)11

cs784(tk)12 (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(tk)13 (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(tk)14 (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(tk)15 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,[]]] ]

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(tk)16

cs784(tk)17 (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(tk)18 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(tk)19 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(tk)20 (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)))) )))