Merge remote-tracking branch 'origin/stable-2.0'
[bpt/guile.git] / doc / ref / api-control.texi
index ed6411f..d8b6a45 100644 (file)
@@ -1,10 +1,9 @@
 @c -*-texinfo-*-
 @c This is part of the GNU Guile Reference Manual.
-@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004
+@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011, 2012
 @c   Free Software Foundation, Inc.
 @c See the file guile.texi for copying conditions.
 
-@page
 @node Control Mechanisms
 @section Controlling the Flow of Program Execution
 
@@ -12,56 +11,105 @@ See @ref{Control Flow} for a discussion of how the more general control
 flow of Scheme affects C code.
 
 @menu
-* begin::                       Evaluating a sequence of expressions.
-* if cond case::                Simple conditional evaluation.
+* begin::                       Sequencing and splicing.
+* Conditionals::                If, when, unless, case, and cond.
 * and or::                      Conditional evaluation of a sequence.
 * while do::                    Iteration mechanisms.
-* Continuations::               Continuations.
+* Prompts::                     Composable, delimited continuations.
+* Continuations::               Non-composable continuations.
 * Multiple Values::             Returning and accepting multiple values.
 * Exceptions::                  Throwing and catching exceptions.
 * Error Reporting::             Procedures for signaling errors.
 * Dynamic Wind::                Dealing with non-local entrance/exit.
 * Handling Errors::             How to handle errors in C code.
+* Continuation Barriers::       Protection from non-local control flow.
 @end menu
 
 @node begin
-@subsection Evaluating a Sequence of Expressions
+@subsection Sequencing and Splicing
 
 @cindex begin
 @cindex sequencing
 @cindex expression sequencing
 
-The @code{begin} syntax is used for grouping several expressions
-together so that they are treated as if they were one expression.
-This is particularly important when syntactic expressions are used
-which only allow one expression, but the programmer wants to use more
-than one expression in that place.  As an example, consider the
-conditional expression below:
+As an expression, the @code{begin} syntax is used to evaluate a sequence
+of sub-expressions in order.  Consider the conditional expression below:
 
 @lisp
 (if (> x 0)
     (begin (display "greater") (newline)))
 @end lisp
 
-If the two calls to @code{display} and @code{newline} were not embedded
-in a @code{begin}-statement, the call to @code{newline} would get
-misinterpreted as the else-branch of the @code{if}-expression.
+If the test is true, we want to display ``greater'' to the current
+output port, then display a newline.  We use @code{begin} to form a
+compound expression out of this sequence of sub-expressions.
 
-@deffn syntax begin expr1 expr2 @dots{}
-The expression(s) are evaluated in left-to-right order and the value
-of the last expression is returned as the value of the
+@deffn syntax begin expr @dots{}
+The expression(s) are evaluated in left-to-right order and the value of
+the last expression is returned as the value of the
 @code{begin}-expression.  This expression type is used when the
 expressions before the last one are evaluated for their side effects.
