summaryrefslogtreecommitdiff
path: root/doc/ref/api-control.texi
diff options
context:
space:
mode:
Diffstat (limited to 'doc/ref/api-control.texi')
-rw-r--r--doc/ref/api-control.texi1337
1 files changed, 1337 insertions, 0 deletions
diff --git a/doc/ref/api-control.texi b/doc/ref/api-control.texi
new file mode 100644
index 000000000..cbc386a05
--- /dev/null
+++ b/doc/ref/api-control.texi
@@ -0,0 +1,1337 @@
+@c -*-texinfo-*-
+@c This is part of the GNU Guile Reference Manual.
+@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004
+@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
+
+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.
+* and or:: Conditional evaluation of a sequence.
+* while do:: Iteration mechanisms.
+* Continuations:: Continuations.
+* 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
+* Handling Errors:: How to handle errors in C code.
+@end menu
+
+@node begin
+@subsection Evaluating a Sequence of Expressions
+
+@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:
+
+@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.
+
+@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
+@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
+@subsection Simple Conditional Evaluation
+
+@cindex conditional evaluation
+@cindex if
+@cindex case
+@cindex cond
+
+Guile provides three syntactic constructs for conditional evaluation.
+@code{if} is the normal if-then-else expression (with an optional else
+branch), @code{cond} is a conditional expression with multiple branches
+and @code{case} branches if an expression has one of a set of constant
+values.
+
+@deffn syntax if test consequent [alternate]
+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.
+
+When @var{alternate} is omitted and the @var{test} evaluates to
+@code{#f}, the value of the expression is not specified.
+@end deffn
+
+@deffn syntax cond clause1 clause2 @dots{}
+Each @code{cond}-clause must look like this:
+
+@lisp
+(@var{test} @var{expression} @dots{})
+@end lisp
+
+where @var{test} and @var{expression} are arbitrary expression, or like
+this
+
+@lisp
+(@var{test} => @var{expression})
+@end lisp
+
+where @var{expression} must evaluate to a procedure.
+
+The @var{test}s of the clauses are evaluated in order and as soon as one
+of them evaluates to a true values, the corresponding @var{expression}s
+are evaluated in order and the last value is returned as the value of
+the @code{cond}-expression. For the @code{=>} clause type,
+@var{expression} is evaluated and the resulting procedure is applied to
+the value of @var{test}. The result of this procedure application is
+then the result of the @code{cond}-expression.
+
+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
+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
+
+@lisp
+((@var{datum1} @dots{}) @var{expr1} @var{expr2} @dots{})
+@end lisp
+
+and the last @var{clause} may have the form
+
+@lisp
+(else @var{expr1} @var{expr2} @dots{})
+@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
+@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.
+
+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.
+@end deffn
+
+
+@node and or
+@subsection Conditional Evaluation of a Sequence of Expressions
+
+@code{and} and @code{or} evaluate all their arguments in order, similar
+to @code{begin}, but evaluation stops as soon as one of the expressions
+evaluates to false or true, respectively.
+
+@deffn syntax and expr @dots{}
+Evaluate the @var{expr}s from left to right and stop evaluation as soon
+as one expression evaluates to @code{#f}; the remaining expressions are
+not evaluated. The value of the last evaluated expression is returned.
+If no expression evaluates to @code{#f}, the value of the last
+expression is returned.
+
+If used without expressions, @code{#t} is returned.
+@end deffn
+
+@deffn syntax or expr @dots{}
+Evaluate the @var{expr}s from left to right and stop evaluation as soon
+as one expression evaluates to a true value (that is, a value different
+from @code{#f}); the remaining expressions are not evaluated. The value
+of the last evaluated expression is returned. If all expressions
+evaluate to @code{#f}, @code{#f} is returned.
+
+If used without expressions, @code{#f} is returned.
+@end deffn
+
+
+@node while do
+@subsection Iteration mechanisms
+
+@cindex iteration
+@cindex looping
+@cindex named let
+
+Scheme has only few iteration mechanisms, mainly because iteration in
+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{}
+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,
+
+@example
+(do ((i 1 (1+ i)))
+ ((> i 4))
+ (display i))
+@print{} 1234
+@end example
+
+@noindent
+Or with two variables and a final return value,
+
+@example
+(do ((i 1 (1+ i))
+ (p 3 (* 3 p)))
+ ((> i 4)
+ p)
+ (format #t "3**~s is ~s\n" i p))
+@print{}
+3**1 is 3
+3**2 is 9
+3**3 is 27
+3**4 is 81
+@result{}
+789
+@end example
+
+The @var{variable} bindings are established like a @code{let}, in that
+the expressions are all evaluated and then all bindings made. When
+iterating, the optional @var{step} expressions are evaluated with the
+previous bindings in scope, then new bindings all made.
+
+The @var{test} expression is a termination condition. Looping stops
+when the @var{test} is true. It's evaluated before running the
+@var{body} each time, so if it's true the first time then @var{body}
+is not run at all.
+
+The optional @var{expr}s after the @var{test} are evaluated at the end
+of looping, with the final @var{variable} bindings available. The
+last @var{expr} gives the return value, or if there are no @var{expr}s
+the return value is unspecified.
+
+Each iteration establishes bindings to fresh locations for the
+@var{variable}s, like a new @code{let} for each iteration. This is
+done for @var{variable}s without @var{step} expressions too. The
+following illustrates this, showing how a new @code{i} is captured by
+the @code{lambda} in each iteration (@pxref{About Closure,, The
+Concept of Closure}).
+
+@example
+(define lst '())
+(do ((i 1 (1+ i)))
+ ((> i 4))
+ (set! lst (cons (lambda () i) lst)))
+(map (lambda (proc) (proc)) lst)
+@result{}
+(4 3 2 1)
+@end example
+@end deffn
+
+@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.
+
+Within @code{while}, two extra bindings are provided, they can be used
+from both @var{cond} and @var{body}.
+
+@deffn {Scheme Procedure} break
+Break out of the @code{while} form.
+@end deffn
+
+@deffn {Scheme Procedure} continue
+Abandon the current iteration, go back to the start and test
+@var{cond} again, etc.
+@end deffn
+
+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.
+For example,
+
+@example
+(while (test1)
+ (let ((outer-break break))
+ (while (test2)
+ (if (something)
+ (outer-break #f))
+ ...)))
+@end example
+
+Note that each @code{break} and @code{continue} procedure can only be
+used within the dynamic extent of its @code{while}. Outside the
+@code{while} their behaviour is unspecified.
+@end deffn
+
+@cindex named let
+Another very common way of expressing iteration in Scheme programs is
+the use of the so-called @dfn{named let}.
+
+Named let is a variant of @code{let} which creates a procedure and calls
+it in one step. Because of the newly created procedure, named let is
+more powerful than @code{do}--it can be used for iteration, but also
+for arbitrary recursion.
+
+@deffn syntax let variable bindings body
+For the definition of @var{bindings} see the documentation about
+@code{let} (@pxref{Local Bindings}).
+
+Named @code{let} works as follows:
+
+@itemize @bullet
+@item
+A new procedure which accepts as many arguments as are in @var{bindings}
+is created and bound locally (using @code{let}) to @var{variable}. The
+new procedure's formal argument names are the name of the
+@var{variables}.
+
+@item
+The @var{body} expressions are inserted into the newly created procedure.
+
+@item
+The procedure is called with the @var{init} expressions as the formal
+arguments.
+@end itemize
+
+The next example implements a loop which iterates (by recursion) 1000
+times.
+
+@lisp
+(let lp ((x 1000))
+ (if (positive? x)
+ (lp (- x 1))
+ x))
+@result{}
+0
+@end lisp
+@end deffn
+
+
+@node Continuations
+@subsection Continuations
+@cindex continuations
+
+A ``continuation'' is the code that will execute when a given function
+or expression returns. For example, consider
+
+@example
+(define (foo)
+ (display "hello\n")
+ (display (bar)) (newline)
+ (exit))
+@end example
+
+The continuation from the call to @code{bar} comprises a
+@code{display} of the value returned, a @code{newline} and an
+@code{exit}. This can be expressed as a function of one argument.
+
+@example
+(lambda (r)
+ (display r) (newline)
+ (exit))
+@end example
+
+In Scheme, continuations are represented as special procedures just
+like this. The special property is that when a continuation is called
+it abandons the current program location and jumps directly to that
+represented by the continuation.
+
+A continuation is like a dynamic label, capturing at run-time a point
+in program execution, including all the nested calls that have lead to
+it (or rather the code that will execute when those calls return).
+
+Continuations are created with the following functions.
+
+@deffn {Scheme Procedure} call-with-current-continuation proc
+@deffnx {Scheme Procedure} call/cc proc
+@rnindex call-with-current-continuation
+Capture the current continuation and call @code{(@var{proc}
+@var{cont})} with it. The return value is the value returned by
+@var{proc}, or when @code{(@var{cont} @var{value})} is later invoked,
+the return is the @var{value} passed.
+
+Normally @var{cont} should be called with one argument, but when the
+location resumed is expecting multiple values (@pxref{Multiple
+Values}) then they should be passed as multiple arguments, for
+instance @code{(@var{cont} @var{x} @var{y} @var{z})}.
+
+@var{cont} may only be used from the dynamic root in which it was
+created (@pxref{Dynamic Roots}), and in a multi-threaded program only
+from the thread in which it was created, since each thread is a
+separate dynamic root.
+
+The call to @var{proc} is not part of the continuation captured, it runs
+only when the continuation is created. Often a program will want to
+store @var{cont} somewhere for later use; this can be done in
+@var{proc}.
+
+The @code{call} in the name @code{call-with-current-continuation}
+refers to the way a call to @var{proc} gives the newly created
+continuation. It's not related to the way a call is used later to
+invoke that continuation.
+
+@code{call/cc} is an alias for @code{call-with-current-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,
+
+@example
+(define kont #f)
+(format #t "the return is ~a\n"
+ (call/cc (lambda (k)
+ (set! kont k)
+ 1)))
+@result{} the return is 1
+
+(kont 2)
+@result{} the return is 2
+@end example
+
+@code{call/cc} captures a continuation in which the value returned is
+going to be displayed by @code{format}. The @code{lambda} stores this
+in @code{kont} and gives an initial return @code{1} which is
+displayed. The later invocation of @code{kont} resumes the captured
+point, but this time returning @code{2}, which is displayed.
+
+When Guile is run interactively, a call to @code{format} like this has
+an implicit return back to the read-eval-print loop. @code{call/cc}
+captures that like any other return, which is why interactively
+@code{kont} will come back to read more input.
+
+@sp 1
+C programmers may note that @code{call/cc} is like @code{setjmp} in
+the way it records at runtime a point in program execution. A call to
+a continuation is like a @code{longjmp} in that it abandons the
+present location and goes to the recorded one. Like @code{longjmp},
+the value passed to the continuation is the value returned by
+@code{call/cc} on resuming there. However @code{longjmp} can only go
+up the program stack, but the continuation mechanism can go anywhere.
+
+When a continuation is invoked, @code{call/cc} and subsequent code
+effectively ``returns'' a second time. It can be confusing to imagine
+a function returning more times than it was called. It may help
+instead to think of it being stealthily re-entered and then program
+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}).
+
+@sp 1
+Continuations are a powerful mechanism, and can be used to implement
+almost any sort of control structure, such as loops, coroutines, or
+exception handlers.
+
+However the implementation of continuations in Guile is not as
+efficient as one might hope, because Guile is designed to cooperate
+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.
+
+Escapes upwards from loops or nested functions are generally best
+handled with exceptions (@pxref{Exceptions}). 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).
+
+
+@node Multiple Values
+@subsection Returning and Accepting Multiple Values
+
+@cindex multiple values
+@cindex receive
+
+Scheme allows a procedure to return more than one value to its caller.
+This is quite different to other languages which only allow
+single-value returns. Returning multiple values is different from
+returning a list (or pair or vector) of values to the caller, because
+conceptually not @emph{one} compound object is returned, but several
+distinct values.
+
+The primitive procedures for handling multiple values are @code{values}
+and @code{call-with-values}. @code{values} is used for returning
+multiple values from a procedure. This is done by placing a call to
+@code{values} with zero or more arguments in tail position in a
+procedure body. @code{call-with-values} combines a procedure returning
+multiple values with a procedure which accepts these values as
+parameters.
+
+@rnindex values
+@deffn {Scheme Procedure} values arg1 @dots{} argN
+@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,
+all continuations take exactly one value. The effect of
+passing no value or more than one value to continuations that
+were not created by @code{call-with-values} is unspecified.
+
+For @code{scm_values}, @var{args} is a list of arguments and the
+return is a multiple-values object which the caller can return. In
+the current implementation that object shares structure with
+@var{args}, so @var{args} should not be modified subsequently.
+@end deffn
+
+@rnindex call-with-values
+@deffn {Scheme Procedure} call-with-values producer consumer
+Calls its @var{producer} argument with no values and a
+continuation that, when passed some values, calls the
+@var{consumer} procedure with those values as arguments. The
+continuation for the call to @var{consumer} is the continuation
+of the call to @code{call-with-values}.
+
+@example
+(call-with-values (lambda () (values 4 5))
+ (lambda (a b) b))
+@result{} 5
+
+@end example
+@example
+(call-with-values * -)
+@result{} -1
+@end example
+@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
+
+@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.
+@end deffn
+
+
+@node Exceptions
+@subsection Exceptions
+@cindex error handling
+@cindex exception handling
+
+A common requirement in applications is to want to jump
+@dfn{non-locally} from the depths of a computation back to, say, the
+application's main processing loop. Usually, the place that is the
+target of the jump is somewhere in the calling stack of procedures that
+called the procedure that wants to jump back. For example, typical
+logic for a key press driven application might look something like this:
+
+@example
+main-loop:
+ read the next key press and call dispatch-key
+
+dispatch-key:
+ lookup the key in a keymap and call an appropriate procedure,
+ say find-file
+
+find-file:
+ interactively read the required file name, then call
+ find-specified-file
+
+find-specified-file:
+ check whether file exists; if not, jump back to main-loop
+ @dots{}
+@end example
+
+The jump back to @code{main-loop} could be achieved by returning through
+the stack one procedure at a time, using the return value of each
+procedure to indicate the error condition, but Guile (like most modern
+programming languages) provides an additional mechanism called
+@dfn{exception handling} that can be used to implement such jumps much
+more conveniently.
+
+@menu
+* Exception Terminology:: Different ways to say the same thing.
+* Catch:: Setting up to catch exceptions.
+* Throw:: Throwing an exception.
+* Lazy Catch:: Catch without unwinding the stack.
+* Exception Implementation:: How Guile implements exceptions.
+@end menu
+
+
+@node Exception Terminology
+@subsubsection Exception Terminology
+
+There are several variations on the terminology for dealing with
+non-local jumps. It is useful to be aware of them, and to realize
+that they all refer to the same basic mechanism.
+
+@itemize @bullet
+@item
+Actually making a non-local jump may be called @dfn{raising an
+exception}, @dfn{raising a signal}, @dfn{throwing an exception} or
+@dfn{doing a long jump}. When the jump indicates an error condition,
+people may talk about @dfn{signalling}, @dfn{raising} or @dfn{throwing}
+@dfn{an error}.
+
+@item
+Handling the jump at its target may be referred to as @dfn{catching} or
+@dfn{handling} the @dfn{exception}, @dfn{signal} or, where an error
+condition is involved, @dfn{error}.
+@end itemize
+
+Where @dfn{signal} and @dfn{signalling} are used, special care is needed
+to avoid the risk of confusion with POSIX signals.
+
+This manual prefers to speak of throwing and catching exceptions, since
+this terminology matches the corresponding Guile primitives.
+
+
+@node Catch
+@subsubsection Catching Exceptions
+
+@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.
+
+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
+exception. For example, Guile throws an exception using the symbol
+@code{numerical-overflow} to indicate numerical overflow errors such as
+division by zero:
+
+@lisp
+(/ 1 0)
+@result{}
+ABORT: (numerical-overflow)
+@end lisp
+
+The @var{key} argument in a @code{catch} expression corresponds to this
+symbol. @var{key} may be a specific symbol, such as
+@code{numerical-overflow}, in which case the @code{catch} applies
+specifically to exceptions of that type; or it may be @code{#t}, which
+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
+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
+calls this thunk.
+
+The third argument of a @code{catch} expression is a handler procedure.
+If an exception is thrown, this procedure is called with exactly the
+arguments specified by the @code{throw}. Therefore, the handler
+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
+@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
+@var{key}, then @var{handler} is invoked this way:
+@lisp
+(handler key args ...)
+@end lisp
+
+@var{key} is a symbol or @code{#t}.
+
+@var{thunk} takes no arguments. If @var{thunk} returns
+normally, that is the return value of @code{catch}.
+
+Handler is invoked outside the scope of its own @code{catch}.
+If @var{handler} again throws to the same key, a new handler
+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}.
+@end deffn
+
+If the handler procedure needs to match a variety of @code{throw}
+expressions with varying numbers of arguments, you should write it like
+this:
+
+@lisp
+(lambda (key . args)
+ @dots{})
+@end lisp
+
+@noindent
+The @var{key} argument is guaranteed always to be present, because a
+@code{throw} without a @var{key} is not valid. The number and
+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.
+
+@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}.
+
+@tpindex scm_t_catch_body
+@tpindex scm_t_catch_handler
+@var{body} and @var{handler} should have the following prototypes.
+@code{scm_t_catch_body} and @code{scm_t_catch_handler} are pointer
+typedefs for these.
+
+@example
+SCM body (void *data);
+SCM handler (void *data, SCM key, SCM args);
+@end example
+
+The @var{body_data} and @var{handler_data} parameters are passed to
+the respective calls so an application can communicate extra
+information to those functions.
+
+If the data consists of an @code{SCM} object, care should be taken
+that it isn't garbage collected while still required. If the
+@code{SCM} is a local C variable, one way to protect it is to pass a
+pointer to that variable as the data parameter, since the C compiler
+will then know the value must be held on the stack. Another way is to
+use @code{scm_remember_upto_here_1} (@pxref{Remembering During
+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}.
+
+@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} 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
+
+@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 Lazy Catch
+@subsubsection Catch Without Unwinding
+
+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}.
+The @var{handler} procedure is not allowed to return:
+it must throw to another catch, or otherwise exit non-locally.
+@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} 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}.
+
+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 (REFFIXME),
+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.
+
+
+@node Exception Implementation
+@subsubsection How Guile Implements Exceptions
+
+It is traditional in Scheme to implement exception systems using
+@code{call-with-current-continuation}. Continuations
+(@pxref{Continuations}) are such a powerful concept that any other
+control mechanism --- including @code{catch} and @code{throw} --- can be
+implemented in terms of them.
+
+Guile does not implement @code{catch} and @code{throw} like this,
+though. Why not? Because Guile is specifically designed to be easy to
+integrate with applications written in C. In a mixed Scheme/C
+environment, the concept of @dfn{continuation} must logically include
+``what happens next'' in the C parts of the application as well as the
+Scheme parts, and it turns out that the only reasonable way of
+implementing continuations like this is to save and restore the complete
+C stack.
+
+So Guile's implementation of @code{call-with-current-continuation} is a
+stack copying one. This allows it to interact well with ordinary C
+code, but means that creating and calling a continuation is slowed down
+by the time that it takes to copy the C stack.
+
+The more targeted mechanism provided by @code{catch} and @code{throw}
+does not need to save and restore the C stack because the @code{throw}
+always jumps to a location higher up the stack of the code that executes
+the @code{throw}. Therefore Guile implements the @code{catch} and
+@code{throw} primitives independently of
+@code{call-with-current-continuation}, in a way that takes advantage of
+this @emph{upwards only} nature of exceptions.
+
+
+@node Error Reporting
+@subsection Procedures for Signaling Errors
+
+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{}
+Raise an error with key @code{misc-error} and a message constructed by
+displaying @var{msg} and writing @var{args}.
+@end deffn
+
+@deffn {Scheme Procedure} scm-error key subr message args data
+@deffnx {C Function} scm_error_scm (key, subr, message, args, data)
+Raise an error with key @var{key}. @var{subr} can be a string
+naming the procedure associated with the error, or @code{#f}.
+@var{message} is the error message string, possibly containing
+@code{~S} and @code{~A} escapes. When an error is reported,
+these are replaced by formatting the corresponding members of
+@var{args}: @code{~A} (was @code{%s} in older versions of
+Guile) formats using @code{display} and @code{~S} (was
+@code{%S}) formats using @code{write}. @var{data} is a list or
+@code{#f} depending on @var{key}: if @var{key} is
+@code{system-error} then it should be a list containing the
+Unix @code{errno} value; If @var{key} is @code{signal} then it
+should be a list containing the Unix signal number; otherwise
+it will usually be @code{#f}.
+@end deffn
+
+@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.
+@end deffn
+
+@c begin (scm-doc-string "boot-9.scm" "false-if-exception")
+@deffn syntax false-if-exception expr
+Returns the result of evaluating its argument; however
+if an exception occurs then @code{#f} is returned instead.
+@end deffn
+@c end
+
+
+@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.
+
+Here is an example that shows how to prevent memory leaks.
+
+@example
+
+/* Suppose there is a function called FOO in some library that you
+ would like to make available to Scheme code (or to C code that
+ follows the Scheme conventions).
+
+ FOO takes two C strings and returns a new string. When an error has
+ occurred in FOO, it returns NULL.
+*/
+
+char *foo (char *s1, char *s2);
+
+/* SCM_FOO interfaces the C function FOO to the Scheme way of life.
+ It takes care to free up all temporary strings in the case of
+ non-local exits.
+
+ It uses SCM_TO_STRING as a helper procedure.
+ */
+
+char *
+scm_to_string (SCM obj)
+@{
+ if (SCM_STRINGP (obj))
+ @{
+ char *res = scm_malloc (SCM_STRING_LENGTH (obj)+1);
+ strcpy (res, SCM_STRING_CHARS (obj));
+ scm_remember_upto_here_1 (obj);
+ return res;
+ @}
+ else
+ scm_wrong_type_arg ("scm_to_string", 1, obj);
+@}
+
+SCM
+scm_foo (SCM s1, SCM s2)
+@{
+ char *c_s1, *c_s2, *c_res;
+
+ scm_frame_begin (0);
+
+ c_s1 = scm_to_string (s1);
+ scm_frame_unwind_handler (free, c_s1, SCM_F_WIND_EXPLICITLY);
+
+ c_s2 = scm_to_string (s2);
+ scm_frame_unwind_handler (free, c_s2, SCM_F_WIND_EXPLICITLY);
+
+ c_res = foo (c_s1, c_s2);
+ if (c_res == NULL)
+ scm_memory_error ("foo");
+
+ scm_frame_end ();
+
+ return scm_take0str (res);
+@}
+@end example
+
+@deftp {C Type} scm_t_frame_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.
+
+@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.
+@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.
+
+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}.
+
+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
+memory leak on non-local exit and thus register an unwind handler that
+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.
+@end deftypefn
+
+@deftypefn {C Function} void scm_frame_end ()
+End the current frame explicitly and make the previous frame 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.
+
+@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.
+@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)
+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}.
+
+The function @code{scm_frame_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)
+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}
+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
+@var{data} is protected from garbage collection.
+@end deftypefn
+
+
+@node Handling Errors
+@subsection How to Handle Errors
+
+Error handling is based on @code{catch} and @code{throw}. Errors are
+always thrown with a @var{key} and four arguments:
+
+@itemize @bullet
+@item
+@var{key}: a symbol which indicates the type of error. The symbols used
+by libguile are listed below.
+
+@item
+@var{subr}: the name of the procedure from which the error is thrown, or
+@code{#f}.
+
+@item
+@var{message}: a string (possibly language and system dependent)
+describing the error. The tokens @code{~A} and @code{~S} can be
+embedded within the message: they will be replaced with members of the
+@var{args} list when the message is printed. @code{~A} indicates an
+argument printed using @code{display}, while @code{~S} indicates an
+argument printed using @code{write}. @var{message} can also be
+@code{#f}, to allow it to be derived from the @var{key} by the error
+handler (may be useful if the @var{key} is to be thrown from both C and
+Scheme).
+
+@item
+@var{args}: a list of arguments to be used to expand @code{~A} and
+@code{~S} tokens in @var{message}. Can also be @code{#f} if no
+arguments are required.
+
+@item
+@var{rest}: a list of any additional objects required. e.g., when the
+key is @code{'system-error}, this contains the C errno value. Can also
+be @code{#f} if no additional objects are required.
+@end itemize
+
+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)
+Display an error message to the output port @var{port}.
+@var{stack} is the saved stack for the error, @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
+the list @var{args} accordingly. @var{rest} is currently
+ignored.
+@end deffn
+
+The following are the error keys defined by libguile and the situations
+in which they are used:
+
+@itemize @bullet
+@item
+@cindex @code{error-signal}
+@code{error-signal}: thrown after receiving an unhandled fatal signal
+such as SIGSEGV, SIGBUS, SIGFPE etc. The @var{rest} argument in the throw
+contains the coded signal number (at present this is not the same as the
+usual Unix signal number).
+
+@item
+@cindex @code{system-error}
+@code{system-error}: thrown after the operating system indicates an
+error condition. The @var{rest} argument in the throw contains the
+errno value.
+
+@item
+@cindex @code{numerical-overflow}
+@code{numerical-overflow}: numerical overflow.
+
+@item
+@cindex @code{out-of-range}
+@code{out-of-range}: the arguments to a procedure do not fall within the
+accepted domain.
+
+@item
+@cindex @code{wrong-type-arg}
+@code{wrong-type-arg}: an argument to a procedure has the wrong type.
+
+@item
+@cindex @code{wrong-number-of-args}
+@code{wrong-number-of-args}: a procedure was called with the wrong number
+of arguments.
+
+@item
+@cindex @code{memory-allocation-error}
+@code{memory-allocation-error}: memory allocation error.
+
+@item
+@cindex @code{stack-overflow}
+@code{stack-overflow}: stack overflow error.
+
+@item
+@cindex @code{regular-expression-syntax}
+@code{regular-expression-syntax}: errors generated by the regular
+expression library.
+
+@item
+@cindex @code{misc-error}
+@code{misc-error}: other errors.
+@end itemize
+
+
+@subsubsection C Support
+
+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.
+@end deftypefn
+
+@deftypefn {C Function} void scm_syserror (char *@var{subr})
+@deftypefnx {C Function} void scm_syserror_msg (char *@var{subr}, char *@var{message}, SCM @var{args})
+Throw an error with key @code{system-error} and supply @code{errno} in
+the @var{rest} argument. For @code{scm_syserror} the message is
+generated using @code{strerror}.
+
+Care should be taken that any code in between the failing operation
+and the call to these routines doesn't change @code{errno}.
+@end deftypefn
+
+@deftypefn {C Function} void scm_num_overflow (char *@var{subr})
+@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_memory_error (char *@var{subr})
+Throw an error with the various keys described above.
+
+For @code{scm_wrong_num_args}, @var{proc} should be a Scheme symbol
+which is the name of the procedure incorrectly invoked.
+@end deftypefn
+
+
+@c Local Variables:
+@c TeX-master: "guile.texi"
+@c End: