Introduction
Scope
Consider a primitive {call-with {id v1} fex v2}
which is equivalent to
{{let1 id v1 fex} v2}
except that the call is dynamically scoped with respect to id (and
only id). Complete the callWith case of interp (below), so
that the following (parser-free) tests pass.
(module+ test
(print-only-errors #t)
(define (example body)
(let1E 'x (numE 3)
(let1E 'f (lamE 'y (plusE (varE 'x) (varE 'y)))
body)))
(test (interp (example (appE (varE 'f) (numE 4))) mt-env)
(numV 7))
(test (interp
(example (callWith 'x (numE 5) (varE 'f) (numE 4))) mt-env)
(numV 9))
(define (interp expr env)
(type-case Exp expr
⋮
[(let1E bound-id named-expr bound-body)
(interp bound-body (extend env bound-id (interp named-expr env)))]
[(lamE bound-id bound-body) (lamV bound-id bound-body env)]
[(callWith with-id with-expr fun-expr arg-expr)
(type-case Value (interp fun-expr env)
[(lamV fun-param body-exp def-env)
___________________________________________________________________
___________________________________________________________________
___________________________________________________________________
___________________________________________________________________
___________________________________________________________________
]
[else (error 'interp "not a function")])]
[(appE fun-expr arg-expr)
(let ([fval (interp fun-expr env)])
(type-case Value fval
[(lamV bound-id bound-body f-env)
(interp bound-body
(extend f-env bound-id (interp arg-expr env)))]
[else (error 'interp
(string-append "`call' expects a function, got: "
(to-string fval)))]))]
Racket Continuations
Use let/cc to complete function target so that the
following continuation based loop works (the working version
prints “109876543210”)
(define (undefined-label v) (error 'goto "undefined label"))
(define target-continuation undefined-label)
(define (target)
_______________________________________________
_______________________________________________
_______________________________________________
_______________________________________________)
(define (jump)
(target-continuation (void)))
(define n 10)
(begin
(target)
(display n)
(when (> n 0)
(begin
(set! n (sub1 n))
(jump))))