Changes from arch/CVS synchronization
[bpt/guile.git] / doc / ref / api-control.texi
index 5f8037b..ed6411f 100644 (file)
@@ -20,8 +20,7 @@ flow of Scheme affects C code.
 * Multiple Values::             Returning and accepting multiple values.
 * Exceptions::                  Throwing and catching exceptions.
 * Error Reporting::             Procedures for signaling errors.
-* Dynamic Wind::                Guarding against non-local entrance/exit.
-* Frames::                      Another way to handle non-localness
+* Dynamic Wind::                Dealing with non-local entrance/exit.
 * Handling Errors::             How to handle errors in C code.
 @end menu
 
@@ -108,6 +107,26 @@ the @code{cond}-expression.  For the @code{=>} clause type,
 the value of @var{test}.  The result of this procedure application is
 then the result of the @code{cond}-expression.
 
+@cindex SRFI-61
+@cindex general cond clause
+@cindex multiple values and cond
+One additional @code{cond}-clause is available as an extension to
+standard Scheme:
+
+@lisp
+(@var{test} @var{guard} => @var{expression})
+@end lisp
+
+where @var{guard} and @var{expression} must evaluate to procedures.
+For this clause type, @var{test} may return multiple values, and
+@code{cond} ignores its boolean state; instead, @code{cond} evaluates
+@var{guard} and applies the resulting procedure to the value(s) of
+@var{test}, as if @var{guard} were the @var{consumer} argument of
+@code{call-with-values}.  Iff the result of that procedure call is a
+true value, it evaluates @var{expression} and applies the resulting
+procedure to the value(s) of @var{test}, in the same manner as the
+@var{guard} was called.
+
 The @var{test} of the last @var{clause} may be the symbol @code{else}.
 Then, if none of the preceding @var{test}s is true, the
 @var{expression}s following the @code{else} are evaluated to produce the
@@ -443,8 +462,7 @@ flow going on as normal.
 
 @code{dynamic-wind} (@pxref{Dynamic Wind}) can be used to ensure setup
 and cleanup code is run when a program locus is resumed or abandoned
-through the continuation mechanism.  C code can use @dfn{frames}
-(@pxref{Frames}).
+through the continuation mechanism.
 
 @sp 1
 Continuations are a powerful mechanism, and can be used to implement
@@ -526,20 +544,34 @@ of the call to @code{call-with-values}.
 @end deffn
 
 In addition to the fundamental procedures described above, Guile has a
-module which exports a syntax called @code{receive}, which is much more
-convenient.  If you want to use it in your programs, you have to load
-the module @code{(ice-9 receive)} with the statement
+module which exports a syntax called @code{receive}, which is much
+more convenient.  This is in the @code{(ice-9 receive)} and is the
+same as specified by SRFI-8 (@pxref{SRFI-8}).
 
 @lisp
 (use-modules (ice-9 receive))
 @end lisp
 
 @deffn {library syntax} receive formals expr body @dots{}
-Evaluate the expression @var{expr}, and bind the result values (zero or
-more) to the formal arguments in the formal argument list @var{formals}.
-@var{formals} must have the same syntax like the formal argument list
-used in @code{lambda} (@pxref{Lambda}).  After binding the variables,
-the expressions in @var{body} @dots{} are evaluated in order.
+Evaluate the expression @var{expr}, and bind the result values (zero
+or more) to the formal arguments in @var{formals}.  @var{formals} is a
+list of symbols, like the argument list in a @code{lambda}
+(@pxref{Lambda}).  After binding the variables, the expressions in
+@var{body} @dots{} are evaluated in order, the return value is the
+result from the last expression.
+
+For example getting results from @code{partition} in SRFI-1
+(@pxref{SRFI-1}),
+
+@example
+(receive (odds evens)
+    (partition odd? '(7 4 2 8 3))
+  (display odds)
+  (display " and ")
+  (display evens))
+@print{} (7 3) and (4 2 8)
+@end example
+
 @end deffn
 
 
@@ -582,8 +614,9 @@ more conveniently.
 @menu
 * Exception Terminology::       Different ways to say the same thing.
 * Catch::                       Setting up to catch exceptions.
-* Throw::                       Throwing an exception.
+* Throw Handlers::              Adding extra handling to a throw.
 * Lazy Catch::                  Catch without unwinding the stack.
+* Throw::                       Throwing an exception.
 * Exception Implementation::    How Guile implements exceptions.
 @end menu
 
@@ -622,11 +655,11 @@ this terminology matches the corresponding Guile primitives.
 @code{catch} is used to set up a target for a possible non-local jump.
 The arguments of a @code{catch} expression are a @dfn{key}, which
 restricts the set of exceptions to which this @code{catch} applies, a
-thunk that specifies the code to execute and a @dfn{handler} procedure
-that says what to do if an exception is thrown while executing the code.
-Note that if the execution thunk executes @dfn{normally}, which means
-without throwing any exceptions, the handler procedure is not called at
-all.
+thunk that specifies the code to execute and one or two @dfn{handler}
+procedures that say what to do if an exception is thrown while executing
+the code.  If the execution thunk executes @dfn{normally}, which means
+without throwing any exceptions, the handler procedures are not called
+at all.
 
 When an exception is thrown using the @code{throw} function, the first
 argument of the @code{throw} is a symbol that indicates the type of the
@@ -661,7 +694,18 @@ procedure must be designed to accept a number of arguments that
 corresponds to the number of arguments in all @code{throw} expressions
 that can be caught by this @code{catch}.
 
-@deffn {Scheme Procedure} catch key thunk handler
+The fourth, optional argument of a @code{catch} expression is another
+handler procedure, called the @dfn{pre-unwind} handler.  It differs from
+the third argument in that if an exception is thrown, it is called,
+@emph{before} the third argument handler, in exactly the dynamic context
+of the @code{throw} expression that threw the exception.  This means
+that it is useful for capturing or displaying the stack at the point of
+the @code{throw}, or for examining other aspects of the dynamic context,
+such as fluid values, before the context is unwound back to that of the
+prevailing @code{catch}.
+
+@deffn {Scheme Procedure} catch key thunk handler [pre-unwind-handler]
+@deffnx {C Function} scm_catch_with_pre_unwind_handler (key, thunk, handler, pre_unwind_handler)
 @deffnx {C Function} scm_catch (key, thunk, handler)
 Invoke @var{thunk} in the dynamic context of @var{handler} for
 exceptions matching @var{key}.  If thunk throws to the symbol
@@ -681,9 +725,24 @@ from further up the call chain is invoked.
 
 If the key is @code{#t}, then a throw to @emph{any} symbol will
 match this call to @code{catch}.
+
+If a @var{pre-unwind-handler} is given and @var{thunk} throws
+an exception that matches @var{key}, Guile calls the
+@var{pre-unwind-handler} before unwinding the dynamic state and
+invoking the main @var{handler}.  @var{pre-unwind-handler} should
+be a procedure with the same signature as @var{handler}, that
+is @code{(lambda (key . args))}.  It is typically used to save
+the stack at the point where the exception occurred, but can also
+query other parts of the dynamic state at that point, such as
+fluid values.
+
+A @var{pre-unwind-handler} can exit either normally or non-locally.
+If it exits normally, Guile unwinds the stack and dynamic context
+and then calls the normal (third argument) handler.  If it exits
+non-locally, that exit determines the continuation.
 @end deffn
 
-If the handler procedure needs to match a variety of @code{throw}
+If a handler procedure needs to match a variety of @code{throw}
 expressions with varying numbers of arguments, you should write it like
 this:
 
@@ -699,24 +758,26 @@ interpretation of the @var{args} varies from one type of exception to
 another, but should be specified by the documentation for each exception
 type.
 
-Note that, once the handler procedure is invoked, the catch that led to
-the handler procedure being called is no longer active.  Therefore, if
-the handler procedure itself throws an exception, that exception can
-only be caught by another active catch higher up the call stack, if
-there is one.
+Note that, once the normal (post-unwind) handler procedure is invoked,
+the catch that led to the handler procedure being called is no longer
+active.  Therefore, if the handler procedure itself throws an exception,
+that exception can only be caught by another active catch higher up the
+call stack, if there is one.
 
 @sp 1
-@deftypefn {C Function} SCM scm_internal_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data)
-The above @code{scm_catch} takes Scheme procedures as body and handler
-arguments.  @code{scm_internal_catch} is an equivalent taking C
-functions.
-
-@var{body} is called as @code{@var{body} (@var{body_data})} with a
-catch on exceptions of the given @var{tag} type.  If an exception is
-caught, @var{handler} is called @code{@var{handler}
-(@var{handler_data}, @var{key}, @var{args})}.  @var{key} and
-@var{args} are the @code{SCM} key and argument list from the
-@code{throw}.
+@deftypefn {C Function} SCM scm_c_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data, scm_t_catch_handler pre_unwind_handler, void *pre_unwind_handler_data)
+@deftypefnx {C Function} SCM scm_internal_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data)
+The above @code{scm_catch_with_pre_unwind_handler} and @code{scm_catch}
+take Scheme procedures as body and handler arguments.
+@code{scm_c_catch} and @code{scm_internal_catch} are equivalents taking
+C functions.
+
+@var{body} is called as @code{@var{body} (@var{body_data})} with a catch
+on exceptions of the given @var{tag} type.  If an exception is caught,
+@var{pre_unwind_handler} and @var{handler} are called as
+@code{@var{handler} (@var{handler_data}, @var{key}, @var{args})}.
+@var{key} and @var{args} are the @code{SCM} key and argument list from
+the @code{throw}.
 
 @tpindex scm_t_catch_body
 @tpindex scm_t_catch_handler
