GNU Info

Info Node: (librep.info)Continuations

(librep.info)Continuations


Prev: Non-Local Exits Up: Control Structures
Enter node , (file) or (file)node

Continuations
=============

   Whenever a function is called, there is a control path waiting to
receive the result of the function, e.g. often the form following the
function invocation. This waiting control path is called the
"continuation" of the function, since control will continue down this
path when the called function exits.

   These continuations are usually not paid much thought, but in some
cases it may be useful to be able to directly manipulate the
continuation of a function. For this purpose rep provides the
`call-with-current-continuation' function (often shortened to
`call/cc') that is standard in the Scheme dialect of Lisp.

 - Function: call/cc function
     FUNCTION is a function with a single parameter; it will be
     immediately invoked with this parameter bound to an object
     representing the current continuation (i.e. the control path that
     would be taken after FUNCTION exits).

     The continuation object passed to FUNCTION is itself a function
     accepting a single argument, when called it transfers control to
     the continuation of FUNCTION, as if FUNCTION had returned the
     argument applied to the continuation object.

 - Function: call-with-current-continuation function
     This is an alias for `call/cc'.

   In its simplest form, `call/cc' can mimic the `catch' and `throw'
procedures (Note: Catch and Throw), for example:

     (defun foo (bar)
       (call/cc (lambda (esc)
                  (when (null bar)
                    ;; throws out of the call/cc
                    (esc nil))
                  ;; do something with bar
                  ...

this is roughly equivalent to:

     (defun foo (bar)
       (catch 'tag
         (when (null bar)
           (throw 'tag nil))
         ;; do something with bar
         ...

   This is only half the story--the most powerful feature of `call/cc'
is that since continuations have dynamic extent (that is, no object is
freed until no references to it exist) it is possible to return control
to scopes that have already exited.

   For example, consider the following fragment of a lisp interaction:

     (prog1 (call/cc (lambda (esc)
                       (setq cont esc)))
       (message "foo!"))
         -| foo!
         => #<closure>
     
     cont
         => #<closure>
     
     (cont 10)
         -| foo!
         => 10

The continuation of the `prog1' form is saved into the variable `cont'.
When subsequently called with a single argument, it has exactly the
same effect as the first time that the second form in the `prog1'
construct was evaluated.

Implementation Notes
--------------------

   `call/cc' works by making a copy of the process' entire call stack.
For this reason, it is likely to be less efficient than using the
control structures described in the previous parts of this section.  Of
course, it is much more powerful than the other constructs, so this
often outweighs the slight inefficiency.

   Also note that currently no attempt is made to save or restore the
dynamic state of the Lisp system, apart from variable bindings (both
lexical and special). This means that any `unwind-protect',
`condition-case' or `catch' forms that are active when invoking a
continuation are all ignored.

   Another restriction is that invoking a continuation may not cause
control to pass across a dynamic root (Note: Threads).


automatically generated by info2www version 1.2.2.9