There is a whole zoo of delimited control operators, and as it does not seem to be a bounded set, Guile implements support for them in a separate module:
(use-modules (ice-9 control))
Firstly, we have a helpful abbreviation for the call-with-prompt
operator.
Evaluate expr in a prompt, optionally specifying a tag and a handler. If no tag is given, the default prompt tag is used.
If no handler is given, a default handler is installed. The default handler accepts a procedure of one argument, which will be called on the captured continuation, within a prompt.
Sometimes it’s easier just to show code, as in this case:
(define (default-prompt-handler k proc) (% (default-prompt-tag) (proc k) default-prompt-handler))
The %
symbol is chosen because it looks like a prompt.
Likewise there is an abbreviation for abort-to-prompt
, which
assumes the default prompt tag:
Abort to the default prompt tag, passing val1 val2 … to the handler.
As mentioned before, (ice-9 control)
also provides other
delimited control operators. This section is a bit technical, and
first-time users of delimited continuations should probably come back to
it after some practice with %
.
Still here? So, when one implements a delimited control operator like
call-with-prompt
, one needs to make two decisions. Firstly, does
the handler run within or outside the prompt? Having the handler run
within the prompt allows an abort inside the handler to return to the
same prompt handler, which is often useful. However it prevents tail
calls from the handler, so it is less general.
Similarly, does invoking a captured continuation reinstate a prompt? Again we have the tradeoff of convenience versus proper tail calls.
These decisions are captured in the Felleisen F operator. If
neither the continuations nor the handlers implicitly add a prompt, the
operator is known as –F–. This is the case for Guile’s
call-with-prompt
and abort-to-prompt
.
If both continuation and handler implicitly add prompts, then the
operator is +F+. shift
and reset
are such
operators.
Establish a prompt, and evaluate body1 body2 … within that prompt.
The prompt handler is designed to work with shift
, described
below.
Abort to the nearest reset
, and evaluate body1 body2
… in a context in which the captured continuation is bound to
cont.
As mentioned above, taken together, the body1 body2 … expressions and the invocations of cont implicitly establish a prompt.
Interested readers are invited to explore Oleg Kiselyov’s wonderful web site at http://okmij.org/ftp/, for more information on these operators.