@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
-@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010, 2011
-@c Free Software Foundation, Inc.
+@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2009, 2010,
+@c 2011, 2012, 2013 Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@node Control Mechanisms
flow of Scheme affects C code.
@menu
-* begin:: Evaluating a sequence of expressions.
-* if cond case:: Simple conditional evaluation.
+* begin:: Sequencing and splicing.
+* Conditionals:: If, when, unless, case, and cond.
* and or:: Conditional evaluation of a sequence.
* while do:: Iteration mechanisms.
* Prompts:: Composable, delimited continuations.
@end menu
@node begin
-@subsection Evaluating a Sequence of Expressions
+@subsection Sequencing and Splicing
@cindex begin
@cindex sequencing
@cindex expression sequencing
-The @code{begin} syntax is used for grouping several expressions
-together so that they are treated as if they were one expression.
-This is particularly important when syntactic expressions are used
-which only allow one expression, but the programmer wants to use more
-than one expression in that place. As an example, consider the
-conditional expression below:
+As an expression, the @code{begin} syntax is used to evaluate a sequence
+of sub-expressions in order. Consider the conditional expression below:
@lisp
(if (> x 0)
(begin (display "greater") (newline)))
@end lisp
-If the two calls to @code{display} and @code{newline} were not embedded
-in a @code{begin}-statement, the call to @code{newline} would get
-misinterpreted as the else-branch of the @code{if}-expression.
+If the test is true, we want to display ``greater'' to the current
+output port, then display a newline. We use @code{begin} to form a
+compound expression out of this sequence of sub-expressions.
-@deffn syntax begin expr1 expr2 @dots{}
-The expression(s) are evaluated in left-to-right order and the value
-of the last expression is returned as the value of the
+@deffn syntax begin expr @dots{}
+The expression(s) are evaluated in left-to-right order and the value of
+the last expression is returned as the value of the
@code{begin}-expression. This expression type is used when the
expressions before the last one are evaluated for their side effects.
-
-Guile also allows the expression @code{(begin)}, a @code{begin} with no
-sub-expressions. Such an expression returns the `unspecified' value.
@end deffn
-@node if cond case
+@cindex splicing
+@cindex definition splicing
+
+The @code{begin} syntax has another role in definition context
+(@pxref{Internal Definitions}). A @code{begin} form in a definition
+context @dfn{splices} its subforms into its place. For example,
+consider the following procedure:
+
+@lisp
+(define (make-seal)
+ (define-sealant seal open)
+ (values seal open))
+@end lisp
+
+Let us assume the existence of a @code{define-sealant} macro that
+expands out to some definitions wrapped in a @code{begin}, like so:
+
+@lisp
+(define (make-seal)
+ (begin
+ (define seal-tag
+ (list 'seal))
+ (define (seal x)
+ (cons seal-tag x))
+ (define (sealed? x)
+ (and (pair? x) (eq? (car x) seal-tag)))
+ (define (open x)
+ (if (sealed? x)
+ (cdr x)
+ (error "Expected a sealed value:" x))))
+ (values seal open))
+@end lisp
+
+Here, because the @code{begin} is in definition context, its subforms
+are @dfn{spliced} into the place of the @code{begin}. This allows the
+definitions created by the macro to be visible to the following
+expression, the @code{values} form.
+
+It is a fine point, but splicing and sequencing are different. It can
+make sense to splice zero forms, because it can make sense to have zero
+internal definitions before the expressions in a procedure or lexical
+binding form. However it does not make sense to have a sequence of zero
+expressions, because in that case it would not be clear what the value
+of the sequence would be, because in a sequence of zero expressions,
+there can be no last value. Sequencing zero expressions is an error.
+
+It would be more elegant in some ways to eliminate splicing from the
+Scheme language, and without macros (@pxref{Macros}), that would be a
+good idea. But it is useful to be able to write macros that expand out
+to multiple definitions, as in @code{define-sealant} above, so Scheme
+abuses the @code{begin} form for these two tasks.
+
+@node Conditionals
@subsection Simple Conditional Evaluation
@cindex conditional evaluation
@cindex if
+@cindex when
+@cindex unless
@cindex case
@cindex cond
All arguments may be arbitrary expressions. First, @var{test} is
evaluated. If it returns a true value, the expression @var{consequent}
is evaluated and @var{alternate} is ignored. If @var{test} evaluates to
-@code{#f}, @var{alternate} is evaluated instead. The value of the
-evaluated branch (@var{consequent} or @var{alternate}) is returned as
-the value of the @code{if} expression.
+@code{#f}, @var{alternate} is evaluated instead. The values of the
+evaluated branch (@var{consequent} or @var{alternate}) are returned as
+the values of the @code{if} expression.
When @var{alternate} is omitted and the @var{test} evaluates to
@code{#f}, the value of the expression is not specified.
@end deffn
+When you go to write an @code{if} without an alternate (a @dfn{one-armed
+@code{if}}), part of what you are expressing is that you don't care
+about the return value (or values) of the expression. As such, you are
+more interested in the @emph{effect} of evaluating the consequent
+expression. (By convention, we use the word @dfn{statement} to refer to
+an expression that is evaluated for effect, not for value).
+
+In such a case, it is considered more clear to express these intentions
+with these special forms, @code{when} and @code{unless}. As an added
+bonus, these forms accept multiple statements to evaluate, which are
+implicitly wrapped in a @code{begin}.
+
+@deffn {Scheme Syntax} when test statement1 statement2 ...
+@deffnx {Scheme Syntax} unless test statement1 statement2 ...
+The actual definitions of these forms are in many ways their most clear
+documentation:
+
+@example
+(define-syntax-rule (when test stmt stmt* ...)
+ (if test (begin stmt stmt* ...)))
+
+(define-syntax-rule (unless condition stmt stmt* ...)
+ (if (not test) (begin stmt stmt* ...)))
+@end example
+
+That is to say, @code{when} evaluates its consequent statements in order
+if @var{test} is true. @code{unless} is the opposite: it evaluates the
+statements if @var{test} is false.
+@end deffn
+
@deffn syntax cond clause1 clause2 @dots{}
Each @code{cond}-clause must look like this:
@code{cond} ignores its boolean state; instead, @code{cond} evaluates
@var{guard} and applies the resulting procedure to the value(s) of
@var{test}, as if @var{guard} were the @var{consumer} argument of
-@code{call-with-values}. Iff the result of that procedure call is a
+@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.
@end deffn
@deffn syntax case key clause1 clause2 @dots{}
-@var{key} may be any expression, the @var{clause}s must have the form
+@var{key} may be any expression, and the @var{clause}s must have the form
@lisp
((@var{datum1} @dots{}) @var{expr1} @var{expr2} @dots{})
@end lisp
+or
+
+@lisp
+((@var{datum1} @dots{}) => @var{expression})
+@end lisp
+
and the last @var{clause} may have the form
@lisp
(else @var{expr1} @var{expr2} @dots{})
@end lisp
+or
+
+@lisp
+(else => @var{expression})
+@end lisp
+
All @var{datum}s must be distinct. First, @var{key} is evaluated. The
result of this evaluation is compared against all @var{datum} values using
@code{eqv?}. When this comparison succeeds, the expression(s) following
@code{else}-clause, the expressions following the @code{else} are
evaluated. If there is no such clause, the result of the expression is
unspecified.
+
+For the @code{=>} clause types, @var{expression} is evaluated and the
+resulting procedure is applied to the value of @var{key}. The result of
+this procedure application is then the result of the
+@code{case}-expression.
@end deffn
R5RS defines a construct for programming loops, calling @code{do}. In
addition, Guile has an explicit looping syntax called @code{while}.
-@deffn syntax do ((variable init [step]) @dots{}) (test [expr @dots{}]) body @dots{}
+@deffn syntax do ((variable init [step]) @dots{}) (test expr @dots{}) body @dots{}
Bind @var{variable}s and evaluate @var{body} until @var{test} is true.
The return value is the last @var{expr} after @var{test}, if given. A
simple example will illustrate the basic form,
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...
+@deffn {Scheme Procedure} break break-arg @dots{}
Break out of the @code{while} form.
@end deffn
@example
(while #f (error "not reached")) @result{} #f
(while #t (break)) @result{} #t
-(while #f (break 1 2 3)) @result{} 1 2 3
+(while #t (break 1 2 3)) @result{} 1 2 3
@end example
Each @code{while} form gets its own @code{break} and @code{continue}
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.
those passed to @code{abort-to-prompt}.
@end deffn
-@deffn {Scheme Procedure} abort-to-prompt tag val ...
+@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
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
+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. Such continuations are invoked only once, and for this
+reason they are sometimes called @dfn{one-shot continuations}. A common
+use of escape continuations is when throwing 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
+
+
+@node Shift and Reset
+@subsubsection Shift, Reset, and All That
+
+There is a whole zoo of delimited control operators, and as it does not
+seem to be a bounded set, Guile implements support for them in a
+separate module:
+
+@example
+(use-modules (ice-9 control))
+@end example
+
+Firstly, we have a helpful abbreviation for the @code{call-with-prompt}
+operator.
+
+@deffn {Scheme Syntax} % expr
+@deffnx {Scheme Syntax} % expr handler
+@deffnx {Scheme Syntax} % tag expr handler
+Evaluate @var{expr} in a prompt, optionally specifying a tag and a
+handler. If no tag is given, the default prompt tag is used.
+
+If no handler is given, a default handler is installed. The default
+handler accepts a procedure of one argument, which will called on the
+captured continuation, within a prompt.
+
+Sometimes it's easier just to show code, as in this case:
+
+@example
+(define (default-prompt-handler k proc)
+ (% (default-prompt-tag)
+ (proc k)
+ default-prompt-handler))
+@end example
+
+The @code{%} symbol is chosen because it looks like a prompt.
+@end deffn
+
+Likewise there is an abbreviation for @code{abort-to-prompt}, which
+assumes the default prompt tag:
+
+@deffn {Scheme Procedure} abort val1 val2 @dots{}
+Abort to the default prompt tag, passing @var{val1} @var{val2} @dots{}
+to the handler.
+@end deffn
+
+As mentioned before, @code{(ice-9 control)} also provides other
+delimited control operators. This section is a bit technical, and
+first-time users of delimited continuations should probably come back to
+it after some practice with @code{%}.
+
+Still here? So, when one implements a delimited control operator like
+@code{call-with-prompt}, one needs to make two decisions. Firstly, does
+the handler run within or outside the prompt? Having the handler run
+within the prompt allows an abort inside the handler to return to the
+same prompt handler, which is often useful. However it prevents tail
+calls from the handler, so it is less general.
+
+Similarly, does invoking a captured continuation reinstate a prompt?
+Again we have the tradeoff of convenience versus proper tail calls.
+
+These decisions are captured in the Felleisen @dfn{F} operator. If
+neither the continuations nor the handlers implicitly add a prompt, the
+operator is known as @dfn{--F--}. This is the case for Guile's
+@code{call-with-prompt} and @code{abort-to-prompt}.
+
+If both continuation and handler implicitly add prompts, then the
+operator is @dfn{+F+}. @code{shift} and @code{reset} are such
+operators.
+
+@deffn {Scheme Syntax} reset body1 body2 @dots{}
+Establish a prompt, and evaluate @var{body1} @var{body2} @dots{} within
+that prompt.
+
+The prompt handler is designed to work with @code{shift}, described
+below.
+@end deffn
+
+@deffn {Scheme Syntax} shift cont body1 body2 @dots{}
+Abort to the nearest @code{reset}, and evaluate @var{body1} @var{body2}
+@dots{} in a context in which the captured continuation is bound to
+@var{cont}.
+
+As mentioned above, taken together, the @var{body1} @var{body2} @dots{}
+expressions and the invocations of @var{cont} implicitly establish a
+prompt.
+@end deffn
+
+Interested readers are invited to explore Oleg Kiselyov's wonderful web
+site at @uref{http://okmij.org/ftp/}, for more information on these
+operators.
+
@node Continuations
@subsection Continuations
parameters.
@rnindex values
-@deffn {Scheme Procedure} values arg1 @dots{} argN
+@deffn {Scheme Procedure} values arg @dots{}
@deffnx {C Function} scm_values (args)
Delivers all of its arguments to its continuation. Except for
continuations created by the @code{call-with-values} procedure,
@var{args}, so @var{args} should not be modified subsequently.
@end deffn
+@deftypefn {C Function} SCM scm_c_values (SCM *base, size_t n)
+@code{scm_c_values} is an alternative to @code{scm_values}. It creates
+a new values object, and copies into it the @var{n} values starting from
+@var{base}.
+
+Currently this creates a list and passes it to @code{scm_values}, but we
+expect that in the future we will be able to use more a efficient
+representation.
+@end deftypefn
+
+@deftypefn {C Function} size_t scm_c_nvalues (SCM obj)
+If @var{obj} is a multiple-values object, returns the number of values
+it contains. Otherwise returns 1.
+@end deftypefn
+
+@deftypefn {C Function} SCM scm_c_value_ref (SCM obj, size_t idx)
+Returns the value at the position specified by @var{idx} in
+@var{obj}. Note that @var{obj} will ordinarily be a
+multiple-values object, but it need not be. Any other object
+represents a single value (itself), and is handled appropriately.
+@end deftypefn
+
@rnindex call-with-values
@deffn {Scheme Procedure} call-with-values producer consumer
Calls its @var{producer} argument with no values and a
This manual prefers to speak of throwing and catching exceptions, since
this terminology matches the corresponding Guile primitives.
+The exception mechanism described in this section has connections with
+@dfn{delimited continuations} (@pxref{Prompts}). In particular,
+throwing an exception is akin to invoking an @dfn{escape continuation}
+(@pxref{Prompt Primitives, @code{call/ec}}).
+
@node Catch
@subsubsection Catching Exceptions
of exception should specify the additional arguments that are expected
for that kind of exception.
-@deffn {Scheme Procedure} throw key . args
+@deffn {Scheme Procedure} throw key arg @dots{}
@deffnx {C Function} scm_throw (key, args)
-Invoke the catch form matching @var{key}, passing @var{args} to the
-@var{handler}.
+Invoke the catch form matching @var{key}, passing @var{arg} @dots{} to
+the @var{handler}.
@var{key} is a symbol. It will match catches of the same symbol or of
@code{#t}.
conditions that are implemented on top of the exception primitives just
described.
-@deffn {Scheme Procedure} error msg args @dots{}
+@deffn {Scheme Procedure} error msg arg @dots{}
Raise an error with key @code{misc-error} and a message constructed by
-displaying @var{msg} and writing @var{args}.
+displaying @var{msg} and writing @var{arg} @enddots{}.
@end deffn
@deffn {Scheme Procedure} scm-error key subr message args data
@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} or @code{wrong-type-arg},
+@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
@deftypefnx {C Function} void scm_wrong_type_arg (char *@var{subr}, int @var{argnum}, SCM @var{bad_value})
@deftypefnx {C Function} void scm_wrong_type_arg_msg (char *@var{subr}, int @var{argnum}, SCM @var{bad_value}, const char *@var{expected})
@deftypefnx {C Function} void scm_memory_error (char *@var{subr})
-Throw an error with the various keys described above.
@deftypefnx {C Function} void scm_misc_error (const char *@var{subr}, const char *@var{message}, SCM @var{args})
+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
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
@code{SCM_ARGn} should be preferred over a raw zero constant.
@end deftypefn
-
@node Continuation Barriers
@subsection Continuation Barriers