This is guile.info, produced by makeinfo version 4.3 from guile.texi. INFO-DIR-SECTION The Algorithmic Language Scheme START-INFO-DIR-ENTRY * Guile Reference: (guile). The Guile reference manual. END-INFO-DIR-ENTRY Guile Reference Manual Copyright (C) 1996 Free Software Foundation Copyright (C) 1997 Free Software Foundation Copyright (C) 2000 Free Software Foundation Copyright (C) 2001 Free Software Foundation Copyright (C) 2002 Free Software Foundation Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.  File: guile.info, Node: Sorting, Next: Copying, Prev: Object Properties, Up: Utility Functions Sorting ======= Sorting is very important in computer programs. Therefore, Guile comes with several sorting procedures built-in. As always, procedures with names ending in `!' are side-effecting, that means that they may modify their parameters in order to produce their results. The first group of procedures can be used to merge two lists (which must be already sorted on their own) and produce sorted lists containing all elements of the input lists. - Scheme Procedure: merge alist blist less - C Function: scm_merge (alist, blist, less) Merge two already sorted lists into one. Given two lists ALIST and BLIST, such that `(sorted? alist less?)' and `(sorted? blist less?)', return a new list in which the elements of ALIST and BLIST have been stably interleaved so that `(sorted? (merge alist blist less?) less?)'. Note: this does _not_ accept vectors. - Scheme Procedure: merge! alist blist less - C Function: scm_merge_x (alist, blist, less) Takes two lists ALIST and BLIST such that `(sorted? alist less?)' and `(sorted? blist less?)' and returns a new list in which the elements of ALIST and BLIST have been stably interleaved so that `(sorted? (merge alist blist less?) less?)'. This is the destructive variant of `merge' Note: this does _not_ accept vectors. The following procedures can operate on sequences which are either vectors or list. According to the given arguments, they return sorted vectors or lists, respectively. The first of the following procedures determines whether a sequence is already sorted, the other sort a given sequence. The variants with names starting with `stable-' are special in that they maintain a special property of the input sequences: If two or more elements are the same according to the comparison predicate, they are left in the same order as they appeared in the input. - Scheme Procedure: sorted? items less - C Function: scm_sorted_p (items, less) Return `#t' iff ITEMS is a list or a vector such that for all 1 <= i <= m, the predicate LESS returns true when applied to all elements i - 1 and i - Scheme Procedure: sort items less - C Function: scm_sort (items, less) Sort the sequence ITEMS, which may be a list or a vector. LESS is used for comparing the sequence elements. This is not a stable sort. - Scheme Procedure: sort! items less - C Function: scm_sort_x (items, less) Sort the sequence ITEMS, which may be a list or a vector. LESS is used for comparing the sequence elements. The sorting is destructive, that means that the input sequence is modified to produce the sorted result. This is not a stable sort. - Scheme Procedure: stable-sort items less - C Function: scm_stable_sort (items, less) Sort the sequence ITEMS, which may be a list or a vector. LESS is used for comparing the sequence elements. This is a stable sort. - Scheme Procedure: stable-sort! items less - C Function: scm_stable_sort_x (items, less) Sort the sequence ITEMS, which may be a list or a vector. LESS is used for comparing the sequence elements. The sorting is destructive, that means that the input sequence is modified to produce the sorted result. This is a stable sort. The procedures in the last group only accept lists or vectors as input, as their names indicate. - Scheme Procedure: sort-list items less - C Function: scm_sort_list (items, less) Sort the list ITEMS, using LESS for comparing the list elements. This is a stable sort. - Scheme Procedure: sort-list! items less - C Function: scm_sort_list_x (items, less) Sort the list ITEMS, using LESS for comparing the list elements. The sorting is destructive, that means that the input list is modified to produce the sorted result. This is a stable sort. - Scheme Procedure: restricted-vector-sort! vec less startpos endpos - C Function: scm_restricted_vector_sort_x (vec, less, startpos, endpos) Sort the vector VEC, using LESS for comparing the vector elements. STARTPOS and ENDPOS delimit the range of the vector which gets sorted. The return value is not specified.  File: guile.info, Node: Copying, Next: General Conversion, Prev: Sorting, Up: Utility Functions Copying Deep Structures ======================= The procedures for copying lists (*note Lists::) only produce a flat copy of the input list, and currently Guile does not even contain procedures for copying vectors. `copy-tree' can be used for these application, as it does not only copy the spine of a list, but also copies any pairs in the cars of the input lists. - Scheme Procedure: copy-tree obj - C Function: scm_copy_tree (obj) Recursively copy the data tree that is bound to OBJ, and return a pointer to the new data structure. `copy-tree' recurses down the contents of both pairs and vectors (since both cons cells and vector cells may point to arbitrary objects), and stops recursing when it hits any other object.  File: guile.info, Node: General Conversion, Next: Hooks, Prev: Copying, Up: Utility Functions General String Conversion ========================= When debugging Scheme programs, but also for providing a human-friendly interface, a procedure for converting any Scheme object into string format is very useful. Conversion from/to strings can of course be done with specialized procedures when the data type of the object to convert is known, but with this procedure, it is often more comfortable. `object->string' converts an object by using a print procedure for writing to a string port, and then returning the resulting string. Converting an object back from the string is only possible if the object type has a read syntax and the read syntax is preserved by the printing procedure. - Scheme Procedure: object->string obj [printer] - C Function: scm_object_to_string (obj, printer) Return a Scheme string obtained by printing OBJ. Printing function can be specified by the optional second argument PRINTER (default: `write').  File: guile.info, Node: Hooks, Prev: General Conversion, Up: Utility Functions Hooks ===== A hook is a list of procedures to be called at well defined points in time. Typically, an application provides a hook H and promises its users that it will call all of the procedures in H at a defined point in the application's processing. By adding its own procedure to H, an application user can tap into or even influence the progress of the application. Guile itself provides several such hooks for debugging and customization purposes: these are listed in a subsection below. When an application first creates a hook, it needs to know how many arguments will be passed to the hook's procedures when the hook is run. The chosen number of arguments (which may be none) is declared when the hook is created, and all the procedures that are added to that hook must be capable of accepting that number of arguments. A hook is created using `make-hook'. A procedure can be added to or removed from a hook using `add-hook!' or `remove-hook!', and all of a hook's procedures can be removed together using `reset-hook!'. When an application wants to run a hook, it does so using `run-hook'. * Menu: * Hook Example:: Hook usage by example. * Hook Reference:: Reference of all hook procedures. * C Hooks:: Hooks for use from C code. * Guile Hooks:: Hooks provided by Guile.  File: guile.info, Node: Hook Example, Next: Hook Reference, Up: Hooks Hook Usage by Example --------------------- Hook usage is shown by some examples in this section. First, we will define a hook of arity 2 -- that is, the procedures stored in the hook will have to accept two arguments. (define hook (make-hook 2)) hook => # Now we are ready to add some procedures to the newly created hook with `add-hook!'. In the following example, two procedures are added, which print different messages and do different things with their arguments. (add-hook! hook (lambda (x y) (display "Foo: ") (display (+ x y)) (newline))) (add-hook! hook (lambda (x y) (display "Bar: ") (display (* x y)) (newline))) Once the procedures have been added, we can invoke the hook using `run-hook'. (run-hook hook 3 4) -| Bar: 12 -| Foo: 7 Note that the procedures are called in the reverse of the order with which they were added. This is because the default behaviour of `add-hook!' is to add its procedure to the _front_ of the hook's procedure list. You can force `add-hook!' to add its procedure to the _end_ of the list instead by providing a third `#t' argument on the second call to `add-hook!'. (add-hook! hook (lambda (x y) (display "Foo: ") (display (+ x y)) (newline))) (add-hook! hook (lambda (x y) (display "Bar: ") (display (* x y)) (newline)) #t) ; <- Change here! (run-hook hook 3 4) -| Foo: 7 -| Bar: 12  File: guile.info, Node: Hook Reference, Next: C Hooks, Prev: Hook Example, Up: Hooks Hook Reference -------------- When you create a hook with `make-hook', you must specify the arity of the procedures which can be added to the hook. If the arity is not given explicitly as an argument to `make-hook', it defaults to zero. All procedures of a given hook must have the same arity, and when the procedures are invoked using `run-hook', the number of arguments passed must match the arity specified at hook creation time. The order in which procedures are added to a hook matters. If the third parameter to `add-hook!' is omitted or is equal to `#f', the procedure is added in front of the procedures which might already be on that hook, otherwise the procedure is added at the end. The procedures are always called from the front to the end of the list when they are invoked via `run-hook'. The ordering of the list of procedures returned by `hook->list' matches the order in which those procedures would be called if the hook was run using `run-hook'. Note that the C functions in the following entries are for handling "Scheme-level" hooks in C. There are also "C-level" hooks which have their own interface (*note C Hooks::). - Scheme Procedure: make-hook [n_args] - C Function: scm_make_hook (n_args) Create a hook for storing procedure of arity N_ARGS. N_ARGS defaults to zero. The returned value is a hook object to be used with the other hook procedures. - Scheme Procedure: hook? x - C Function: scm_hook_p (x) Return `#t' if X is a hook, `#f' otherwise. - Scheme Procedure: hook-empty? hook - C Function: scm_hook_empty_p (hook) Return `#t' if HOOK is an empty hook, `#f' otherwise. - Scheme Procedure: add-hook! hook proc [append_p] - C Function: scm_add_hook_x (hook, proc, append_p) Add the procedure PROC to the hook HOOK. The procedure is added to the end if APPEND_P is true, otherwise it is added to the front. The return value of this procedure is not specified. - Scheme Procedure: remove-hook! hook proc - C Function: scm_remove_hook_x (hook, proc) Remove the procedure PROC from the hook HOOK. The return value of this procedure is not specified. - Scheme Procedure: reset-hook! hook - C Function: scm_reset_hook_x (hook) Remove all procedures from the hook HOOK. The return value of this procedure is not specified. - Scheme Procedure: hook->list hook - C Function: scm_hook_to_list (hook) Convert the procedure list of HOOK to a list. - Scheme Procedure: run-hook hook . args - C Function: scm_run_hook (hook, args) Apply all procedures from the hook HOOK to the arguments ARGS. The order of the procedure application is first to last. The return value of this procedure is not specified. If, in C code, you are certain that you have a hook object and well formed argument list for that hook, you can also use `scm_c_run_hook', which is identical to `scm_run_hook' but does no type checking. - C Function: void scm_c_run_hook (SCM hook, SCM args) The same as `scm_run_hook' but without any type checking to confirm that HOOK is actually a hook object and that ARGS is a well-formed list matching the arity of the hook. For C code, `SCM_HOOKP' is a faster alternative to `scm_hook_p': - C Macro: int SCM_HOOKP (x) Return 1 if X is a Scheme-level hook, 0 otherwise. Handling Scheme-level hooks from C code --------------------------------------- Here is an example of how to handle Scheme-level hooks from C code using the above functions. if (SCM_NFALSEP (scm_hook_p (obj))) /* handle Scheme-level hook using C functions */ scm_reset_hook_x (obj); else /* do something else (obj is not a hook) */  File: guile.info, Node: C Hooks, Next: Guile Hooks, Prev: Hook Reference, Up: Hooks Hooks For C Code. ----------------- The hooks already described are intended to be populated by Scheme-level procedures. In addition to this, the Guile library provides an independent set of interfaces for the creation and manipulation of hooks that are designed to be populated by functions implemented in C. The original motivation here was to provide a kind of hook that could safely be invoked at various points during garbage collection. Scheme-level hooks are unsuitable for this purpose as running them could itself require memory allocation, which would then invoke garbage collection recursively ... However, it is also the case that these hooks are easier to work with than the Scheme-level ones if you only want to register C functions with them. So if that is mainly what your code needs to do, you may prefer to use this interface. To create a C hook, you should allocate storage for a structure of type `scm_t_c_hook' and then initialize it using `scm_c_hook_init'. - C Type: scm_t_c_hook Data type for a C hook. The internals of this type should be treated as opaque. - C Enum: scm_t_c_hook_type Enumeration of possible hook types, which are: `SCM_C_HOOK_NORMAL' Type of hook for which all the registered functions will always be called. `SCM_C_HOOK_OR' Type of hook for which the sequence of registered functions will be called only until one of them returns C true (a non-NULL pointer). `SCM_C_HOOK_AND' Type of hook for which the sequence of registered functions will be called only until one of them returns C false (a NULL pointer). - C Function: void scm_c_hook_init (scm_t_c_hook *hook, void *hook_data, scm_t_c_hook_type type) Initialize the C hook at memory pointed to by HOOK. TYPE should be one of the values of the `scm_t_c_hook_type' enumeration, and controls how the hook functions will be called. HOOK_DATA is a closure parameter that will be passed to all registered hook functions when they are called. To add or remove a C function from a C hook, use `scm_c_hook_add' or `scm_c_hook_remove'. A hook function must expect three `void *' parameters which are, respectively: HOOK_DATA The hook closure data that was specified at the time the hook was initialized by `scm_c_hook_init'. FUNC_DATA The function closure data that was specified at the time that that function was registered with the hook by `scm_c_hook_add'. DATA The call closure data specified by the `scm_c_hook_run' call that runs the hook. - C Type: scm_t_c_hook_function Function type for a C hook function: takes three `void *' parameters and returns a `void *' result. - C Function: void scm_c_hook_add (scm_t_c_hook *hook, scm_t_c_hook_function func, void *func_data, int appendp) Add function FUNC, with function closure data FUNC_DATA, to the C hook HOOK. The new function is appended to the hook's list of functions if APPENDP is non-zero, otherwise prepended. - C Function: void scm_c_hook_remove (scm_t_c_hook *hook, scm_t_c_hook_function func, void *func_data) Remove function FUNC, with function closure data FUNC_DATA, from the C hook HOOK. `scm_c_hook_remove' checks both FUNC and FUNC_DATA so as to allow for the same FUNC being registered multiple times with different closure data. Finally, to invoke a C hook, call the `scm_c_hook_run' function specifying the hook and the call closure data for this run: - C Function: void * scm_c_hook_run (scm_t_c_hook *hook, void *data) Run the C hook HOOK will call closure data DATA. Subject to the variations for hook types `SCM_C_HOOK_OR' and `SCM_C_HOOK_AND', `scm_c_hook_run' calls HOOK's registered functions in turn, passing them the hook's closure data, each function's closure data, and the call closure data. `scm_c_hook_run''s return value is the return value of the last function to be called.  File: guile.info, Node: Guile Hooks, Prev: C Hooks, Up: Hooks Hooks Provided by Guile ----------------------- * Menu: * GC Hooks:: Garbage collection hooks. * REPL Hooks:: Hooks into the Guile REPL.  File: guile.info, Node: GC Hooks, Next: REPL Hooks, Up: Guile Hooks Hooks for Garbage Collection ............................ Whenever Guile performs a garbage collection, it calls the following hooks in the order shown. - C Hook: scm_before_gc_c_hook C hook called at the very start of a garbage collection, after setting `scm_gc_running_p' to 1, but before entering the GC critical section. If garbage collection is blocked because `scm_block_gc' is non-zero, GC exits early soon after calling this hook, and no further hooks will be called. - C Hook: scm_before_mark_c_hook C hook called before beginning the mark phase of garbage collection, after the GC thread has entered a critical section. - C Hook: scm_before_sweep_c_hook C hook called before beginning the sweep phase of garbage collection. This is the same as at the end of the mark phase, since nothing else happens between marking and sweeping. - C Hook: scm_after_sweep_c_hook C hook called after the end of the sweep phase of garbage collection, but while the GC thread is still inside its critical section. - C Hook: scm_after_gc_c_hook C hook called at the very end of a garbage collection, after the GC thread has left its critical section. - Scheme Hook: after-gc-hook Scheme hook with arity 0. This hook is run asynchronously (*note Asyncs::) soon after the GC has completed and any other events that were deferred during garbage collection have been processed. (Also accessible from C with the name `scm_after_gc_hook'.) All the C hooks listed here have type `SCM_C_HOOK_NORMAL', are initialized with hook closure data NULL, are are invoked by `scm_c_hook_run' with call closure data NULL. The Scheme hook `after-gc-hook' is particularly useful in conjunction with guardians (*note Guardians::). Typically, if you are using a guardian, you want to call the guardian after garbage collection to see if any of the objects added to the guardian have been collected. By adding a thunk that performs this call to `after-gc-hook', you can ensure that your guardian is tested after every garbage collection cycle.  File: guile.info, Node: REPL Hooks, Prev: GC Hooks, Up: Guile Hooks Hooks into the Guile REPL .........................  File: guile.info, Node: Binding Constructs, Next: Control Mechanisms, Prev: Utility Functions, Up: Top Definitions and Variable Bindings ********************************* Scheme supports the definition of variables in different contexts. Variables can be defined at the top level, so that they are visible in the entire program, and variables can be defined locally to procedures and expressions. This is important for modularity and data abstraction. * Menu: * Top Level:: Top level variable definitions. * Local Bindings:: Local variable bindings. * Internal Definitions:: Internal definitions. * Binding Reflection:: Querying variable bindings.  File: guile.info, Node: Top Level, Next: Local Bindings, Up: Binding Constructs Top Level Variable Definitions ============================== On the top level of a program (i.e. when not inside the body of a procedure definition or a `let', `let*' or `letrec' expression), a definition of the form (define a VALUE) defines a variable called `a' and sets it to the value VALUE. If the variable already exists, because it has already been created by a previous `define' expression with the same name, its value is simply changed to the new VALUE. In this case, then, the above form is completely equivalent to (set! a VALUE) This equivalence means that `define' can be used interchangeably with `set!' to change the value of variables at the top level of the REPL or a Scheme source file. It is useful during interactive development when reloading a Scheme file that you have modified, because it allows the `define' expressions in that file to work as expected both the first time that the file is loaded and on subsequent occasions. Note, though, that `define' and `set!' are not always equivalent. For example, a `set!' is not allowed if the named variable does not already exist, and the two expressions can behave differently in the case where there are imported variables visible from another module. - Scheme Syntax: define name value Create a top level variable named NAME with value VALUE. If the named variable already exists, just change its value. The return value of a `define' expression is unspecified. The C API equivalents of `define' are `scm_define' and `scm_c_define', which differ from each other in whether the variable name is specified as a `SCM' symbol or as a null-terminated C string. - C Function: scm_define (sym, value) - C Function: scm_c_define (const char *name, value) C equivalents of `define', with variable name specified either by SYM, a symbol, or by NAME, a null-terminated C string. Both variants return the new or preexisting variable object. `define' (when it occurs at top level), `scm_define' and `scm_c_define' all create or set the value of a variable in the top level environment of the current module. If there was not already a variable with the specified name belonging to the current module, but a similarly named variable from another module was visible through having been imported, the newly created variable in the current module will shadow the imported variable, such that the imported variable is no longer visible. Attention: Scheme definitions inside local binding constructs (*note Local Bindings::) act differently (*note Internal Definitions::).  File: guile.info, Node: Local Bindings, Next: Internal Definitions, Prev: Top Level, Up: Binding Constructs Local Variable Bindings ======================= As opposed to definitions at the top level, which are visible in the whole program (or current module, when Guile modules are used), it is also possible to define variables which are only visible in a well-defined part of the program. Normally, this part of a program will be a procedure or a subexpression of a procedure. With the constructs for local binding (`let', `let*' and `letrec'), the Scheme language has a block structure like most other programming languages since the days of ALGOL 60. Readers familiar to languages like C or Java should already be used to this concept, but the family of `let' expressions has a few properties which are well worth knowing. The first local binding construct is `let'. The other constructs `let*' and `letrec' are specialized versions for usage where using plain `let' is a bit inconvenient. - syntax: let bindings body BINDINGS has the form ((VARIABLE1 INIT1) ...) that is zero or more two-element lists of a variable and an arbitrary expression each. All VARIABLE names must be distinct. A `let' expression is evaluated as follows. * All INIT expressions are evaluated. * New storage is allocated for the VARIABLES. * The values of the INIT expressions are stored into the variables. * The expressions in BODY are evaluated in order, and the value of the last expression is returned as the value of the `let' expression. * The storage for the VARIABLES is freed. The INIT expressions are not allowed to refer to any of the VARIABLES. - syntax: let* bindings body Similar to `let', but the variable bindings are performed sequentially, that means that all INIT expression are allowed to use the variables defined on their left in the binding list. A `let*' expression can always be expressed with nested `let' expressions. (let* ((a 1) (b a)) b) == (let ((a 1)) (let ((b a)) b)) - syntax: letrec bindings body Similar to `let', but it is possible to refer to the VARIABLE from lambda expression created in any of the INITS. That is, procedures created in the INIT expression can recursively refer to the defined variables. (letrec ((even? (lambda (n) (if (zero? n) #t (odd? (- n 1))))) (odd? (lambda (n) (if (zero? n) #f (even? (- n 1)))))) (even? 88)) => #t There is also an alternative form of the `let' form, which is used for expressing iteration. Because of the use as a looping construct, this form (the "named let") is documented in the section about iteration (*note Iteration: while do.)  File: guile.info, Node: Internal Definitions, Next: Binding Reflection, Prev: Local Bindings, Up: Binding Constructs Internal definitions ==================== A `define' form which appears inside the body of a `lambda', `let', `let*', `letrec' or equivalent expression is called an "internal definition". An internal definition differs from a top level definition (*note Top Level::), because the definition is only visible inside the complete body of the enclosing form. Let us examine the following example. (let ((frumble "froz")) (define banana (lambda () (apple 'peach))) (define apple (lambda (x) x)) (banana)) => peach Here the enclosing form is a `let', so the `define's in the `let'-body are internal definitions. Because the scope of the internal definitions is the *complete* body of the `let'-expression, the `lambda'-expression which gets bound to the variable `banana' may refer to the variable `apple', even though it's definition appears lexically _after_ the definition of `banana'. This is because a sequence of internal definition acts as if it were a `letrec' expression. (let () (define a 1) (define b 2) (+ a b)) is equivalent to (let () (letrec ((a 1) (b 2)) (+ a b))) Another noteworthy difference to top level definitions is that within one group of internal definitions all variable names must be distinct. That means where on the top level a second define for a given variable acts like a `set!', an exception is thrown for internal definitions with duplicate bindings.  File: guile.info, Node: Binding Reflection, Prev: Internal Definitions, Up: Binding Constructs Querying variable bindings ========================== Guile provides a procedure for checking whether a symbol is bound in the top level environment. - Scheme Procedure: defined? sym [env] - C Function: scm_definedp (sym, env) Return `#t' if SYM is defined in the lexical environment ENV. When ENV is not specified, look in the top-level environment as defined by the current module.  File: guile.info, Node: Control Mechanisms, Next: Input and Output, Prev: Binding Constructs, Up: Top 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. * Handling Errors:: How to handle errors in C code.  File: guile.info, Node: begin, Next: if cond case, Up: Control Mechanisms Evaluating a Sequence of Expressions ==================================== `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: (if (> x 0) (begin (display "greater") (newline))) If the two calls to `display' and `newline' were not embedded in a `begin'-statement, the call to `newline' would get misinterpreted as the else-branch of the `if'-expression. - syntax: begin expr1 expr2 ... The expression(s) are evaluated in left-to-right order and the value of the last expression is returned as the value of the `begin'-expression. This expression type is used when the expressions before the last one are evaluated for their side effects.  File: guile.info, Node: if cond case, Next: and or, Prev: begin, Up: Control Mechanisms Simple Conditional Evaluation ============================= Guile provides three syntactic constructs for conditional evaluation. `if' is the normal if-then-else expression (with an optional else branch), `cond' is a conditional expression with multiple branches and `case' branches if an expression has one of a set of constant values. - syntax: if test consequent [alternate] All arguments may be arbitrary expressions. First, TEST is evaluated. If it returns a true value, the expression CONSEQUENT is evaluated and ALTERNATE is ignored. If TEST evaluates to `#f', ALTERNATE is evaluated instead. The value of the evaluated branch (CONSEQUENT or ALTERNATE) is returned as the value of the `if' expression. When ALTERNATE is omitted and the TEST evaluates to `#f', the value of the expression is not specified. - syntax: cond clause1 clause2 ... Each `cond'-clause must look like this: (TEST EXPRESSION ...) where TEST and EXPRESSION are arbitrary expression, or like this (TEST => EXPRESSION where EXPRESSION must evaluate to a procedure. The TESTs of the clauses are evaluated in order and as soon as one of them evaluates to a true values, the corresponding EXPRESSIONs are evaluated in order and the last value is returned as the value of the `cond'-expression. For the `=>' clause type, EXPRESSION is evaluated and the resulting procedure is applied to the value of TEST. The result of this procedure application is then the result of the `cond'-expression. The TEST of the last CLAUSE may be the keyword `else'. Then, if none of the preceding TESTs is true, the EXPRESSIONs following the `else' are evaluated to produce the result of the `cond'-expression. - syntax: case key clause1 clause2 ... KEY may be any expression, the CLAUSEs must have the form ((DATUM1 ...) EXPR1 EXPR2 ...) and the last CLAUSE may have the form (else EXPR1 EXPR2 ...) All DATUMs must be distinct. First, KEY is evaluated. The the result of this evaluation is compared against all DATUMs using `eqv?'. When this comparison succeeds, the expression(s) following the DATUM are evaluated from left to right, returning the value of the last expression as the result of the `case' expression. If the KEY matches no DATUM and there is an `else'-clause, the expressions following the `else' are evaluated. If there is no such clause, the result of the expression is unspecified.  File: guile.info, Node: and or, Next: while do, Prev: if cond case, Up: Control Mechanisms Conditional Evaluation of a Sequence of Expressions =================================================== `and' and `or' evaluate all their arguments, similar to `begin', but evaluation stops as soon as one of the expressions evaluates to false or true, respectively. - syntax: and expr ... Evaluate the EXPRs from left to right and stop evaluation as soon as one expression evaluates to `#f'; the remaining expressions are not evaluated. The value of the last evaluated expression is returned. If no expression evaluates to `#f', the value of the last expression is returned. If used without expressions, `#t' is returned. - syntax: or expr ... Evaluate the EXPRs from left to right and stop evaluation as soon as one expression evaluates to a true value (that is, a value different from `#f'); the remaining expressions are not evaluated. The value of the last evaluated expression is returned. If all expressions evaluate to `#f', `#f' is returned. If used without expressions, `#f' is returned.  File: guile.info, Node: while do, Next: Continuations, Prev: and or, Up: Control Mechanisms Iteration mechanisms ==================== 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 `do'. In addition, Guile has an explicit looping syntax called `while'. - syntax: do ((variable1 init1 step1) ...) (test expr ...) command ... The INIT expressions are evaluated and the VARIABLES are bound to their values. Then looping starts with testing the TEST expression. If TEST evaluates to a true value, the EXPR following the TEST are evaluated and the value of the last EXPR is returned as the value of the `do' expression. If TEST evaluates to false, the COMMANDs are evaluated in order, the STEPs are evaluated and stored into the VARIABLES and the next iteration starts. Any of the STEP expressions may be omitted, so that the corresponding variable is not changed during looping. - syntax: while cond body ... Evaluate all expressions in BODY in order, as long as COND evaluates to a true value. The COND expression is tested before every iteration, so that the body is not evaluated at all if COND is `#f' right from the start. Another very common way of expressing iteration in Scheme programs is the use of the so-called "named let". Named let is a variant of `let' which creates a procedure and calls it in one step. Because of the newly created procedure, named let is more powerful than `do'-it can be used for iteration, but also for arbitrary recursion. - syntax: let variable bindings body For the definition of BINDINGS see the documentation about `let' (*note Local Bindings::). Named `let' works as follows: * A new procedure which accepts as many arguments as are in BINDINGS is created and bound locally (using `let') to VARIABLE. The new procedure's formal argument names are the name of the VARIABLES. * The BODY expressions are inserted into the newly created procedure. * The procedure is called with the INIT expressions as the formal arguments. The next example implements a loop which iterates (by recursion) 1000 times. (let lp ((x 1000)) (if (positive? x) (lp (- x 1)) x)) => 0  File: guile.info, Node: Continuations, Next: Multiple Values, Prev: while do, Up: Control Mechanisms Continuations ============= The ability to explicitly capture continuations using `call-with-current-continuation' (also often called `call/cc' for short), and to invoke such continuations later any number of times, and from any other point in a program, provides maybe the most powerful control structure known. All other control structures, such as loops and coroutines, can be emulated using continuations. The implementation of continuations in Guile is not as efficient as one might hope, because it is constrained by the fact that Guile is designed to cooperate with programs written in other languages, such as C, which do not know about continuations. So continuations should be used when there is no other simple way of achieving the desired behaviour, or where the advantages of the elegant continuation mechanism outweigh the need for optimum performance. If you find yourself using `call/cc' for escape procedures and your program is running too slow, you might want to use exceptions (*note Exceptions::) instead. - Scheme Procedure: call-with-current-continuation proc Capture the current continuation and call PROC with the captured continuation as the single argument. This continuation can then be called with arbitrarily many arguments. Such a call will work like a goto to the invocation location of `call-with-current-continuation', passing the arguments in a way that they are returned by the call to `call-with-current-continuation'. Since it is legal to store the captured continuation in a variable or to pass it to other procedures, it is possible that a procedure returns more than once, even if it is called only one time. This can be confusing at times. (define kont #f) (call-with-current-continuation (lambda (k) (set! kont k) 1)) => 1 (kont 2) => 2  File: guile.info, Node: Multiple Values, Next: Exceptions, Prev: Continuations, Up: Control Mechanisms Returning and Accepting Multiple Values ======================================= 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 _one_ compound object is returned, but several distinct values. The primitive procedures for handling multiple values are `values' and `call-with-values'. `values' is used for returning multiple values from a procedure. This is done by placing a call to `values' with zero or more arguments in tail position in a procedure body. `call-with-values' combines a procedure returning multiple values with a procedure which accepts these values as parameters. - Scheme Procedure: values . args - C Function: scm_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. - Scheme Procedure: 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 In addition to the fundamental procedures described above, Guile has a module which exports a syntax called `receive', which is much more convenient. If you want to use it in your programs, you have to load the module `(ice-9 receive)' with the statement (use-modules (ice-9 receive)) - library syntax: receive formals expr body ... Evaluate the expression EXPR, and bind the result values (zero or more) to the formal arguments in the formal argument list FORMALS. FORMALS must have the same syntax like the formal argument list used in `lambda' (*note Lambda::). After binding the variables, the expressions in BODY ... are evaluated in order.  File: guile.info, Node: Exceptions, Next: Error Reporting, Prev: Multiple Values, Up: Control Mechanisms Exceptions ========== A common requirement in applications is to want to jump "non-locally" from the depths of a computation back to, say, the application's main processing loop. Usually, the place that is the target of the jump is somewhere in the calling stack of procedures that called the procedure that wants to jump back. For example, typical logic for a key press driven application might look something like this: 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, jump back to main-loop ... The jump back to `main-loop' could be achieved by returning through the stack one procedure at a time, using the return value of each procedure to indicate the error condition, but Guile (like most modern programming languages) provides an additional mechanism called "exception handling" that can be used to implement such jumps much more conveniently. * Menu: * Exception Terminology:: Different ways to say the same thing. * Catch:: Setting up to catch exceptions. * Throw:: Throwing an exception. * Lazy Catch:: Catch without unwinding the stack. * Exception Implementation:: How Guile implements exceptions.  File: guile.info, Node: Exception Terminology, Next: Catch, Up: Exceptions Exception Terminology --------------------- There are several variations on the terminology for dealing with non-local jumps. It is useful to be aware of them, and to realize that they all refer to the same basic mechanism. * Actually making a non-local jump may be called "raising an exception", "raising a signal", "throwing an exception" or "doing a long jump". When the jump indicates an error condition, people may talk about "signalling", "raising" or "throwing" "an error". * Handling the jump at its target may be referred to as "catching" or "handling" the "exception", "signal" or, where an error condition is involved, "error". Where "signal" and "signalling" are used, special care is needed to avoid the risk of confusion with POSIX signals. (Especially considering that Guile handles POSIX signals by throwing a corresponding kind of exception: REFFIXME.) This manual prefers to speak of throwing and catching exceptions, since this terminology matches the corresponding Guile primitives.  File: guile.info, Node: Catch, Next: Throw, Prev: Exception Terminology, Up: Exceptions Catching Exceptions ------------------- `catch' is used to set up a target for a possible non-local jump. The arguments of a `catch' expression are a "key", which restricts the set of exceptions to which this `catch' applies, a thunk that specifies the "normal case" code -- i.e. what should happen if no exceptions are thrown -- and a "handler" procedure that says what to do if an exception is thrown. Note that if the "normal case" thunk executes "normally", which means without throwing any exceptions, the handler procedure is not executed at all. When an exception is thrown using the `throw' primitive, the first argument of the `throw' is a symbol that indicates the type of the exception. For example, Guile throws an exception using the symbol `numerical-overflow' to indicate numerical overflow errors such as division by zero: (/ 1 0) => ABORT: (numerical-overflow) The KEY argument in a `catch' expression corresponds to this symbol. KEY may be a specific symbol, such as `numerical-overflow', in which case the `catch' applies specifically to exceptions of that type; or it may be `#t', which means that the `catch' applies to all exceptions, irrespective of their type. The second argument of a `catch' expression should be a thunk (i.e. a procedure that accepts no arguments) that specifies the normal case code. The `catch' is active for the execution of this thunk, including any code called directly or indirectly by the thunk's body. Evaluation of the `catch' expression activates the catch and then calls this thunk. The third argument of a `catch' expression is a handler procedure. If an exception is thrown, this procedure is called with exactly the arguments specified by the `throw'. Therefore, the handler procedure must be designed to accept a number of arguments that corresponds to the number of arguments in all `throw' expressions that can be caught by this `catch'. - Scheme Procedure: catch key thunk handler - C Function: scm_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'. If the handler procedure needs to match a variety of `throw' expressions with varying numbers of arguments, you should write it like this: (lambda (key . args) ...) The KEY argument is guaranteed always to be present, because a `throw' without a KEY is not valid. The number and interpretation of the ARGS varies from one type of exception to another, but should be specified by the documentation for each exception type. Note that, once the handler procedure is invoked, the catch that led to the handler procedure being called is no longer active. Therefore, if the handler procedure itself throws an exception, that exception can only be caught by another active catch higher up the call stack, if there is one.