@page @node Control Mechanisms @chapter Controlling the Flow of Program Execution @menu * begin:: Evaluating a sequence of expressions. * if cond case:: Simple conditional evaluation. * and or:: Conditional evaluation of a sequence. * while do:: Iteration mechanisms. * Continuations:: Continuations. * Multiple Values:: Returning and accepting multiple values. * Exceptions:: Throwing and catching exceptions. * Error Reporting:: Procedures for signaling errors. * Dynamic Wind:: Guarding against non-local entrance/exit. @end menu @node begin @section Evaluating a Sequence of Expressions @c FIXME::martin: Review me! @c FIXME::martin: Maybe add examples? @cindex begin @cindex sequencing @cindex expression sequencing @code{begin} is used for grouping several expression together so that they syntactically are treated as if they were one expression. This is particularly important when syntactic expressions are used which only allow one expression, but the programmer wants to use more than one expression in that place. As an example, consider the conditional expression below: @lisp (if (> x 0) (begin (display "greater") (newline))) @end lisp If the two calls to @code{display} and @code{newline} were not embedded in a @code{begin}--statement, the call to @code{newline} would get misinterpreted as the else--branch of the @code{if}--expression. @deffn syntax begin expr1 expr2 @dots{} The expression(s) are evaluated in left--to--right order and the value of the last expression is returned as the value of the @code{begin}--expression. This expression type is used when the expressions before the last one are evaluated for their side effects. @end deffn @node if cond case @section Simple Conditional Evaluation @c FIXME::martin: Review me! @c FIXME::martin: Maybe add examples? @cindex conditional evaluation @cindex if @cindex case @cindex cond Guile provides three syntactic constructs for conditional evaluation. @code{if} is the normal if--then--else expression (with an optional else branch), @code{cond} is a conditional expression with multiple branches and @code{case} branches if an expression has one of a set of constant values. @deffn syntax if test consequent [alternate] All arguments may be arbitrary expressions. First, @var{test} is evaluated. If it returns a true value, the expression @var{consequent} is evaluated and @var{alternate} is ignoret. If @var{test} evaluates to @code{#f}, @var{alternate} is evaluated instead. The value of the evaluated branch (@var{consequent} or @var{alternate}) is returned as the value of the @code{if} expression. When @var{alternate} is omitted and the @var{test} evaluates to @code{#f}, the value of the expression is not specified. @end deffn @deffn syntax cond clause1 clause2 @dots{} Each @code{cond}-clause must look like this: @lisp (@var{test} @var{expression} @dots{}) @end lisp where @var{test} and @var{expression} are arbitrary expression, or like this @lisp (@var{test} => @var{expression} @end lisp where @var{expression} must evaluate to a procedure. The @var{test}s of the clauses are evaluated in order and as soon as one of them evaluates to a true values, the corresponding @var{expression}s are evaluated in order and the last value is returned as the value of the @code{cond}--expression. For the @code{=>} clause type, @var{expression} is evaluated and the resulting procedure is applied to the value of @var{test}. The result of this procedure application is then the result of the @code{cond}--expression. The @var{test} of the last @var{clause} may be the keyword @code{else}. Then, if none of the preceding @var{test}s is true, the @var{expression}s following the @code{else} are evaluated to produce the result of the @code{cond}--expression. @end deffn @deffn syntax case key clause1 clause2 @dots{} @var{key} may be any expression, the @var{clause}s must have the form @lisp ((@var{datum1} @dots{}) @var{expr1} @var{expr2} @dots{}) @end lisp and the last @var{clause} may have the form @lisp (else @var{expr1} @var{expr2} @dots{}) @end lisp All @var{datum}s must be distinct. First, @var{key} is evaluated. The the result of this evaluation is compared against all @var{datum}s using @code{eqv?}. When this comparison succeeds, the epression(s) following the @var{datum} are evaluated from left to right, returning the value of the last expression as the result of the @code{case} expression. If the @var{key} matches no @var{datum} and there is an @code{else}--clause, the expressions following the @code{else} are evaluated. If there is no such clause, the result of the expression is unspecified. @end deffn @node and or @section Conditional Evaluation of a Sequence of Expressions @c FIXME::martin: Review me! @c FIXME::martin: Maybe add examples? @code{and} and @code{or} evaluate all their arguments, 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 @section Iteration mechanisms @c FIXME::martin: Review me! @c FIXME::martin: Maybe add examples? @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 ((variable1 init1 step1) @dots{}) (test expr @dots{}) command @dots{} The @var{init} expressions are evaluated and the @var{variables} are bound to their values. Then looping starts with testing the @var{test} expression. If @var{test} evaluates to a true value, the @var{expr} following the @var{test} are evaluated and the value of the last @var{expr} is returned as the value of the @code{do} expression. If @var{test} evaluates to false, the @var{command}s are evaluated in order, the @var{step}s are evaluated and stored into the @var{variables} and the next iteration starts. Any of the @var{step} expressions may be omitted, so that the corresponding variable is not changed during looping. @end deffn @deffn syntax while cond body @dots{} Evaluate all expressions in @var{body} in order, as long as @var{cond} evaluates to a true value. The @var{cond} expression is tested before every iteration, so that the body is not evaluated at all if @var{cond} is @code{#f} right from the start. @end deffn @cindex named let Another very common way of expressing iteration in Scheme programs is the use of the so--called @dfn{named let}. Named let is a variant of @code{let} which creates a procedure and calls it in one step. Because of the newly created procedure, named let is more powerful than @code{do}---it can be used for iteration, but also for arbitrary recursion. @deffn syntax let variable bindings body For the definition of @var{bindings} see the documentation about @code{let} (@pxref{Local Bindings}). Named @code{let} works as follows: @itemize @bullet @item A new procedure which accepts as many arguments as are in @var{bindings} is created and bound locally (using @code{let}) to @var{variable}. The new procedure's formal argument names are the name of the @var{variables}. @item The @var{body} expressions are inserted into the newly created procedure. @item The procedure is called with the @var{init} expressions as the formal arguments. @end itemize The next example implements a loop which iterates (by recursion) 1000 times. @lisp (let lp ((x 1000)) (if (positive? x) (lp (- x 1)) x)) @result{} 0 @end lisp @end deffn @node Continuations @section Continuations @rnindex call-with-current-continuation @c FIXME::martin: Document me! @deffn primitive call-with-current-continuation @end deffn @node Multiple Values @section Returning and Accepting Multiple Values @c FIXME::martin: Review me! @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 conceptionally 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 primitive values expr @dots{} 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. @end deffn @rnindex call-with-values @deffn primitive 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)) ==> 5 @end example @example (call-with-values * -) ==> -1 @end example @end deffn In addition to the fundamental procedures described above, Guile has a module which exports a syntax called @code{receive}, which is much more convenient. If you want to use it in your programs, you have to load the module @code{(ice-9 receive)} with the statement @lisp (use-modules (ice-9 receive)) @end lisp @deffn {library syntax} receive formals expr body @dots{} Evaluate the expression @var{expr}, and bind the result values (zero or more) to the formal arguments in the formal argument list @var{formals}. @var{formals} must have the same syntax like the formal argument list used in @code{lambda} (@pxref{Lambda}). After binding the variables, the expressions in @var{body} @dots{} are evaluated in order. @end deffn @node Exceptions @section Exceptions @cindex error handling @cindex exception handling It is traditional in Scheme to implement exception systems using @code{call-with-current-continuation}. Guile does not do this, for performance reasons. The implementation of @code{call-with-current-continuation} is a stack copying implementation. This allows it to interact well with ordinary C code. Unfortunately, a stack-copying implementation can be slow -- creating a new continuation involves a block copy of the stack. Instead of using @code{call-with-current-continuation}, the exception primitives documented here are implemented as built-ins that take advantage of the @emph{upward only} nature of exceptions. @deffn primitive catch key thunk handler Invoke @var{thunk} in the dynamic context of @var{handler} for exceptions matching @var{key}. If thunk throws to the symbol @var{key}, then @var{handler} is invoked this way: @lisp (handler key args ...) @end lisp @var{key} is a symbol or @code{#t}. @var{thunk} takes no arguments. If @var{thunk} returns normally, that is the return value of @code{catch}. Handler is invoked outside the scope of its own @code{catch}. If @var{handler} again throws to the same key, a new handler from further up the call chain is invoked. If the key is @code{#t}, then a throw to @emph{any} symbol will match this call to @code{catch}. @end deffn @deffn primitive throw key . args Invoke the catch form matching @var{key}, passing @var{args} to the @var{handler}. @var{key} is a symbol. It will match catches of the same symbol or of #t. If there is no handler at all, an error is signaled. @end deffn @deffn primitive lazy-catch key thunk handler This behaves exactly like @code{catch}, except that it does not unwind the stack (this is the major difference), and if handler returns, its value is returned from the throw. @end deffn @node Error Reporting @section 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. @c begin (scm-doc-string "boot-9.scm" "error") @deffn procedure error msg args @dots{} Raise an error with key @code{misc-error} and a message constructed by displaying @var{msg} and writing @var{args}. @end deffn @c end @deffn primitive scm-error key subr message args data Raise an error with key @var{key}. @var{subr} can be a string naming the procedure associated with the error, or @code{#f}. @var{message} is the error message string, possibly containing @code{~S} and @code{~A} escapes. When an error is reported, these are replaced by formatting the corresponding members of @var{args}: @code{~A} (was @code{%s} in older versions of Guile) formats using @code{display} and @code{~S} (was @code{%S}) formats using @code{write}. @var{data} is a list or @code{#f} depending on @var{key}: if @var{key} is @code{system-error} then it should be a list containing the Unix @code{errno} value; If @var{key} is @code{signal} then it should be a list containing the Unix signal number; otherwise it will usually be @code{#f}. @end deffn @deffn primitive strerror err Return the Unix error message corresponding to @var{err}, which must be an integer value. @end deffn @c begin (scm-doc-string "boot-9.scm" "false-if-exception") @deffn syntax false-if-exception expr Returns the result of evaluating its argument; however if an exception occurs then @code{#f} is returned instead. @end deffn @c end @node Dynamic Wind @section Dynamic Wind [FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed] @rnindex dynamic-wind @deffn primitive 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 continuation of the @code{dynamic_wind} expression is escaped non-locally, @var{out_guard} is called. If the continuation 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 @c Local Variables: @c TeX-master: "guile.texi" @c End: