mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-09 21:40:33 +02:00
* Extended documentation on exceptions.
* Minor changes to Martin's doc on continuations.
This commit is contained in:
parent
7a7f7c5314
commit
006064cefe
2 changed files with 126 additions and 18 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2001-04-22 Neil Jerram <neil@ossau.uklinux.net>
|
||||||
|
|
||||||
|
* scheme-control.texi (Exceptions): Extended documentation.
|
||||||
|
(Continuations): Correct "except" typo, and fix reference to
|
||||||
|
Exceptions node. Plus minor review changes.
|
||||||
|
|
||||||
2001-04-20 Neil Jerram <neil@ossau.uklinux.net>
|
2001-04-20 Neil Jerram <neil@ossau.uklinux.net>
|
||||||
|
|
||||||
* scheme-control.texi (Exceptions): Reorganized and extended
|
* scheme-control.texi (Exceptions): Reorganized and extended
|
||||||
|
|
|
@ -249,25 +249,27 @@ times.
|
||||||
@node Continuations
|
@node Continuations
|
||||||
@section Continuations
|
@section Continuations
|
||||||
|
|
||||||
@c FIXME::martin: Review me!
|
|
||||||
|
|
||||||
@cindex call/cc
|
@cindex call/cc
|
||||||
The possibility to explicitly capture continuation and the use of
|
@cindex call-with-current-continuation
|
||||||
|
The ability to explicitly capture continuations using
|
||||||
@code{call-with-current-continuation} (also often called @code{call/cc}
|
@code{call-with-current-continuation} (also often called @code{call/cc}
|
||||||
for shortness) is maybe the most powerful control structure known. All
|
for short), and to invoke such continuations later any number of times,
|
||||||
other control structures like loops or coroutines can be emulated using
|
and from any other point in a program, provides maybe the most powerful
|
||||||
continuation.
|
control structure known. All other control structures, such as loops
|
||||||
|
and coroutines, can be emulated using continuations.
|
||||||
|
|
||||||
|
@c NJFIXME - need a little something here about what continuations are
|
||||||
|
@c and what they do for you.
|
||||||
|
|
||||||
@c FIXME::martin: Is this too much of understatement, maybe confusing?
|
|
||||||
@c I'm not sure.
|
|
||||||
The implementation of continuations in Guile is not as efficient as one
|
The implementation of continuations in Guile is not as efficient as one
|
||||||
might except, because it is constrained by the fact that Guile is
|
might hope, because it is constrained by the fact that Guile is designed
|
||||||
required to be cooperative to programs written in other languages, such
|
to cooperate with programs written in other languages, such as C, which
|
||||||
as C which do not know about continuations. So continuations should be
|
do not know about continuations. So continuations should be used when
|
||||||
used when there is no other possibility to get the needed effect. If
|
there is no other simple way of achieving the desired behaviour, or
|
||||||
you find yourself using @code{call/cc} for escape procedures and your
|
where the advantages of the elegant continuation mechanism outweigh the
|
||||||
program is running to slow, you might want to use exceptions (REFFIXME)
|
need for optimum performance. If you find yourself using @code{call/cc}
|
||||||
instead.
|
for escape procedures and your program is running too slow, you might
|
||||||
|
want to use exceptions (@pxref{Exceptions}) instead.
|
||||||
|
|
||||||
@rnindex call-with-current-continuation
|
@rnindex call-with-current-continuation
|
||||||
@deffn primitive call-with-current-continuation proc
|
@deffn primitive call-with-current-continuation proc
|
||||||
|
@ -404,15 +406,89 @@ programming languages) provides an additional mechanism called
|
||||||
more conveniently.
|
more conveniently.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Catch and Throw:: Basic exception handling primitives.
|
* Exception Terminology:: Different ways to say the same thing.
|
||||||
|
* Catch:: Setting up to catch exceptions.
|
||||||
|
* Throw:: Throwing an exception.
|
||||||
* Lazy Catch:: Catch without unwinding.
|
* Lazy Catch:: Catch without unwinding.
|
||||||
* Stack Catch:: Capturing the stack at a throw.
|
* Stack Catch:: Capturing the stack at a throw.
|
||||||
* Exception Implementation:: How Guile implements exceptions.
|
* Exception Implementation:: How Guile implements exceptions.
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
@node Catch and Throw
|
@node Exception Terminology
|
||||||
@subsection Basic Exception Handling Primitives
|
@subsection 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. (Especially
|
||||||
|
considering that Guile handles POSIX signals by throwing a corresponding
|
||||||
|
kind of exception: REFFIXME.)
|
||||||
|
|
||||||
|
This manual prefers to speak of throwing and catching exceptions, since
|
||||||
|
this terminology matches the corresponding Guile primitives.
|
||||||
|
|
||||||
|
|
||||||
|
@node Catch
|
||||||
|
@subsection 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 @dfn{normal case} code --- i.e. what should
|
||||||
|
happen if no exceptions are thrown --- and a @dfn{handler} procedure
|
||||||
|
that says what to do if an exception is thrown. Note that if the
|
||||||
|
@dfn{normal case} thunk executes @dfn{normally}, which means without
|
||||||
|
throwing any exceptions, the handler procedure is not executed at all.
|
||||||
|
|
||||||
|
When an exception is thrown using the @code{throw} primitive, 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 primitive catch key thunk handler
|
@deffn primitive catch key thunk handler
|
||||||
Invoke @var{thunk} in the dynamic context of @var{handler} for
|
Invoke @var{thunk} in the dynamic context of @var{handler} for
|
||||||
|
@ -431,6 +507,32 @@ If the key is @code{#t}, then a throw to @emph{any} symbol will
|
||||||
match this call to @code{catch}.
|
match this call to @code{catch}.
|
||||||
@end deffn
|
@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.
|
||||||
|
|
||||||
|
|
||||||
|
@node Throw
|
||||||
|
@subsection Throwing Exceptions
|
||||||
|
|
||||||
@deffn primitive throw key . args
|
@deffn primitive throw key . args
|
||||||
Invoke the catch form matching @var{key}, passing @var{args} to the
|
Invoke the catch form matching @var{key}, passing @var{args} to the
|
||||||
@var{handler}.
|
@var{handler}.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue