closure and apply-proc
helper functions: one which uses higher-order (that is, functional) representation of procedures, and another that uses data-structural representation of procedures. You may use either data-structural or procedural representation of environments.
First, add the d-lambda form to your interpreter; d-lambda is a variant of lambda that
implements dynamic scope.
Then redefine the higher-order version of closure and apply-proc as necessary.
Here are two tests that should pass once you have added
d-lambda to the interpreter:
(define let-static
'(let ([x 2])
(let ([f (lambda (e) x)])
(let ([x 5])
(f 0)))))
(define let-dynamic
'(let ([x 2])
(let ([f (d-lambda (e) x)])
(let ([x 5])
(f 0)))))
(test "let-test-static"
(value-of let-static (empty-env))
2)
(test "let-test-dynamic"
(value-of let-dynamic (empty-env))
5)
Once the tests above pass, re-define your data structural implementation of
apply-proc and closure, in order to support d-lambda.
You must not change your definition of value-of.
(let ([y (* 3 4)]) ((lambda (x) (* x y)) (sub1 6)))Explain the order in which the sub-expressions are evaluated, when the environment is extended (and with which bindings), which environment is saved when the procedure is created, and so on. Pay special attention to procedure creation and application. A complete, detailed description of this process will be between a quarter of a page and half a page in length. To repeat:
a4.scm and submit it to Vincent. Comment-out your description using semi-colons (;), so that your file loads under Chez. Brainteaser: Write another interpreter, representation independent
with respect to both closures and environments (using any representation you
like), which includes support for multiple-argument lambda, let, let*, and d-lambda expressions.
Super Mondo Brainteaser!:
Add to your interpreter a limited version of the fluid-let form, named flet, which uses the following "macro" expansion:
(flet ((x e)) body)
=>
(let ((t x))
(begin
(set! x e)
(let ((v body))
(begin
(set! x t)
v))))
flet, you will need to add both set! and begin to your interpreter. Once you have done so, the following tests should pass:
(define flet-1
'(let ((x 3))
(let ((f (lambda () x)))
(flet ((x 4))
(f)))))
(define flet-2
'(let ((x 3))
(let ((f (lambda () x)))
(let ((x 5))
(flet ((x 4))
(f))))))
(test "flet-1"
(value-of flet-1 (empty-env))
4)
(test "flet-2"
(value-of flet-2 (empty-env))
3)