@@ -743,73 +804,58 @@ Operations}).
 @end deftypefn
 
 
-@node Throw
-@subsubsection Throwing Exceptions
-
-The @code{throw} primitive is used to throw an exception.  One argument,
-the @var{key}, is mandatory, and must be a symbol; it indicates the type
-of exception that is being thrown.  Following the @var{key},
-@code{throw} accepts any number of additional arguments, whose meaning
-depends on the exception type.  The documentation for each possible type
-of exception should specify the additional arguments that are expected
-for that kind of exception.
-
-@deffn {Scheme Procedure} throw key . args
-@deffnx {C Function} scm_throw (key, args)
-Invoke the catch form matching @var{key}, passing @var{args} to the
-@var{handler}.  
+@node Throw Handlers
+@subsubsection Throw Handlers
 
-@var{key} is a symbol.  It will match catches of the same symbol or of
-@code{#t}.
+It's sometimes useful to be able to intercept an exception that is being
+thrown, but without changing where in the dynamic context that exception
+will eventually be caught.  This could be to clean up some related state
+or to pass information about the exception to a debugger, for example.
+The @code{with-throw-handler} procedure provides a way to do this.
 
-If there is no handler at all, Guile prints an error and then exits.
+@deffn {Scheme Procedure} with-throw-handler key thunk handler
+@deffnx {C Function} scm_with_throw_handler (key, thunk, handler)
+Add @var{handler} to the dynamic context as a throw handler
+for key @var{key}, then invoke @var{thunk}.
 @end deffn
 
-When an exception is thrown, it will be caught by the innermost
-@code{catch} expression that applies to the type of the thrown
-exception; in other words, the innermost @code{catch} whose @var{key} is
-@code{#t} or is the same symbol as that used in the @code{throw}
-expression.  Once Guile has identified the appropriate @code{catch}, it
-handles the exception by applying that @code{catch} expression's handler
-procedure to the arguments of the @code{throw}.
-
-If there is no appropriate @code{catch} for a thrown exception, Guile
-prints an error to the current error port indicating an uncaught
-exception, and then exits.  In practice, it is quite difficult to
-observe this behaviour, because Guile when used interactively installs a
-top level @code{catch} handler that will catch all exceptions and print
-an appropriate error message @emph{without} exiting.  For example, this
-is what happens if you try to throw an unhandled exception in the
-standard Guile REPL; note that Guile's command loop continues after the
-error message:
-
-@lisp
-guile> (throw 'badex)
-<unnamed port>:3:1: In procedure gsubr-apply @dots{}
-<unnamed port>:3:1: unhandled-exception: badex
-ABORT: (misc-error)
-guile> 
-@end lisp
-
-The default uncaught exception behaviour can be observed by evaluating a
-@code{throw} expression from the shell command line:
-
-@example
-$ guile -c "(begin (throw 'badex) (display \"here\\n\"))"
-guile: uncaught throw to badex: ()
-$ 
-@end example
+@deftypefn {C Function} SCM scm_c_with_throw_handler (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data, int lazy_catch_p)
+The above @code{scm_with_throw_handler} takes Scheme procedures as body
+(thunk) and handler arguments.  @code{scm_c_with_throw_handler} is an
+equivalent taking C functions.  See @code{scm_c_catch} (@pxref{Catch})
+for a description of the parameters, the behaviour however of course
+follows @code{with-throw-handler}.
+@end deftypefn
 
-@noindent
-That Guile exits immediately following the uncaught exception
-is shown by the absence of any output from the @code{display}
-expression, because Guile never gets to the point of evaluating that
-expression.
+If @var{thunk} throws an exception, Guile handles that exception by
+invoking the innermost @code{catch} or throw handler whose key matches
+that of the exception.  When the innermost thing is a throw handler,
+Guile calls the specified handler procedure using @code{(apply
+@var{handler} key args)}.  The handler procedure may either return
+normally or exit non-locally.  If it returns normally, Guile passes the
+exception on to the next innermost @code{catch} or throw handler.  If it
+exits non-locally, that exit determines the continuation.
+
+The behaviour of a throw handler is very similar to that of a
+@code{catch} expression's optional pre-unwind handler.  In particular, a
+throw handler's handler procedure is invoked in the exact dynamic
+context of the @code{throw} expression, just as a pre-unwind handler is.
+@code{with-throw-handler} may be seen as a half-@code{catch}: it does
+everything that a @code{catch} would do until the point where
+@code{catch} would start unwinding the stack and dynamic context, but
+then it rethrows to the next innermost @code{catch} or throw handler
+instead.
 
 
 @node Lazy Catch
 @subsubsection Catch Without Unwinding
 
+Before version 1.8, Guile's closest equivalent to
+@code{with-throw-handler} was @code{lazy-catch}.  From version 1.8
+onwards we recommend using @code{with-throw-handler} because its
+behaviour is more useful than that of @code{lazy-catch}, but
+@code{lazy-catch} is still supported as well.
+
 A @dfn{lazy catch} is used in the same way as a normal @code{catch},
 with @var{key}, @var{thunk} and @var{handler} arguments specifying the
 exception type, normal case code and handler procedure, but differs in
@@ -821,8 +867,10 @@ that caused the handler to be invoked.
 @deffnx {C Function} scm_lazy_catch (key, thunk, handler)
 This behaves exactly like @code{catch}, except that it does
 not unwind the stack before invoking @var{handler}.
-The @var{handler} procedure is not allowed to return:
-it must throw to another catch, or otherwise exit non-locally.
+If the @var{handler} procedure returns normally, Guile
+rethrows the same exception again to the next innermost catch,
+lazy-catch or throw handler.  If the @var{handler} exits
+non-locally, that exit determines the continuation.
 @end deffn
 
 @deftypefn {C Function} SCM scm_internal_lazy_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data)
@@ -833,11 +881,9 @@ a description of the parameters, the behaviour however of course
 follows @code{lazy-catch}.
 @end deftypefn
 
-Typically, @var{handler} should save any desired state associated with
-the stack at the point where the corresponding @code{throw} occurred,
-and then throw an exception itself --- usually the same exception as the
-one it caught.  If @var{handler} is invoked and does @emph{not} throw an
-exception, Guile itself throws an exception with key @code{misc-error}.
+Typically @var{handler} is used to display a backtrace of the stack at
+the point where the corresponding @code{throw} occurred, or to save off
+this information for possible display later.
 
 Not unwinding the stack means that throwing an exception that is caught
 by a @code{lazy-catch} is @emph{almost} equivalent to calling the
@@ -908,6 +954,123 @@ debuggers and other reflective programming tools that need to access the
 state of the call stack at the exact point where an exception or an
 error is thrown.  For an example of this, see REFFIXME:stack-catch.
 
+It should be obvious from the above that @code{lazy-catch} is very
+similar to @code{with-throw-handler}.  In fact Guile implements
+@code{lazy-catch} in exactly the same way as @code{with-throw-handler},
+except with a flag set to say ``where there are slight differences
+between what @code{with-throw-handler} and @code{lazy-catch} would do,
+do what @code{lazy-catch} has always done''.  There are two such
+differences:
+
+@enumerate
+@item
+@code{with-throw-handler} handlers execute in the full dynamic context
+of the originating @code{throw} call.  @code{lazy-catch} handlers
+execute in the dynamic context of the @code{lazy-catch} expression,
+excepting only that the stack has not yet been unwound from the point of
+the @code{throw} call.
+
+@item
+If a @code{with-throw-handler} handler throws to a key that does not
+match the @code{with-throw-handler} expression's @var{key}, the new
+throw may be handled by a @code{catch} or throw handler that is _closer_
+to the throw than the first @code{with-throw-handler}.  If a
+@code{lazy-catch} handler throws, it will always be handled by a
+@code{catch} or throw handler that is higher up the dynamic context than
+the first @code{lazy-catch}.
+@end enumerate
+
+Here is an example to illustrate the second difference:
+
+@lisp
+(catch 'a
+  (lambda ()
+    (with-throw-handler 'b
+      (lambda ()
+        (catch 'a
+          (lambda ()
+            (throw 'b))
+          inner-handler))
+      (lambda (key . args)
+        (throw 'a))))
+  outer-handler)
+@end lisp
+
+@noindent
+This code will call @code{inner-handler} and then continue with the
+continuation of the inner @code{catch}.  If the
+@code{with-throw-handler} was changed to @code{lazy-catch}, however, the
+code would call @code{outer-handler} and then continue with the
+continuation of the outer @code{catch}.
+
+Modulo these two differences, any statements in the previous and
+following subsections about throw handlers apply to lazy catches as
+well.
+
+
+@node Throw
+@subsubsection Throwing Exceptions
+
+The @code{throw} primitive is used to throw an exception.  One argument,
+the @var{key}, is mandatory, and must be a symbol; it indicates the type
+of exception that is being thrown.  Following the @var{key},
+@code{throw} accepts any number of additional arguments, whose meaning
+depends on the exception type.  The documentation for each possible type
+of exception should specify the additional arguments that are expected
+for that kind of exception.
+
+@deffn {Scheme Procedure} throw key . args
+@deffnx {C Function} scm_throw (key, args)
+Invoke the catch form matching @var{key}, passing @var{args} to the
+@var{handler}.  
+
+@var{key} is a symbol.  It will match catches of the same symbol or of
+@code{#t}.
+
+If there is no handler at all, Guile prints an error and then exits.
+@end deffn
+
+When an exception is thrown, it will be caught by the innermost
+@code{catch} or throw handler that applies to the type of the thrown
+exception; in other words, whose @var{key} is either @code{#t} or the
+same symbol as that used in the @code{throw} expression.  Once Guile has
+identified the appropriate @code{catch} or throw handler, it handles the
+exception by applying the relevant handler procedure(s) to the arguments
+of the @code{throw}.
+
+If there is no appropriate @code{catch} or throw handler for a thrown
+exception, Guile prints an error to the current error port indicating an
+uncaught exception, and then exits.  In practice, it is quite difficult
+to observe this behaviour, because Guile when used interactively
+installs a top level @code{catch} handler that will catch all exceptions
+and print an appropriate error message @emph{without} exiting.  For
+example, this is what happens if you try to throw an unhandled exception
+in the standard Guile REPL; note that Guile's command loop continues
+after the error message:
+
+@lisp
+guile> (throw 'badex)
+<unnamed port>:3:1: In procedure gsubr-apply @dots{}
+<unnamed port>:3:1: unhandled-exception: badex
+ABORT: (misc-error)
+guile> 
+@end lisp
+
+The default uncaught exception behaviour can be observed by evaluating a
+@code{throw} expression from the shell command line:
+
+@example
+$ guile -c "(begin (throw 'badex) (display \"here\\n\"))"
+guile: uncaught throw to badex: ()
+$ 
+@end example
+
+@noindent
+That Guile exits immediately following the uncaught exception
+is shown by the absence of any output from the @code{display}
+expression, because Guile never gets to the point of evaluating that
+expression.
+
 
 @node Exception Implementation
 @subsubsection How Guile Implements Exceptions
@@ -974,8 +1137,12 @@ it will usually be @code{#f}.
 
 @deffn {Scheme Procedure} strerror err
 @deffnx {C Function} scm_strerror (err)
-Return the Unix error message corresponding to @var{err}, which
-must be an integer value.
+Return the Unix error message corresponding to @var{err}, an integer
+@code{errno} value.
+
+When @code{setlocale} has been called (@pxref{Locales}), the message
+is in the language and charset of @code{LC_MESSAGES}.  (This is done
+by the C library.)
 @end deffn
 
 @c begin (scm-doc-string "boot-9.scm" "false-if-exception")
@@ -989,78 +1156,22 @@ if an exception occurs then @code{#f} is returned instead.
 @node Dynamic Wind
 @subsection Dynamic Wind
 
-@rnindex dynamic-wind
-@deffn {Scheme Procedure} dynamic-wind in_guard thunk out_guard
-@deffnx {C Function} scm_dynamic_wind (in_guard, thunk, out_guard)
-All three arguments must be 0-argument procedures.
-@var{in_guard} is called, then @var{thunk}, then
-@var{out_guard}.
-
-If, any time during the execution of @var{thunk}, the
-dynamic extent of the @code{dynamic-wind} expression is escaped
-non-locally, @var{out_guard} is called.  If the dynamic extent of
-the dynamic-wind is re-entered, @var{in_guard} is called.  Thus
-@var{in_guard} and @var{out_guard} may be called any number of
-times.
-@lisp
-(define x 'normal-binding)
-@result{} x
-(define a-cont  (call-with-current-continuation
-                  (lambda (escape)
-                     (let ((old-x x))
-                       (dynamic-wind
-                          ;; in-guard:
-                          ;;
-                          (lambda () (set! x 'special-binding))
-
-                          ;; thunk
-                          ;;
-                          (lambda () (display x) (newline)
-                                     (call-with-current-continuation escape)
-                                     (display x) (newline)
-                                     x)
-
-                          ;; out-guard:
-                          ;;
-                          (lambda () (set! x old-x)))))))
-
-;; Prints:
-special-binding
-;; Evaluates to:
-@result{} a-cont
-x
-@result{} normal-binding
-(a-cont #f)
-;; Prints:
-special-binding
-;; Evaluates to:
-@result{} a-cont  ;; the value of the (define a-cont...)
-x
-@result{} normal-binding
-a-cont
-@result{} special-binding
-@end lisp
-@end deffn
-
-@node Frames
-@subsection Frames
-
 For Scheme code, the fundamental procedure to react to non-local entry
-and exits of dynamic contexts is @code{dynamic-wind}.  C code could use
-@code{scm_internal_dynamic_wind}, but since C does not allow the
-convenient construction of anonymous procedures that close over lexical
-variables, this will be, well, inconvenient.  Instead, C code can use
-@dfn{frames}.
-
-Guile offers the functions @code{scm_frame_begin} and
-@code{scm_frame_end} to delimit a dynamic extent.  Within this dynamic
-extent, which is called a @dfn{frame}, you can perform various
-@dfn{frame actions} that control what happens when the frame is entered
-or left.  For example, you can register a cleanup routine with
-@code{scm_frame_unwind} that is executed when the frame is left.  There are
-several other more specialized frame actions as well, for example to
-temporarily block the execution of asyncs or to temporarily change the
-current output port.  They are described elsewhere in this manual.
+and exits of dynamic contexts is @code{dynamic-wind}.  C code could
+use @code{scm_internal_dynamic_wind}, but since C does not allow the
+convenient construction of anonymous procedures that close over
+lexical variables, this will be, well, inconvenient.
+
+Therefore, Guile offers the functions @code{scm_dynwind_begin} and
+@code{scm_dynwind_end} to delimit a dynamic extent.  Within this
+dynamic extent, which is called a @dfn{dynwind context}, you can
+perform various @dfn{dynwind actions} that control what happens when
+the dynwind context is entered or left.  For example, you can register
+a cleanup routine with @code{scm_dynwind_unwind_handler} that is
+executed when the context is left.  There are several other more
+specialized dynwind actions as well, for example to temporarily block
+the execution of asyncs or to temporarily change the current output
+port.  They are described elsewhere in this manual.
 
 Here is an example that shows how to prevent memory leaks.
 
@@ -1086,51 +1197,107 @@ scm_foo (SCM s1, SCM s2)
 @{
   char *c_s1, *c_s2, *c_res;
 
-  scm_frame_begin (0);
+  scm_dynwind_begin (0);
 
   c_s1 = scm_to_locale_string (s1);
 
-  /* Call 'free (c_s1)' when the frame is left. 
+  /* Call 'free (c_s1)' when the dynwind context is left. 
   */
-  scm_frame_unwind_handler (free, c_s1, SCM_F_WIND_EXPLICITLY);
+  scm_dynwind_unwind_handler (free, c_s1, SCM_F_WIND_EXPLICITLY);
 
   c_s2 = scm_to_locale_string (s2);
   
   /* Same as above, but more concisely.
   */
-  scm_frame_free (c_s2);
+  scm_dynwind_free (c_s2);
 
   c_res = foo (c_s1, c_s2);
   if (c_res == NULL)
     scm_memory_error ("foo");
 
-  scm_frame_end ();
+  scm_dynwind_end ();
 
   return scm_take_locale_string (res);
 @}
 @end example
 
-@deftp {C Type} scm_t_frame_flags
+@rnindex dynamic-wind
+@deffn {Scheme Procedure} dynamic-wind in_guard thunk out_guard
+@deffnx {C Function} scm_dynamic_wind (in_guard, thunk, out_guard)
+All three arguments must be 0-argument procedures.
+@var{in_guard} is called, then @var{thunk}, then
+@var{out_guard}.
+
+If, any time during the execution of @var{thunk}, the
+dynamic extent of the @code{dynamic-wind} expression is escaped
+non-locally, @var{out_guard} is called.  If the dynamic extent of
+the dynamic-wind is re-entered, @var{in_guard} is called.  Thus
+@var{in_guard} and @var{out_guard} may be called any number of
+times.
+
+@lisp
+(define x 'normal-binding)
+@result{} x
+(define a-cont
+  (call-with-current-continuation
+   (lambda (escape)
+     (let ((old-x x))
+       (dynamic-wind
+           ;; in-guard:
+           ;;
+           (lambda () (set! x 'special-binding))
+
+           ;; thunk
+           ;;
+           (lambda () (display x) (newline)
+                      (call-with-current-continuation escape)
+                      (display x) (newline)
+                      x)
+
+           ;; out-guard:
+           ;;
+           (lambda () (set! x old-x)))))))
+;; Prints:
+special-binding
+;; Evaluates to:
+@result{} a-cont
+x
+@result{} normal-binding
+(a-cont #f)
+;; Prints:
+special-binding
+;; Evaluates to:
+@result{} a-cont  ;; the value of the (define a-cont...)
+x
+@result{} normal-binding
+a-cont
+@result{} special-binding
+@end lisp
+@end deffn
+
+@deftp {C Type} scm_t_dynwind_flags
 This is an enumeration of several flags that modify the behavior of
-@code{scm_begin_frame}.  The flags are listed in the following table.
+@code{scm_dynwind_begin}.  The flags are listed in the following
+table.
 
 @table @code
-@item SCM_F_FRAME_REWINDABLE
-The frame is @dfn{rewindable}.  This means that it can be reentered
-non-locally (via the invokation of a continuation).  The default is that
-a frame can not be reentered non-locally.
+@item SCM_F_DYNWIND_REWINDABLE
+The dynamic context is @dfn{rewindable}.  This means that it can be
+reentered non-locally (via the invokation of a continuation).  The
+default is that a dynwind context can not be reentered non-locally.
 @end table
 
 @end deftp
 
-@deftypefn {C Function} void scm_frame_begin (scm_t_frame_flags flags)
-The function @code{scm_begin_frame} starts a new frame and makes it the
-`current' one.  
+@deftypefn {C Function} void scm_dynwind_begin (scm_t_dynwind_flags flags)
+The function @code{scm_dynwind_begin} starts a new dynamic context and
+makes it the `current' one.
 
-The @var{flags} argument determines the default behavior of the frame.
-For normal frames, use 0.  This will result in a frame that can not be
-reentered with a captured continuation.  When you are prepared to handle
-reentries, include @code{SCM_F_FRAME_REWINDABLE} in @var{flags}.
+The @var{flags} argument determines the default behavior of the
+context.  Normally, use 0.  This will result in a context that can not
+be reentered with a captured continuation.  When you are prepared to
+handle reentries, include @code{SCM_F_DYNWIND_REWINDABLE} in
+@var{flags}.
 
 Being prepared for reentry means that the effects of unwind handlers
 can be undone on reentry.  In the example above, we want to prevent a
@@ -1139,54 +1306,64 @@ frees the memory.  But once the memory is freed, we can not get it
 back on reentry.  Thus reentry can not be allowed.
 
 The consequence is that continuations become less useful when
-non-reenterable frames are captured, but you don't need to worry about
-that too much.
-
-The frame is ended either implicitly when a non-local exit happens, or
-explicitly with @code{scm_end_frame}.  You must make sure that a frame
-is indeed ended properly.  If you fail to call @code{scm_end_frame}
-for each @code{scm_begin_frame}, the behavior is undefined.
+non-reenterable contexts are captured, but you don't need to worry
+about that too much.
+
+The context is ended either implicitly when a non-local exit happens,
+or explicitly with @code{scm_dynwind_end}.  You must make sure that a
+dynwind context is indeed ended properly.  If you fail to call
+@code{scm_dynwind_end} for each @code{scm_dynwind_begin}, the behavior
+is undefined.
 @end deftypefn
 
-@deftypefn {C Function} void scm_frame_end ()
-End the current frame explicitly and make the previous frame current.
+@deftypefn {C Function} void scm_dynwind_end ()
+End the current dynamic context explicitly and make the previous one
+current.
 @end deftypefn
 
 @deftp {C Type} scm_t_wind_flags
 This is an enumeration of several flags that modify the behavior of
-@code{scm_on_unwind_handler} and @code{scm_on_rewind_handler}.  The
-flags are listed in the following table.
+@code{scm_dynwind_unwind_handler} and
+@code{scm_dynwind_rewind_handler}.  The flags are listed in the
+following table.
 
 @table @code
 @item SCM_F_WIND_EXPLICITLY
 @vindex SCM_F_WIND_EXPLICITLY
-The registered action is also carried out when the frame is entered or
-left locally.
+The registered action is also carried out when the dynwind context is
+entered or left locally.
 @end table
 @end deftp
 
-@deftypefn {C Function} void scm_frame_unwind_handler (void (*func)(void *), void *data, scm_t_wind_flags flags)
-@deftypefnx {C Function} void scm_frame_unwind_handler_with_scm (void (*func)(SCM), SCM data, scm_t_wind_flags flags)
+@deftypefn {C Function} void scm_dynwind_unwind_handler (void (*func)(void *), void *data, scm_t_wind_flags flags)
+@deftypefnx {C Function} void scm_dynwind_unwind_handler_with_scm (void (*func)(SCM), SCM data, scm_t_wind_flags flags)
 Arranges for @var{func} to be called with @var{data} as its arguments
-when the current frame ends implicitly.  If @var{flags} contains
-@code{SCM_F_WIND_EXPLICITLY}, @var{func} is also called when the frame
-ends explicitly with @code{scm_frame_end}.
+when the current context ends implicitly.  If @var{flags} contains
+@code{SCM_F_WIND_EXPLICITLY}, @var{func} is also called when the
+context ends explicitly with @code{scm_dynwind_end}.
 
-The function @code{scm_frame_unwind_handler_with_scm} takes care that
+The function @code{scm_dynwind_unwind_handler_with_scm} takes care that
 @var{data} is protected from garbage collection.
 @end deftypefn
 
-@deftypefn {C Function} void scm_frame_rewind_handler (void (*func)(void *), void *data, scm_t_wind_flags flags)
-@deftypefnx {C Function} void scm_frame_rewind_handler_with_scm (void (*func)(SCM), SCM data, scm_t_wind_flags flags)
+@deftypefn {C Function} void scm_dynwind_rewind_handler (void (*func)(void *), void *data, scm_t_wind_flags flags)
+@deftypefnx {C Function} void scm_dynwind_rewind_handler_with_scm (void (*func)(SCM), SCM data, scm_t_wind_flags flags)
 Arrange for @var{func} to be called with @var{data} as its argument when
-the current frame is restarted by rewinding the stack.  When @var{flags}
+the current context is restarted by rewinding the stack.  When @var{flags}
 contains @code{SCM_F_WIND_EXPLICITLY}, @var{func} is called immediately
 as well.
 
-The function @code{scm_frame_rewind_handler_with_scm} takes care that
+The function @code{scm_dynwind_rewind_handler_with_scm} takes care that
 @var{data} is protected from garbage collection.
 @end deftypefn
 
+@deftypefn {C Function} void scm_dynwind_free (void *mem)
+Arrange for @var{mem} to be freed automatically whenever the current
+context is exited, whether normally or non-locally.
+@code{scm_dynwind_free (mem)} is an equivalent shorthand for
+@code{scm_dynwind_unwind_handler (free, mem, SCM_F_WIND_EXPLICITLY)}.
+@end deftypefn
+
 
 @node Handling Errors
 @subsection How to Handle Errors
@@ -1299,7 +1476,7 @@ In the following C functions, @var{SUBR} and @var{MESSAGE} parameters
 can be @code{NULL} to give the effect of @code{#f} described above.
 
 @deftypefn {C Function} SCM scm_error (SCM @var{key}, char *@var{subr}, char *@var{message}, SCM @var{args}, SCM @var{rest})
-Throw an error, as per @code{scm-error} above.
+Throw an error, as per @code{scm-error} (@pxref{Error Reporting}).
 @end deftypefn
 
 @deftypefn {C Function} void scm_syserror (char *@var{subr})