1 / 10

3.6 Interpreter: Recursion

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: Why letrec and not let ?. 3.6 Recursion.

more
Download Presentation

3.6 Interpreter: Recursion

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 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: Why letrecand notlet?

  2. 3.6 Recursion • Implement letrec for procedures in our toy language: • --> letrec fact(x)= • if zero?(x) then 1 • else *(x, (fact sub1(x))) • in (fact 6) • 720 • --> • We'll use letrec only for procedures....

  3. 3.6 Recursion • Syntax: • <expression> • ::= letrec • {<identifier>({<identifier>}*(,))= <expression>}* • in <expression> letrec-exp (proc-names idss bodies letrec-body) • Question: Why idssand notids?

  4. 3.6 Recursion • Add some code to eval-expression: • (define eval-expression • (lambda (exp env) • (cases expression exp • ... • (letrec-exp (proc-names idss bodies letrec-body) • (eval-expression letrec-body • (extend-env-recursively • proc-names idss bodies env))) • ...))) • So how to write extend-env-recursively?

  5. 3.6 Recursion First augment environment type to include recursive procs: (define-datatype environment environment? (empty-env-record) (extended-env-record (syms (list-of symbol?)) (vals (list-of scheme-value?)) (env environment?)) (recursively-extended-env-record (proc-names (list-of symbol?)) (idss (list-of (list-of symbol?))) (bodies (list-of expression?)) (env environment?)))

  6. 3.6 Recursion • Now write extend-env-recursively as a constructor: • (define extend-env-recursively • (lambda (proc-names idss bodies env) • (recursively-extended-env-record • proc-names idss bodies env))) • Recall that we look up symbols using apply-env: • (define eval-expression • (lambda (exp env) • (cases expression exp • (var-exp (id) (apply-env env id)

  7. 3.6 Recursion Current version: (define apply-env (lambda (env sym) (cases environment env (empty-env-record () (eopl:error ...)) (extended-env-record (syms vals old-env) (let ((pos (list-find-pos sym syms))) (if (number? pos) ; found (list-ref vals pos) (apply-env old-env sym)))))))

  8. 3.6 Recursion (define apply-env (lambda (env sym) (cases environment env ... (recursively-extended-env-record (proc-names idss bodies old-env) (let ((pos (list-find-pos sym proc-names))) (if (number? pos); found (closure (list-ref idss pos) (list-ref bodies pos) env) ; circular! (apply-env old-env sym)))))));notfound

  9. 3.6 Recursion • For our fact example: • proc-names = '(fact) • idss = '((x)) • bodies = '( <<if zero?(x) then 1 • else *(x, fact sub1(x))>> ) • env = '( (fact) • (<closure: fact, x, <<if...) )

  10. 3.6 Recursion fact closure(x) <<if zero? (x) then 1 else fact sub1(x)>>

More Related