Controlling the Flow of Program Execution
*****************************************

Evaluating a Sequence of Expressions
====================================

Simple Conditional Evaluation
=============================

Conditional Evaluation of a Sequence of Expressions
===================================================

Iteration mechanisms
====================

Continuations
=============

 -- primitive: call-with-current-continuation

Returning and Accepting Multiple Values
=======================================

 -- primitive: values . args
     Delivers all of its arguments to its continuation.  Except for continuations created by the 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 call-with-values is unspecified.

 -- primitive: call-with-values producer consumer
     Calls its PRODUCER argument with no values and a continuation that, when passed some values, calls the CONSUMER procedure with those values as arguments.  The continuation for the call to CONSUMER is the continuation of the call to call-with-values.

          (call-with-values (lambda () (values 4 5))
                            (lambda (a b) b))
                                                       ==>  5

          (call-with-values * -)                             ==>  -1

Exceptions
==========

It is traditional in Scheme to implement exception systems using call-with-current-continuation.  Guile does not do this, for performance reasons.  The implementation of 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 call-with-current-continuation, the exception primitives documented here are implemented as built-ins that take advantage of the upward only nature of exceptions.

 -- primitive: catch key thunk handler
     Invoke THUNK in the dynamic context of HANDLER for exceptions matching KEY.  If thunk throws to the symbol KEY, then HANDLER is invoked this way:

          (handler key args ...)

     KEY is a symbol or #t. THUNK takes no arguments.  If THUNK returns normally, that is the return value of catch. Handler is invoked outside the scope of its own catch. If HANDLER again throws to the same key, a new handler from further up the call chain is invoked. If the key is #t, then a throw to any symbol will match this call to catch.

 -- primitive: throw key . args
     Invoke the catch form matching KEY, passing ARGS to the HANDLER.

     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.

 -- primitive: lazy-catch key thunk handler
     This behaves exactly like 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.

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.

 -- procedure: error msg args ...
     Raise an error with key misc-error and a message constructed by displaying MSG and writing ARGS.

 -- primitive: scm-error key subr message args data
     Raise an error with key KEY.  SUBR can be a string naming the procedure associated with the error, or #f. MESSAGE is the error message string, possibly containing ~S and ~A escapes.  When an error is reported, these are replaced by formatting the corresponding members of ARGS: ~A (was %s in older versions of Guile) formats using display and ~S (was %S) formats using write.  DATA is a list or #f depending on KEY: if KEY is system-error then it should be a list containing the Unix errno value; If KEY is signal then it should be a list containing the Unix signal number; otherwise it will usually be #f.

 -- primitive: strerror err
     Return the Unix error message corresponding to ERR, which must be an integer value.

 -- syntax: false-if-exception expr
     Returns the result of evaluating its argument; however if an exception occurs then #f is returned instead.

Dynamic Wind
============

[FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed]

 -- primitive: dynamic-wind in_guard thunk out_guard
     All three arguments must be 0-argument procedures. IN_GUARD is called, then THUNK, then OUT_GUARD. If, any time during the execution of THUNK, the continuation of the dynamic_wind expression is escaped non-locally, OUT_GUARD is called.  If the continuation of the dynamic-wind is re-entered, IN_GUARD is called.  Thus IN_GUARD and OUT_GUARD may be called any number of times.

          (define x 'normal-binding)
          => 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:
          => a-cont
          x
          => normal-binding
          (a-cont #f)
          ;; Prints:
          special-binding
          ;; Evaluates to:
          => a-cont  ;; the value of the (define a-cont...)
          x
          => normal-binding
          a-cont
          => special-binding