-
-Guile also allows the expression @code{(begin)}, a @code{begin} with no
-sub-expressions.  Such an expression returns the `unspecified' value.
 @end deffn
 
-@node if cond case
+@cindex splicing
+@cindex definition splicing
+
+The @code{begin} syntax has another role in definition context
+(@pxref{Internal Definitions}).  A @code{begin} form in a definition
+context @dfn{splices} its subforms into its place.  For example,
+consider the following procedure:
+
+@lisp
+(define (make-seal)
+  (define-sealant seal open)
+  (values seal open))
+@end lisp
+
+Let us assume the existence of a @code{define-sealant} macro that
+expands out to some definitions wrapped in a @code{begin}, like so:
+
+@lisp
+(define (make-seal)
+  (begin
+    (define seal-tag
+      (list 'seal))
+    (define (seal x)
+      (cons seal-tag x))
+    (define (sealed? x)
+      (and (pair? x) (eq? (car x) seal-tag)))
+    (define (open x)
+      (if (sealed? x)
+          (cdr x)
+          (error "Expected a sealed value:" x))))
+  (values seal open))
+@end lisp
+
+Here, because the @code{begin} is in definition context, its subforms
+are @dfn{spliced} into the place of the @code{begin}.  This allows the
+definitions created by the macro to be visible to the following
+expression, the @code{values} form.
+
+It is a fine point, but splicing and sequencing are different.  It can
+make sense to splice zero forms, because it can make sense to have zero
+internal definitions before the expressions in a procedure or lexical
+binding form.  However it does not make sense to have a sequence of zero
+expressions, because in that case it would not be clear what the value
+of the sequence would be, because in a sequence of zero expressions,
+there can be no last value.  Sequencing zero expressions is an error.
+
+It would be more elegant in some ways to eliminate splicing from the
+Scheme language, and without macros (@pxref{Macros}), that would be a
+good idea.  But it is useful to be able to write macros that expand out
+to multiple definitions, as in @code{define-sealant} above, so Scheme
+abuses the @code{begin} form for these two tasks.
+
+@node Conditionals
 @subsection Simple Conditional Evaluation
 
 @cindex conditional evaluation
 @cindex if
+@cindex when
+@cindex unless
 @cindex case
 @cindex cond
 
@@ -75,14 +123,44 @@ values.
 All arguments may be arbitrary expressions.  First, @var{test} is
 evaluated.  If it returns a true value, the expression @var{consequent}
 is evaluated and @var{alternate} is ignored.  If @var{test} evaluates to
-@code{#f}, @var{alternate} is evaluated instead.  The value of the
-evaluated branch (@var{consequent} or @var{alternate}) is returned as
-the value of the @code{if} expression.
+@code{#f}, @var{alternate} is evaluated instead.  The values of the
+evaluated branch (@var{consequent} or @var{alternate}) are returned as
+the values of the @code{if} expression.
 
 When @var{alternate} is omitted and the @var{test} evaluates to
 @code{#f}, the value of the expression is not specified.
 @end deffn
 
+When you go to write an @code{if} without an alternate (a @dfn{one-armed
+@code{if}}), part of what you are expressing is that you don't care
+about the return value (or values) of the expression.  As such, you are
+more interested in the @emph{effect} of evaluating the consequent
+expression.  (By convention, we use the word @dfn{statement} to refer to
+an expression that is evaluated for effect, not for value).
+
+In such a case, it is considered more clear to express these intentions
+with these special forms, @code{when} and @code{unless}.  As an added
+bonus, these forms accept multiple statements to evaluate, which are
+implicitly wrapped in a @code{begin}.
+
+@deffn {Scheme Syntax} when test statement1 statement2 ...
+@deffnx {Scheme Syntax} unless test statement1 statement2 ...
+The actual definitions of these forms are in many ways their most clear
+documentation:
+
+@example
+(define-syntax-rule (when test stmt stmt* ...)
+  (if test (begin stmt stmt* ...)))
+
+(define-syntax-rule (unless condition stmt stmt* ...)
+  (if (not test) (begin stmt stmt* ...)))
+@end example
+
+That is to say, @code{when} evaluates its consequent statements in order
+if @var{test} is true.  @code{unless} is the opposite: it evaluates the
+statements if @var{test} is false.
+@end deffn
+
 @deffn syntax cond clause1 clause2 @dots{}
 Each @code{cond}-clause must look like this:
 
@@ -134,20 +212,32 @@ result of the @code{cond}-expression.
 @end deffn
 
 @deffn syntax case key clause1 clause2 @dots{}
-@var{key} may be any expression, the @var{clause}s must have the form
+@var{key} may be any expression, and the @var{clause}s must have the form
 
 @lisp
 ((@var{datum1} @dots{}) @var{expr1} @var{expr2} @dots{})
 @end lisp
 
+or
+
+@lisp
+((@var{datum1} @dots{}) => @var{expression})
+@end lisp
+
 and the last @var{clause} may have the form
 
 @lisp
 (else @var{expr1} @var{expr2} @dots{})
 @end lisp
 
+or
+
+@lisp
+(else => @var{expression})
+@end lisp
+
 All @var{datum}s must be distinct.  First, @var{key} is evaluated.  The
-the result of this evaluation is compared against all @var{datum}s using
+result of this evaluation is compared against all @var{datum} values using
 @code{eqv?}.  When this comparison succeeds, the expression(s) following
 the @var{datum} are evaluated from left to right, returning the value of
 the last expression as the result of the @code{case} expression.
@@ -156,6 +246,11 @@ If the @var{key} matches no @var{datum} and there is an
 @code{else}-clause, the expressions following the @code{else} are
 evaluated.  If there is no such clause, the result of the expression is
 unspecified.
+
+For the @code{=>} clause types, @var{expression} is evaluated and the
+resulting procedure is applied to the value of @var{key}.  The result of
+this procedure application is then the result of the
+@code{case}-expression.
 @end deffn
 
 
@@ -199,7 +294,7 @@ Scheme programs is normally expressed using recursion.  Nevertheless,
 R5RS defines a construct for programming loops, calling @code{do}.  In
 addition, Guile has an explicit looping syntax called @code{while}.
 
-@deffn syntax do ((variable init [step]) @dots{}) (test [expr @dots{}]) body @dots{}
+@deffn syntax do ((variable init [step]) @dots{}) (test expr @dots{}) body @dots{}
 Bind @var{variable}s and evaluate @var{body} until @var{test} is true.
 The return value is the last @var{expr} after @var{test}, if given.  A
 simple example will illustrate the basic form,
@@ -265,13 +360,12 @@ Concept of Closure}).
 @deffn syntax while cond body @dots{}
 Run a loop executing the @var{body} forms while @var{cond} is true.
 @var{cond} is tested at the start of each iteration, so if it's
-@code{#f} the first time then @var{body} is not executed at all.  The
-return value is unspecified.
+@code{#f} the first time then @var{body} is not executed at all.
 
 Within @code{while}, two extra bindings are provided, they can be used
 from both @var{cond} and @var{body}.
 
-@deffn {Scheme Procedure} break
+@deffn {Scheme Procedure} break break-arg @dots{}
 Break out of the @code{while} form.
 @end deffn
 
@@ -280,6 +374,19 @@ Abandon the current iteration, go back to the start and test
 @var{cond} again, etc.
 @end deffn
 
+If the loop terminates normally, by the @var{cond} evaluating to
+@code{#f}, then the @code{while} expression as a whole evaluates to
+@code{#f}.  If it terminates by a call to @code{break} with some number
+of arguments, those arguments are returned from the @code{while}
+expression, as multiple values.  Otherwise if it terminates by a call to
+@code{break} with no arguments, then return value is @code{#t}.
+
+@example
+(while #f (error "not reached")) @result{} #f
+(while #t (break)) @result{} #t
+(while #t (break 1 2 3)) @result{} 1 2 3
+@end example
+
 Each @code{while} form gets its own @code{break} and @code{continue}
 procedures, operating on that @code{while}.  This means when loops are
 nested the outer @code{break} can be used to escape all the way out.
@@ -343,6 +450,227 @@ times.
 @end deffn
 
 
+@node Prompts
+@subsection Prompts
+@cindex prompts
+@cindex delimited continuations
+@cindex composable continuations
+@cindex non-local exit
+
+Prompts are control-flow barriers between different parts of a program. In the
+same way that a user sees a shell prompt (e.g., the Bash prompt) as a barrier
+between the operating system and her programs, Scheme prompts allow the Scheme
+programmer to treat parts of programs as if they were running in different
+operating systems.
+
+We use this roundabout explanation because, unless you're a functional
+programming junkie, you probably haven't heard the term, ``delimited, composable
+continuation''. That's OK; it's a relatively recent topic, but a very useful
+one to know about.
+
+@menu
+* Prompt Primitives::           Call-with-prompt and abort-to-prompt.
+* Shift and Reset::             The zoo of delimited control operators.
+@end menu
+
+@node Prompt Primitives
+@subsubsection Prompt Primitives
+
+Guile's primitive delimited control operators are
+@code{call-with-prompt} and @code{abort-to-prompt}.
+
+@deffn {Scheme Procedure} call-with-prompt tag thunk handler
+Set up a prompt, and call @var{thunk} within that prompt.
+
+During the dynamic extent of the call to @var{thunk}, a prompt named @var{tag}
+will be present in the dynamic context, such that if a user calls
+@code{abort-to-prompt} (see below) with that tag, control rewinds back to the
+prompt, and the @var{handler} is run.
+
+@var{handler} must be a procedure. The first argument to @var{handler} will be
+the state of the computation begun when @var{thunk} was called, and ending with
+the call to @code{abort-to-prompt}. The remaining arguments to @var{handler} are
+those passed to @code{abort-to-prompt}.
+@end deffn
+
+@deffn {Scheme Procedure} make-prompt-tag [stem]
+Make a new prompt tag.  A prompt tag is simply a unique object.
+Currently, a prompt tag is a fresh pair.  This may change in some future
+Guile version.
+@end deffn
+
+@deffn {Scheme Procedure} default-prompt-tag
+Return the default prompt tag.  Having a distinguished default prompt
+tag allows some useful prompt and abort idioms, discussed in the next
+section.  Note that @code{default-prompt-tag} is actually a parameter,
+and so may be dynamically rebound using @code{parameterize}.
+@xref{Parameters}.
+@end deffn
+
+@deffn {Scheme Procedure} abort-to-prompt tag val1 val2 @dots{}
+Unwind the dynamic and control context to the nearest prompt named @var{tag},
+also passing the given values.
+@end deffn
+
+C programmers may recognize @code{call-with-prompt} and @code{abort-to-prompt}
+as a fancy kind of @code{setjmp} and @code{longjmp}, respectively. Prompts are
+indeed quite useful as non-local escape mechanisms. Guile's @code{catch} and
+@code{throw} are implemented in terms of prompts. Prompts are more convenient
+than @code{longjmp}, in that one has the opportunity to pass multiple values to
+the jump target.
+
+Also unlike @code{longjmp}, the prompt handler is given the full state of the
+process that was aborted, as the first argument to the prompt's handler. That
+state is the @dfn{continuation} of the computation wrapped by the prompt. It is
+a @dfn{delimited continuation}, because it is not the whole continuation of the
+program; rather, just the computation initiated by the call to
+@code{call-with-prompt}.
+
+The continuation is a procedure, and may be reinstated simply by invoking it,
+with any number of values. Here's where things get interesting, and complicated
+as well. Besides being described as delimited, continuations reified by prompts
+are also @dfn{composable}, because invoking a prompt-saved continuation composes
+that continuation with the current one.
+
+Imagine you have saved a continuation via call-with-prompt:
+
+@example
+(define cont
+  (call-with-prompt
+   ;; tag
+   'foo
+   ;; thunk
+   (lambda ()
+     (+ 34 (abort-to-prompt 'foo)))
+   ;; handler
+   (lambda (k) k)))
+@end example
+
+The resulting continuation is the addition of 34. It's as if you had written:
+
+@example
+(define cont
+  (lambda (x)
+    (+ 34 x)))
+@end example
+
+So, if we call @code{cont} with one numeric value, we get that number,
+incremented by 34:
+
+@example
+(cont 8)
+@result{} 42
+(* 2 (cont 8))
+@result{} 84
+@end example
+
+The last example illustrates what we mean when we say, "composes with the
+current continuation". We mean that there is a current continuation -- some
+remaining things to compute, like @code{(lambda (x) (* x 2))} -- and that
+calling the saved continuation doesn't wipe out the current continuation, it
+composes the saved continuation with the current one.
+
+We're belaboring the point here because traditional Scheme continuations, as
+discussed in the next section, aren't composable, and are actually less
+expressive than continuations captured by prompts. But there's a place for them
+both.
+
+Before moving on, we should mention that if the handler of a prompt is a
+@code{lambda} expression, and the first argument isn't referenced, an abort to
+that prompt will not cause a continuation to be reified. This can be an
+important efficiency consideration to keep in mind.
+
+@node Shift and Reset
+@subsubsection Shift, Reset, and All That
+
+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:
+
+@example
+(use-modules (ice-9 control))
+@end example
+
+Firstly, we have a helpful abbreviation for the @code{call-with-prompt}
+operator.
+
+@deffn {Scheme Syntax} % expr
+@deffnx {Scheme Syntax} % expr handler
+@deffnx {Scheme Syntax} % tag expr handler
+Evaluate @var{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 called on the
+captured continuation, within a prompt.
+
+Sometimes it's easier just to show code, as in this case:
+
+@example
+(define (default-prompt-handler k proc)
+  (% (default-prompt-tag)
+     (proc k)
+     default-prompt-handler))
+@end example
+
+The @code{%} symbol is chosen because it looks like a prompt.
+@end deffn
+
+Likewise there is an abbreviation for @code{abort-to-prompt}, which
+assumes the default prompt tag:
+
+@deffn {Scheme Procedure} abort val1 val2 @dots{}
+Abort to the default prompt tag, passing @var{val1} @var{val2} @dots{}
+to the handler.
+@end deffn
+
+As mentioned before, @code{(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 @code{%}.
+
+Still here?  So, when one implements a delimited control operator like
+@code{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 @dfn{F} operator.  If
+neither the continuations nor the handlers implicitly add a prompt, the
+operator is known as @dfn{--F--}.  This is the case for Guile's
+@code{call-with-prompt} and @code{abort-to-prompt}.
+
+If both continuation and handler implicitly add prompts, then the
+operator is @dfn{+F+}.  @code{shift} and @code{reset} are such
+operators.
+
+@deffn {Scheme Syntax} reset body1 body2 @dots{}
+Establish a prompt, and evaluate @var{body1} @var{body2} @dots{} within
+that prompt.
+
+The prompt handler is designed to work with @code{shift}, described
+below.
+@end deffn
+
+@deffn {Scheme Syntax} shift cont body1 body2 @dots{}
+Abort to the nearest @code{reset}, and evaluate @var{body1} @var{body2}
+@dots{} in a context in which the captured continuation is bound to
+@var{cont}.
+
+As mentioned above, taken together, the @var{body1} @var{body2} @dots{}
+expressions and the invocations of @var{cont} implicitly establish a
+prompt.
+@end deffn
+
+Interested readers are invited to explore Oleg Kiselyov's wonderful web
+site at @uref{http://okmij.org/ftp/}, for more information on these
+operators.
+
+
 @node Continuations
 @subsection Continuations
 @cindex continuations
@@ -409,15 +737,6 @@ invoke that continuation.
 This is in common use since the latter is rather long.
 @end deffn
 
-@deftypefn {C Function} SCM scm_make_continuation (int *first)
-Capture the current continuation as described above.  The return value
-is the new continuation, and @var{*first} is set to 1.
-
-When the continuation is invoked, @code{scm_make_continuation} will
-return again, this time returning the value (or set of multiple
-values) passed in that invocation, and with @var{*first} set to 0.
-@end deftypefn
-
 @sp 1
 @noindent
 Here is a simple example,
@@ -475,13 +794,12 @@ with programs written in other languages, such as C, which do not know
 about continuations.  Basically continuations are captured by a block
 copy of the stack, and resumed by copying back.
 
-For this reason, generally continuations should be used only when
-there is no other simple way to achieve the desired result, or when
-the elegance of the continuation mechanism outweighs the need for
-performance.
+For this reason, continuations captured by @code{call/cc} should be used only
+when there is no other simple way to achieve the desired result, or when the
+elegance of the continuation mechanism outweighs the need for performance.
 
 Escapes upwards from loops or nested functions are generally best
-handled with exceptions (@pxref{Exceptions}).  Coroutines can be
+handled with prompts (@pxref{Prompts}).  Coroutines can be
 efficiently implemented with cooperating threads (a thread holds a
 full program stack but doesn't copy it around the way continuations
 do).
@@ -509,7 +827,7 @@ multiple values with a procedure which accepts these values as
 parameters.
 
 @rnindex values
-@deffn {Scheme Procedure} values arg1 @dots{} argN
+@deffn {Scheme Procedure} values arg @dots{}
 @deffnx {C Function} scm_values (args)
 Delivers all of its arguments to its continuation.  Except for
 continuations created by the @code{call-with-values} procedure,
@@ -523,6 +841,28 @@ the current implementation that object shares structure with
 @var{args}, so @var{args} should not be modified subsequently.
 @end deffn
 
+@deftypefn {C Function} SCM scm_c_values (SCM *base, size_t n)
+@code{scm_c_values} is an alternative to @code{scm_values}.  It creates
+a new values object, and copies into it the @var{n} values starting from
+@var{base}.
+
+Currently this creates a list and passes it to @code{scm_values}, but we
+expect that in the future we will be able to use more a efficient
+representation.
+@end deftypefn
+
+@deftypefn {C Function} size_t scm_c_nvalues (SCM obj)
+If @var{obj} is a multiple-values object, returns the number of values
+it contains.  Otherwise returns 1.
+@end deftypefn
+
+@deftypefn {C Function} SCM scm_c_value_ref (SCM obj, size_t idx)
+Returns the value at the position specified by @var{idx} in
+@var{obj}.  Note that @var{obj} will ordinarily be a
+multiple-values object, but it need not be.  Any other object
+represents a single value (itself), and is handled appropriately.
+@end deftypefn
+
 @rnindex call-with-values
 @deffn {Scheme Procedure} call-with-values producer consumer
 Calls its @var{producer} argument with no values and a
@@ -614,8 +954,7 @@ more conveniently.
 @menu
 * Exception Terminology::       Different ways to say the same thing.
 * Catch::                       Setting up to catch exceptions.
-* Throw Handlers::              Adding extra handling to a throw.
-* Lazy Catch::                  Catch without unwinding the stack.
+* Throw Handlers::              Handling exceptions before unwinding the stack.
 * Throw::                       Throwing an exception.
 * Exception Implementation::    How Guile implements exceptions.
 @end menu
@@ -681,7 +1020,7 @@ means that the @code{catch} applies to all exceptions, irrespective of
 their type.
 
 The second argument of a @code{catch} expression should be a thunk
-(i.e. a procedure that accepts no arguments) that specifies the normal
+(i.e.@: a procedure that accepts no arguments) that specifies the normal
 case code.  The @code{catch} is active for the execution of this thunk,
 including any code called directly or indirectly by the thunk's body.
 Evaluation of the @code{catch} expression activates the catch and then
@@ -808,17 +1147,53 @@ Operations}).
 @subsubsection Throw Handlers
 
 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.
+thrown before the stack is unwound. This could be to clean up some
+related state, to print a backtrace, or to pass information about the
+exception to a debugger, for example. The @code{with-throw-handler}
+procedure provides a way to do this.
 
 @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}.
+
+This behaves exactly like @code{catch}, except that it does not unwind
+the stack before invoking @var{handler}. If the @var{handler} procedure
+returns normally, Guile rethrows the same exception again to the next
+innermost catch or throw handler. @var{handler} may exit nonlocally, of
+course, via an explicit throw or via invoking a continuation.
 @end deffn
 
+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 handled
+via a throw handler is equivalent to calling the throw handler handler
+inline instead of each @code{throw}, and then omitting the surrounding
+@code{with-throw-handler}. In other words,
+
+@lisp
+(with-throw-handler 'key
+  (lambda () @dots{} (throw 'key args @dots{}) @dots{})
+  handler)
+@end lisp
+
+@noindent
+is mostly equivalent to
+
+@lisp
+((lambda () @dots{} (handler 'key args @dots{}) @dots{}))
+@end lisp
+
+In particular, the dynamic context when @var{handler} is invoked is that
+of the site where @code{throw} is called. The examples are not quite
+equivalent, because the body of a @code{with-throw-handler} is not in
+tail position with respect to the @code{with-throw-handler}, and if
+@var{handler} exits normally, Guile arranges to rethrow the error, but
+hopefully the intention is clear. (For an introduction to what is meant
+by dynamic context, @xref{Dynamic Wind}.)
+
 @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
@@ -846,141 +1221,13 @@ everything that a @code{catch} would do until the point where
 then it rethrows to the next innermost @code{catch} or throw handler
 instead.
 
+Note also that since the dynamic context is not unwound, 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 @emph{closer} to
+the throw than the first @code{with-throw-handler}.
 
-@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
-one important respect: the handler procedure is executed without
-unwinding the call stack from the context of the @code{throw} expression
-that caused the handler to be invoked.
-
-@deffn {Scheme Procedure} lazy-catch key thunk handler
-@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}.
-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)
-The above @code{scm_lazy_catch} takes Scheme procedures as body and
-handler arguments.  @code{scm_internal_lazy_catch} is an equivalent
-taking C functions.  See @code{scm_internal_catch} (@pxref{Catch}) for
-a description of the parameters, the behaviour however of course
-follows @code{lazy-catch}.
-@end deftypefn
-
-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
-@code{lazy-catch}'s handler inline instead of each @code{throw}, and
-then omitting the surrounding @code{lazy-catch}.  In other words,
-
-@lisp
-(lazy-catch 'key
-  (lambda () @dots{} (throw 'key args @dots{}) @dots{})
-  handler)
-@end lisp
-
-@noindent
-is @emph{almost} equivalent to
-
-@lisp
-((lambda () @dots{} (handler 'key args @dots{}) @dots{}))
-@end lisp
-
-@noindent
-But why only @emph{almost}?  The difference is that with
-@code{lazy-catch} (as with normal @code{catch}), the dynamic context is
-unwound back to just outside the @code{lazy-catch} expression before
-invoking the handler.  (For an introduction to what is meant by dynamic
-context, @xref{Dynamic Wind}.)
-
-Then, when the handler @emph{itself} throws an exception, that exception
-must be caught by some kind of @code{catch} (including perhaps another
-@code{lazy-catch}) higher up the call stack.
-
-The dynamic context also includes @code{with-fluids} blocks
-(@pxref{Fluids and Dynamic States}),
-so the effect of unwinding the dynamic context can also be seen in fluid
-variable values.  This is illustrated by the following code, in which
-the normal case thunk uses @code{with-fluids} to temporarily change the
-value of a fluid:
-
-@lisp
-(define f (make-fluid))
-(fluid-set! f "top level value")
-
-(define (handler . args)
-  (cons (fluid-ref f) args))
-
-(lazy-catch 'foo
-            (lambda ()
-              (with-fluids ((f "local value"))
-                (throw 'foo)))
-            handler)
-@result{}
-("top level value" foo)
-
-((lambda ()
-   (with-fluids ((f "local value"))
-     (handler 'foo))))
-@result{}
-("local value" foo)
-@end lisp
-
-@noindent
-In the @code{lazy-catch} version, the unwinding of dynamic context
-restores @code{f} to its value outside the @code{with-fluids} block
-before the handler is invoked, so the handler's @code{(fluid-ref f)}
-returns the external value.
-
-@code{lazy-catch} is useful because it permits the implementation of
-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:
+Here is an example to illustrate this behavior:
 
 @lisp
 (catch 'a
@@ -998,14 +1245,7 @@ Here is an example to illustrate the second difference:
 
 @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.
+continuation of the inner @code{catch}.
 
 
 @node Throw
@@ -1019,10 +1259,10 @@ 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
+@deffn {Scheme Procedure} throw key arg @dots{}
 @deffnx {C Function} scm_throw (key, args)
-Invoke the catch form matching @var{key}, passing @var{args} to the
-@var{handler}.  
+Invoke the catch form matching @var{key}, passing @var{arg} @dots{} to
+the @var{handler}.
 
 @var{key} is a symbol.  It will match catches of the same symbol or of
 @code{#t}.
@@ -1111,9 +1351,9 @@ Guile provides a set of convenience procedures for signaling error
 conditions that are implemented on top of the exception primitives just
 described.
 
-@deffn {Scheme Procedure} error msg args @dots{}
+@deffn {Scheme Procedure} error msg arg @dots{}
 Raise an error with key @code{misc-error} and a message constructed by
-displaying @var{msg} and writing @var{args}.
+displaying @var{msg} and writing @var{arg} @enddots{}.
 @end deffn
 
 @deffn {Scheme Procedure} scm-error key subr message args data
@@ -1283,7 +1523,7 @@ table.
 @table @code
 @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
+reentered non-locally (via the invocation of a continuation).  The
 default is that a dynwind context can not be reentered non-locally.
 @end table
 
@@ -1306,7 +1546,7 @@ 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 contexts are captured, but you don't need to worry
+non-reentrant 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,
@@ -1405,10 +1645,10 @@ be @code{#f} if no additional objects are required.
 In addition to @code{catch} and @code{throw}, the following Scheme
 facilities are available:
 
-@deffn {Scheme Procedure} display-error stack port subr message args rest
-@deffnx {C Function} scm_display_error (stack, port, subr, message, args, rest)
+@deffn {Scheme Procedure} display-error frame port subr message args rest
+@deffnx {C Function} scm_display_error (frame, port, subr, message, args, rest)
 Display an error message to the output port @var{port}.
-@var{stack} is the saved stack for the error, @var{subr} is
+@var{frame} is the frame in which the error occurred, @var{subr} is
 the name of the procedure in which the error occurred and
 @var{message} is the actual error message, which may contain
 formatting instructions. These will format the arguments in
@@ -1493,11 +1733,87 @@ and the call to these routines doesn't change @code{errno}.
 @deftypefnx {C Function} void scm_out_of_range (char *@var{subr}, SCM @var{bad_value})
 @deftypefnx {C Function} void scm_wrong_num_args (SCM @var{proc})
 @deftypefnx {C Function} void scm_wrong_type_arg (char *@var{subr}, int @var{argnum}, SCM @var{bad_value})
+@deftypefnx {C Function} void scm_wrong_type_arg_msg (char *@var{subr}, int @var{argnum}, SCM @var{bad_value}, const char *@var{expected})
 @deftypefnx {C Function} void scm_memory_error (char *@var{subr})
 Throw an error with the various keys described above.
+@deftypefnx {C Function} void scm_misc_error (const char *@var{subr}, const char *@var{message}, SCM @var{args})
+
+In @code{scm_wrong_num_args}, @var{proc} should be a Scheme symbol
+which is the name of the procedure incorrectly invoked.  The other
+routines take the name of the invoked procedure as a C string.
+
+In @code{scm_wrong_type_arg_msg}, @var{expected} is a C string
+describing the type of argument that was expected.
+
+In @code{scm_misc_error}, @var{message} is the error message string,
+possibly containing @code{simple-format} escapes (@pxref{Writing}), and
+the corresponding arguments in the @var{args} list.
+@end deftypefn
+
+
+@subsubsection Signalling Type Errors
+
+Every function visible at the Scheme level should aggressively check the
+types of its arguments, to avoid misinterpreting a value, and perhaps
+causing a segmentation fault.  Guile provides some macros to make this
+easier.
+
+@deftypefn Macro void SCM_ASSERT (int @var{test}, SCM @var{obj}, unsigned int @var{position}, const char *@var{subr})
+@deftypefnx Macro void SCM_ASSERT_TYPE (int @var{test}, SCM @var{obj}, unsigned int @var{position}, const char *@var{subr}, const char *@var{expected}) 
+If @var{test} is zero, signal a ``wrong type argument'' error,
+attributed to the subroutine named @var{subr}, operating on the value
+@var{obj}, which is the @var{position}'th argument of @var{subr}.
+
+In @code{SCM_ASSERT_TYPE}, @var{expected} is a C string describing the
+type of argument that was expected.
+@end deftypefn
+
+@deftypefn Macro int SCM_ARG1
+@deftypefnx Macro int SCM_ARG2
+@deftypefnx Macro int SCM_ARG3
+@deftypefnx Macro int SCM_ARG4
+@deftypefnx Macro int SCM_ARG5
+@deftypefnx Macro int SCM_ARG6
+@deftypefnx Macro int SCM_ARG7
+One of the above values can be used for @var{position} to indicate the
+number of the argument of @var{subr} which is being checked.
+Alternatively, a positive integer number can be used, which allows to
+check arguments after the seventh.  However, for parameter numbers up to
+seven it is preferable to use @code{SCM_ARGN} instead of the
+corresponding raw number, since it will make the code easier to
+understand.
+@end deftypefn
+
+@deftypefn Macro int SCM_ARGn
+Passing a value of zero or @code{SCM_ARGn} for @var{position} allows to
+leave it unspecified which argument's type is incorrect.  Again,
+@code{SCM_ARGn} should be preferred over a raw zero constant.
+@end deftypefn
+
+@node Continuation Barriers
+@subsection Continuation Barriers
+
+The non-local flow of control caused by continuations might sometimes
+not be wanted. You can use @code{with-continuation-barrier} to erect
+fences that continuations can not pass.
+
+@deffn {Scheme Procedure} with-continuation-barrier proc
+@deffnx {C Function} scm_with_continuation_barrier (proc)
+Call @var{proc} and return its result.  Do not allow the invocation of
+continuations that would leave or enter the dynamic extent of the call
+to @code{with-continuation-barrier}.  Such an attempt causes an error
+to be signaled.
+
+Throws (such as errors) that are not caught from within @var{proc} are
+caught by @code{with-continuation-barrier}.  In that case, a short
+message is printed to the current error port and @code{#f} is returned.
+
+Thus, @code{with-continuation-barrier} returns exactly once.
+@end deffn
 
-For @code{scm_wrong_num_args}, @var{proc} should be a Scheme symbol
-which is the name of the procedure incorrectly invoked.
+@deftypefn {C Function} {void *} scm_c_with_continuation_barrier (void *(*func) (void *), void *data)
+Like @code{scm_with_continuation_barrier} but call @var{func} on
+@var{data}.  When an error is caught, @code{NULL} is returned.
 @end deftypefn