srfi-154- First-class dynamic extents
This module provides a convenent way to reify the dynamic environment.
A continuation captured by
call/cc includes the dynamic environment,
as well as the control flow. Sometimes you only want the dynamic enviornment
part. A dynamic extent is a reified dynamic environment.
Let’s see an example. You want a procedure that prints out
a message to the error port, so you wrote this
(define print-error (lambda (msg) (display msg (current-error-port))))
print-error is called while the current error port
is altered, it is affected. It is supposed to be so, that’s
the point of
(call-with-output-string (^p (with-error-to-port p (^ (print-error "abc\n"))))) ⇒ "abc\n"
If you do want
print-error to use the error port
at the time it is defined, you have to extract the dynamic value
at the moment.
(define print-error (let1 eport (current-error-port) (lambda (msg) (display msg eport))))
This would be quickly cumbersome when you need to capture multiple
dynamic values, or the original
print-error is called indirectly
and you can’t modify it the way shown above.
dynamic-lambda addresses this issue. It not only captures
the lexical environment, but also the dynamic environment when it
is evaluated. So the
current-error-port in its body
returns the current error port at the time of
being defined, not when it is called:
(define print-error (dynamic-lambda (msg) (display msg (current-error-port))))
Returns a dynamic-extent object that reifies the current dynamic environment.
#t iff obj is a dynamic-extent object.
Calls the thunk in the dynamic extent dynext, and returns the values yielded by thunk.
lambda, but this not only captures the lexical environment,
but also the dynamic environment. Yields a procedure.
dynamic-lambda needs to swap the dynamic environment
after executing body, the last expression of body isn’t
called in the tail contenxt even if the procedure created by
dynamic-lambda is called in tail context.