mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-29 19:30:36 +02:00
* NEWS: * doc/ref/api-control.texi: * doc/ref/api-data.texi: * doc/ref/api-debug.texi: * doc/ref/api-deprecated.texi: * doc/ref/api-evaluation.texi: * doc/ref/api-foreign.texi: * doc/ref/api-i18n.texi: * doc/ref/api-io.texi: * doc/ref/api-languages.texi: * doc/ref/api-macros.texi: * doc/ref/api-memory.texi: * doc/ref/api-modules.texi: * doc/ref/api-options.texi: * doc/ref/api-peg.texi: * doc/ref/api-procedures.texi: * doc/ref/api-scheduling.texi: * doc/ref/api-undocumented.texi: * doc/ref/api-utility.texi: * doc/ref/expect.texi: * doc/ref/goops.texi: * doc/ref/misc-modules.texi: * doc/ref/posix.texi: * doc/ref/repl-modules.texi: * doc/ref/scheme-ideas.texi: * doc/ref/scheme-scripts.texi: * doc/ref/srfi-modules.texi: * gc-benchmarks/larceny/dynamic.sch: * gc-benchmarks/larceny/twobit-input-long.sch: * gc-benchmarks/larceny/twobit.sch: * libguile/gc.h: * libguile/ioext.c: * libguile/list.c: * libguile/options.c: * libguile/posix.c: * libguile/threads.c: * module/ice-9/boot-9.scm: * module/ice-9/optargs.scm: * module/ice-9/ports.scm: * module/ice-9/pretty-print.scm: * module/ice-9/psyntax.scm: * module/language/elisp/parser.scm: * module/language/tree-il/compile-bytecode.scm: * module/srfi/srfi-37.scm: * module/srfi/srfi-43.scm: * module/statprof.scm: * module/texinfo/reflection.scm: * test-suite/tests/eval.test: * test-suite/tests/fluids.test: Fix typos. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2373 lines
88 KiB
Text
2373 lines
88 KiB
Text
@c -*-texinfo-*-
|
|
@c This is part of the GNU Guile Reference Manual.
|
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010,
|
|
@c 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
|
|
@c See the file guile.texi for copying conditions.
|
|
|
|
@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:: Sequencing and splicing.
|
|
* Conditionals:: If, when, unless, case, and cond.
|
|
* and or:: Conditional evaluation of a sequence.
|
|
* while do:: Iteration mechanisms.
|
|
* Prompts:: Composable, delimited continuations.
|
|
* Continuations:: Non-composable continuations.
|
|
* Multiple Values:: Returning and accepting multiple values.
|
|
* Exceptions:: Raising and handling exceptions.
|
|
* Error Reporting:: Procedures for signaling errors.
|
|
* Dynamic Wind:: Dealing with non-local entrance/exit.
|
|
* Fluids and Dynamic States:: Dynamic scope building blocks.
|
|
* Parameters:: A dynamic scope facility.
|
|
* Handling Errors:: How to handle errors in C code.
|
|
* Continuation Barriers:: Protection from non-local control flow.
|
|
@end menu
|
|
|
|
@node begin
|
|
@subsection Sequencing and Splicing
|
|
|
|
@cindex begin
|
|
@cindex sequencing
|
|
@cindex expression sequencing
|
|
|
|
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 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 expr @dots{}
|
|
The expression(s) are evaluated in left-to-right order and the values of
|
|
the last expression are returned as the result of the
|
|
@code{begin}-expression. This expression type is used when the
|
|
expressions before the last one are evaluated for their side effects.
|
|
@end deffn
|
|
|
|
@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
|
|
|
|
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 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 the special forms @code{when} and @code{unless}. As an added
|
|
bonus, these forms take a @emph{body} like in a @code{let} expression,
|
|
which can contain internal definitions and multiple statements to
|
|
evaluate (@pxref{Local Bindings}).
|
|
|
|
@deffn {Scheme Syntax} when test body
|
|
@deffnx {Scheme Syntax} unless test body
|
|
The actual definitions of these forms may be their most clear documentation:
|
|
|
|
@example
|
|
(define-syntax-rule (when test stmt stmt* ...)
|
|
(if test (let () stmt stmt* ...)))
|
|
|
|
(define-syntax-rule (unless test stmt stmt* ...)
|
|
(if (not test) (let () 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:
|
|
|
|
@lisp
|
|
(@var{test} @var{body})
|
|
@end lisp
|
|
|
|
where @var{test} is an 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 value, the corresponding @var{body} is
|
|
evaluated to produce the result 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.
|
|
|
|
@cindex SRFI-61
|
|
@cindex general cond clause
|
|
@cindex multiple values and cond
|
|
One additional @code{cond}-clause is available as an extension to
|
|
standard Scheme:
|
|
|
|
@lisp
|
|
(@var{test} @var{guard} => @var{expression})
|
|
@end lisp
|
|
|
|
where @var{guard} and @var{expression} must evaluate to procedures.
|
|
For this clause type, @var{test} may return multiple values, and
|
|
@code{cond} ignores its boolean state; instead, @code{cond} evaluates
|
|
@var{guard} and applies the resulting procedure to the value(s) of
|
|
@var{test}, as if @var{guard} were the @var{consumer} argument of
|
|
@code{call-with-values}. If the result of that procedure call is a
|
|
true value, it evaluates @var{expression} and applies the resulting
|
|
procedure to the value(s) of @var{test}, in the same manner as the
|
|
@var{guard} was called.
|
|
|
|
The @var{test} of the last @var{clause} may be the symbol @code{else}.
|
|
Then, if none of the preceding @var{test}s is true, the
|
|
@var{body} following the @code{else} is 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, and the @var{clause}s must have the form
|
|
|
|
@lisp
|
|
((@var{datum1} @dots{}) @var{body})
|
|
@end lisp
|
|
|
|
or
|
|
|
|
@lisp
|
|
((@var{datum1} @dots{}) => @var{expression})
|
|
@end lisp
|
|
|
|
and the last @var{clause} may have the form
|
|
|
|
@lisp
|
|
(else @var{body})
|
|
@end lisp
|
|
|
|
or
|
|
|
|
@lisp
|
|
(else => @var{expression})
|
|
@end lisp
|
|
|
|
All @var{datum}s must be distinct. First, @var{key} is evaluated. The
|
|
result of this evaluation is compared against all @var{datum} values
|
|
using @code{eqv?}. When this comparison succeeds, the @var{body}
|
|
following the @var{datum} is evaluated to produce the result of the
|
|
@code{case} expression.
|
|
|
|
If the @var{key} matches no @var{datum} and there is an
|
|
@code{else}-clause, the @var{body} following the @code{else} is
|
|
evaluated to produce the result of the @code{case} expression. 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
|
|
|
|
|
|
@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{}
|
|
243
|
|
@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.
|
|
|
|
Within @code{while}, two extra bindings are provided, they can be used
|
|
from both @var{cond} and @var{body}.
|
|
|
|
@deffn {Scheme Procedure} break break-arg @dots{}
|
|
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
|
|
|
|
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.
|
|
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 behavior 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 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{with-exception-handler} and
|
|
@code{raise-exception} 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.
|
|
|
|
@cindex continuation, escape
|
|
One example where this optimization matters is @dfn{escape
|
|
continuations}. Escape continuations are delimited continuations whose
|
|
only use is to make a non-local exit---i.e., to escape from the current
|
|
continuation. A common use of escape continuations is when handling an
|
|
exception (@pxref{Exceptions}).
|
|
|
|
The constructs below are syntactic sugar atop prompts to simplify the
|
|
use of escape continuations.
|
|
|
|
@deffn {Scheme Procedure} call-with-escape-continuation proc
|
|
@deffnx {Scheme Procedure} call/ec proc
|
|
Call @var{proc} with an escape continuation.
|
|
|
|
In the example below, the @var{return} continuation is used to escape
|
|
the continuation of the call to @code{fold}.
|
|
|
|
@lisp
|
|
(use-modules (ice-9 control)
|
|
(srfi srfi-1))
|
|
|
|
(define (prefix x lst)
|
|
;; Return all the elements before the first occurrence
|
|
;; of X in LST.
|
|
(call/ec
|
|
(lambda (return)
|
|
(fold (lambda (element prefix)
|
|
(if (equal? element x)
|
|
(return (reverse prefix)) ; escape `fold'
|
|
(cons element prefix)))
|
|
'()
|
|
lst))))
|
|
|
|
(prefix 'a '(0 1 2 a 3 4 5))
|
|
@result{} (0 1 2)
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Syntax} let-escape-continuation k body @dots{}
|
|
@deffnx {Scheme Syntax} let/ec k body @dots{}
|
|
Bind @var{k} within @var{body} to an escape continuation.
|
|
|
|
This is equivalent to
|
|
@code{(call/ec (lambda (@var{k}) @var{body} @dots{}))}.
|
|
@end deffn
|
|
|
|
Additionally there is another helper primitive exported by @code{(ice-9
|
|
control)}, so load up that module for @code{suspendable-continuation?}:
|
|
|
|
@example
|
|
(use-modules (ice-9 control))
|
|
@end example
|
|
|
|
@deffn {Scheme Procedure} suspendable-continuation? tag
|
|
Return @code{#t} if a call to @code{abort-to-prompt} with the prompt tag
|
|
@var{tag} would produce a delimited continuation that could be resumed
|
|
later.
|
|
|
|
Almost all continuations have this property. The exception is where
|
|
some code between the @code{call-with-prompt} and the
|
|
@code{abort-to-prompt} recursed through C for some reason, the
|
|
@code{abort-to-prompt} will succeed but any attempt to resume the
|
|
continuation (by calling it) would fail. This is because composing a
|
|
saved continuation with the current continuation involves relocating the
|
|
stack frames that were saved from the old stack onto a (possibly) new
|
|
position on the new stack, and Guile can only do this for stack frames
|
|
that it created for Scheme code, not stack frames created by the C
|
|
compiler. It's a bit gnarly but if you stick with Scheme, you won't
|
|
have any problem.
|
|
|
|
If no prompt is found with the given tag, this procedure just returns
|
|
@code{#f}.
|
|
@end deffn
|
|
|
|
@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 be 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
|
|
|
|
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 same side of a continuation
|
|
barrier as it was created (@pxref{Continuation Barriers}), and in a
|
|
multi-threaded program only from the thread in which it was created.
|
|
|
|
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
|
|
|
|
@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.
|
|
|
|
@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, 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 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).
|
|
|
|
|
|
@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 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,
|
|
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
|
|
|
|
@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 a more 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
|
|
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. This is in the @code{(ice-9 receive)} and is the
|
|
same as specified by SRFI-8 (@pxref{SRFI-8}).
|
|
|
|
@lisp
|
|
(use-modules (ice-9 receive))
|
|
@end lisp
|
|
|
|
@deffn {library syntax} receive formals expr body
|
|
Evaluate the expression @var{expr}, and bind the result values (zero
|
|
or more) to the formal arguments in @var{formals}. @var{formals} is a
|
|
list of symbols, like the argument list in a @code{lambda}
|
|
(@pxref{Lambda}). After binding the variables, the @var{body} is
|
|
evaluated to produce the result of the @code{receive} expression.
|
|
|
|
For example getting results from @code{partition} in SRFI-1
|
|
(@pxref{SRFI-1}),
|
|
|
|
@example
|
|
(receive (odds evens)
|
|
(partition odd? '(7 4 2 8 3))
|
|
(display odds)
|
|
(display " and ")
|
|
(display evens))
|
|
@print{} (7 3) and (4 2 8)
|
|
@end example
|
|
|
|
@end deffn
|
|
|
|
|
|
@node Exceptions
|
|
@subsection Exceptions
|
|
@cindex error handling
|
|
@cindex exception handling
|
|
|
|
What happens when things go wrong? Guile's exception facility exists to
|
|
help answer this question, allowing programs to describe the problem and
|
|
to handle the situation in a flexible way.
|
|
|
|
When a program runs into a problem, such as division by zero, it will
|
|
raise an exception. Sometimes exceptions get raised by Guile on a
|
|
program's behalf. Sometimes a program will want to raise exceptions of
|
|
its own. Raising an exception stops the current computation and instead
|
|
invokes the current exception handler, passing it an exception object
|
|
describing the unexpected situation.
|
|
|
|
Usually an exception handler will unwind the computation back to some
|
|
kind of safe point. 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, raise an exception
|
|
@dots{}
|
|
@end example
|
|
|
|
In this case, @code{main-loop} can install an exception handler that
|
|
would cause any exception raised inside @code{dispatch-key} to print a
|
|
warning and jump back to the main loop.
|
|
|
|
The following subsections go into more detail about exception objects,
|
|
raising exceptions, and handling exceptions. It also presents a
|
|
historical interface that was used in Guile's first 25 years and which
|
|
won't be going away any time soon.
|
|
|
|
@menu
|
|
* Exception Objects:: What went wrong?
|
|
* Raising and Handling Exceptions:: What to do when something goes wrong.
|
|
* Throw and Catch:: An older approach to exceptions.
|
|
* Exceptions and C:: Specialized interfaces for C.
|
|
@end menu
|
|
|
|
|
|
@node Exception Objects
|
|
@subsubsection Exception Objects
|
|
|
|
When Guile encounters an exceptional situation, it raises an exception,
|
|
where the exception is an object that describes the exceptional
|
|
situation. Exception objects are structured data, built on the record
|
|
facility (@pxref{Records}).
|
|
|
|
@deftp {Exception Type} &exception
|
|
The base exception type. All exception objects are composed of
|
|
instances of subtypes of @code{&exception}.
|
|
@end deftp
|
|
|
|
@deffn {Scheme Procedure} exception-type? obj
|
|
Return true if @var{obj} is an exception type.
|
|
@end deffn
|
|
|
|
Exception types exist in a hierarchy. New exception types can be
|
|
defined using @code{make-exception-type}.
|
|
|
|
@deffn {Scheme Procedure} make-exception-type id parent field-names
|
|
Return a new exception type named @var{id}, inheriting from
|
|
@var{parent}, and with the fields whose names are listed in
|
|
@var{field-names}. @var{field-names} must be a list of symbols and must
|
|
not contain names already used by @var{parent} or one of its supertypes.
|
|
@end deffn
|
|
|
|
Exception type objects are record type objects, and as such, one can use
|
|
@code{record-constructor} on an exception type to get its constructor.
|
|
The constructor will take as many arguments as the exception has fields
|
|
(including supertypes). @xref{Records}.
|
|
|
|
However, @code{record-predicate} and @code{record-accessor} aren't
|
|
usually what you want to use as exception type predicates and field
|
|
accessors. The reason is, instances of exception types can be composed
|
|
into @dfn{compound exceptions}. Exception accessors should pick out the
|
|
specific component of a compound exception, and then access the field on
|
|
that specific component.
|
|
|
|
@deffn {Scheme Procedure} make-exception exceptions @dots{}
|
|
Return an exception object composed of @var{exceptions}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} exception? obj
|
|
Return true if @var{obj} is an exception object.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} exception-predicate type
|
|
Return a procedure that will return true if its argument is a simple
|
|
exception that is an instance of @var{type}, or a compound exception
|
|
composed of such an instance.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} exception-accessor rtd proc
|
|
Return a procedure that will tail-call @var{proc} on an instance of the
|
|
exception type @var{rtd}, or on the component of a compound exception
|
|
that is an instance of @var{rtd}.
|
|
@end deffn
|
|
|
|
Compound exceptions are useful to separately express the different
|
|
aspects of a situation. For example, compound exceptions allow a
|
|
programmer to say that ``this situation is a programming error, and also
|
|
here's a useful message to show to the user, and here are some relevant
|
|
objects that can give more information about the error''. This error
|
|
could be composed of instances of the @code{&programming-error},
|
|
@code{&message}, and @code{&irritants} exception types.
|
|
|
|
The subtyping relationship in exceptions is useful to let
|
|
different-but-similar situations to be treated the same; for example
|
|
there are many varieties of programming errors (for example,
|
|
divide-by-zero or type mismatches), but perhaps there are common ways
|
|
that the user would like to handle them all, and that common way might
|
|
be different than how one might handle an error originating outside the
|
|
program (for example, a file-not-found error).
|
|
|
|
The standard exception hierarchy in Guile takes its cues from R6RS,
|
|
though the names of some of the types are different. @xref{rnrs
|
|
exceptions}, for more details.
|
|
|
|
To have access to Guile's exception type hierarchy, import the
|
|
@code{(ice-9 exceptions)} module:
|
|
|
|
@example
|
|
(use-modules (ice-9 exceptions))
|
|
@end example
|
|
|
|
The following diagram gives an overview of the standard exception type
|
|
hierarchy.
|
|
|
|
@example
|
|
&exception
|
|
|- &warning
|
|
|- &message
|
|
|- &irritants
|
|
|- &origin
|
|
\- &error
|
|
|- &external-error
|
|
\- &programming-error
|
|
|- &assertion-failure
|
|
|- &non-continuable
|
|
|- &implementation-restriction
|
|
|- &lexical
|
|
|- &syntax
|
|
\- &undefined-variable
|
|
@end example
|
|
|
|
@deftp {Exception Type} &warning
|
|
An exception type denoting warnings. These are usually raised using
|
|
@code{#:continuable? #t}; see the @code{raise-exception} documentation
|
|
for more.
|
|
@end deftp
|
|
@deffn {Scheme Procedure} make-warning
|
|
@deffnx {Scheme Procedure} warning? obj
|
|
Constructor and predicate for @code{&warning} exception objects.
|
|
@end deffn
|
|
|
|
@deftp {Exception Type} &message message
|
|
An exception type that provides a message to display to the user.
|
|
Usually used as a component of a compound exception.
|
|
@end deftp
|
|
@deffn {Scheme Procedure} make-exception-with-message message
|
|
@deffnx {Scheme Procedure} exception-with-message? obj
|
|
@deffnx {Scheme Procedure} exception-message exn
|
|
Constructor, predicate, and accessor for @code{&message} exception
|
|
objects.
|
|
@end deffn
|
|
|
|
@deftp {Exception Type} &irritants irritants
|
|
An exception type that provides a list of objects that were unexpected
|
|
in some way. Usually used as a component of a compound exception.
|
|
@end deftp
|
|
@deffn {Scheme Procedure} make-exception-with-irritants irritants
|
|
@deffnx {Scheme Procedure} exception-with-irritants? obj
|
|
@deffnx {Scheme Procedure} exception-irritants exn
|
|
Constructor, predicate, and accessor for @code{&irritants} exception
|
|
objects.
|
|
@end deffn
|
|
|
|
@deftp {Exception Type} &origin origin
|
|
An exception type that indicates the origin of an exception, typically
|
|
expressed as a procedure name, as a symbol. Usually used as a component
|
|
of a compound exception.
|
|
@end deftp
|
|
@deffn {Scheme Procedure} make-exception-with-origin origin
|
|
@deffnx {Scheme Procedure} exception-with-origin? obj
|
|
@deffnx {Scheme Procedure} exception-origin exn
|
|
Constructor, predicate, and accessor for @code{&origin} exception
|
|
objects.
|
|
@end deffn
|
|
|
|
@deftp {Exception Type} &error
|
|
An exception type denoting errors: situations that are not just
|
|
exceptional, but wrong.
|
|
@end deftp
|
|
@deffn {Scheme Procedure} make-error
|
|
@deffnx {Scheme Procedure} error? obj
|
|
Constructor and predicate for @code{&error} exception objects.
|
|
@end deffn
|
|
|
|
@deftp {Exception Type} &external-error
|
|
An exception type denoting errors that proceed from the interaction of
|
|
the program with the world, for example a ``file not found'' error.
|
|
@end deftp
|
|
@deffn {Scheme Procedure} make-external-error
|
|
@deffnx {Scheme Procedure} external-error? obj
|
|
Constructor and predicate for @code{&external-error} exception objects.
|
|
@end deffn
|
|
|
|
@deftp {Exception Type} &programming-error
|
|
An exception type denoting errors that proceed from inside a program:
|
|
type mismatches and so on.
|
|
@end deftp
|
|
@deffn {Scheme Procedure} make-programming-error
|
|
@deffnx {Scheme Procedure} programming-error? obj
|
|
Constructor and predicate for @code{&programming-error} exception
|
|
objects.
|
|
@end deffn
|
|
|
|
@deftp {Exception Type} &non-continuable
|
|
An exception type denoting errors that proceed from inside a program:
|
|
type mismatches and so on.
|
|
@end deftp
|
|
@deffn {Scheme Procedure} make-non-continuable-error
|
|
@deffnx {Scheme Procedure} non-continuable-error? obj
|
|
Constructor and predicate for @code{&non-continuable} exception objects.
|
|
@end deffn
|
|
|
|
@deftp {Exception Type} &lexical
|
|
An exception type denoting lexical errors, for example unbalanced
|
|
parentheses.
|
|
@end deftp
|
|
@deffn {Scheme Procedure} make-lexical-error
|
|
@deffnx {Scheme Procedure} lexical-error? obj
|
|
Constructor and predicate for @code{&lexical} exception objects.
|
|
@end deffn
|
|
|
|
@deftp {Exception Type} &syntax form subform
|
|
An exception type denoting syntax errors, for example a @code{cond}
|
|
expression with invalid syntax. The @var{form} field indicates the form
|
|
containing the error, and @var{subform} indicates the unexpected
|
|
subcomponent, or @code{#f} if unavailable.
|
|
@end deftp
|
|
@deffn {Scheme Procedure} make-syntax-error form subform
|
|
@deffnx {Scheme Procedure} syntax-error? obj
|
|
@deffnx {Scheme Procedure} syntax-error-form exn
|
|
@deffnx {Scheme Procedure} syntax-error-subform exn
|
|
Constructor, predicate, and accessors for @code{&syntax} exception
|
|
objects.
|
|
@end deffn
|
|
|
|
@deftp {Exception Type} &undefined-variable
|
|
An exception type denoting undefined variables.
|
|
@end deftp
|
|
@deffn {Scheme Procedure} make-undefine-variable-error
|
|
@deffnx {Scheme Procedure} undefined-variable-error? obj
|
|
Constructor and predicate for @code{&undefined-variable} exception
|
|
objects.
|
|
@end deffn
|
|
|
|
Incidentally, the @code{(ice-9 exceptions)} module also includes a
|
|
@code{define-exception-type} macro that can be used to conveniently add
|
|
new exception types to the hierarchy.
|
|
|
|
@deffn {Syntax} define-exception-type name parent @
|
|
constructor predicate @
|
|
(field accessor) @dots{}
|
|
Define @var{name} to be a new exception type, inheriting from
|
|
@var{parent}. Define @var{constructor} and @var{predicate} to be the
|
|
exception constructor and predicate, respectively, and define an
|
|
@var{accessor} for each @var{field}.
|
|
@end deffn
|
|
|
|
|
|
@node Raising and Handling Exceptions
|
|
@subsubsection Raising and Handling Exceptions
|
|
|
|
An exception object describes an exceptional situation. To bring that
|
|
description to the attention of the user or to handle the situation
|
|
programmatically, the first step is to @dfn{raise} the exception.
|
|
|
|
@deffn {Scheme Procedure} raise-exception obj [#:continuable?=#f]
|
|
Raise an exception by invoking the current exception handler on
|
|
@var{obj}. The handler is called with a continuation whose dynamic
|
|
environment is that of the call to @code{raise}, except that the current
|
|
exception handler is the one that was in place when the handler being
|
|
called was installed.
|
|
|
|
If @var{continuable?} is true, the handler is invoked in tail position
|
|
relative to the @code{raise-exception} call. Otherwise if the handler
|
|
returns, a non-continuable exception of type @code{&non-continuable} is
|
|
raised in the same dynamic environment as the handler.
|
|
@end deffn
|
|
|
|
As the above description notes, Guile has a notion of a @dfn{current
|
|
exception handler}. At the REPL, this exception handler may enter a
|
|
recursive debugger; in a standalone program, it may simply print a
|
|
representation of the error and exit.
|
|
|
|
To establish an exception handler within the dynamic extent of a call,
|
|
use @code{with-exception-handler}.
|
|
|
|
@deffn {Scheme Procedure} with-exception-handler handler thunk @
|
|
[#:unwind?=#f] [#:unwind-for-type=#t]
|
|
Establish @var{handler}, a procedure of one argument, as the current
|
|
exception handler during the dynamic extent of invoking @var{thunk}.
|
|
|
|
If @code{raise-exception} is called during the dynamic extent of
|
|
invoking @var{thunk}, @var{handler} will be invoked on the argument of
|
|
@code{raise-exception}.
|
|
@end deffn
|
|
|
|
There are two kinds of exception handlers: unwinding and non-unwinding.
|
|
|
|
By default, exception handlers are non-unwinding. Unless
|
|
@code{with-exception-handler} was invoked with @code{#:unwind? #t},
|
|
exception handlers are invoked within the continuation of the error,
|
|
without unwinding the stack. The dynamic environment of the handler
|
|
call will be that of the @code{raise-exception} call, with the
|
|
difference that the current exception handler will be ``unwound'' to the
|
|
``outer'' handler (the one that was in place when the corresponding
|
|
@code{with-exception-handler} was called).
|
|
|
|
However, it's often the case that one would like to handle an exception
|
|
by unwinding the computation to an earlier state and running the error
|
|
handler there. After all, unless the @code{raise-exception} call is
|
|
continuable, the exception handler needs to abort the continuation. To
|
|
support this use case, if @code{with-exception-handler} was invoked with
|
|
@code{#:unwind? #t} is true, @code{raise-exception} will first unwind
|
|
the stack by invoking an @dfn{escape continuation} (@pxref{Prompt
|
|
Primitives, @code{call/ec}}), and then invoke the handler with the
|
|
continuation of the @code{with-exception-handler} call.
|
|
|
|
Finally, one more wrinkle: for unwinding exception handlers, it can be
|
|
useful to Guile if it can determine whether an exception handler would
|
|
indeed handle a particular exception or not. This is especially the
|
|
case for exceptions raised in resource-exhaustion scenarios like
|
|
@code{stack-overflow} or @code{out-of-memory}, where you want to
|
|
immediately shrink resource use before recovering. @xref{Stack
|
|
Overflow}. For this purpose, the @code{#:unwind-for-type} keyword
|
|
argument allows users to specify the kind of exception handled by an
|
|
exception handler; if @code{#t}, all exceptions will be handled; if an
|
|
exception type object, only exceptions of that type will be handled;
|
|
otherwise if a symbol, only that exceptions with the given
|
|
@code{exception-kind} will be handled.
|
|
|
|
|
|
@node Throw and Catch
|
|
@subsubsection Throw and Catch
|
|
|
|
Guile only adopted @code{with-exception-handler} and
|
|
@code{raise-exception} as its primary exception-handling facility in
|
|
2019. Before then, exception handling was fundamentally based on three
|
|
other primitives with a somewhat more complex interface: @code{catch},
|
|
@code{with-throw-handler}, and @code{throw}.
|
|
|
|
@deffn {Scheme Procedure} catch key thunk handler [pre-unwind-handler]
|
|
@deffnx {C Function} scm_catch_with_pre_unwind_handler (key, thunk, handler, pre_unwind_handler)
|
|
@deffnx {C Function} scm_catch (key, thunk, handler)
|
|
Establish an exception handler during the dynamic extent of the call to
|
|
@var{thunk}. @var{key} is either @code{#t}, indicating that all
|
|
exceptions should be handled, or a symbol, restricting the exceptions
|
|
handled to those having the @var{key} as their @code{exception-kind}.
|
|
|
|
If @var{thunk} executes normally, meaning without throwing any
|
|
exceptions, the handler procedures are not called at all and the result
|
|
of the @code{thunk} call is the result of the @code{catch}. Otherwise
|
|
if an exception is thrown that matches @var{key}, @var{handler} is
|
|
called with the continuation of the @code{catch} call.
|
|
@end deffn
|
|
|
|
Given the discussion from the previous section, it is most precise and
|
|
concise to specify what @code{catch} does by expressing it in terms of
|
|
@code{with-exception-handler}. Calling @code{catch} with the three
|
|
arguments is the same as:
|
|
|
|
@example
|
|
(define (catch key thunk handler)
|
|
(with-exception-handler
|
|
(lambda (exn)
|
|
(apply handler (exception-kind exn) (exception-args exn)))
|
|
thunk
|
|
#:unwind? #t
|
|
#:unwind-for-type key))
|
|
@end example
|
|
|
|
By invoking @code{with-exception-handler} with @code{#:unwind? #t},
|
|
@code{catch} sets up an escape continuation that will be invoked in an
|
|
exceptional situation before the handler is called.
|
|
|
|
If @code{catch} is called with four arguments, then the use of
|
|
@var{thunk} should be replaced with:
|
|
|
|
@example
|
|
(lambda ()
|
|
(with-throw-handler key thunk pre-unwind-handler))
|
|
@end example
|
|
|
|
As can be seen above, if a pre-unwind-handler is passed to @code{catch},
|
|
it's like calling @code{with-throw-handler} inside the body thunk.
|
|
|
|
@code{with-throw-handler} is the second of the older primitives, and is
|
|
used to be able to intercept an exception that is being 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.
|
|
|
|
@deffn {Scheme Procedure} with-throw-handler key thunk handler
|
|
@deffnx {C Function} scm_with_throw_handler (key, thunk, handler)
|
|
Add @var{handler} to the dynamic context as a throw handler
|
|
for key @var{key}, then invoke @var{thunk}.
|
|
@end deffn
|
|
|
|
It's not possible to exactly express @code{with-throw-handler} in terms
|
|
of @code{with-exception-handler}, but we can get close.
|
|
|
|
@example
|
|
(define (with-throw-handler key thunk handler)
|
|
(with-exception-handler
|
|
(lambda (exn)
|
|
(when (or (eq? key #t) (eq? key (exception-kind exn)))
|
|
(apply handler (exception-kind exn) (exception-args exn)))
|
|
(raise-exception exn))
|
|
thunk))
|
|
@end example
|
|
|
|
As you can see, unlike in the case of @code{catch}, the handler for
|
|
@code{with-throw-handler} is invoked within the continuation of
|
|
@code{raise-exception}, before unwinding the stack. If the throw
|
|
handler returns normally, the exception will be re-raised, to be handled
|
|
by the next exception handler.
|
|
|
|
The special wrinkle of @code{with-throw-handler} that can't be shown
|
|
above is that if invoking the handler causes a @code{raise-exception}
|
|
instead of completing normally, the exception is thrown in the
|
|
@emph{original} dynamic environment of the @code{raise-exception}. Any
|
|
inner exception handler will get another shot at handling the exception.
|
|
Here is an example to illustrate this behavior:
|
|
|
|
@lisp
|
|
(catch 'a
|
|
(lambda ()
|
|
(with-throw-handler 'b
|
|
(lambda ()
|
|
(catch 'a
|
|
(lambda ()
|
|
(throw 'b))
|
|
inner-handler))
|
|
(lambda (key . args)
|
|
(throw 'a))))
|
|
outer-handler)
|
|
@end lisp
|
|
|
|
@noindent
|
|
This code will call @code{inner-handler} and then continue with the
|
|
continuation of the inner @code{catch}.
|
|
|
|
Finally, we get to @code{throw}, which is the older equivalent to
|
|
@code{raise-exception}.
|
|
|
|
@deffn {Scheme Procedure} throw key arg @dots{}
|
|
@deffnx {C Function} scm_throw (key, args)
|
|
Raise an exception with kind @var{key} and arguments @var{args}.
|
|
@var{key} is a symbol, denoting the ``kind'' of the exception.
|
|
@end deffn
|
|
|
|
Again, we can specify what @code{throw} does by expressing it in terms
|
|
of @code{raise-exception}.
|
|
|
|
@example
|
|
(define (throw key . args)
|
|
(raise-exception (make-exception-from-throw key args)))
|
|
@end example
|
|
|
|
At this point, we should mention the primitive that manage the
|
|
relationship between structured exception objects @code{throw}.
|
|
|
|
@deffn {Scheme Procedure} make-exception-from-throw key args
|
|
Create an exception object for the given @var{key} and @var{args} passed
|
|
to @code{throw}. This may be a specific type of exception, for example
|
|
@code{&programming-error}; Guile maintains a set of custom transformers
|
|
for the various @var{key} values that have been used historically.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} exception-kind exn
|
|
If @var{exn} is an exception created via
|
|
@code{make-exception-from-throw}, return the corresponding @var{key} for
|
|
the exception. Otherwise, unless @var{exn} is an exception of a type
|
|
with a known mapping to @code{throw}, return the symbol
|
|
@code{%exception}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} exception-args exn
|
|
If @var{exn} is an exception created via
|
|
@code{make-exception-from-throw}, return the corresponding @var{args}
|
|
for the exception. Otherwise, unless @var{exn} is an exception of a
|
|
type with a known mapping to @code{throw}, return @code{(list @var{exn})}.
|
|
@end deffn
|
|
|
|
|
|
@node Exceptions and C
|
|
@subsubsection Exceptions and C
|
|
|
|
There are some specific versions of Guile's original @code{catch} and
|
|
@code{with-throw-handler} exception-handling primitives that are still
|
|
widely used in C code.
|
|
|
|
@deftypefn {C Function} SCM scm_c_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data, scm_t_catch_handler pre_unwind_handler, void *pre_unwind_handler_data)
|
|
@deftypefnx {C Function} SCM scm_internal_catch (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data)
|
|
The above @code{scm_catch_with_pre_unwind_handler} and @code{scm_catch}
|
|
take Scheme procedures as body and handler arguments.
|
|
@code{scm_c_catch} and @code{scm_internal_catch} are equivalents taking
|
|
C functions.
|
|
|
|
@var{body} is called as @code{@var{body} (@var{body_data})} with a catch
|
|
on exceptions of the given @var{tag} type. If an exception is caught,
|
|
@var{pre_unwind_handler} and @var{handler} are called as
|
|
@code{@var{handler} (@var{handler_data}, @var{key}, @var{args})}.
|
|
@var{key} and @var{args} are the @code{SCM} key and argument list from
|
|
the @code{throw}.
|
|
|
|
@tpindex scm_t_catch_body
|
|
@tpindex scm_t_catch_handler
|
|
@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{Foreign Object Memory
|
|
Management}).
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_c_with_throw_handler (SCM tag, scm_t_catch_body body, void *body_data, scm_t_catch_handler handler, void *handler_data, int lazy_catch_p)
|
|
The above @code{scm_with_throw_handler} takes Scheme procedures as body
|
|
(thunk) and handler arguments. @code{scm_c_with_throw_handler} is an
|
|
equivalent taking C functions. See @code{scm_c_catch}
|
|
(@pxref{Exceptions and C}) for a description of the parameters, the
|
|
behavior however of course follows @code{with-throw-handler}.
|
|
@end deftypefn
|
|
|
|
|
|
@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 arg @dots{}
|
|
Raise an error with key @code{misc-error} and a message constructed by
|
|
displaying @var{msg} and writing @var{arg} @enddots{}.
|
|
@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; If
|
|
@var{key} is @code{out-of-range}, @code{wrong-type-arg},
|
|
or @code{keyword-argument-error},
|
|
it is a list containing the bad value; 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}, an integer
|
|
@code{errno} value.
|
|
|
|
When @code{setlocale} has been called (@pxref{Locales}), the message
|
|
is in the language and charset of @code{LC_MESSAGES}. (This is done
|
|
by the C library.)
|
|
@end deffn
|
|
|
|
@c begin (scm-doc-string "boot-9.scm" "false-if-exception")
|
|
@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
|
|
|
|
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.
|
|
|
|
Therefore, Guile offers the functions @code{scm_dynwind_begin} and
|
|
@code{scm_dynwind_end} to delimit a dynamic extent. Within this
|
|
dynamic extent, which is called a @dfn{dynwind context}, you can
|
|
perform various @dfn{dynwind actions} that control what happens when
|
|
the dynwind context is entered or left. For example, you can register
|
|
a cleanup routine with @code{scm_dynwind_unwind_handler} that is
|
|
executed when the context is left. There are several other more
|
|
specialized dynwind actions as well, for example to temporarily block
|
|
the execution of asyncs or to temporarily change the current output
|
|
port. They are described elsewhere in this manual.
|
|
|
|
Here is an example that shows how to prevent memory leaks.
|
|
|
|
@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.
|
|
*/
|
|
|
|
SCM
|
|
scm_foo (SCM s1, SCM s2)
|
|
@{
|
|
char *c_s1, *c_s2, *c_res;
|
|
|
|
scm_dynwind_begin (0);
|
|
|
|
c_s1 = scm_to_locale_string (s1);
|
|
|
|
/* Call 'free (c_s1)' when the dynwind context is left.
|
|
*/
|
|
scm_dynwind_unwind_handler (free, c_s1, SCM_F_WIND_EXPLICITLY);
|
|
|
|
c_s2 = scm_to_locale_string (s2);
|
|
|
|
/* Same as above, but more concisely.
|
|
*/
|
|
scm_dynwind_free (c_s2);
|
|
|
|
c_res = foo (c_s1, c_s2);
|
|
if (c_res == NULL)
|
|
scm_report_out_of_memory ();
|
|
|
|
scm_dynwind_end ();
|
|
|
|
return scm_take_locale_string (res);
|
|
@}
|
|
@end example
|
|
|
|
@rnindex dynamic-wind
|
|
@deffn {Scheme Procedure} dynamic-wind in_guard thunk out_guard
|
|
@deffnx {C Function} scm_dynamic_wind (in_guard, thunk, out_guard)
|
|
All three arguments must be 0-argument procedures.
|
|
@var{in_guard} is called, then @var{thunk}, then
|
|
@var{out_guard}.
|
|
|
|
If, any time during the execution of @var{thunk}, the
|
|
dynamic extent of the @code{dynamic-wind} expression is escaped
|
|
non-locally, @var{out_guard} is called. If the dynamic extent of
|
|
the dynamic-wind is re-entered, @var{in_guard} is called. Thus
|
|
@var{in_guard} and @var{out_guard} may be called any number of
|
|
times.
|
|
|
|
@lisp
|
|
(define x 'normal-binding)
|
|
@result{} x
|
|
(define a-cont
|
|
(call-with-current-continuation
|
|
(lambda (escape)
|
|
(let ((old-x x))
|
|
(dynamic-wind
|
|
;; in-guard:
|
|
;;
|
|
(lambda () (set! x 'special-binding))
|
|
|
|
;; thunk
|
|
;;
|
|
(lambda () (display x) (newline)
|
|
(call-with-current-continuation escape)
|
|
(display x) (newline)
|
|
x)
|
|
|
|
;; out-guard:
|
|
;;
|
|
(lambda () (set! x old-x)))))))
|
|
;; Prints:
|
|
special-binding
|
|
;; Evaluates to:
|
|
@result{} a-cont
|
|
x
|
|
@result{} normal-binding
|
|
(a-cont #f)
|
|
;; Prints:
|
|
special-binding
|
|
;; Evaluates to:
|
|
@result{} a-cont ;; the value of the (define a-cont...)
|
|
x
|
|
@result{} normal-binding
|
|
a-cont
|
|
@result{} special-binding
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deftp {C Type} scm_t_dynwind_flags
|
|
This is an enumeration of several flags that modify the behavior of
|
|
@code{scm_dynwind_begin}. The flags are listed in the following
|
|
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 invocation of a continuation). The
|
|
default is that a dynwind context can not be reentered non-locally.
|
|
@end table
|
|
|
|
@end deftp
|
|
|
|
@deftypefn {C Function} void scm_dynwind_begin (scm_t_dynwind_flags flags)
|
|
The function @code{scm_dynwind_begin} starts a new dynamic context and
|
|
makes it the `current' one.
|
|
|
|
The @var{flags} argument determines the default behavior of the
|
|
context. Normally, use 0. This will result in a context that can not
|
|
be reentered with a captured continuation. When you are prepared to
|
|
handle reentries, include @code{SCM_F_DYNWIND_REWINDABLE} in
|
|
@var{flags}.
|
|
|
|
Being prepared for reentry means that the effects of unwind handlers
|
|
can be undone on reentry. In the example above, we want to prevent a
|
|
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-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,
|
|
or explicitly with @code{scm_dynwind_end}. You must make sure that a
|
|
dynwind context is indeed ended properly. If you fail to call
|
|
@code{scm_dynwind_end} for each @code{scm_dynwind_begin}, the behavior
|
|
is undefined.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} void scm_dynwind_end ()
|
|
End the current dynamic context explicitly and make the previous one
|
|
current.
|
|
@end deftypefn
|
|
|
|
@deftp {C Type} scm_t_wind_flags
|
|
This is an enumeration of several flags that modify the behavior of
|
|
@code{scm_dynwind_unwind_handler} and
|
|
@code{scm_dynwind_rewind_handler}. The flags are listed in the
|
|
following table.
|
|
|
|
@table @code
|
|
@item SCM_F_WIND_EXPLICITLY
|
|
@vindex SCM_F_WIND_EXPLICITLY
|
|
The registered action is also carried out when the dynwind context is
|
|
entered or left locally.
|
|
@end table
|
|
@end deftp
|
|
|
|
@deftypefn {C Function} void scm_dynwind_unwind_handler (void (*func)(void *), void *data, scm_t_wind_flags flags)
|
|
@deftypefnx {C Function} void scm_dynwind_unwind_handler_with_scm (void (*func)(SCM), SCM data, scm_t_wind_flags flags)
|
|
Arranges for @var{func} to be called with @var{data} as its arguments
|
|
when the current context ends implicitly. If @var{flags} contains
|
|
@code{SCM_F_WIND_EXPLICITLY}, @var{func} is also called when the
|
|
context ends explicitly with @code{scm_dynwind_end}.
|
|
|
|
The function @code{scm_dynwind_unwind_handler_with_scm} takes care that
|
|
@var{data} is protected from garbage collection.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} void scm_dynwind_rewind_handler (void (*func)(void *), void *data, scm_t_wind_flags flags)
|
|
@deftypefnx {C Function} void scm_dynwind_rewind_handler_with_scm (void (*func)(SCM), SCM data, scm_t_wind_flags flags)
|
|
Arrange for @var{func} to be called with @var{data} as its argument when
|
|
the current context is restarted by rewinding the stack. When @var{flags}
|
|
contains @code{SCM_F_WIND_EXPLICITLY}, @var{func} is called immediately
|
|
as well.
|
|
|
|
The function @code{scm_dynwind_rewind_handler_with_scm} takes care that
|
|
@var{data} is protected from garbage collection.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} void scm_dynwind_free (void *mem)
|
|
Arrange for @var{mem} to be freed automatically whenever the current
|
|
context is exited, whether normally or non-locally.
|
|
@code{scm_dynwind_free (mem)} is an equivalent shorthand for
|
|
@code{scm_dynwind_unwind_handler (free, mem, SCM_F_WIND_EXPLICITLY)}.
|
|
@end deftypefn
|
|
|
|
|
|
@node Fluids and Dynamic States
|
|
@subsection Fluids and Dynamic States
|
|
|
|
@cindex fluids
|
|
|
|
A @emph{fluid} is a variable whose value is associated with the dynamic
|
|
extent of a function call. In the same way that an operating system
|
|
runs a process with a given set of current input and output ports (or
|
|
file descriptors), in Guile you can arrange to call a function while
|
|
binding a fluid to a particular value. That association between fluid
|
|
and value will exist during the dynamic extent of the function call.
|
|
|
|
Fluids are therefore a building block for implementing dynamically
|
|
scoped variables. Dynamically scoped variables are useful when you want
|
|
to set a variable to a value during some dynamic extent in the execution
|
|
of your program and have them revert to their original value when the
|
|
control flow is outside of this dynamic extent. See the description of
|
|
@code{with-fluids} below for details. This association between fluids,
|
|
values, and dynamic extents is robust to multiple entries (as when a
|
|
captured continuation is invoked more than once) and early exits (for
|
|
example, when throwing exceptions).
|
|
|
|
Guile uses fluids to implement parameters (@pxref{Parameters}). Usually
|
|
you just want to use parameters directly. However it can be useful to
|
|
know what a fluid is and how it works, so that's what this section is
|
|
about.
|
|
|
|
The current set of fluid-value associations can be captured in a
|
|
@emph{dynamic state} object. A dynamic extent is simply that: a
|
|
snapshot of the current fluid-value associations. Guile users can
|
|
capture the current dynamic state with @code{current-dynamic-state} and
|
|
restore it later via @code{with-dynamic-state} or similar procedures.
|
|
This facility is especially useful when implementing lightweight
|
|
thread-like abstractions.
|
|
|
|
New fluids are created with @code{make-fluid} and @code{fluid?} is
|
|
used for testing whether an object is actually a fluid. The values
|
|
stored in a fluid can be accessed with @code{fluid-ref} and
|
|
@code{fluid-set!}.
|
|
|
|
@xref{Thread Local Variables}, for further notes on fluids, threads,
|
|
parameters, and dynamic states.
|
|
|
|
@deffn {Scheme Procedure} make-fluid [dflt]
|
|
@deffnx {C Function} scm_make_fluid ()
|
|
@deffnx {C Function} scm_make_fluid_with_default (dflt)
|
|
Return a newly created fluid, whose initial value is @var{dflt}, or
|
|
@code{#f} if @var{dflt} is not given.
|
|
Fluids are objects that can hold one
|
|
value per dynamic state. That is, modifications to this value are
|
|
only visible to code that executes with the same dynamic state as
|
|
the modifying code. When a new dynamic state is constructed, it
|
|
inherits the values from its parent. Because each thread normally executes
|
|
with its own dynamic state, you can use fluids for thread local storage.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} make-unbound-fluid
|
|
@deffnx {C Function} scm_make_unbound_fluid ()
|
|
Return a new fluid that is initially unbound (instead of being
|
|
implicitly bound to some definite value).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} fluid? obj
|
|
@deffnx {C Function} scm_fluid_p (obj)
|
|
Return @code{#t} if @var{obj} is a fluid; otherwise, return
|
|
@code{#f}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} fluid-ref fluid
|
|
@deffnx {C Function} scm_fluid_ref (fluid)
|
|
Return the value associated with @var{fluid} in the current
|
|
dynamic root. If @var{fluid} has not been set, then return
|
|
its default value. Calling @code{fluid-ref} on an unbound fluid produces
|
|
a runtime error.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} fluid-set! fluid value
|
|
@deffnx {C Function} scm_fluid_set_x (fluid, value)
|
|
Set the value associated with @var{fluid} in the current dynamic root.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} fluid-ref* fluid depth
|
|
@deffnx {C Function} scm_fluid_ref_star (fluid, depth)
|
|
Return the @var{depth}th oldest value associated with @var{fluid} in the
|
|
current thread. If @var{depth} equals or exceeds the number of values
|
|
that have been assigned to @var{fluid}, return the default value of the
|
|
fluid. @code{(fluid-ref* f 0)} is equivalent to @code{(fluid-ref f)}.
|
|
|
|
@code{fluid-ref*} is useful when you want to maintain a stack-like
|
|
structure in a fluid, such as the stack of current exception handlers.
|
|
Using @code{fluid-ref*} instead of an explicit stack allows any partial
|
|
continuation captured by @code{call-with-prompt} to only capture the
|
|
bindings made within the limits of the prompt instead of the entire
|
|
continuation. @xref{Prompts}, for more on delimited continuations.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} fluid-unset! fluid
|
|
@deffnx {C Function} scm_fluid_unset_x (fluid)
|
|
Disassociate the given fluid from any value, making it unbound.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} fluid-bound? fluid
|
|
@deffnx {C Function} scm_fluid_bound_p (fluid)
|
|
Returns @code{#t} if the given fluid is bound to a value, otherwise
|
|
@code{#f}.
|
|
@end deffn
|
|
|
|
@code{with-fluids*} temporarily changes the values of one or more fluids,
|
|
so that the given procedure and each procedure called by it access the
|
|
given values. After the procedure returns, the old values are restored.
|
|
|
|
@deffn {Scheme Procedure} with-fluid* fluid value thunk
|
|
@deffnx {C Function} scm_with_fluid (fluid, value, thunk)
|
|
Set @var{fluid} to @var{value} temporarily, and call @var{thunk}.
|
|
@var{thunk} must be a procedure with no argument.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} with-fluids* fluids values thunk
|
|
@deffnx {C Function} scm_with_fluids (fluids, values, thunk)
|
|
Set @var{fluids} to @var{values} temporary, and call @var{thunk}.
|
|
@var{fluids} must be a list of fluids and @var{values} must be the
|
|
same number of their values to be applied. Each substitution is done
|
|
in the order given. @var{thunk} must be a procedure with no argument.
|
|
It is called inside a @code{dynamic-wind} and the fluids are
|
|
set/restored when control enter or leaves the established dynamic
|
|
extent.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Macro} with-fluids ((fluid value) @dots{}) body
|
|
Execute @var{body} (@pxref{Local Bindings}) while each @var{fluid} is
|
|
set to the corresponding @var{value}. Both @var{fluid} and @var{value}
|
|
are evaluated and @var{fluid} must yield a fluid. The body is executed
|
|
inside a @code{dynamic-wind} and the fluids are set/restored when
|
|
control enter or leaves the established dynamic extent.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} SCM scm_c_with_fluids (SCM fluids, SCM vals, SCM (*cproc)(void *), void *data)
|
|
@deftypefnx {C Function} SCM scm_c_with_fluid (SCM fluid, SCM val, SCM (*cproc)(void *), void *data)
|
|
The function @code{scm_c_with_fluids} is like @code{scm_with_fluids}
|
|
except that it takes a C function to call instead of a Scheme thunk.
|
|
|
|
The function @code{scm_c_with_fluid} is similar but only allows one
|
|
fluid to be set instead of a list.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} void scm_dynwind_fluid (SCM fluid, SCM val)
|
|
This function must be used inside a pair of calls to
|
|
@code{scm_dynwind_begin} and @code{scm_dynwind_end} (@pxref{Dynamic
|
|
Wind}). During the dynwind context, the fluid @var{fluid} is set to
|
|
@var{val}.
|
|
|
|
More precisely, the value of the fluid is swapped with a `backup'
|
|
value whenever the dynwind context is entered or left. The backup
|
|
value is initialized with the @var{val} argument.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} dynamic-state? obj
|
|
@deffnx {C Function} scm_dynamic_state_p (obj)
|
|
Return @code{#t} if @var{obj} is a dynamic state object;
|
|
return @code{#f} otherwise.
|
|
@end deffn
|
|
|
|
@deftypefn {C Procedure} int scm_is_dynamic_state (SCM obj)
|
|
Return non-zero if @var{obj} is a dynamic state object;
|
|
return zero otherwise.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} current-dynamic-state
|
|
@deffnx {C Function} scm_current_dynamic_state ()
|
|
Return a snapshot of the current fluid-value associations as a fresh
|
|
dynamic state object.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} set-current-dynamic-state state
|
|
@deffnx {C Function} scm_set_current_dynamic_state (state)
|
|
Restore the saved fluid-value associations from @var{state}, replacing
|
|
the current fluid-value associations. Return the current fluid-value
|
|
associations as a dynamic state object, as in
|
|
@code{current-dynamic-state}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} with-dynamic-state state proc
|
|
@deffnx {C Function} scm_with_dynamic_state (state, proc)
|
|
Call @var{proc} while the fluid bindings from @var{state} have been made
|
|
current, saving the current fluid bindings. When control leaves the
|
|
invocation of @var{proc}, restore the saved bindings, saving instead the
|
|
fluid bindings from inside the call. If control later re-enters
|
|
@var{proc}, restore those saved bindings, saving the current bindings,
|
|
and so on.
|
|
@end deffn
|
|
|
|
@deftypefn {C Procedure} void scm_dynwind_current_dynamic_state (SCM state)
|
|
Set the current dynamic state to @var{state} for the current dynwind
|
|
context. Like @code{with-dynamic-state}, but in terms of Guile's
|
|
``dynwind'' C API.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Procedure} {void *} scm_c_with_dynamic_state (SCM state, void *(*func)(void *), void *data)
|
|
Like @code{scm_with_dynamic_state}, but call @var{func} with
|
|
@var{data}.
|
|
@end deftypefn
|
|
|
|
@node Parameters
|
|
@subsection Parameters
|
|
|
|
@cindex SRFI-39
|
|
@cindex parameter object
|
|
@tindex Parameter
|
|
|
|
Parameters are Guile's facility for dynamically bound variables.
|
|
|
|
On the most basic level, a parameter object is a procedure. Calling it
|
|
with no arguments returns its value. Calling it with one argument sets
|
|
the value.
|
|
|
|
@example
|
|
(define my-param (make-parameter 123))
|
|
(my-param) @result{} 123
|
|
(my-param 456)
|
|
(my-param) @result{} 456
|
|
@end example
|
|
|
|
The @code{parameterize} special form establishes new locations for
|
|
parameters, those new locations having effect within the dynamic extent
|
|
of the @code{parameterize} body. Leaving restores the previous
|
|
locations. Re-entering (through a saved continuation) will again use
|
|
the new locations.
|
|
|
|
@example
|
|
(parameterize ((my-param 789))
|
|
(my-param)) @result{} 789
|
|
(my-param) @result{} 456
|
|
@end example
|
|
|
|
Parameters are like dynamically bound variables in other Lisp dialects.
|
|
They allow an application to establish parameter settings (as the name
|
|
suggests) just for the execution of a particular bit of code, restoring
|
|
when done. Examples of such parameters might be case-sensitivity for a
|
|
search, or a prompt for user input.
|
|
|
|
Global variables are not as good as parameter objects for this sort of
|
|
thing. Changes to them are visible to all threads, but in Guile
|
|
parameter object locations are per-thread, thereby truly limiting the
|
|
effect of @code{parameterize} to just its dynamic execution.
|
|
|
|
Passing arguments to functions is thread-safe, but that soon becomes
|
|
tedious when there's more than a few or when they need to pass down
|
|
through several layers of calls before reaching the point they should
|
|
affect. Introducing a new setting to existing code is often easier with
|
|
a parameter object than adding arguments.
|
|
|
|
@deffn {Scheme Procedure} make-parameter init [converter]
|
|
Return a new parameter object, with initial value @var{init}.
|
|
|
|
If a @var{converter} is given, then a call @code{(@var{converter}
|
|
val)} is made for each value set, its return is the value stored.
|
|
Such a call is made for the @var{init} initial value too.
|
|
|
|
A @var{converter} allows values to be validated, or put into a
|
|
canonical form. For example,
|
|
|
|
@example
|
|
(define my-param (make-parameter 123
|
|
(lambda (val)
|
|
(if (not (number? val))
|
|
(error "must be a number"))
|
|
(inexact->exact val))))
|
|
(my-param 0.75)
|
|
(my-param) @result{} 3/4
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {library syntax} parameterize ((param value) @dots{}) body1 body2 @dots{}
|
|
Establish a new dynamic scope with the given @var{param}s bound to new
|
|
locations and set to the given @var{value}s. @var{body1} @var{body2}
|
|
@dots{} is evaluated in that environment. The value returned is that of
|
|
last body form.
|
|
|
|
Each @var{param} is an expression which is evaluated to get the
|
|
parameter object. Often this will just be the name of a variable
|
|
holding the object, but it can be anything that evaluates to a
|
|
parameter.
|
|
|
|
The @var{param} expressions and @var{value} expressions are all
|
|
evaluated before establishing the new dynamic bindings, and they're
|
|
evaluated in an unspecified order.
|
|
|
|
For example,
|
|
|
|
@example
|
|
(define prompt (make-parameter "Type something: "))
|
|
(define (get-input)
|
|
(display (prompt))
|
|
...)
|
|
|
|
(parameterize ((prompt "Type a number: "))
|
|
(get-input)
|
|
...)
|
|
@end example
|
|
@end deffn
|
|
|
|
Parameter objects are implemented using fluids (@pxref{Fluids and
|
|
Dynamic States}), so each dynamic state has its own parameter
|
|
locations. That includes the separate locations when outside any
|
|
@code{parameterize} form. When a parameter is created it gets a
|
|
separate initial location in each dynamic state, all initialized to the
|
|
given @var{init} value.
|
|
|
|
New code should probably just use parameters instead of fluids, because
|
|
the interface is better. But for migrating old code or otherwise
|
|
providing interoperability, Guile provides the @code{fluid->parameter}
|
|
procedure:
|
|
|
|
@deffn {Scheme Procedure} fluid->parameter fluid [conv]
|
|
Make a parameter that wraps a fluid.
|
|
|
|
The value of the parameter will be the same as the value of the fluid.
|
|
If the parameter is rebound in some dynamic extent, perhaps via
|
|
@code{parameterize}, the new value will be run through the optional
|
|
@var{conv} procedure, as with any parameter. Note that unlike
|
|
@code{make-parameter}, @var{conv} is not applied to the initial value.
|
|
@end deffn
|
|
|
|
As alluded to above, because each thread usually has a separate dynamic
|
|
state, each thread has its own locations behind parameter objects, and
|
|
changes in one thread are not visible to any other. When a new dynamic
|
|
state or thread is created, the values of parameters in the originating
|
|
context are copied, into new locations.
|
|
|
|
@cindex SRFI-39
|
|
Guile's parameters conform to SRFI-39 (@pxref{SRFI-39}).
|
|
|
|
|
|
@node Handling Errors
|
|
@subsection How to Handle Errors
|
|
|
|
Guile is currently in a transition from its historical @code{catch} and
|
|
@code{throw} error handling and signaling operators to the new
|
|
structured exception facility; @xref{Exceptions}. However in the
|
|
meantime, here is some documentation on errors and the older
|
|
@code{catch} and @code{throw} interface.
|
|
|
|
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 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{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
|
|
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}, const char *@var{subr}, const char *@var{message}, SCM @var{args}, SCM @var{rest})
|
|
Throw an error, as per @code{scm-error} (@pxref{Error Reporting}).
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} void scm_syserror (const char *@var{subr})
|
|
@deftypefnx {C Function} void scm_syserror_msg (const char *@var{subr}, const 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 (const char *@var{subr})
|
|
@deftypefnx {C Function} void scm_out_of_range (const 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 (const char *@var{subr}, int @var{argnum}, SCM @var{bad_value})
|
|
@deftypefnx {C Function} void scm_wrong_type_arg_msg (const char *@var{subr}, int @var{argnum}, SCM @var{bad_value}, const char *@var{expected})
|
|
@deftypefnx {C Function} void scm_misc_error (const char *@var{subr}, const char *@var{message}, SCM @var{args})
|
|
Throw an error with the various keys described above.
|
|
|
|
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{Simple
|
|
Output}), and the corresponding arguments in the @var{args} list.
|
|
@end deftypefn
|
|
|
|
|
|
@subsubsection Signaling 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
|
|
|
|
@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
|
|
|
|
|
|
@c Local Variables:
|
|
@c TeX-master: "guile.texi"
|
|
@c End:
|