Implementing Recursion - PowerPoint PPT Presentation

About This Presentation
Title:

Implementing Recursion

Description:

Problem : The closure to be formed must freeze the environment containing the ' ... Delay the creation of the closure until a suitable environment has been formed. ... – PowerPoint PPT presentation

Number of Views:16
Avg rating:3.0/5.0
Slides: 18
Provided by: csWr
Learn more at: http://cecs.wright.edu
Category:

less

Transcript and Presenter's Notes

Title: Implementing Recursion


1
Implementing Recursion
2
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!

3
Correct Environment Circularity
Old approach
4
  • Concrete syntax
  • ltexpressiongt letrec ltprocdeclgt
  • in ltexpressiongt
  • ltidlistgt ()
  • (ltidentifiergt , ltidentifiergt)
  • ltprocdeclgt
  • ltidentifiergt ltidlistgt ltexpressiongt
  • Abstract Syntax
  • letrec-exp
  • (proc-names idss bodies letrec-body)

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

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

7
Delayed Closure Creation (New Env.)
  • So far, each procedure definition is translated
    as a closure (lt formals, body, creation-time-envir
    onment gt), 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.

8
  • (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)
  • (eoplerror '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

9
Extended Recursive Environments
  • (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?))
  • )

10
(contd)
  • (define (empty-env)
  • (empty-env-record))
  • (define (extend-env syms vals env)
  • (extended-env-record syms
  • (list-gtvector vals) env))
  • (define (extend-env-recursively
  • proc-names idss bodies old-env)
  • (recursively-extended-env-record
  • proc-names idss bodies old-env))

11
(contd)
  • (define (apply-env env sym)
  • (cases environment env
  • (empty-env-record ()
  • (eoplerror '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))))
  • ))

12
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 y8, x 6,
  • REC-EXT-ENV
  • pD1,qD2y8, x 6,
  • EXT-ENV
  • z10,
  • pD1,qD2y8, x 6,

Closure D1pD1,qD2y8, x 6,
13
Another Implementation (based on procedures)
  • (define environment? procedure?)
  • (define (apply-env env sym)
  • (env sym))
  • (define (empty-env)
  • (lambda (sym)
  • (eoplerror '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)))
  • ))

14
(contd)
  • (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)
  • )

15
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
  • )

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

17
(contd)
  • (define apply-env
  • (lambda (env sym)
  • (cases environment env
  • (empty-env-record ()
  • (eoplerror '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))))
  • )))
Write a Comment
User Comments (0)
About PowerShow.com