srfi.154
- First-class dynamic extents ¶This module provides a convenient 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 environment
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 print-error
:
(define print-error (lambda (msg) (display msg (current-error-port))))
However, if 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 current-error-port
.
(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.
Using 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 print-error
being defined, not when it is called:
(define print-error (dynamic-lambda (msg) (display msg (current-error-port))))
[SRFI-154]{srfi.154
}
Returns a dynamic-extent object that reifies the current dynamic
environment.
[SRFI-154]{srfi.154
}
Returns #t
iff obj is a dynamic-extent object.
[SRFI-154]{srfi.154
}
Calls the thunk in the dynamic extent dynext, and
returns the values yielded by thunk.
[SRFI-154]{srfi.154
}
Like lambda
, but this not only captures the lexical environment,
but also the dynamic environment. Yields a procedure.
Note: Since dynamic-lambda
needs to swap the dynamic environment
after executing body, the last expression of body isn’t
called in the tail context even if the procedure created by
dynamic-lambda
is called in tail context.