This manual documents Guile version 3.0.10.

   Copyright (C) 1996-1997, 2000-2005, 2009-2023 Free Software
Foundation, Inc.
Copyright (C) 2021 Maxime Devos
Copyright (C) 2024 Tomas Volf

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.  A
copy of the license is included in the section entitled "GNU Free
Documentation License."

6.6.18.1 Vtables
................

A vtable is a structure type, specifying its layout, and other
information.  A vtable is actually itself a structure, but there's no
need to worry about that initially (see Vtable Contents.)

 -- Scheme Procedure: make-vtable fields [print]
     Create a new vtable.

     FIELDS is a string describing the fields in the structures to be
     created.  Each field is represented by two characters, a type
     letter and a permissions letter, for example ‘"pw"’.  The types are
     as follows.

        • ‘p’ - a Scheme value.  "p" stands for "protected" meaning it's
          protected against garbage collection.

        • ‘u’ - an arbitrary word of data (an ‘scm_t_bits’).  At the
          Scheme level it's read and written as an unsigned integer.
          "u" stands for "unboxed", as it's stored as a raw value
          without additional type annotations.

     It used to be that the second letter for each field was a
     permission code, such as ‘w’ for writable or ‘r’ for read-only.
     However over time structs have become more of a raw low-level
     facility; access control is better implemented as a layer on top.
     After all, ‘struct-set!’ is a cross-cutting operator that can
     bypass abstractions made by higher-level record facilities; it's
     not generally safe (in the sense of abstraction-preserving) to
     expose ‘struct-set!’ to "untrusted" code, even if the fields happen
     to be writable.  Additionally, permission checks added overhead to
     every structure access in a way that couldn't be optimized out,
     hampering the ability of structs to act as a low-level building
     block.  For all of these reasons, all fields in Guile structs are
     now writable; attempting to make a read-only field will now issue a
     deprecation warning, and the field will be writable regardless.

          (make-vtable "pw")      ;; one scheme field
          (make-vtable "pwuwuw")  ;; one scheme and two unboxed fields

     The optional PRINT argument is a function called by ‘display’ and
     ‘write’ (etc) to give a printed representation of a structure
     created from this vtable.  It's called ‘(PRINT struct port)’ and
     should look at STRUCT and write to PORT.  The default print merely
     gives a form like ‘#<struct ADDR:ADDR>’ with a pair of machine
     addresses.

     The following print function for example shows the two fields of
     its structure.

          (make-vtable "pwpw"
                       (lambda (struct port)
                         (format port "#<~a and ~a>"
                                 (struct-ref struct 0)
                                 (struct-ref struct 1))))

6.6.18.2 Structure Basics
.........................

This section describes the basic procedures for working with structures.
‘make-struct/no-tail’ creates a structure, and ‘struct-ref’ and
‘struct-set!’ access its fields.

 -- Scheme Procedure: make-struct/no-tail vtable init ...
     Create a new structure, with layout per the given VTABLE (see
     Vtables).

     The optional INIT... arguments are initial values for the fields of
     the structure.  This is the only way to put values in read-only
     fields.  If there are fewer INIT arguments than fields then the
     defaults are ‘#f’ for a Scheme field (type ‘p’) or 0 for an unboxed
     field (type ‘u’).

     The name is a bit strange, we admit.  The reason for it is that
     Guile used to have a ‘make-struct’ that took an additional
     argument; while we deprecate that old interface,
     ‘make-struct/no-tail’ is the new name for this functionality.

     For example,

          (define v (make-vtable "pwpwpw"))
          (define s (make-struct/no-tail v 123 "abc" 456))
          (struct-ref s 0) ⇒ 123
          (struct-ref s 1) ⇒ "abc"

 -- C Function: SCM scm_make_struct (SCM vtable, SCM tail_size, SCM
          init_list)
 -- C Function: SCM scm_c_make_struct (SCM vtable, SCM tail_size, SCM
          init, ...)
 -- C Function: SCM scm_c_make_structv (SCM vtable, SCM tail_size,
          size_t n_inits, scm_t_bits init[])
     There are a few ways to make structures from C. ‘scm_make_struct’
     takes a list, ‘scm_c_make_struct’ takes variable arguments
     terminated with SCM_UNDEFINED, and ‘scm_c_make_structv’ takes a
     packed array.

     For all of these, TAIL_SIZE should be zero (as a SCM value).

 -- Scheme Procedure: struct? obj
 -- C Function: scm_struct_p (obj)
     Return ‘#t’ if OBJ is a structure, or ‘#f’ if not.

 -- Scheme Procedure: struct-ref struct n
 -- C Function: scm_struct_ref (struct, n)
     Return the contents of field number N in STRUCT.  The first field
     is number 0.

     An error is thrown if N is out of range.

 -- Scheme Procedure: struct-set! struct n value
 -- C Function: scm_struct_set_x (struct, n, value)
     Set field number N in STRUCT to VALUE.  The first field is number
     0.

     An error is thrown if N is out of range, or if the field cannot be
     written because it's ‘r’ read-only.

   Unboxed fields (those with type ‘u’) need to be accessed with special
procedures.

 -- Scheme Procedure: struct-ref/unboxed struct n
 -- Scheme Procedure: struct-set!/unboxed struct n value
 -- C Function: scm_struct_ref_unboxed (struct, n)
 -- C Function: scm_struct_set_x_unboxed (struct, n, value)
     Like ‘struct-ref’ and ‘struct-set!’, except that these may only be
     used on unboxed fields.  ‘struct-ref/unboxed’ will always return a
     positive integer.  Likewise, ‘struct-set!/unboxed’ takes an
     unsigned integer as the VALUE argument, and will signal an error
     otherwise.

 -- Scheme Procedure: struct-vtable struct
 -- C Function: scm_struct_vtable (struct)
     Return the vtable that describes STRUCT.

     The vtable is effectively the type of the structure.  See
     Vtable Contents, for more on vtables.

6.6.18.3 Vtable Contents
........................

A vtable is itself a structure.  It has a specific set of fields
describing various aspects of its “instances”: the structures created
from a vtable.  Some of the fields are internal to Guile, some of them
are part of the public interface, and there may be additional fields
added on by the user.

   Every vtable has a field for the layout of their instances, a field
for the procedure used to print its instances, and a field for the name
of the vtable itself.  Access to the layout and printer is exposed
directly via field indexes.  Access to the vtable name is exposed via
accessor procedures.

 -- Scheme Variable: vtable-index-layout
 -- C Macro: scm_vtable_index_layout
     The field number of the layout specification in a vtable.  The
     layout specification is a symbol like ‘pwpw’ formed from the fields
     string passed to ‘make-vtable’, or created by ‘make-struct-layout’
     (see Meta-Vtables).

          (define v (make-vtable "pwpw" 0))
          (struct-ref v vtable-index-layout) ⇒ pwpw

     This field is read-only, since the layout of structures using a
     vtable cannot be changed.

 -- Scheme Variable: vtable-index-printer
 -- C Macro: scm_vtable_index_printer
     The field number of the printer function.  This field contains ‘#f’
     if the default print function should be used.

          (define (my-print-func struct port)
            ...)
          (define v (make-vtable "pwpw" my-print-func))
          (struct-ref v vtable-index-printer) ⇒ my-print-func

     This field is writable, allowing the print function to be changed
     dynamically.

 -- Scheme Procedure: struct-vtable-name vtable
 -- Scheme Procedure: set-struct-vtable-name! vtable name
 -- C Function: scm_struct_vtable_name (vtable)
 -- C Function: scm_set_struct_vtable_name_x (vtable, name)
     Get or set the name of VTABLE.  NAME is a symbol and is used in the
     default print function when printing structures created from
     VTABLE.

          (define v (make-vtable "pw"))
          (set-struct-vtable-name! v 'my-name)

          (define s (make-struct v 0))
          (display s) ⊣ #<my-name b7ab3ae0:b7ab3730>

6.6.18.4 Meta-Vtables
.....................

As a structure, a vtable also has a vtable, which is also a structure.
Structures, their vtables, the vtables of the vtables, and so on form a
tree of structures.  Making a new structure adds a leaf to the tree, and
if that structure is a vtable, it may be used to create other leaves.

   If you traverse up the tree of vtables, via calling ‘struct-vtable’,
eventually you reach a root which is the vtable of itself:

     scheme@(guile-user)> (current-module)
     $1 = #<directory (guile-user) 221b090>
     scheme@(guile-user)> (struct-vtable $1)
     $2 = #<record-type module>
     scheme@(guile-user)> (struct-vtable $2)
     $3 = #<<standard-vtable> 12c30a0>
     scheme@(guile-user)> (struct-vtable $3)
     $4 = #<<standard-vtable> 12c3fa0>
     scheme@(guile-user)> (struct-vtable $4)
     $5 = #<<standard-vtable> 12c3fa0>
     scheme@(guile-user)> <standard-vtable>
     $6 = #<<standard-vtable> 12c3fa0>

   In this example, we can say that ‘$1’ is an instance of ‘$2’, ‘$2’ is
an instance of ‘$3’, ‘$3’ is an instance of ‘$4’, and ‘$4’, strangely
enough, is an instance of itself.  The value bound to ‘$4’ in this
console session also bound to ‘<standard-vtable>’ in the default
environment.

 -- Scheme Variable: <standard-vtable>
     A meta-vtable, useful for making new vtables.

   All of these values are structures.  All but ‘$1’ are vtables.  As
‘$2’ is an instance of ‘$3’, and ‘$3’ is a vtable, we can say that ‘$3’
is a “meta-vtable”: a vtable that can create vtables.

   With this definition, we can specify more precisely what a vtable is:
a vtable is a structure made from a meta-vtable.  Making a structure
from a meta-vtable runs some special checks to ensure that the first
field of the structure is a valid layout.  Additionally, if these checks
see that the layout of the child vtable contains all the required fields
of a vtable, in the correct order, then the child vtable will also be a
meta-table, inheriting a magical bit from the parent.

 -- Scheme Procedure: struct-vtable? obj
 -- C Function: scm_struct_vtable_p (obj)
     Return ‘#t’ if OBJ is a vtable structure: an instance of a
     meta-vtable.

   ‘<standard-vtable>’ is a root of the vtable tree.  (Normally there is
only one root in a given Guile process, but due to some legacy
interfaces there may be more than one.)

   The set of required fields of a vtable is the set of fields in the
‘<standard-vtable>’, and is bound to ‘standard-vtable-fields’ in the
default environment.  It is possible to create a meta-vtable that with
additional fields in its layout, which can be used to create vtables
with additional data:

     scheme@(guile-user)> (struct-ref $3 vtable-index-layout)
     $6 = pwuhuhpwphuhuhpwpwpw
     scheme@(guile-user)> (struct-ref $4 vtable-index-layout)
     $7 = pwuhuhpwphuhuh
     scheme@(guile-user)> standard-vtable-fields
     $8 = "pwuhuhpwphuhuh"
     scheme@(guile-user)> (struct-ref $2 vtable-offset-user)
     $9 = module

   In this continuation of our earlier example, ‘$2’ is a vtable that
has extra fields, because its vtable, ‘$3’, was made from a meta-vtable
with an extended layout.  ‘vtable-offset-user’ is a convenient
definition that indicates the number of fields in
‘standard-vtable-fields’.

 -- Scheme Variable: standard-vtable-fields
     A string containing the ordered set of fields that a vtable must
     have.

 -- Scheme Variable: vtable-offset-user
     The first index in a vtable that is available for a user.

 -- Scheme Procedure: make-struct-layout fields
 -- C Function: scm_make_struct_layout (fields)
     Return a structure layout symbol, from a FIELDS string.  FIELDS is
     as described under ‘make-vtable’ (see Vtables).  An invalid
     FIELDS string is an error.

   With these definitions, one can define ‘make-vtable’ in this way:

     (define* (make-vtable fields #:optional printer)
       (make-struct/no-tail <standard-vtable>
         (make-struct-layout fields)
         printer))

6.6.18.5 Vtable Example
.......................

Let us bring these points together with an example.  Consider a simple
object system with single inheritance.  Objects will be normal
structures, and classes will be vtables with three extra class fields:
the name of the class, the parent class, and the list of fields.

   So, first we need a meta-vtable that allocates instances with these
extra class fields.

     (define <class>
       (make-vtable
        (string-append standard-vtable-fields "pwpwpw")
        (lambda (x port)
          (format port "<<class> ~a>" (class-name x)))))

     (define (class? x)
       (and (struct? x)
            (eq? (struct-vtable x) <class>)))

   To make a structure with a specific meta-vtable, we will use
‘make-struct/no-tail’, passing it the computed instance layout and
printer, as with ‘make-vtable’, and additionally the extra three class
fields.

     (define (make-class name parent fields)
       (let* ((fields (compute-fields parent fields))
              (layout (compute-layout fields)))
         (make-struct/no-tail <class>
           layout
           (lambda (x port)
             (print-instance x port))
           name
           parent
           fields)))

   Instances will store their associated data in slots in the structure:
as many slots as there are fields.  The ‘compute-layout’ procedure below
can compute a layout, and ‘field-index’ returns the slot corresponding
to a field.

     (define-syntax-rule (define-accessor name n)
       (define (name obj)
         (struct-ref obj n)))

     ;; Accessors for classes
     (define-accessor class-name (+ vtable-offset-user 0))
     (define-accessor class-parent (+ vtable-offset-user 1))
     (define-accessor class-fields (+ vtable-offset-user 2))

     (define (compute-fields parent fields)
       (if parent
           (append (class-fields parent) fields)
           fields))

     (define (compute-layout fields)
       (make-struct-layout
        (string-concatenate (make-list (length fields) "pw"))))

     (define (field-index class field)
       (list-index (class-fields class) field))

     (define (print-instance x port)
       (format port "<~a" (class-name (struct-vtable x)))
       (for-each (lambda (field idx)
                   (format port " ~a: ~a" field (struct-ref x idx)))
                 (class-fields (struct-vtable x))
                 (iota (length (class-fields (struct-vtable x)))))
       (format port ">"))

   So, at this point we can actually make a few classes:

     (define-syntax-rule (define-class name parent field ...)
       (define name (make-class 'name parent '(field ...))))

     (define-class <surface> #f
       width height)

     (define-class <window> <surface>
       x y)

   And finally, make an instance:

     (make-struct/no-tail <window> 400 300 10 20)
     ⇒ <<window> width: 400 height: 300 x: 10 y: 20>

   And that's that.  Note that there are many possible optimizations and
feature enhancements that can be made to this object system, and the
included GOOPS system does make most of them.  For more simple use
cases, the records facility is usually sufficient.  But sometimes you
need to make new kinds of data abstractions, and for that purpose,
structs are here.

6.6.19 Dictionary Types
-----------------------

A “dictionary” object is a data structure used to index information in a
user-defined way.  In standard Scheme, the main aggregate data types are
lists and vectors.  Lists are not really indexed at all, and vectors are
indexed only by number (e.g. ‘(vector-ref foo 5)’).  Often you will find
it useful to index your data on some other type; for example, in a
library catalog you might want to look up a book by the name of its
author.  Dictionaries are used to help you organize information in such
a way.

   An “association list” (or “alist” for short) is a list of key-value
pairs.  Each pair represents a single quantity or object; the ‘car’ of
the pair is a key which is used to identify the object, and the ‘cdr’ is
the object's value.

   A “hash table” also permits you to index objects with arbitrary keys,
but in a way that makes looking up any one object extremely fast.  A
well-designed hash system makes hash table lookups almost as fast as
conventional array or vector references.

   Alists are popular among Lisp programmers because they use only the
language's primitive operations (lists, “car”, “cdr” and the equality
primitives).  No changes to the language core are necessary.  Therefore,
with Scheme's built-in list manipulation facilities, it is very
convenient to handle data stored in an association list.  Also, alists
are highly portable and can be easily implemented on even the most
minimal Lisp systems.

   However, alists are inefficient, especially for storing large
quantities of data.  Because we want Guile to be useful for large
software systems as well as small ones, Guile provides a rich set of
tools for using either association lists or hash tables.

6.6.20 Association Lists
------------------------

An association list is a conventional data structure that is often used
to implement simple key-value databases.  It consists of a list of
entries in which each entry is a pair.  The “key” of each entry is the
‘car’ of the pair and the “value” of each entry is the ‘cdr’.

     ASSOCIATION LIST ::=  '( (KEY1 . VALUE1)
                              (KEY2 . VALUE2)
                              (KEY3 . VALUE3)
                              ...
                            )

Association lists are also known, for short, as “alists”.

   The structure of an association list is just one example of the
infinite number of possible structures that can be built using pairs and
lists.  As such, the keys and values in an association list can be
manipulated using the general list structure procedures ‘cons’, ‘car’,
‘cdr’, ‘set-car!’, ‘set-cdr!’ and so on.  However, because association
lists are so useful, Guile also provides specific procedures for
manipulating them.

6.6.20.1 Alist Key Equality
...........................

All of Guile's dedicated association list procedures, apart from
‘acons’, come in three flavors, depending on the level of equality that
is required to decide whether an existing key in the association list is
the same as the key that the procedure call uses to identify the
required entry.

   • Procedures with “assq” in their name use ‘eq?’ to determine key
     equality.

   • Procedures with “assv” in their name use ‘eqv?’ to determine key
     equality.

   • Procedures with “assoc” in their name use ‘equal?’ to determine key
     equality.

   ‘acons’ is an exception because it is used to build association lists
which do not require their entries' keys to be unique.

6.6.20.2 Adding or Setting Alist Entries
........................................

‘acons’ adds a new entry to an association list and returns the combined
association list.  The combined alist is formed by consing the new entry
onto the head of the alist specified in the ‘acons’ procedure call.  So
the specified alist is not modified, but its contents become shared with
the tail of the combined alist that ‘acons’ returns.

   In the most common usage of ‘acons’, a variable holding the original
association list is updated with the combined alist:

     (set! address-list (acons name address address-list))

   In such cases, it doesn't matter that the old and new values of
‘address-list’ share some of their contents, since the old value is
usually no longer independently accessible.

   Note that ‘acons’ adds the specified new entry regardless of whether
the alist may already contain entries with keys that are, in some sense,
the same as that of the new entry.  Thus ‘acons’ is ideal for building
alists where there is no concept of key uniqueness.

     (set! task-list (acons 3 "pay gas bill" '()))
     task-list
     ⇒
     ((3 . "pay gas bill"))

     (set! task-list (acons 3 "tidy bedroom" task-list))
     task-list
     ⇒
     ((3 . "tidy bedroom") (3 . "pay gas bill"))

   ‘assq-set!’, ‘assv-set!’ and ‘assoc-set!’ are used to add or replace
an entry in an association list where there _is_ a concept of key
uniqueness.  If the specified association list already contains an entry
whose key is the same as that specified in the procedure call, the
existing entry is replaced by the new one.  Otherwise, the new entry is
consed onto the head of the old association list to create the combined
alist.  In all cases, these procedures return the combined alist.

   ‘assq-set!’ and friends _may_ destructively modify the structure of
the old association list in such a way that an existing variable is
correctly updated without having to ‘set!’ it to the value returned:

     address-list
     ⇒
     (("mary" . "34 Elm Road") ("james" . "16 Bow Street"))

     (assoc-set! address-list "james" "1a London Road")
     ⇒
     (("mary" . "34 Elm Road") ("james" . "1a London Road"))

     address-list
     ⇒
     (("mary" . "34 Elm Road") ("james" . "1a London Road"))

   Or they may not:

     (assoc-set! address-list "bob" "11 Newington Avenue")
     ⇒
     (("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
      ("james" . "1a London Road"))

     address-list
     ⇒
     (("mary" . "34 Elm Road") ("james" . "1a London Road"))

   The only safe way to update an association list variable when adding
or replacing an entry like this is to ‘set!’ the variable to the
returned value:

     (set! address-list
           (assoc-set! address-list "bob" "11 Newington Avenue"))
     address-list
     ⇒
     (("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
      ("james" . "1a London Road"))

   Because of this slight inconvenience, you may find it more convenient
to use hash tables to store dictionary data.  If your application will
not be modifying the contents of an alist very often, this may not make
much difference to you.

   If you need to keep the old value of an association list in a form
independent from the list that results from modification by ‘acons’,
‘assq-set!’, ‘assv-set!’ or ‘assoc-set!’, use ‘list-copy’ to copy the
old association list before modifying it.

 -- Scheme Procedure: acons key value alist
 -- C Function: scm_acons (key, value, alist)
     Add a new key-value pair to ALIST.  A new pair is created whose car
     is KEY and whose cdr is VALUE, and the pair is consed onto ALIST,
     and the new list is returned.  This function is _not_ destructive;
     ALIST is not modified.

 -- Scheme Procedure: assq-set! alist key val
 -- Scheme Procedure: assv-set! alist key value
 -- Scheme Procedure: assoc-set! alist key value
 -- C Function: scm_assq_set_x (alist, key, val)
 -- C Function: scm_assv_set_x (alist, key, val)
 -- C Function: scm_assoc_set_x (alist, key, val)
     Reassociate KEY in ALIST with VALUE: find any existing ALIST entry
     for KEY and associate it with the new VALUE.  If ALIST does not
     contain an entry for KEY, add a new one.  Return the (possibly new)
     alist.

     These functions do not attempt to verify the structure of ALIST,
     and so may cause unusual results if passed an object that is not an
     association list.

6.6.20.3 Retrieving Alist Entries
.................................

‘assq’, ‘assv’ and ‘assoc’ find the entry in an alist for a given key,
and return the ‘(KEY . VALUE)’ pair.  ‘assq-ref’, ‘assv-ref’ and
‘assoc-ref’ do a similar lookup, but return just the VALUE.

 -- Scheme Procedure: assq key alist
 -- Scheme Procedure: assv key alist
 -- Scheme Procedure: assoc key alist
 -- C Function: scm_assq (key, alist)
 -- C Function: scm_assv (key, alist)
 -- C Function: scm_assoc (key, alist)
     Return the first entry in ALIST with the given KEY.  The return is
     the pair ‘(KEY . VALUE)’ from ALIST.  If there's no matching entry
     the return is ‘#f’.

     ‘assq’ compares keys with ‘eq?’, ‘assv’ uses ‘eqv?’ and ‘assoc’
     uses ‘equal?’.  See also SRFI-1 which has an extended ‘assoc’
     (see SRFI-1 Association Lists).

 -- Scheme Procedure: assq-ref alist key
 -- Scheme Procedure: assv-ref alist key
 -- Scheme Procedure: assoc-ref alist key
 -- C Function: scm_assq_ref (alist, key)
 -- C Function: scm_assv_ref (alist, key)
 -- C Function: scm_assoc_ref (alist, key)
     Return the value from the first entry in ALIST with the given KEY,
     or ‘#f’ if there's no such entry.

     ‘assq-ref’ compares keys with ‘eq?’, ‘assv-ref’ uses ‘eqv?’ and
     ‘assoc-ref’ uses ‘equal?’.

     Notice these functions have the KEY argument last, like other
     ‘-ref’ functions, but this is opposite to what ‘assq’ etc above
     use.

     When the return is ‘#f’ it can be either KEY not found, or an entry
     which happens to have value ‘#f’ in the ‘cdr’.  Use ‘assq’ etc
     above if you need to differentiate these cases.

6.6.20.4 Removing Alist Entries
...............................

To remove the element from an association list whose key matches a
specified key, use ‘assq-remove!’, ‘assv-remove!’ or ‘assoc-remove!’
(depending, as usual, on the level of equality required between the key
that you specify and the keys in the association list).

   As with ‘assq-set!’ and friends, the specified alist may or may not
be modified destructively, and the only safe way to update a variable
containing the alist is to ‘set!’ it to the value that ‘assq-remove!’
and friends return.

     address-list
     ⇒
     (("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
      ("james" . "1a London Road"))

     (set! address-list (assoc-remove! address-list "mary"))
     address-list
     ⇒
     (("bob" . "11 Newington Avenue") ("james" . "1a London Road"))

   Note that, when ‘assq/v/oc-remove!’ is used to modify an association
list that has been constructed only using the corresponding
‘assq/v/oc-set!’, there can be at most one matching entry in the alist,
so the question of multiple entries being removed in one go does not
arise.  If ‘assq/v/oc-remove!’ is applied to an association list that
has been constructed using ‘acons’, or an ‘assq/v/oc-set!’ with a
different level of equality, or any mixture of these, it removes only
the first matching entry from the alist, even if the alist might contain
further matching entries.  For example:

     (define address-list '())
     (set! address-list (assq-set! address-list "mary" "11 Elm Street"))
     (set! address-list (assq-set! address-list "mary" "57 Pine Drive"))
     address-list
     ⇒
     (("mary" . "57 Pine Drive") ("mary" . "11 Elm Street"))

     (set! address-list (assoc-remove! address-list "mary"))
     address-list
     ⇒
     (("mary" . "11 Elm Street"))

   In this example, the two instances of the string "mary" are not the
same when compared using ‘eq?’, so the two ‘assq-set!’ calls add two
distinct entries to ‘address-list’.  When compared using ‘equal?’, both
"mary"s in ‘address-list’ are the same as the "mary" in the
‘assoc-remove!’ call, but ‘assoc-remove!’ stops after removing the first
matching entry that it finds, and so one of the "mary" entries is left
in place.

 -- Scheme Procedure: assq-remove! alist key
 -- Scheme Procedure: assv-remove! alist key
 -- Scheme Procedure: assoc-remove! alist key
 -- C Function: scm_assq_remove_x (alist, key)
 -- C Function: scm_assv_remove_x (alist, key)
 -- C Function: scm_assoc_remove_x (alist, key)
     Delete the first entry in ALIST associated with KEY, and return the
     resulting alist.

6.6.20.5 Sloppy Alist Functions
...............................

‘sloppy-assq’, ‘sloppy-assv’ and ‘sloppy-assoc’ behave like the
corresponding non-‘sloppy-’ procedures, except that they return ‘#f’
when the specified association list is not well-formed, where the
non-‘sloppy-’ versions would signal an error.

   Specifically, there are two conditions for which the non-‘sloppy-’
procedures signal an error, which the ‘sloppy-’ procedures handle
instead by returning ‘#f’.  Firstly, if the specified alist as a whole
is not a proper list:

     (assoc "mary" '((1 . 2) ("key" . "door") . "open sesame"))
     ⇒
     ERROR: In procedure assoc in expression (assoc "mary" (quote #)):
     ERROR: Wrong type argument in position 2 (expecting
        association list): ((1 . 2) ("key" . "door") . "open sesame")

     (sloppy-assoc "mary" '((1 . 2) ("key" . "door") . "open sesame"))
     ⇒
     #f

Secondly, if one of the entries in the specified alist is not a pair:

     (assoc 2 '((1 . 1) 2 (3 . 9)))
     ⇒
     ERROR: In procedure assoc in expression (assoc 2 (quote #)):
     ERROR: Wrong type argument in position 2 (expecting
        association list): ((1 . 1) 2 (3 . 9))

     (sloppy-assoc 2 '((1 . 1) 2 (3 . 9)))
     ⇒
     #f

   Unless you are explicitly working with badly formed association
lists, it is much safer to use the non-‘sloppy-’ procedures, because
they help to highlight coding and data errors that the ‘sloppy-’
versions would silently cover up.

 -- Scheme Procedure: sloppy-assq key alist
 -- C Function: scm_sloppy_assq (key, alist)
     Behaves like ‘assq’ but does not do any error checking.
     Recommended only for use in Guile internals.

 -- Scheme Procedure: sloppy-assv key alist
 -- C Function: scm_sloppy_assv (key, alist)
     Behaves like ‘assv’ but does not do any error checking.
     Recommended only for use in Guile internals.

 -- Scheme Procedure: sloppy-assoc key alist
 -- C Function: scm_sloppy_assoc (key, alist)
     Behaves like ‘assoc’ but does not do any error checking.
     Recommended only for use in Guile internals.

6.6.20.6 Alist Example
......................

Here is a longer example of how alists may be used in practice.

     (define capitals '(("New York" . "Albany")
                        ("Oregon"   . "Salem")
                        ("Florida"  . "Miami")))

     ;; What's the capital of Oregon?
     (assoc "Oregon" capitals)       ⇒ ("Oregon" . "Salem")
     (assoc-ref capitals "Oregon")   ⇒ "Salem"

     ;; We left out South Dakota.
     (set! capitals
           (assoc-set! capitals "South Dakota" "Pierre"))
     capitals
     ⇒ (("South Dakota" . "Pierre")
         ("New York" . "Albany")
         ("Oregon" . "Salem")
         ("Florida" . "Miami"))

     ;; And we got Florida wrong.
     (set! capitals
           (assoc-set! capitals "Florida" "Tallahassee"))
     capitals
     ⇒ (("South Dakota" . "Pierre")
         ("New York" . "Albany")
         ("Oregon" . "Salem")
         ("Florida" . "Tallahassee"))

     ;; After Oregon secedes, we can remove it.
     (set! capitals
           (assoc-remove! capitals "Oregon"))
     capitals
     ⇒ (("South Dakota" . "Pierre")
         ("New York" . "Albany")
         ("Florida" . "Tallahassee"))

6.6.21 VList-Based Hash Lists or "VHashes"
------------------------------------------

The ‘(ice-9 vlist)’ module provides an implementation of “VList-based
hash lists” (see VLists).  VList-based hash lists, or “vhashes”, are
an immutable dictionary type similar to association lists that maps
“keys” to “values”.  However, unlike association lists, accessing a
value given its key is typically a constant-time operation.

   The VHash programming interface of ‘(ice-9 vlist)’ is mostly the same
as that of association lists found in SRFI-1, with procedure names
prefixed by ‘vhash-’ instead of ‘alist-’ (see SRFI-1 Association Lists).

   In addition, vhashes can be manipulated using VList operations:

     (vlist-head (vhash-consq 'a 1 vlist-null))
     ⇒ (a . 1)

     (define vh1 (vhash-consq 'b 2 (vhash-consq 'a 1 vlist-null)))
     (define vh2 (vhash-consq 'c 3 (vlist-tail vh1)))

     (vhash-assq 'a vh2)
     ⇒ (a . 1)
     (vhash-assq 'b vh2)
     ⇒ #f
     (vhash-assq 'c vh2)
     ⇒ (c . 3)
     (vlist->list vh2)
     ⇒ ((c . 3) (a . 1))

   However, keep in mind that procedures that construct new VLists
(‘vlist-map’, ‘vlist-filter’, etc.)  return raw VLists, not vhashes:

     (define vh (alist->vhash '((a . 1) (b . 2) (c . 3)) hashq))
     (vhash-assq 'a vh)
     ⇒ (a . 1)

     (define vl
       ;; This will create a raw vlist.
       (vlist-filter (lambda (key+value) (odd? (cdr key+value))) vh))
     (vhash-assq 'a vl)
     ⇒ ERROR: Wrong type argument in position 2

     (vlist->list vl)
     ⇒ ((a . 1) (c . 3))

 -- Scheme Procedure: vhash? obj
     Return true if OBJ is a vhash.

 -- Scheme Procedure: vhash-cons key value vhash [hash-proc]
 -- Scheme Procedure: vhash-consq key value vhash
 -- Scheme Procedure: vhash-consv key value vhash
     Return a new hash list based on VHASH where KEY is associated with
     VALUE, using HASH-PROC to compute the hash of KEY.  VHASH must be
     either ‘vlist-null’ or a vhash returned by a previous call to
     ‘vhash-cons’.  HASH-PROC defaults to ‘hash’ (see ‘hash’ procedure).
     With ‘vhash-consq’, the ‘hashq’
     hash function is used; with ‘vhash-consv’ the ‘hashv’ hash function
     is used.

     All ‘vhash-cons’ calls made to construct a vhash should use the
     same HASH-PROC.  Failing to do that, the result is undefined.

 -- Scheme Procedure: vhash-assoc key vhash [equal? [hash-proc]]
 -- Scheme Procedure: vhash-assq key vhash
 -- Scheme Procedure: vhash-assv key vhash
     Return the first key/value pair from VHASH whose key is equal to
     KEY according to the EQUAL? equality predicate (which defaults to
     ‘equal?’), and using HASH-PROC (which defaults to ‘hash’) to
     compute the hash of KEY.  The second form uses ‘eq?’ as the
     equality predicate and ‘hashq’ as the hash function; the last form
     uses ‘eqv?’ and ‘hashv’.

     Note that it is important to consistently use the same hash
     function for HASH-PROC as was passed to ‘vhash-cons’.  Failing to
     do that, the result is unpredictable.

 -- Scheme Procedure: vhash-delete key vhash [equal? [hash-proc]]
 -- Scheme Procedure: vhash-delq key vhash
 -- Scheme Procedure: vhash-delv key vhash
     Remove all associations from VHASH with KEY, comparing keys with
     EQUAL? (which defaults to ‘equal?’), and computing the hash of KEY
     using HASH-PROC (which defaults to ‘hash’).  The second form uses
     ‘eq?’ as the equality predicate and ‘hashq’ as the hash function;
     the last one uses ‘eqv?’ and ‘hashv’.

     Again the choice of HASH-PROC must be consistent with previous
     calls to ‘vhash-cons’.

 -- Scheme Procedure: vhash-fold proc init vhash
 -- Scheme Procedure: vhash-fold-right proc init vhash
     Fold over the key/value elements of VHASH in the given direction,
     with each call to PROC having the form ‘(PROC key value result)’,
     where RESULT is the result of the previous call to PROC and INIT
     the value of RESULT for the first call to PROC.

 -- Scheme Procedure: vhash-fold* proc init key vhash [equal? [hash]]
 -- Scheme Procedure: vhash-foldq* proc init key vhash
 -- Scheme Procedure: vhash-foldv* proc init key vhash
     Fold over all the values associated with KEY in VHASH, with each
     call to PROC having the form ‘(proc value result)’, where RESULT is
     the result of the previous call to PROC and INIT the value of
     RESULT for the first call to PROC.

     Keys in VHASH are hashed using HASH are compared using EQUAL?.  The
     second form uses ‘eq?’ as the equality predicate and ‘hashq’ as the
     hash function; the third one uses ‘eqv?’ and ‘hashv’.

     Example:

          (define vh
            (alist->vhash '((a . 1) (a . 2) (z . 0) (a . 3))))

          (vhash-fold* cons '() 'a vh)
          ⇒ (3 2 1)

          (vhash-fold* cons '() 'z vh)
          ⇒ (0)

 -- Scheme Procedure: alist->vhash alist [hash-proc]
     Return the vhash corresponding to ALIST, an association list, using
     HASH-PROC to compute key hashes.  When omitted, HASH-PROC defaults
     to ‘hash’.

6.6.22 Hash Tables
------------------

Hash tables are dictionaries which offer similar functionality as
association lists: They provide a mapping from keys to values.  The
difference is that association lists need time linear in the size of
elements when searching for entries, whereas hash tables can normally
search in constant time.  The drawback is that hash tables require a
little bit more memory, and that you can not use the normal list
procedures (see Lists) for working with them.

6.6.22.1 Hash Table Examples
............................

For demonstration purposes, this section gives a few usage examples of
some hash table procedures, together with some explanation what they do.

   First we start by creating a new hash table with 31 slots, and
populate it with two key/value pairs.

     (define h (make-hash-table 31))

     ;; This is an opaque object
     h
     ⇒
     #<hash-table 0/31>

     ;; Inserting into a hash table can be done with hashq-set!
     (hashq-set! h 'foo "bar")
     ⇒
     "bar"

     (hashq-set! h 'braz "zonk")
     ⇒
     "zonk"

     ;; Or with hash-create-handle!
     (hashq-create-handle! h 'frob #f)
     ⇒
     (frob . #f)

   You can get the value for a given key with the procedure ‘hashq-ref’,
but the problem with this procedure is that you cannot reliably
determine whether a key does exists in the table.  The reason is that
the procedure returns ‘#f’ if the key is not in the table, but it will
return the same value if the key is in the table and just happens to
have the value ‘#f’, as you can see in the following examples.

     (hashq-ref h 'foo)
     ⇒
     "bar"

     (hashq-ref h 'frob)
     ⇒
     #f

     (hashq-ref h 'not-there)
     ⇒
     #f

   It is often better is to use the procedure ‘hashq-get-handle’, which
makes a distinction between the two cases.  Just like ‘assq’, this
procedure returns a key/value-pair on success, and ‘#f’ if the key is
not found.

     (hashq-get-handle h 'foo)
     ⇒
     (foo . "bar")

     (hashq-get-handle h 'not-there)
     ⇒
     #f

   Interesting results can be computed by using ‘hash-fold’ to work
through each element.  This example will count the total number of
elements:

     (hash-fold (lambda (key value seed) (+ 1 seed)) 0 h)
     ⇒
     3

   The same thing can be done with the procedure ‘hash-count’, which can
also count the number of elements matching a particular predicate.  For
example, count the number of elements with string values:

     (hash-count (lambda (key value) (string? value)) h)
     ⇒
     2

   Counting all the elements is a simple task using ‘const’:

     (hash-count (const #t) h)
     ⇒
     3

6.6.22.2 Hash Table Reference
.............................

Like the association list functions, the hash table functions come in
several varieties, according to the equality test used for the keys.
Plain ‘hash-’ functions use ‘equal?’, ‘hashq-’ functions use ‘eq?’,
‘hashv-’ functions use ‘eqv?’, and the ‘hashx-’ functions use an
application supplied test.

   A single ‘make-hash-table’ creates a hash table suitable for use with
any set of functions, but it's imperative that just one set is then used
consistently, or results will be unpredictable.

   Hash tables are implemented as a vector indexed by a hash value
formed from the key, with an association list of key/value pairs for
each bucket in case distinct keys hash together.  Direct access to the
pairs in those lists is provided by the ‘-handle-’ functions.

   When the number of entries in a hash table goes above a threshold,
the vector is made larger and the entries are rehashed, to prevent the
bucket lists from becoming too long and slowing down accesses.  When the
number of entries goes below a threshold, the vector is shrunk to save
space.

   For the ‘hashx-’ "extended" routines, an application supplies a HASH
function producing an integer index like ‘hashq’ etc below, and an ASSOC
alist search function like ‘assq’ etc (see Retrieving Alist Entries).
Here's an example of such functions implementing
case-insensitive hashing of string keys,

     (use-modules (srfi srfi-1)
                  (srfi srfi-13))

     (define (my-hash str size)
       (remainder (string-hash-ci str) size))
     (define (my-assoc str alist)
       (find (lambda (pair) (string-ci=? str (car pair))) alist))

     (define my-table (make-hash-table))
     (hashx-set! my-hash my-assoc my-table "foo" 123)

     (hashx-ref my-hash my-assoc my-table "FOO")
     ⇒ 123

   In a ‘hashx-’ HASH function the aim is to spread keys across the
vector, so bucket lists don't become long.  But the actual values are
arbitrary as long as they're in the range 0 to SIZE-1.  Helpful
functions for forming a hash value, in addition to ‘hashq’ etc below,
include ‘symbol-hash’ (see Symbol Keys), ‘string-hash’ and
‘string-hash-ci’ (see String Comparison), and ‘char-set-hash’ (see
Character Set Predicates/Comparison).

 -- Scheme Procedure: make-hash-table [size]
     Create a new hash table object, with an optional minimum vector
     SIZE.

     When SIZE is given, the table vector will still grow and shrink
     automatically, as described above, but with SIZE as a minimum.  If
     an application knows roughly how many entries the table will hold
     then it can use SIZE to avoid rehashing when initial entries are
     added.

 -- Scheme Procedure: alist->hash-table alist
 -- Scheme Procedure: alist->hashq-table alist
 -- Scheme Procedure: alist->hashv-table alist
 -- Scheme Procedure: alist->hashx-table hash assoc alist
     Convert ALIST into a hash table.  When keys are repeated in ALIST,
     the leftmost association takes precedence.

          (use-modules (ice-9 hash-table))
          (alist->hash-table '((foo . 1) (bar . 2)))

     When converting to an extended hash table, custom HASH and ASSOC
     procedures must be provided.

          (alist->hashx-table hash assoc '((foo . 1) (bar . 2)))

 -- Scheme Procedure: hash-table? obj
 -- C Function: scm_hash_table_p (obj)
     Return ‘#t’ if OBJ is a abstract hash table object.

 -- Scheme Procedure: hash-clear! table
 -- C Function: scm_hash_clear_x (table)
     Remove all items from TABLE (without triggering a resize).

 -- Scheme Procedure: hash-ref table key [dflt]
 -- Scheme Procedure: hashq-ref table key [dflt]
 -- Scheme Procedure: hashv-ref table key [dflt]
 -- Scheme Procedure: hashx-ref hash assoc table key [dflt]
 -- C Function: scm_hash_ref (table, key, dflt)
 -- C Function: scm_hashq_ref (table, key, dflt)
 -- C Function: scm_hashv_ref (table, key, dflt)
 -- C Function: scm_hashx_ref (hash, assoc, table, key, dflt)
     Lookup KEY in the given hash TABLE, and return the associated
     value.  If KEY is not found, return DFLT, or ‘#f’ if DFLT is not
     given.

 -- Scheme Procedure: hash-set! table key val
 -- Scheme Procedure: hashq-set! table key val
 -- Scheme Procedure: hashv-set! table key val
 -- Scheme Procedure: hashx-set! hash assoc table key val
 -- C Function: scm_hash_set_x (table, key, val)
 -- C Function: scm_hashq_set_x (table, key, val)
 -- C Function: scm_hashv_set_x (table, key, val)
 -- C Function: scm_hashx_set_x (hash, assoc, table, key, val)
     Associate VAL with KEY in the given hash TABLE.  If KEY is already
     present then it's associated value is changed.  If it's not present
     then a new entry is created.

 -- Scheme Procedure: hash-remove! table key
 -- Scheme Procedure: hashq-remove! table key
 -- Scheme Procedure: hashv-remove! table key
 -- Scheme Procedure: hashx-remove! hash assoc table key
 -- C Function: scm_hash_remove_x (table, key)
 -- C Function: scm_hashq_remove_x (table, key)
 -- C Function: scm_hashv_remove_x (table, key)
 -- C Function: scm_hashx_remove_x (hash, assoc, table, key)
     Remove any association for KEY in the given hash TABLE.  If KEY is
     not in TABLE then nothing is done.

 -- Scheme Procedure: hash key size
 -- Scheme Procedure: hashq key size
 -- Scheme Procedure: hashv key size
 -- C Function: scm_hash (key, size)
 -- C Function: scm_hashq (key, size)
 -- C Function: scm_hashv (key, size)
     Return a hash value for KEY.  This is a number in the range 0 to
     SIZE-1, which is suitable for use in a hash table of the given
     SIZE.

     Note that ‘hashq’ and ‘hashv’ may use internal addresses of
     objects, so if an object is garbage collected and re-created it can
     have a different hash value, even when the two are notionally
     ‘eq?’.  For instance with symbols,

          (hashq 'something 123)   ⇒ 19
          (gc)
          (hashq 'something 123)   ⇒ 62

     In normal use this is not a problem, since an object entered into a
     hash table won't be garbage collected until removed.  It's only if
     hashing calculations are somehow separated from normal references
     that its lifetime needs to be considered.

 -- Scheme Procedure: hash-get-handle table key
 -- Scheme Procedure: hashq-get-handle table key
 -- Scheme Procedure: hashv-get-handle table key
 -- Scheme Procedure: hashx-get-handle hash assoc table key
 -- C Function: scm_hash_get_handle (table, key)
 -- C Function: scm_hashq_get_handle (table, key)
 -- C Function: scm_hashv_get_handle (table, key)
 -- C Function: scm_hashx_get_handle (hash, assoc, table, key)
     Return the ‘(KEY . VALUE)’ pair for KEY in the given hash TABLE, or
     ‘#f’ if KEY is not in TABLE.

 -- Scheme Procedure: hash-create-handle! table key init
 -- Scheme Procedure: hashq-create-handle! table key init
 -- Scheme Procedure: hashv-create-handle! table key init
 -- Scheme Procedure: hashx-create-handle! hash assoc table key init
 -- C Function: scm_hash_create_handle_x (table, key, init)
 -- C Function: scm_hashq_create_handle_x (table, key, init)
 -- C Function: scm_hashv_create_handle_x (table, key, init)
 -- C Function: scm_hashx_create_handle_x (hash, assoc, table, key,
          init)
     Return the ‘(KEY . VALUE)’ pair for KEY in the given hash TABLE.
     If KEY is not in TABLE then create an entry for it with INIT as the
     value, and return that pair.

 -- Scheme Procedure: hash-map->list proc table
 -- Scheme Procedure: hash-for-each proc table
 -- C Function: scm_hash_map_to_list (proc, table)
 -- C Function: scm_hash_for_each (proc, table)
     Apply PROC to the entries in the given hash TABLE.  Each call is
     ‘(PROC KEY VALUE)’.  ‘hash-map->list’ returns a list of the results
     from these calls, ‘hash-for-each’ discards the results and returns
     an unspecified value.

     Calls are made over the table entries in an unspecified order, and
     for ‘hash-map->list’ the order of the values in the returned list
     is unspecified.  Results will be unpredictable if TABLE is modified
     while iterating.

     For example the following returns a new alist comprising all the
     entries from ‘mytable’, in no particular order.

          (hash-map->list cons mytable)

 -- Scheme Procedure: hash-for-each-handle proc table
 -- C Function: scm_hash_for_each_handle (proc, table)
     Apply PROC to the entries in the given hash TABLE.  Each call is
     ‘(PROC HANDLE)’, where HANDLE is a ‘(KEY . VALUE)’ pair.  Return an
     unspecified value.

     ‘hash-for-each-handle’ differs from ‘hash-for-each’ only in the
     argument list of PROC.

 -- Scheme Procedure: hash-fold proc init table
 -- C Function: scm_hash_fold (proc, init, table)
     Accumulate a result by applying PROC to the elements of the given
     hash TABLE.  Each call is ‘(PROC KEY VALUE PRIOR-RESULT)’, where
     KEY and VALUE are from the TABLE and PRIOR-RESULT is the return
     from the previous PROC call.  For the first call, PRIOR-RESULT is
     the given INIT value.

     Calls are made over the table entries in an unspecified order.
     Results will be unpredictable if TABLE is modified while
     ‘hash-fold’ is running.

     For example, the following returns a count of how many keys in
     ‘mytable’ are strings.

          (hash-fold (lambda (key value prior)
                       (if (string? key) (1+ prior) prior))
                     0 mytable)

 -- Scheme Procedure: hash-count pred table
 -- C Function: scm_hash_count (pred, table)
     Return the number of elements in the given hash TABLE that cause
     ‘(PRED KEY VALUE)’ to return true.  To quickly determine the total
     number of elements, use ‘(const #t)’ for PRED.

6.6.23 Other Types
------------------

Procedures are documented in their own section.  See Procedures.

   Variable objects are documented as part of the description of Guile's
module system: see Variables.

   See Scheduling, for discussion of threads, mutexes, and so on.

   Ports are described in the section on I/O: see Input and Output.

   Regular expressions are described in their own section: see
Regular Expressions.

   There are quite a number of additional data types documented in this
manual; if you feel a link is missing here, please file a bug.

6.7 Procedures
==============

6.7.1 Lambda: Basic Procedure Creation
--------------------------------------

A ‘lambda’ expression evaluates to a procedure.  The environment which
is in effect when a ‘lambda’ expression is evaluated is enclosed in the
newly created procedure, this is referred to as a “closure” (see About Closure).

   When a procedure created by ‘lambda’ is called with some actual
arguments, the environment enclosed in the procedure is extended by
binding the variables named in the formal argument list to new locations
and storing the actual arguments into these locations.  Then the body of
the ‘lambda’ expression is evaluated sequentially.  The result of the
last expression in the procedure body is then the result of the
procedure invocation.

   The following examples will show how procedures can be created using
‘lambda’, and what you can do with these procedures.

     (lambda (x) (+ x x))       ⇒ a procedure
     ((lambda (x) (+ x x)) 4)   ⇒ 8

   The fact that the environment in effect when creating a procedure is
enclosed in the procedure is shown with this example:

     (define add4
       (let ((x 4))
         (lambda (y) (+ x y))))
     (add4 6)                   ⇒ 10

 -- syntax: lambda formals body
     FORMALS should be a formal argument list as described in the
     following table.

     ‘(VARIABLE1 ...)’
          The procedure takes a fixed number of arguments; when the
          procedure is called, the arguments will be stored into the
          newly created location for the formal variables.
     ‘VARIABLE’
          The procedure takes any number of arguments; when the
          procedure is called, the sequence of actual arguments will be
          converted into a list and stored into the newly created
          location for the formal variable.
     ‘(VARIABLE1 ... VARIABLEN . VARIABLEN+1)’
          If a space-delimited period precedes the last variable, then
          the procedure takes N or more variables where N is the number
          of formal arguments before the period.  There must be at least
          one argument before the period.  The first N actual arguments
          will be stored into the newly allocated locations for the
          first N formal arguments and the sequence of the remaining
          actual arguments is converted into a list and the stored into
          the location for the last formal argument.  If there are
          exactly N actual arguments, the empty list is stored into the
          location of the last formal argument.

     The list in VARIABLE or VARIABLEN+1 is always newly created and the
     procedure can modify it if desired.  This is the case even when the
     procedure is invoked via ‘apply’, the required part of the list
     argument there will be copied (see Procedures for On the Fly Evaluation).

     BODY is a sequence of Scheme expressions which are evaluated in
     order when the procedure is invoked.

6.7.2 Primitive Procedures
--------------------------

Procedures written in C can be registered for use from Scheme, provided
they take only arguments of type ‘SCM’ and return ‘SCM’ values.
‘scm_c_define_gsubr’ is likely to be the most useful mechanism,
combining the process of registration (‘scm_c_make_gsubr’) and
definition (‘scm_define’).

 -- Function: SCM scm_c_make_gsubr (const char *name, int req, int opt,
          int rst, fcn)
     Register a C procedure FCN as a "subr" -- a primitive subroutine
     that can be called from Scheme.  It will be associated with the
     given NAME but no environment binding will be created.  The
     arguments REQ, OPT and RST specify the number of required, optional
     and "rest" arguments respectively.  The total number of these
     arguments should match the actual number of arguments to FCN, but
     may not exceed 10.  The number of rest arguments should be 0 or 1.
     ‘scm_c_make_gsubr’ returns a value of type ‘SCM’ which is a
     "handle" for the procedure.

 -- Function: SCM scm_c_define_gsubr (const char *name, int req, int
          opt, int rst, fcn)
     Register a C procedure FCN, as for ‘scm_c_make_gsubr’ above, and
     additionally create a top-level Scheme binding for the procedure in
     the "current environment" using ‘scm_define’.  ‘scm_c_define_gsubr’
     returns a handle for the procedure in the same way as
     ‘scm_c_make_gsubr’, which is usually not further required.

   See Foreign Functions, for another interface to call procedures
written in C from Scheme.

6.7.3 Compiled Procedures
-------------------------

The evaluation strategy given in Lambda describes how procedures
are “interpreted”.  Interpretation operates directly on expanded Scheme
source code, recursively calling the evaluator to obtain the value of
nested expressions.

   Most procedures are compiled, however.  This means that Guile has
done some pre-computation on the procedure, to determine what it will
need to do each time the procedure runs.  Compiled procedures run faster
than interpreted procedures.

   Loading files is the normal way that compiled procedures come to
being.  If Guile sees that a file is uncompiled, or that its compiled
file is out of date, it will attempt to compile the file when it is
loaded, and save the result to disk.  Procedures can be compiled at
runtime as well.  See Read/Load/Eval/Compile, for more information
on runtime compilation.

   Compiled procedures, also known as “programs”, respond to all
procedures that operate on procedures: you can pass a program to
‘procedure?’, ‘procedure-name’, and so on (see Procedure Properties).
In addition, there are a few more accessors for
low-level details on programs.

   Most people won't need to use the routines described in this section,
but it's good to have them documented.  You'll have to include the
appropriate module first, though:

     (use-modules (system vm program))

 -- Scheme Procedure: program? obj
 -- C Function: scm_program_p (obj)
     Returns ‘#t’ if OBJ is a compiled procedure, or ‘#f’ otherwise.

 -- Scheme Procedure: program-code program
 -- C Function: scm_program_code (program)
     Returns the address of the program's entry, as an integer.  This
     address is mostly useful to procedures in ‘(system vm debug)’.

 -- Scheme Procedure: program-num-free-variable program
 -- C Function: scm_program_num_free_variables (program)
     Return the number of free variables captured by this program.

 -- Scheme Procedure: program-free-variable-ref program n
 -- C Function: scm_program_free_variable-ref (program, n)
 -- Scheme Procedure: program-free-variable-set! program n val
 -- C Function: scm_program_free_variable_set_x (program, n, val)
     Accessors for a program's free variables.  Some of the values
     captured are actually in variable "boxes".  See Variables and the VM,
     for more information.

     Users must not modify the returned value unless they think they're
     really clever.

 -- Scheme Procedure: program-sources program
 -- Scheme Procedure: source:addr source
 -- Scheme Procedure: source:line source
 -- Scheme Procedure: source:column source
 -- Scheme Procedure: source:file source
     Source location annotations for programs, along with their
     accessors.

     Source location information propagates through the compiler and
     ends up being serialized to the program's metadata.  This
     information is keyed by the offset of the instruction pointer
     within the object code of the program.  Specifically, it is keyed
     on the ‘ip’ _just following_ an instruction, so that backtraces can
     find the source location of a call that is in progress.

 -- Scheme Procedure: program-arities program
 -- C Function: scm_program_arities (program)
 -- Scheme Procedure: program-arity program ip
 -- Scheme Procedure: arity:start arity
 -- Scheme Procedure: arity:end arity
 -- Scheme Procedure: arity:nreq arity
 -- Scheme Procedure: arity:nopt arity
 -- Scheme Procedure: arity:rest? arity
 -- Scheme Procedure: arity:kw arity
 -- Scheme Procedure: arity:allow-other-keys? arity
     Accessors for a representation of the "arity" of a program.

     The normal case is that a procedure has one arity.  For example,
     ‘(lambda (x) x)’, takes one required argument, and that's it.  One
     could access that number of required arguments via ‘(arity:nreq
     (program-arities (lambda (x) x)))’.  Similarly, ‘arity:nopt’ gets
     the number of optional arguments, and ‘arity:rest?’ returns a true
     value if the procedure has a rest arg.

     ‘arity:kw’ returns a list of ‘(KW . IDX)’ pairs, if the procedure
     has keyword arguments.  The IDX refers to the IDXth local variable;
     see Variables and the VM, for more information.  Finally
     ‘arity:allow-other-keys?’ returns a true value if other keys are
     allowed.  See Optional Arguments, for more information.

     So what about ‘arity:start’ and ‘arity:end’, then?  They return the
     range of bytes in the program's bytecode for which a given arity is
     valid.  You see, a procedure can actually have more than one arity.
     The question, "what is a procedure's arity" only really makes sense
     at certain points in the program, delimited by these ‘arity:start’
     and ‘arity:end’ values.

 -- Scheme Procedure: program-arguments-alist program [ip]
     Return an association list describing the arguments that PROGRAM
     accepts, or ‘#f’ if the information cannot be obtained.

     The alist keys that are currently defined are 'required',
     'optional', 'keyword', 'allow-other-keys?', and 'rest'.  For
     example:

          (program-arguments-alist
           (lambda* (a b #:optional c #:key (d 1) #:rest e)
             #t)) ⇒
          ((required . (a b))
           (optional . (c))
           (keyword . ((#:d . 4)))
           (allow-other-keys? . #f)
           (rest . d))

 -- Scheme Procedure: program-lambda-list program [ip]
     Return a representation of the arguments of PROGRAM as a lambda
     list, or ‘#f’ if this information is not available.

     For example:

          (program-lambda-list
           (lambda* (a b #:optional c #:key (d 1) #:rest e)
             #t)) ⇒

6.7.4 Optional Arguments
------------------------

Scheme procedures, as defined in R5RS, can either handle a fixed number
of actual arguments, or a fixed number of actual arguments followed by
arbitrarily many additional arguments.  Writing procedures of variable
arity can be useful, but unfortunately, the syntactic means for handling
argument lists of varying length is a bit inconvenient.  It is possible
to give names to the fixed number of arguments, but the remaining
(optional) arguments can be only referenced as a list of values (see
Lambda).

   For this reason, Guile provides an extension to ‘lambda’, ‘lambda*’,
which allows the user to define procedures with optional and keyword
arguments.  In addition, Guile's virtual machine has low-level support
for optional and keyword argument dispatch.  Calls to procedures with
optional and keyword arguments can be made cheaply, without allocating a
rest list.

6.7.4.1 lambda* and define*.
............................

‘lambda*’ is like ‘lambda’, except with some extensions to allow
optional and keyword arguments.

 -- library syntax: lambda* ([var...]
          [#:optional vardef...]
          [#:key vardef... [#:allow-other-keys]]
          [#:rest var | . var])
          body1 body2 ...

     Create a procedure which takes optional and/or keyword arguments
     specified with ‘#:optional’ and ‘#:key’.  For example,

          (lambda* (a b #:optional c d . e) '())

     is a procedure with fixed arguments A and B, optional arguments C
     and D, and rest argument E.  If the optional arguments are omitted
     in a call, the variables for them are bound to ‘#f’.

     Likewise, ‘define*’ is syntactic sugar for defining procedures
     using ‘lambda*’.

     ‘lambda*’ can also make procedures with keyword arguments.  For
     example, a procedure defined like this:

          (define* (sir-yes-sir #:key action how-high)
            (list action how-high))

     can be called as ‘(sir-yes-sir #:action 'jump)’, ‘(sir-yes-sir
     #:how-high 13)’, ‘(sir-yes-sir #:action 'lay-down #:how-high 0)’,
     or just ‘(sir-yes-sir)’.  Whichever arguments are given as keywords
     are bound to values (and those not given are ‘#f’).

     Optional and keyword arguments can also have default values to take
     when not present in a call, by giving a two-element list of
     variable name and expression.  For example in

          (define* (frob foo #:optional (bar 42) #:key (baz 73))
            (list foo bar baz))

     FOO is a fixed argument, BAR is an optional argument with default
     value 42, and baz is a keyword argument with default value 73.
     Default value expressions are not evaluated unless they are needed,
     and until the procedure is called.

     Normally it's an error if a call has keywords other than those
     specified by ‘#:key’, but adding ‘#:allow-other-keys’ to the
     definition (after the keyword argument declarations) will ignore
     unknown keywords.

     If a call has a keyword given twice, the last value is used.  For
     example,

          (define* (flips #:key (heads 0) (tails 0))
            (display (list heads tails)))

          (flips #:heads 37 #:tails 42 #:heads 99)
          ⊣ (99 42)

     ‘#:rest’ is a synonym for the dotted syntax rest argument.  The
     argument lists ‘(a . b)’ and ‘(a #:rest b)’ are equivalent in all
     respects.  This is provided for more similarity to DSSSL,
     MIT-Scheme and Kawa among others, as well as for refugees from
     other Lisp dialects.

     When ‘#:key’ is used together with a rest argument, the keyword
     parameters in a call all remain in the rest list.  This is the same
     as Common Lisp.  For example,

          ((lambda* (#:key (x 0) #:allow-other-keys #:rest r)
             (display r))
           #:x 123 #:y 456)
          ⊣ (#:x 123 #:y 456)

     ‘#:optional’ and ‘#:key’ establish their bindings successively,
     from left to right.  This means default expressions can refer back
     to prior parameters, for example

          (lambda* (start #:optional (end (+ 10 start)))
            (do ((i start (1+ i)))
                ((> i end))
              (display i)))

     The exception to this left-to-right scoping rule is the rest
     argument.  If there is a rest argument, it is bound after the
     optional arguments, but before the keyword arguments.

6.7.4.2 (ice-9 optargs)
.......................

Before Guile 2.0, ‘lambda*’ and ‘define*’ were implemented using macros
that processed rest list arguments.  This was not optimal, as calling
procedures with optional arguments had to allocate rest lists at every
procedure invocation.  Guile 2.0 improved this situation by bringing
optional and keyword arguments into Guile's core.

   However there are occasions in which you have a list and want to
parse it for optional or keyword arguments.  Guile's ‘(ice-9 optargs)’
provides some macros to help with that task.

   The syntax ‘let-optional’ and ‘let-optional*’ are for destructuring
rest argument lists and giving names to the various list elements.
‘let-optional’ binds all variables simultaneously, while ‘let-optional*’
binds them sequentially, consistent with ‘let’ and ‘let*’ (see Local Bindings).

 -- library syntax: let-optional rest-arg (binding ...) body1 body2 ...
 -- library syntax: let-optional* rest-arg (binding ...) body1 body2 ...
     These two macros give you an optional argument interface that is
     very “Schemey” and introduces no fancy syntax.  They are compatible
     with the scsh macros of the same name, but are slightly extended.
     Each of BINDING may be of one of the forms VAR or ‘(VAR
     DEFAULT-VALUE)’.  REST-ARG should be the rest-argument of the
     procedures these are used from.  The items in REST-ARG are
     sequentially bound to the variable names are given.  When REST-ARG
     runs out, the remaining vars are bound either to the default values
     or ‘#f’ if no default value was specified.  REST-ARG remains bound
     to whatever may have been left of REST-ARG.

     After binding the variables, the expressions BODY1 BODY2 ... are
     evaluated in order.

   Similarly, ‘let-keywords’ and ‘let-keywords*’ extract values from
keyword style argument lists, binding local variables to those values or
to defaults.

 -- library syntax: let-keywords args allow-other-keys? (binding ...)
          body1 body2 ...
 -- library syntax: let-keywords* args allow-other-keys? (binding ...)
          body1 body2 ...
     ARGS is evaluated and should give a list of the form ‘(#:keyword1
     value1 #:keyword2 value2 ...)’.  The BINDINGs are variables and
     default expressions, with the variables to be set (by name) from
     the keyword values.  The BODY1 BODY2 ... forms are then evaluated
     and the last is the result.  An example will make the syntax
     clearest,

          (define args '(#:xyzzy "hello" #:foo "world"))

          (let-keywords args #t
                ((foo  "default for foo")
                 (bar  (string-append "default" "for" "bar")))
            (display foo)
            (display ", ")
            (display bar))
          ⊣ world, defaultforbar

     The binding for ‘foo’ comes from the ‘#:foo’ keyword in ‘args’.
     But the binding for ‘bar’ is the default in the ‘let-keywords’,
     since there's no ‘#:bar’ in the args.

     ALLOW-OTHER-KEYS? is evaluated and controls whether unknown
     keywords are allowed in the ARGS list.  When true other keys are
     ignored (such as ‘#:xyzzy’ in the example), when ‘#f’ an error is
     thrown for anything unknown.

   ‘(ice-9 optargs)’ also provides some more ‘define*’ sugar, which is
not so useful with modern Guile coding, but still supported:
‘define*-public’ is the ‘lambda*’ version of ‘define-public’;
‘defmacro*’ and ‘defmacro*-public’ exist for defining macros with the
improved argument list handling possibilities.  The ‘-public’ versions
not only define the procedures/macros, but also export them from the
current module.

 -- library syntax: define*-public formals body1 body2 ...
     Like a mix of ‘define*’ and ‘define-public’.

 -- library syntax: defmacro* name formals body1 body2 ...
 -- library syntax: defmacro*-public name formals body1 body2 ...
     These are just like ‘defmacro’ and ‘defmacro-public’ except that
     they take ‘lambda*’-style extended parameter lists, where
     ‘#:optional’, ‘#:key’, ‘#:allow-other-keys’ and ‘#:rest’ are
     allowed with the usual semantics.  Here is an example of a macro
     with an optional argument:

          (defmacro* transmogrify (a #:optional b)
            (a 1))

6.7.5 Case-lambda
-----------------

R5RS's rest arguments are indeed useful and very general, but they often
aren't the most appropriate or efficient means to get the job done.  For
example, ‘lambda*’ is a much better solution to the optional argument
problem than ‘lambda’ with rest arguments.

   Likewise, ‘case-lambda’ works well for when you want one procedure to
do double duty (or triple, or ...), without the penalty of consing a
rest list.

   For example:

     (define (make-accum n)
       (case-lambda
         (() n)
         ((m) (set! n (+ n m)) n)))

     (define a (make-accum 20))
     (a) ⇒ 20
     (a 10) ⇒ 30
     (a) ⇒ 30

   The value returned by a ‘case-lambda’ form is a procedure which
matches the number of actual arguments against the formals in the
various clauses, in order.  The first matching clause is selected, the
corresponding values from the actual parameter list are bound to the
variable names in the clauses and the body of the clause is evaluated.
If no clause matches, an error is signaled.

   The syntax of the ‘case-lambda’ form is defined in the following EBNF
grammar.  “Formals” means a formal argument list just like with ‘lambda’
(see Lambda).

     <case-lambda>
        --> (case-lambda <case-lambda-clause>*)
        --> (case-lambda <docstring> <case-lambda-clause>*)
     <case-lambda-clause>
        --> (<formals> <definition-or-command>*)
     <formals>
        --> (<identifier>*)
          | (<identifier>* . <identifier>)
          | <identifier>

   Rest lists can be useful with ‘case-lambda’:

     (define plus
       (case-lambda
         "Return the sum of all arguments."
         (() 0)
         ((a) a)
         ((a b) (+ a b))
         ((a b . rest) (apply plus (+ a b) rest))))
     (plus 1 2 3) ⇒ 6

   Also, for completeness.  Guile defines ‘case-lambda*’ as well, which
is like ‘case-lambda’, except with ‘lambda*’ clauses.  A ‘case-lambda*’
clause matches if the arguments fill the required arguments, but are not
too many for the optional and/or rest arguments.

   Keyword arguments are possible with ‘case-lambda*’ as well, but they
do not contribute to the "matching" behavior, and their interactions
with required, optional, and rest arguments can be surprising.

   For the purposes of ‘case-lambda*’ (and of ‘case-lambda’, as a
special case), a clause “matches” if it has enough required arguments,
and not too many positional arguments.  The required arguments are any
arguments before the ‘#:optional’, ‘#:key’, and ‘#:rest’ arguments.
“Positional” arguments are the required arguments, together with the
optional arguments.

   In the absence of ‘#:key’ or ‘#:rest’ arguments, it's easy to see how
there could be too many positional arguments: you pass 5 arguments to a
function that only takes 4 arguments, including optional arguments.  If
there is a ‘#:rest’ argument, there can never be too many positional
arguments: any application with enough required arguments for a clause
will match that clause, even if there are also ‘#:key’ arguments.

   Otherwise, for applications to a clause with ‘#:key’ arguments (and
without a ‘#:rest’ argument), a clause will match there only if there
are enough required arguments and if the next argument after binding
required and optional arguments, if any, is a keyword.  For efficiency
reasons, Guile is currently unable to include keyword arguments in the
matching algorithm.  Clauses match on positional arguments only, not by
comparing a given keyword to the available set of keyword arguments that
a function has.

   Some examples follow.

     (define f
       (case-lambda*
         ((a #:optional b) 'clause-1)
         ((a #:optional b #:key c) 'clause-2)
         ((a #:key d) 'clause-3)
         ((#:key e #:rest f) 'clause-4)))

     (f) ⇒ clause-4
     (f 1) ⇒ clause-1
     (f) ⇒ clause-4
     (f #:e 10) clause-1
     (f 1 #:foo) clause-1
     (f 1 #:c 2) clause-2
     (f #:a #:b #:c #:d #:e) clause-4

     ;; clause-2 will match anything that clause-3 would match.
     (f 1 #:d 2) ⇒ error: bad keyword args in clause 2

   Don't forget that the clauses are matched in order, and the first
matching clause will be taken.  This can result in a keyword being bound
to a required argument, as in the case of ‘f #:e 10’.

6.7.6 Higher-Order Functions
----------------------------

As a functional programming language, Scheme allows the definition of
“higher-order functions”, i.e., functions that take functions as
arguments and/or return functions.  Utilities to derive procedures from
other procedures are provided and described below.

 -- Scheme Procedure: const value
     Return a procedure that accepts any number of arguments and returns
     VALUE.

          (procedure? (const 3))        ⇒ #t
          ((const 'hello))              ⇒ hello
          ((const 'hello) 'world)       ⇒ hello

 -- Scheme Procedure: negate proc
     Return a procedure with the same arity as PROC that returns the
     ‘not’ of PROC's result.

          (procedure? (negate number?)) ⇒ #t
          ((negate odd?) 2)             ⇒ #t
          ((negate real?) 'dream)       ⇒ #t
          ((negate string-prefix?) "GNU" "GNU Guile")
                                        ⇒ #f
          (filter (negate number?) '(a 2 "b"))
                                        ⇒ (a "b")

 -- Scheme Procedure: compose proc1 proc2 ...
     Compose PROC1 with the procedures PROC2 ... such that the last PROC
     argument is applied first and PROC1 last, and return the resulting
     procedure.  The given procedures must have compatible arity.

          (procedure? (compose 1+ 1-)) ⇒ #t
          ((compose sqrt 1+ 1+) 2)     ⇒ 2.0
          ((compose 1+ sqrt) 3)        ⇒ 2.73205080756888
          (eq? (compose 1+) 1+)        ⇒ #t

          ((compose zip unzip2) '((1 2) (a b)))
                                       ⇒ ((1 2) (a b))

 -- Scheme Procedure: identity x
     Return X.

 -- Scheme Procedure: and=> value proc
     When VALUE is ‘#f’, return ‘#f’.  Otherwise, return ‘(PROC VALUE)’.

6.7.7 Procedure Properties and Meta-information
-----------------------------------------------

In addition to the information that is strictly necessary to run,
procedures may have other associated information.  For example, the name
of a procedure is information not for the procedure, but about the
procedure.  This meta-information can be accessed via the procedure
properties interface.

 -- Scheme Procedure: procedure? obj
 -- C Function: scm_procedure_p (obj)
     Return ‘#t’ if OBJ is a procedure.

 -- Scheme Procedure: thunk? obj
 -- C Function: scm_thunk_p (obj)
     Return ‘#t’ if OBJ is a procedure that can be called with zero
     arguments.  See Compiled Procedures, to get more information on
     what arguments a procedure will accept.

   Procedure properties are general properties associated with
procedures.  These can be the name of a procedure or other relevant
information, such as debug hints.

   The most general way to associate a property of a procedure is
programmatically:

 -- Scheme Procedure: procedure-property proc key
 -- C Function: scm_procedure_property (proc, key)
     Return the property of PROC with name KEY, or ‘#f’ if not found.

 -- Scheme Procedure: set-procedure-property! proc key value
 -- C Function: scm_set_procedure_property_x (proc, key, value)
     Set PROC's property named KEY to VALUE.

   However, there is a more efficient interface that allows constant
properties to be embedded into compiled binaries in a way that does not
incur any overhead until someone asks for the property: initial non-tail
elements of the body of a lambda expression that are literal vectors of
pairs are interpreted as declaring procedure properties.  This is
easiest to see with an example:

     (define proc
       (lambda args
         #((a . "hey") (b . "ho")) ;; procedure properties!
         42))
     (procedure-property proc 'a) ; ⇒ "hey"
     (procedure-property proc 'b) ; ⇒ "ho"

   There is a shorthand for declaring the ‘documentation’ property,
which is a literal string instead of a literal vector:

     (define proc
       (lambda args
         "This is a docstring."
         42))
     (procedure-property proc 'documentation)
     ;; ⇒ "This is a docstring."

   Calling ‘procedure-property’ with a key of ‘documentation’ is exactly
the same as calling ‘procedure-documentation’.  Similarly,
‘procedure-name’ is the same as the ‘name’ procedure property, and
‘procedure-source’ is for the ‘source’ property.

 -- Scheme Procedure: procedure-name proc
 -- C Function: scm_procedure_name (proc)
 -- Scheme Procedure: procedure-source proc
 -- C Function: scm_procedure_source (proc)
 -- Scheme Procedure: procedure-documentation proc
 -- C Function: scm_procedure_documentation (proc)
     Return the value of the ‘name’, ‘source’, or ‘documentation’
     property for PROC, or ‘#f’ if no property is set.

   One can also work on the entire set of procedure properties.

 -- Scheme Procedure: procedure-properties proc
 -- C Function: scm_procedure_properties (proc)
     Return the properties associated with PROC, as an association list.

 -- Scheme Procedure: set-procedure-properties! proc alist
 -- C Function: scm_set_procedure_properties_x (proc, alist)
     Set PROC's property list to ALIST.

6.7.8 Procedures with Setters
-----------------------------

A “procedure with setter” is a special kind of procedure which normally
behaves like any accessor procedure, that is a procedure which accesses
a data structure.  The difference is that this kind of procedure has a
so-called “setter” attached, which is a procedure for storing something
into a data structure.

   Procedures with setters are treated specially when the procedure
appears in the special form ‘set!’.  How it works is best shown by
example.

   Suppose we have a procedure called ‘foo-ref’, which accepts two
arguments, a value of type ‘foo’ and an integer.  The procedure returns
the value stored at the given index in the ‘foo’ object.  Let ‘f’ be a
variable containing such a ‘foo’ data structure.(1)

     (foo-ref f 0)       ⇒ bar
     (foo-ref f 1)       ⇒ braz

   Also suppose that a corresponding setter procedure called ‘foo-set!’
does exist.

     (foo-set! f 0 'bla)
     (foo-ref f 0)       ⇒ bla

   Now we could create a new procedure called ‘foo’, which is a
procedure with setter, by calling ‘make-procedure-with-setter’ with the
accessor and setter procedures ‘foo-ref’ and ‘foo-set!’.  Let us call
this new procedure ‘foo’.

     (define foo (make-procedure-with-setter foo-ref foo-set!))

   ‘foo’ can from now on be used to either read from the data structure
stored in ‘f’, or to write into the structure.

     (set! (foo f 0) 'dum)
     (foo f 0)          ⇒ dum

 -- Scheme Procedure: make-procedure-with-setter procedure setter
 -- C Function: scm_make_procedure_with_setter (procedure, setter)
     Create a new procedure which behaves like PROCEDURE, but with the
     associated setter SETTER.

 -- Scheme Procedure: procedure-with-setter? obj
 -- C Function: scm_procedure_with_setter_p (obj)
     Return ‘#t’ if OBJ is a procedure with an associated setter
     procedure.

 -- Scheme Procedure: procedure proc
 -- C Function: scm_procedure (proc)
     Return the procedure of PROC, which must be an applicable struct.

 -- Scheme Procedure: setter proc
     Return the setter of PROC, which must be either a procedure with
     setter or an operator struct.

   ---------- Footnotes ----------

   (1) Working definitions would be:
     (define foo-ref vector-ref)
     (define foo-set! vector-set!)
     (define f (make-vector 2 #f))

6.7.9 Inlinable Procedures
--------------------------

You can define an “inlinable procedure” by using ‘define-inlinable’
instead of ‘define’.  An inlinable procedure behaves the same as a
regular procedure, but direct calls will result in the procedure body
being inlined into the caller.

   Bear in mind that starting from version 2.0.3, Guile has a partial
evaluator that can inline the body of inner procedures when deemed
appropriate:

     scheme@(guile-user)> ,optimize (define (foo x)
                                      (define (bar) (+ x 3))
                                      (* (bar) 2))
     $1 = (define foo
            (lambda (#{x 94}#) (* (+ #{x 94}# 3) 2)))

The partial evaluator does not inline top-level bindings, though, so
this is a situation where you may find it interesting to use
‘define-inlinable’.

   Procedures defined with ‘define-inlinable’ are _always_ inlined, at
all direct call sites.  This eliminates function call overhead at the
expense of an increase in code size.  Additionally, the caller will not
transparently use the new definition if the inline procedure is
redefined.  It is not possible to trace an inlined procedures or install
a breakpoint in it (see Traps).  For these reasons, you should not
make a procedure inlinable unless it demonstrably improves performance
in a crucial way.

   In general, only small procedures should be considered for inlining,
as making large procedures inlinable will probably result in an increase
in code size.  Additionally, the elimination of the call overhead rarely
matters for large procedures.

 -- Scheme Syntax: define-inlinable (name parameter ...) body1 body2 ...
     Define NAME as a procedure with parameters PARAMETERs and bodies
     BODY1, BODY2, ....

6.8 Macros
==========

At its best, programming in Lisp is an iterative process of building up
a language appropriate to the problem at hand, and then solving the
problem in that language.  Defining new procedures is part of that, but
Lisp also allows the user to extend its syntax, with its famous
“macros”.

   Macros are syntactic extensions which cause the expression that they
appear in to be transformed in some way _before_ being evaluated.  In
expressions that are intended for macro transformation, the identifier
that names the relevant macro must appear as the first element, like
this:

     (MACRO-NAME MACRO-ARGS ...)

   Macro expansion is a separate phase of evaluation, run before code is
interpreted or compiled.  A macro is a program that runs on programs,
translating an embedded language into core Scheme(1).

   ---------- Footnotes ----------

   (1) These days such embedded languages are often referred to as
“embedded domain-specific languages”, or EDSLs.

6.8.1 Defining Macros
---------------------

A macro is a binding between a keyword and a syntax transformer.  Since
it's difficult to discuss ‘define-syntax’ without discussing the format
of transformers, consider the following example macro definition:

     (define-syntax when
       (syntax-rules ()
         ((when condition exp ...)
          (if condition
              (begin exp ...)))))

     (when #t
       (display "hey ho\n")
       (display "let's go\n"))
     ⊣ hey ho
     ⊣ let's go

   In this example, the ‘when’ binding is bound with ‘define-syntax’.
Syntax transformers are discussed in more depth in Syntax Rules
and Syntax Case.

 -- Syntax: define-syntax keyword transformer
     Bind KEYWORD to the syntax transformer obtained by evaluating
     TRANSFORMER.

     After a macro has been defined, further instances of KEYWORD in
     Scheme source code will invoke the syntax transformer defined by
     TRANSFORMER.

   One can also establish local syntactic bindings with ‘let-syntax’.

 -- Syntax: let-syntax ((keyword transformer) ...) exp1 exp2 ...
     Bind each KEYWORD to its corresponding TRANSFORMER while expanding
     EXP1 EXP2 ....

     A ‘let-syntax’ binding only exists at expansion-time.

          (let-syntax ((unless
                        (syntax-rules ()
                          ((unless condition exp ...)
                           (if (not condition)
                               (begin exp ...))))))
            (unless #t
              (primitive-exit 1))
            "rock rock rock")
          ⇒ "rock rock rock"

   A ‘define-syntax’ form is valid anywhere a definition may appear: at
the top-level, or locally.  Just as a local ‘define’ expands out to an
instance of ‘letrec’, a local ‘define-syntax’ expands out to
‘letrec-syntax’.

 -- Syntax: letrec-syntax ((keyword transformer) ...) exp1 exp2 ...
     Bind each KEYWORD to its corresponding TRANSFORMER while expanding
     EXP1 EXP2 ....

     In the spirit of ‘letrec’ versus ‘let’, an expansion produced by
     TRANSFORMER may reference a KEYWORD bound by the same
     LETREC-SYNTAX.

          (letrec-syntax ((my-or
                           (syntax-rules ()
                             ((my-or)
                              #t)
                             ((my-or exp)
                              exp)
                             ((my-or exp rest ...)
                              (let ((t exp))
                                (if t
                                    t
                                    (my-or rest ...)))))))
            (my-or #f "rockaway beach"))
          ⇒ "rockaway beach"

6.8.2 Syntax-rules Macros
-------------------------

‘syntax-rules’ macros are simple, pattern-driven syntax transformers,
with a beauty worthy of Scheme.

 -- Syntax: syntax-rules literals (pattern template) ...
     Create a syntax transformer that will rewrite an expression using
     the rules embodied in the PATTERN and TEMPLATE clauses.

   A ‘syntax-rules’ macro consists of three parts: the literals (if
any), the patterns, and as many templates as there are patterns.

   When the syntax expander sees the invocation of a ‘syntax-rules’
macro, it matches the expression against the patterns, in order, and
rewrites the expression using the template from the first matching
pattern.  If no pattern matches, a syntax error is signaled.

6.8.2.1 Patterns
................

We have already seen some examples of patterns in the previous section:
‘(unless condition exp ...)’, ‘(my-or exp)’, and so on.  A pattern is
structured like the expression that it is to match.  It can have nested
structure as well, like ‘(let ((var val) ...) exp exp* ...)’.  Broadly
speaking, patterns are made of lists, improper lists, vectors,
identifiers, and datums.  Users can match a sequence of patterns using
the ellipsis (‘...’).

   Identifiers in a pattern are called “literals” if they are present in
the ‘syntax-rules’ literals list, and “pattern variables” otherwise.
When building up the macro output, the expander replaces instances of a
pattern variable in the template with the matched subexpression.

     (define-syntax kwote
       (syntax-rules ()
         ((kwote exp)
          (quote exp))))
     (kwote (foo . bar))
     ⇒ (foo . bar)

   An improper list of patterns matches as rest arguments do:

     (define-syntax let1
       (syntax-rules ()
         ((_ (var val) . exps)
          (let ((var val)) . exps))))

   However this definition of ‘let1’ probably isn't what you want, as
the tail pattern EXPS will match non-lists, like ‘(let1 (foo 'bar) .
baz)’.  So often instead of using improper lists as patterns, ellipsized
patterns are better.  Instances of a pattern variable in the template
must be followed by an ellipsis.

     (define-syntax let1
       (syntax-rules ()
         ((_ (var val) exp ...)
          (let ((var val)) exp ...))))

   This ‘let1’ probably still doesn't do what we want, because the body
matches sequences of zero expressions, like ‘(let1 (foo 'bar))’.  In
this case we need to assert we have at least one body expression.  A
common idiom for this is to name the ellipsized pattern variable with an
asterisk:

     (define-syntax let1
       (syntax-rules ()
         ((_ (var val) exp exp* ...)
          (let ((var val)) exp exp* ...))))

   A vector of patterns matches a vector whose contents match the
patterns, including ellipsizing and tail patterns.

     (define-syntax letv
       (syntax-rules ()
         ((_ #((var val) ...) exp exp* ...)
          (let ((var val) ...) exp exp* ...))))
     (letv #((foo 'bar)) foo)
     ⇒ bar

   Literals are used to match specific datums in an expression, like the
use of ‘=>’ and ‘else’ in ‘cond’ expressions.

     (define-syntax cond1
       (syntax-rules (=> else)
         ((cond1 test => fun)
          (let ((exp test))
            (if exp (fun exp) #f)))
         ((cond1 else exp exp* ...)
          (begin exp exp* ...))
         ((cond1 test exp exp* ...)
          (if test (begin exp exp* ...)))))

     (define (square x) (* x x))
     (cond1 10 => square)
     ⇒ 100
     (let ((=> #t))
       (cond1 10 => square))
     ⇒ #<procedure square (x)>

   A literal matches an input expression if the input expression is an
identifier with the same name as the literal, and both are unbound(1).

   Although literals can be unbound, usually they are bound to allow
them to be imported, exported, and renamed.  See Modules, for more
information on imports and exports.  In Guile there are a few standard
auxiliary syntax definitions, as specified by R6RS and R7RS:

 -- Scheme Syntax: else
 -- Scheme Syntax: =>
 -- Scheme Syntax: _
 -- Scheme Syntax: ...
     Auxiliary syntax definitions.

     These are defined with a macro that never matches, e.g.:

          (define-syntax else (syntax-rules ()))

   If a pattern is not a list, vector, or an identifier, it matches as a
literal, with ‘equal?’.

     (define-syntax define-matcher-macro
       (syntax-rules ()
         ((_ name lit)
          (define-syntax name
            (syntax-rules ()
             ((_ lit) #t)
             ((_ else) #f))))))

     (define-matcher-macro is-literal-foo? "foo")

     (is-literal-foo? "foo")
     ⇒ #t
     (is-literal-foo? "bar")
     ⇒ #f
     (let ((foo "foo"))
       (is-literal-foo? foo))
     ⇒ #f

   The last example indicates that matching happens at expansion-time,
not at run-time.

   Syntax-rules macros are always used as ‘(MACRO . ARGS)’, and the
MACRO will always be a symbol.  Correspondingly, a ‘syntax-rules’
pattern must be a list (proper or improper), and the first pattern in
that list must be an identifier.  Incidentally it can be any identifier
- it doesn't have to actually be the name of the macro.  Thus the
following three are equivalent:

     (define-syntax when
       (syntax-rules ()
         ((when c e ...)
          (if c (begin e ...)))))

     (define-syntax when
       (syntax-rules ()
         ((_ c e ...)
          (if c (begin e ...)))))

     (define-syntax when
       (syntax-rules ()
         ((something-else-entirely c e ...)
          (if c (begin e ...)))))

   For clarity, use one of the first two variants.  Also note that since
the pattern variable will always match the macro itself (e.g., ‘cond1’),
it is actually left unbound in the template.

6.8.2.2 Hygiene
...............

‘syntax-rules’ macros have a magical property: they preserve referential
transparency.  When you read a macro definition, any free bindings in
that macro are resolved relative to the macro definition; and when you
read a macro instantiation, all free bindings in that expression are
resolved relative to the expression.

   This property is sometimes known as “hygiene”, and it does aid in
code cleanliness.  In your macro definitions, you can feel free to
introduce temporary variables, without worrying about inadvertently
introducing bindings into the macro expansion.

   Consider the definition of ‘my-or’ from the previous section:

     (define-syntax my-or
       (syntax-rules ()
         ((my-or)
          #t)
         ((my-or exp)
          exp)
         ((my-or exp rest ...)
          (let ((t exp))
            (if t
                t
                (my-or rest ...))))))

   A naive expansion of ‘(let ((t #t)) (my-or #f t))’ would yield:

     (let ((t #t))
       (let ((t #f))
         (if t t t)))
     ⇒ #f

Which clearly is not what we want.  Somehow the ‘t’ in the definition is
distinct from the ‘t’ at the site of use; and it is indeed this
distinction that is maintained by the syntax expander, when expanding
hygienic macros.

   This discussion is mostly relevant in the context of traditional Lisp
macros (see Defmacros), which do not preserve referential
transparency.  Hygiene adds to the expressive power of Scheme.

6.8.2.3 Shorthands
..................

One often ends up writing simple one-clause ‘syntax-rules’ macros.
There is a convenient shorthand for this idiom, in the form of
‘define-syntax-rule’.

 -- Syntax: define-syntax-rule (keyword . pattern) [docstring] template
     Define KEYWORD as a new ‘syntax-rules’ macro with one clause.

   Cast into this form, our ‘when’ example is significantly shorter:

     (define-syntax-rule (when c e ...)
       (if c (begin e ...)))

6.8.2.4 Reporting Syntax Errors in Macros
.........................................

 -- Syntax: syntax-error message [arg ...]
     Report an error at macro-expansion time.  MESSAGE must be a string
     literal, and the optional ARG operands can be arbitrary expressions
     providing additional information.

   ‘syntax-error’ is intended to be used within ‘syntax-rules’
templates.  For example:

     (define-syntax simple-let
       (syntax-rules ()
         ((_ (head ... ((x . y) val) . tail)
             body1 body2 ...)
          (syntax-error
           "expected an identifier but got"
           (x . y)))
         ((_ ((name val) ...) body1 body2 ...)
          ((lambda (name ...) body1 body2 ...)
           val ...))))

6.8.2.5 Specifying a Custom Ellipsis Identifier
...............................................

When writing macros that generate macro definitions, it is convenient to
use a different ellipsis identifier at each level.  Guile allows the
desired ellipsis identifier to be specified as the first operand to
‘syntax-rules’, as specified by SRFI-46 and R7RS. For example:

     (define-syntax define-quotation-macros
       (syntax-rules ()
         ((_ (macro-name head-symbol) ...)
          (begin (define-syntax macro-name
                   (syntax-rules ::: ()
                     ((_ x :::)
                      (quote (head-symbol x :::)))))
                 ...))))
     (define-quotation-macros (quote-a a) (quote-b b) (quote-c c))
     (quote-a 1 2 3) ⇒ (a 1 2 3)

6.8.2.6 Further Information
...........................

For a formal definition of ‘syntax-rules’ and its pattern language, see
Macros (r5rs).

   ‘syntax-rules’ macros are simple and clean, but do they have
limitations.  They do not lend themselves to expressive error messages:
patterns either match or they don't.  Their ability to generate code is
limited to template-driven expansion; often one needs to define a number
of helper macros to get real work done.  Sometimes one wants to
introduce a binding into the lexical context of the generated code; this
is impossible with ‘syntax-rules’.  Relatedly, they cannot
programmatically generate identifiers.

   The solution to all of these problems is to use ‘syntax-case’ if you
need its features.  But if for some reason you're stuck with
‘syntax-rules’, you might enjoy Joe Marshall's ‘syntax-rules’ Primer for
the Merely Eccentric (https://web.archive.org/web/20121111060531/
https://d655165b-a-62cb3a1a-s-sites.googlegroups.com/site/evalapply/
eccentric.txt?attachauth=ANoY7cqZJK0iAkVoFlTZqjKSFX1rW6pgA71to347P957URfJwmFRH
5Yyddp6gASBSaG38_9MfSlq59KN5Ozzja0WMVuHWi5a_bfGeJHv13bfhYbtwA8WcVHaL_xTA5AvlLH
__qHKE2UVPj2qrWYyrcBCx3ihmR8CWUfyo8D4GbdvFGkNon3owtrR_CL_wbPr7VGE_8Gq0aJp7tWGt
tZSjip9rySlqAO4aQ%3D%3D&attredirects=0).(2)

   ---------- Footnotes ----------

   (1) Language lawyers probably see the need here for use of
‘literal-identifier=?’ rather than ‘free-identifier=?’, and would
probably be correct.  Patches accepted.

   (2) Archived from the original
(http://sites.google.com/site/evalapply/eccentric.txt) on 2013-05-03.

6.8.3 Support for the ‘syntax-case’ System
------------------------------------------

‘syntax-case’ macros are procedural syntax transformers, with a power
worthy of Scheme.

 -- Syntax: syntax-case syntax literals (pattern [guard] exp) ...
     Match the syntax object SYNTAX against the given patterns, in
     order.  If a PATTERN matches, return the result of evaluating the
     associated EXP.

   Compare the following definitions of ‘when’:

     (define-syntax when
       (syntax-rules ()
         ((_ test e e* ...)
          (if test (begin e e* ...)))))

     (define-syntax when
       (lambda (x)
         (syntax-case x ()
           ((_ test e e* ...)
            #'(if test (begin e e* ...))))))

   Clearly, the ‘syntax-case’ definition is similar to its
‘syntax-rules’ counterpart, and equally clearly there are some
differences.  The ‘syntax-case’ definition is wrapped in a ‘lambda’, a
function of one argument; that argument is passed to the ‘syntax-case’
invocation; and the "return value" of the macro has a ‘#'’ prefix.

   All of these differences stem from the fact that ‘syntax-case’ does
not define a syntax transformer itself - instead, ‘syntax-case’
expressions provide a way to destructure a “syntax object”, and to
rebuild syntax objects as output.

   So the ‘lambda’ wrapper is simply a leaky implementation detail, that
syntax transformers are just functions that transform syntax to syntax.
This should not be surprising, given that we have already described
macros as "programs that write programs".  ‘syntax-case’ is simply a way
to take apart and put together program text, and to be a valid syntax
transformer it needs to be wrapped in a procedure.

   Unlike traditional Lisp macros (see Defmacros), ‘syntax-case’
macros transform syntax objects, not raw Scheme forms.  Recall the naive
expansion of ‘my-or’ given in the previous section:

     (let ((t #t))
       (my-or #f t))
     ;; naive expansion:
     (let ((t #t))
       (let ((t #f))
         (if t t t)))

   Raw Scheme forms simply don't have enough information to distinguish
the first two ‘t’ instances in ‘(if t t t)’ from the third ‘t’.  So
instead of representing identifiers as symbols, the syntax expander
represents identifiers as annotated syntax objects, attaching such
information to those syntax objects as is needed to maintain referential
transparency.

 -- Syntax: syntax form
     Create a syntax object wrapping FORM within the current lexical
     context.

   Syntax objects are typically created internally to facilitate the
process of expansion, but it is possible to create them outside of
syntax expansion:

     (syntax (foo bar baz))
     ⇒ #<some representation of that syntax>

However it is more common, and useful, to create syntax objects when
building output from a ‘syntax-case’ expression.

     (define-syntax add1
       (lambda (x)
         (syntax-case x ()
           ((_ exp)
            (syntax (+ exp 1))))))

   It is not strictly necessary for a ‘syntax-case’ expression to return
a syntax object, because ‘syntax-case’ expressions can be used in helper
functions, or otherwise used outside of syntax expansion itself.
However a syntax transformer procedure must return a syntax object, so
most uses of ‘syntax-case’ do end up returning syntax objects.

   Here in this case, the form that built the return value was ‘(syntax
(+ exp 1))’.  The interesting thing about this is that within a ‘syntax’
expression, any appearance of a pattern variable is substituted into the
resulting syntax object, carrying with it all relevant metadata from the
source expression, such as lexical identity and source location.

   Indeed, a pattern variable may only be referenced from inside a
‘syntax’ form.  The syntax expander would raise an error when defining
‘add1’ if it found EXP referenced outside a ‘syntax’ form.

   Since ‘syntax’ appears frequently in macro-heavy code, it has a
special reader macro: ‘#'’.  ‘#'foo’ is transformed by the reader into
‘(syntax foo)’, just as ‘'foo’ is transformed into ‘(quote foo)’.

   The pattern language used by ‘syntax-case’ is conveniently the same
language used by ‘syntax-rules’.  Given this, Guile actually defines
‘syntax-rules’ in terms of ‘syntax-case’:

     (define-syntax syntax-rules
       (lambda (x)
         (syntax-case x ()
           ((_ (k ...) ((keyword . pattern) template) ...)
            #'(lambda (x)
                (syntax-case x (k ...)
                  ((dummy . pattern) #'template)
                  ...))))))

   And that's that.

6.8.3.1 Why ‘syntax-case’?
..........................

The examples we have shown thus far could just as well have been
expressed with ‘syntax-rules’, and have just shown that ‘syntax-case’ is
more verbose, which is true.  But there is a difference: ‘syntax-case’
creates _procedural_ macros, giving the full power of Scheme to the
macro expander.  This has many practical applications.

   A common desire is to be able to match a form only if it is an
identifier.  This is impossible with ‘syntax-rules’, given the datum
matching forms.  But with ‘syntax-case’ it is easy:

 -- Scheme Procedure: identifier? syntax-object
     Returns ‘#t’ if SYNTAX-OBJECT is an identifier, or ‘#f’ otherwise.

     ;; relying on previous add1 definition
     (define-syntax add1!
       (lambda (x)
         (syntax-case x ()
           ((_ var) (identifier? #'var)
            #'(set! var (add1 var))))))

     (define foo 0)
     (add1! foo)
     foo ⇒ 1
     (add1! "not-an-identifier") ⇒ error

   With ‘syntax-rules’, the error for ‘(add1! "not-an-identifier")’
would be something like "invalid ‘set!’".  With ‘syntax-case’, it will
say something like "invalid ‘add1!’", because we attach the “guard
clause” to the pattern: ‘(identifier? #'var)’.  This becomes more
important with more complicated macros.  It is necessary to use
‘identifier?’, because to the expander, an identifier is more than a
bare symbol.

   Note that even in the guard clause, we reference the VAR pattern
variable within a ‘syntax’ form, via ‘#'var’.

   Another common desire is to introduce bindings into the lexical
context of the output expression.  One example would be in the so-called
"anaphoric macros", like ‘aif’.  Anaphoric macros bind some expression
to a well-known identifier, often ‘it’, within their bodies.  For
example, in ‘(aif (foo) (bar it))’, ‘it’ would be bound to the result of
‘(foo)’.

   To begin with, we should mention a solution that doesn't work:

     ;; doesn't work
     (define-syntax aif
       (lambda (x)
         (syntax-case x ()
           ((_ test then else)
            #'(let ((it test))
                (if it then else))))))

   The reason that this doesn't work is that, by default, the expander
will preserve referential transparency; the THEN and ELSE expressions
won't have access to the binding of ‘it’.

   But they can, if we explicitly introduce a binding via
‘datum->syntax’.

 -- Scheme Procedure: datum->syntax template-id datum [#:source=#f]
     Create a syntax object that wraps DATUM, within the lexical context
     corresponding to the identifier TEMPLATE-ID.  If TEMPLATE-ID is
     false, the datum will have no lexical context information.

     Syntax objects have an associated source location.  Internally this
     is represented as a 3-element vector of filename, line, and column.
     Usually this location ultimately is provided by ‘read-syntax’;
     see Annotated Scheme Read.

     If a syntax object is passed as SOURCE, the resulting syntax object
     will have the source location of SOURCE.  Otherwise if SOURCE is a
     3-element source location vector, that vector will be the source
     location of the resulting syntax object.  If SOURCE is a source
     properties alist, those will be parsed and set as the source
     location of the resulting syntax object.  Otherwise if SOURCE is
     false, the source properties are looked up from ‘(source-properties
     DATUM)’.  See Source Properties.

   For completeness, we should mention that it is possible to strip the
metadata from a syntax object, returning a raw Scheme datum:

 -- Scheme Procedure: syntax->datum syntax-object
     Strip the metadata from SYNTAX-OBJECT, returning its contents as a
     raw Scheme datum.

   In this case we want to introduce ‘it’ in the context of the whole
expression, so we can create a syntax object as ‘(datum->syntax x 'it)’,
where ‘x’ is the whole expression, as passed to the transformer
procedure.

   Here's another solution that doesn't work:

     ;; doesn't work either
     (define-syntax aif
       (lambda (x)
         (syntax-case x ()
           ((_ test then else)
            (let ((it (datum->syntax x 'it)))
              #'(let ((it test))
                  (if it then else)))))))

   The reason that this one doesn't work is that there are really two
environments at work here - the environment of pattern variables, as
bound by ‘syntax-case’, and the environment of lexical variables, as
bound by normal Scheme.  The outer let form establishes a binding in the
environment of lexical variables, but the inner let form is inside a
syntax form, where only pattern variables will be substituted.  Here we
need to introduce a piece of the lexical environment into the pattern
variable environment, and we can do so using ‘syntax-case’ itself:

     ;; works, but is obtuse
     (define-syntax aif
       (lambda (x)
         (syntax-case x ()
           ((_ test then else)
            ;; invoking syntax-case on the generated
            ;; syntax object to expose it to `syntax'
            (syntax-case (datum->syntax x 'it) ()
              (it
                #'(let ((it test))
                    (if it then else))))))))

     (aif (getuid) (display it) (display "none")) (newline)
     ⊣ 500

   However there are easier ways to write this.  ‘with-syntax’ is often
convenient:

 -- Syntax: with-syntax ((pat val) ...) exp ...
     Bind patterns PAT from their corresponding values VAL, within the
     lexical context of EXP ....

          ;; better
          (define-syntax aif
            (lambda (x)
              (syntax-case x ()
                ((_ test then else)
                 (with-syntax ((it (datum->syntax x 'it)))
                   #'(let ((it test))
                       (if it then else)))))))

   As you might imagine, ‘with-syntax’ is defined in terms of
‘syntax-case’.  But even that might be off-putting to you if you are an
old Lisp macro hacker, used to building macro output with ‘quasiquote’.
The issue is that ‘with-syntax’ creates a separation between the point
of definition of a value and its point of substitution.

   So for cases in which a ‘quasiquote’ style makes more sense,
‘syntax-case’ also defines ‘quasisyntax’, and the related ‘unsyntax’ and
‘unsyntax-splicing’, abbreviated by the reader as ‘#`’, ‘#,’, and ‘#,@’,
respectively.

   For example, to define a macro that inserts a compile-time timestamp
into a source file, one may write:

     (define-syntax display-compile-timestamp
       (lambda (x)
         (syntax-case x ()
           ((_)
            #`(begin
               (display "The compile timestamp was: ")
               (display #,(current-time))
               (newline))))))

   Readers interested in further information on ‘syntax-case’ macros
should see R. Kent Dybvig's excellent ‘The Scheme Programming Language’,
either edition 3 or 4, in the chapter on syntax.  Dybvig was the primary
author of the ‘syntax-case’ system.  The book itself is available online
at <http://scheme.com/tspl4/>.

6.8.3.2 Custom Ellipsis Identifiers for syntax-case Macros
..........................................................

When writing procedural macros that generate macro definitions, it is
convenient to use a different ellipsis identifier at each level.  Guile
supports this for procedural macros using the ‘with-ellipsis’ special
form:

 -- Syntax: with-ellipsis ellipsis body ...
     ELLIPSIS must be an identifier.  Evaluate BODY in a special lexical
     environment such that all macro patterns and templates within BODY
     will use ELLIPSIS as the ellipsis identifier instead of the usual
     three dots (‘...’).

   For example:

     (define-syntax define-quotation-macros
       (lambda (x)
         (syntax-case x ()
           ((_ (macro-name head-symbol) ...)
            #'(begin (define-syntax macro-name
                       (lambda (x)
                         (with-ellipsis :::
                           (syntax-case x ()
                             ((_ x :::)
                              #'(quote (head-symbol x :::)))))))
                     ...)))))
     (define-quotation-macros (quote-a a) (quote-b b) (quote-c c))
     (quote-a 1 2 3) ⇒ (a 1 2 3)

   Note that ‘with-ellipsis’ does not affect the ellipsis identifier of
the generated code, unless ‘with-ellipsis’ is included around the
generated code.

6.8.3.3 Syntax objects can be data too
......................................

Generally speaking, you want the macro expander to pick apart all syntax
objects in a source term.  The source and scope annotations attached to
the syntax object are of interest to how the macro expander computes the
result, but no syntax object itself should appear in the expanded
term--usually.  Sometimes, though, a macro will want a syntax object to
appear in the expanded output.  Normally you would just use ‘quote’ to
introduce the syntax object as a value, but the expander strips syntax
objects from subexpression of ‘quote’.  For this rare use case, Guile
has ‘quote-syntax’, which does not strip its subexpression.

 -- Syntax: quote-syntax form
     Expand to the syntax object ‘form’, as a constant literal.  Like
     ‘quote’, but without calling ‘syntax->datum’.

6.8.4 Syntax Transformer Helpers
--------------------------------

As noted in the previous section, Guile's syntax expander operates on
syntax objects.  Procedural macros consume and produce syntax objects.
This section describes some of the auxiliary helpers that procedural
macros can use to compare, generate, and query objects of this data
type.

 -- Scheme Procedure: bound-identifier=? a b
     Return ‘#t’ if the syntax objects A and B refer to the same
     lexically-bound identifier, or ‘#f’ otherwise.

 -- Scheme Procedure: free-identifier=? a b
     Return ‘#t’ if the syntax objects A and B refer to the same free
     identifier, or ‘#f’ otherwise.

 -- Scheme Procedure: generate-temporaries ls
     Return a list of temporary identifiers as long as LS is long.

 -- Scheme Procedure: syntax-source x
     Return the source properties that correspond to the syntax object
     X.  See Source Properties, for more information.

   Guile also offers some more experimental interfaces in a separate
module.  As was the case with the Large Hadron Collider, it is unclear
to our senior macrologists whether adding these interfaces will result
in awesomeness or in the destruction of Guile via the creation of a
singularity.  We will preserve their functionality through the 2.0
series, but we reserve the right to modify them in a future stable
series, to a more than usual degree.

     (use-modules (system syntax))

 -- Scheme Procedure: syntax-module id
     Return the name of the module whose source contains the identifier
     ID.

 -- Scheme Procedure: syntax-sourcev stx
     Like ‘syntax-source’, but returns its result in a more compact
     ‘#(FILENAME LINE COLUMN)’ format.  This format is used as the
     internal representation of source locations for syntax objects.

 -- Scheme Procedure: syntax-local-binding id
          [#:resolve-syntax-parameters?=#t]
     Resolve the identifier ID, a syntax object, within the current
     lexical environment, and return two values, the binding type and a
     binding value.  The binding type is a symbol, which may be one of
     the following:

     ‘lexical’
          A lexically-bound variable.  The value is a unique token (in
          the sense of ‘eq?’) identifying this binding.
     ‘macro’
          A syntax transformer, either local or global.  The value is
          the transformer procedure.
     ‘syntax-parameter’
          A syntax parameter (see Syntax Parameters).  By default,
          ‘syntax-local-binding’ will resolve syntax parameters, so that
          this value will not be returned.  Pass
          ‘#:resolve-syntax-parameters? #f’ to indicate that you are
          interested in syntax parameters.  The value is the default
          transformer procedure, as in ‘macro’.
     ‘pattern-variable’
          A pattern variable, bound via ‘syntax-case’.  The value is an
          opaque object, internal to the expander.
     ‘ellipsis’
          An internal binding, bound via ‘with-ellipsis’.  The value is
          the (anti-marked) local ellipsis identifier.
     ‘displaced-lexical’
          A lexical variable that has gone out of scope.  This can
          happen if a badly-written procedural macro saves a syntax
          object, then attempts to introduce it in a context in which it
          is unbound.  The value is ‘#f’.
     ‘global’
          A global binding.  The value is a pair, whose head is the
          symbol, and whose tail is the name of the module in which to
          resolve the symbol.
     ‘other’
          Some other binding, like ‘lambda’ or other core bindings.  The
          value is ‘#f’.

     This is a very low-level procedure, with limited uses.  One case in
     which it is useful is to build abstractions that associate
     auxiliary information with macros:

          (define aux-property (make-object-property))
          (define-syntax-rule (with-aux aux value)
            (let ((trans value))
              (set! (aux-property trans) aux)
              trans))
          (define-syntax retrieve-aux
            (lambda (x)
              (syntax-case x ()
                ((x id)
                 (call-with-values (lambda () (syntax-local-binding #'id))
                   (lambda (type val)
                     (with-syntax ((aux (datum->syntax #'here
                                                       (and (eq? type 'macro)
                                                            (aux-property val)))))
                       #''aux)))))))
          (define-syntax foo
            (with-aux 'bar
              (syntax-rules () ((_) 'foo))))
          (foo)
          ⇒ foo
          (retrieve-aux foo)
          ⇒ bar

     ‘syntax-local-binding’ must be called within the dynamic extent of
     a syntax transformer; to call it otherwise will signal an error.

 -- Scheme Procedure: syntax-locally-bound-identifiers id
     Return a list of identifiers that were visible lexically when the
     identifier ID was created, in order from outermost to innermost.

     This procedure is intended to be used in specialized procedural
     macros, to provide a macro with the set of bound identifiers that
     the macro can reference.

     As a technical implementation detail, the identifiers returned by
     ‘syntax-locally-bound-identifiers’ will be anti-marked, like the
     syntax object that is given as input to a macro.  This is to signal
     to the macro expander that these bindings were present in the
     original source, and do not need to be hygienically renamed, as
     would be the case with other introduced identifiers.  See the
     discussion of hygiene in section 12.1 of the R6RS, for more
     information on marks.

          (define (local-lexicals id)
            (filter (lambda (x)
                      (eq? (syntax-local-binding x) 'lexical))
                    (syntax-locally-bound-identifiers id)))
          (define-syntax lexicals
            (lambda (x)
              (syntax-case x ()
                ((lexicals) #'(lexicals lexicals))
                ((lexicals scope)
                 (with-syntax (((id ...) (local-lexicals #'scope)))
                   #'(list (cons 'id id) ...))))))

          (let* ((x 10) (x 20)) (lexicals))
          ⇒ ((x . 10) (x . 20))

6.8.5 Lisp-style Macro Definitions
----------------------------------

The traditional way to define macros in Lisp is very similar to
procedure definitions.  The key differences are that the macro
definition body should return a list that describes the transformed
expression, and that the definition is marked as a macro definition
(rather than a procedure definition) by the use of a different
definition keyword: in Lisp, ‘defmacro’ rather than ‘defun’, and in
Scheme, ‘define-macro’ rather than ‘define’.

   Guile supports this style of macro definition using both ‘defmacro’
and ‘define-macro’.  The only difference between them is how the macro
name and arguments are grouped together in the definition:

     (defmacro NAME (ARGS ...) BODY ...)

is the same as

     (define-macro (NAME ARGS ...) BODY ...)

The difference is analogous to the corresponding difference between
Lisp's ‘defun’ and Scheme's ‘define’.

   Having read the previous section on ‘syntax-case’, it's probably
clear that Guile actually implements defmacros in terms of
‘syntax-case’, applying the transformer on the expression between
invocations of ‘syntax->datum’ and ‘datum->syntax’.  This realization
leads us to the problem with defmacros, that they do not preserve
referential transparency.  One can be careful to not introduce bindings
into expanded code, via liberal use of ‘gensym’, but there is no getting
around the lack of referential transparency for free bindings in the
macro itself.

   Even a macro as simple as our ‘when’ from before is difficult to get
right:

     (define-macro (when cond exp . rest)
       `(if ,cond
            (begin ,exp . ,rest)))

     (when #f (display "Launching missiles!\n"))
     ⇒ #f

     (let ((if list))
       (when #f (display "Launching missiles!\n")))
     ⊣ Launching missiles!
     ⇒ (#f #<unspecified>)

   Guile's perspective is that defmacros have had a good run, but that
modern macros should be written with ‘syntax-rules’ or ‘syntax-case’.
There are still many uses of defmacros within Guile itself, but we will
be phasing them out over time.  Of course we won't take away ‘defmacro’
or ‘define-macro’ themselves, as there is lots of code out there that
uses them.

6.8.6 Identifier Macros
-----------------------

When the syntax expander sees a form in which the first element is a
macro, the whole form gets passed to the macro's syntax transformer.
One may visualize this as:

     (define-syntax foo foo-transformer)
     (foo ARG...)
     ;; expands via
     (foo-transformer #'(foo ARG...))

   If, on the other hand, a macro is referenced in some other part of a
form, the syntax transformer is invoked with only the macro reference,
not the whole form.

     (define-syntax foo foo-transformer)
     foo
     ;; expands via
     (foo-transformer #'foo)

   This allows bare identifier references to be replaced
programmatically via a macro.  ‘syntax-rules’ provides some syntax to
effect this transformation more easily.

 -- Syntax: identifier-syntax exp
     Returns a macro transformer that will replace occurrences of the
     macro with EXP.

   For example, if you are importing external code written in terms of
‘fx+’, the fixnum addition operator, but Guile doesn't have ‘fx+’, you
may use the following to replace ‘fx+’ with ‘+’:

     (define-syntax fx+ (identifier-syntax +))

   There is also special support for recognizing identifiers on the
left-hand side of a ‘set!’ expression, as in the following:

     (define-syntax foo foo-transformer)
     (set! foo VAL)
     ;; expands via
     (foo-transformer #'(set! foo VAL))
     ;; if foo-transformer is a "variable transformer"

   As the example notes, the transformer procedure must be explicitly
marked as being a "variable transformer", as most macros aren't written
to discriminate on the form in the operator position.

 -- Scheme Procedure: make-variable-transformer transformer
     Mark the TRANSFORMER procedure as being a "variable transformer".
     In practice this means that, when bound to a syntactic keyword, it
     may detect references to that keyword on the left-hand-side of a
     ‘set!’.

          (define bar 10)
          (define-syntax bar-alias
            (make-variable-transformer
             (lambda (x)
               (syntax-case x (set!)
                 ((set! var val) #'(set! bar val))
                 ((var arg ...) #'(bar arg ...))
                 (var (identifier? #'var) #'bar)))))

          bar-alias ⇒ 10
          (set! bar-alias 20)
          bar ⇒ 20
          (set! bar 30)
          bar-alias ⇒ 30

   There is an extension to identifier-syntax which allows it to handle
the ‘set!’ case as well:

 -- Syntax: identifier-syntax (var exp1) ((set! var val) exp2)
     Create a variable transformer.  The first clause is used for
     references to the variable in operator or operand position, and the
     second for appearances of the variable on the left-hand-side of an
     assignment.

     For example, the previous ‘bar-alias’ example could be expressed
     more succinctly like this:

          (define-syntax bar-alias
            (identifier-syntax
              (var bar)
              ((set! var val) (set! bar val))))

     As before, the templates in ‘identifier-syntax’ forms do not need
     wrapping in ‘#'’ syntax forms.

6.8.7 Syntax Parameters
-----------------------

Syntax parameters(1) are a mechanism for rebinding a macro definition
within the dynamic extent of a macro expansion.  This provides a
convenient solution to one of the most common types of unhygienic macro:
those that introduce a unhygienic binding each time the macro is used.
Examples include a ‘lambda’ form with a ‘return’ keyword, or class
macros that introduce a special ‘self’ binding.

   With syntax parameters, instead of introducing the binding
unhygienically each time, we instead create one binding for the keyword,
which we can then adjust later when we want the keyword to have a
different meaning.  As no new bindings are introduced, hygiene is
preserved.  This is similar to the dynamic binding mechanisms we have at
run-time (see parameters), except that the dynamic binding
only occurs during macro expansion.  The code after macro expansion
remains lexically scoped.

 -- Syntax: define-syntax-parameter keyword transformer
     Binds KEYWORD to the value obtained by evaluating TRANSFORMER.  The
     TRANSFORMER provides the default expansion for the syntax
     parameter, and in the absence of ‘syntax-parameterize’, is
     functionally equivalent to ‘define-syntax’.  Usually, you will just
     want to have the TRANSFORMER throw a syntax error indicating that
     the KEYWORD is supposed to be used in conjunction with another
     macro, for example:
          (define-syntax-parameter return
            (lambda (stx)
              (syntax-violation 'return "return used outside of a lambda^" stx)))

 -- Syntax: syntax-parameterize ((keyword transformer) ...) exp ...
     Adjusts KEYWORD ... to use the values obtained by evaluating their
     TRANSFORMER ..., in the expansion of the EXP ... forms.  Each
     KEYWORD must be bound to a syntax-parameter.  ‘syntax-parameterize’
     differs from ‘let-syntax’, in that the binding is not shadowed, but
     adjusted, and so uses of the keyword in the expansion of EXP ...
     use the new transformers.  This is somewhat similar to how
     ‘parameterize’ adjusts the values of regular parameters, rather
     than creating new bindings.

          (define-syntax lambda^
            (syntax-rules ()
              [(lambda^ argument-list body body* ...)
               (lambda argument-list
                 (call-with-current-continuation
                  (lambda (escape)
                    ;; In the body we adjust the 'return' keyword so that calls
                    ;; to 'return' are replaced with calls to the escape
                    ;; continuation.
                    (syntax-parameterize ([return (syntax-rules ()
                                                    [(return vals (... ...))
                                                     (escape vals (... ...))])])
                      body body* ...))))]))

          ;; Now we can write functions that return early.  Here, 'product' will
          ;; return immediately if it sees any 0 element.
          (define product
            (lambda^ (list)
                     (fold (lambda (n o)
                             (if (zero? n)
                                 (return 0)
                                 (* n o)))
                           1
                           list)))

   ---------- Footnotes ----------

   (1) Described in the paper ‘Keeping it Clean with Syntax Parameters’
by Barzilay, Culpepper and Flatt.

6.8.8 Eval-when
---------------

As ‘syntax-case’ macros have the whole power of Scheme available to
them, they present a problem regarding time: when a macro runs, what
parts of the program are available for the macro to use?

   The default answer to this question is that when you import a module
(via ‘define-module’ or ‘use-modules’), that module will be loaded up at
expansion-time, as well as at run-time.  Additionally, top-level
syntactic definitions within one compilation unit made by
‘define-syntax’ are also evaluated at expansion time, in the order that
they appear in the compilation unit (file).

   But if a syntactic definition needs to call out to a normal procedure
at expansion-time, it might well need special declarations to indicate
that the procedure should be made available at expansion-time.

   For example, the following code tries to embed a compilation
timestamp in the compiled bytecode using a macro that expands to the
date as a string literal.  It will work at a REPL, but not in a file, as
it cannot be byte-compiled:

     (use-modules (srfi srfi-19))
     (define start-date (date->string (current-date)))
     (define-syntax *compilation-date*
      (lambda (syntax)
         start-date))
     (display *compilation-date*)
     (newline)

   It works at a REPL because the expressions are evaluated one-by-one,
in order, but if placed in a file, the expressions are expanded
one-by-one, but not evaluated until the compiled file is loaded.

   The fix is to use ‘eval-when’.

     (use-modules (srfi srfi-19))
     (eval-when (expand load eval)
       (define start-date (date->string (current-date))))
     (define-syntax *compilation-date*
      (lambda (syntax)
         start-date))
     (display *compilation-date*)
     (newline)

 -- Syntax: eval-when conditions exp...
     Evaluate EXP... under the given CONDITIONS.  Valid conditions
     include:

     ‘expand’
          Evaluate during macro expansion, whether compiling or not.

     ‘load’
          Evaluate during the evaluation phase of compiled code, e.g.
          when loading a compiled module or running compiled code at the
          REPL.

     ‘eval’
          Evaluate during the evaluation phase of non-compiled code.

     ‘compile’
          Evaluate during macro expansion, but only when compiling.

     In other words, when using the primitive evaluator, ‘eval-when’
     expressions with ‘expand’ are run during macro expansion, and those
     with ‘eval’ are run during the evaluation phase.

     When using the compiler, ‘eval-when’ expressions with either
     ‘expand’ or ‘compile’ are run during macro expansion, and those
     with ‘load’ are run during the evaluation phase.

     When in doubt, use the three conditions ‘(expand load eval)’, as in
     the example above.  Other uses of ‘eval-when’ may void your
     warranty or poison your cat.

6.8.9 Macro Expansion
---------------------

Usually, macros are expanded on behalf of the user as needed.  Macro
expansion is an integral part of ‘eval’ and ‘compile’.  Users can also
expand macros at the REPL prompt via the ‘expand’ REPL command; see
Compile Commands.

   Macros can also be expanded programmatically, via ‘macroexpand’, but
the details get a bit hairy for two reasons.

   The first complication is that the result of macro-expansion isn't
Scheme: it's Tree-IL, Guile's high-level intermediate language.  See
Tree-IL.  As "hygienic macros" can produce identifiers that are
distinct but have the same name, the output format needs to be able to
represent distinctions between variable identities and names.  Again,
see Tree-IL, for all the details.  The easiest thing is to just run
‘tree-il->scheme’ on the result of macro-expansion:

     (macroexpand '(+ 1 2))
     ⇒
     #<tree-il (call (toplevel +) (const 1) (const 2))>

     (use-modules (language tree-il))
     (tree-il->scheme (macroexpand '(+ 1 2)))
     ⇒
     (+ 1 2)

   The second complication involves ‘eval-when’.  As an example, what
would it mean to macro-expand the definition of a macro?

     (macroexpand '(define-syntax qux (identifier-syntax 'bar)))
     ⇒
     ?

   The answer is that it depends who is macro-expanding, and why.  Do
you define the macro in the current environment?  Residualize a macro
definition?  Both?  Neither?  The default is to expand in "eval" mode,
which means an ‘eval-when’ clauses will only proceed when ‘eval’ (or
‘expand’) is in its condition set.  Top-level macros will be ‘eval’'d in
the top-level environment.

   In this way ‘(macroexpand FOO)’ is equivalent to ‘(macroexpand FOO 'e
'(eval))’.  The second argument is the mode (‘'e’ for "eval") and the
third is the eval-syntax-expanders-when parameter (only ‘eval’ in this
default setting).

   But if you are compiling the macro definition, probably you want to
reify the macro definition itself.  In that case you pass ‘'c’ as the
second argument to ‘macroexpand’.  But probably you want the macro
definition to be present at compile time as well, so you pass ‘'(compile
load eval)’ as the ESEW parameter.  In fact ‘(compile FOO #:to
'tree-il)’ is entirely equivalent to ‘(macroexpand FOO 'c '(compile load
eval))’; see The Scheme Compiler.

   It's a terrible interface; we know.  The macroexpander is somewhat
tricky regarding modes, so unless you are building a macro-expanding
tool, we suggest to avoid invoking it directly.

6.8.10 Hygiene and the Top-Level
--------------------------------

Consider the following macro.

     (define-syntax-rule (defconst name val)
       (begin
         (define t val)
         (define-syntax-rule (name) t)))

   If we use it to make a couple of bindings:

     (defconst foo 42)
     (defconst bar 37)

   The expansion would look something like this:

     (begin
       (define t 42)
       (define-syntax-rule (foo) t))
     (begin
       (define t 37)
       (define-syntax-rule (bar) t))

   As the two ‘t’ bindings were introduced by the macro, they should be
introduced hygienically - and indeed they are, inside a lexical contour
(a ‘let’ or some other lexical scope).  The ‘t’ reference in ‘foo’ is
distinct to the reference in ‘bar’.

   At the top-level things are more complicated.  Before Guile 2.2, a
use of ‘defconst’ at the top-level would not introduce a fresh binding
for ‘t’.  This was consistent with a weaselly interpretation of the
Scheme standard, in which all possible bindings may be assumed to exist,
at the top-level, and in which we merely take advantage of toplevel
‘define’ of an existing binding being equivalent to ‘set!’.  But it's
not a good reason.

   The solution is to create fresh names for all bindings introduced by
macros - not just bindings in lexical contours, but also bindings
introduced at the top-level.

   However, the obvious strategy of just giving random names to
introduced toplevel identifiers poses a problem for separate
compilation.  Consider without loss of generality a ‘defconst’ of ‘foo’
in module ‘a’ that introduces the fresh top-level name ‘t-1’.  If we
then compile a module ‘b’ that uses ‘foo’, there is now a reference to
‘t-1’ in module ‘b’.  If module ‘a’ is then expanded again, for whatever
reason, for example in a simple recompilation, the introduced ‘t’ gets a
fresh name; say, ‘t-2’.  Now module ‘b’ has broken because module ‘a’ no
longer has a binding for ‘t-1’.

   If introduced top-level identifiers "escape" a module, in whatever
way, they then form part of the binary interface (ABI) of a module.  It
is unacceptable from an engineering point of view to allow the ABI to
change randomly.  (It also poses practical problems in meeting the
recompilation conditions of the Lesser GPL license, for such modules.)
For this reason many people prefer to never use identifier-introducing
macros at the top-level, instead making those macros receive the names
for their introduced identifiers as part of their arguments, or to
construct them programmatically and use ‘datum->syntax’.  But this
approach requires omniscience as to the implementation of all macros one
might use, and also limits the expressive power of Scheme macros.

   There is no perfect solution to this issue.  Guile does a terrible
thing here.  When it goes to introduce a top-level identifier, Guile
gives the identifier a pseudo-fresh name: a name that depends on the
hash of the source expression in which the name occurs.  The result in
this case is that the introduced definitions expand as:

     (begin
       (define t-1dc5e42de7c1050c 42)
       (define-syntax-rule (foo) t-1dc5e42de7c1050c))
     (begin
       (define t-10cb8ce9fdddd6e9 37)
       (define-syntax-rule (bar) t-10cb8ce9fdddd6e9))

   However, note that as the hash depends solely on the expression
introducing the definition, we also have:

     (defconst baz 42)
     ⇒ (begin
         (define t-1dc5e42de7c1050c 42)
         (define-syntax-rule (baz) t-1dc5e42de7c1050c))

   Note that the introduced binding has the same name!  This is because
the source expression, ‘(define t 42)’, was the same.  Probably you will
never see an error in this area, but it is important to understand the
components of the interface of a module, and that interface may include
macro-introduced identifiers.

6.8.11 Internal Macros
----------------------

 -- Scheme Procedure: make-syntax-transformer name type binding
     Construct a syntax transformer object.  This is part of Guile's
     low-level support for syntax-case.

 -- Scheme Procedure: macro? obj
 -- C Function: scm_macro_p (obj)
     Return ‘#t’ if OBJ is a syntax transformer, or ‘#f’ otherwise.

     Note that it's a bit difficult to actually get a macro as a
     first-class object; simply naming it (like ‘case’) will produce a
     syntax error.  But it is possible to get these objects using
     ‘module-ref’:

          (macro? (module-ref (current-module) 'case))
          ⇒ #t

 -- Scheme Procedure: macro-type m
 -- C Function: scm_macro_type (m)
     Return the TYPE that was given when M was constructed, via
     ‘make-syntax-transformer’.

 -- Scheme Procedure: macro-name m
 -- C Function: scm_macro_name (m)
     Return the name of the macro M.

 -- Scheme Procedure: macro-binding m
 -- C Function: scm_macro_binding (m)
     Return the binding of the macro M.

 -- Scheme Procedure: macro-transformer m
 -- C Function: scm_macro_transformer (m)
     Return the transformer of the macro M.  This will return a
     procedure, for which one may ask the docstring.  That's the whole
     reason this section is documented.  Actually a part of the result
     of ‘macro-binding’.

6.9 General Utility Functions
=============================

This chapter contains information about procedures which are not cleanly
tied to a specific data type.  Because of their wide range of
applications, they are collected in a “utility” chapter.

6.9.1 Equality
--------------

There are three kinds of core equality predicates in Scheme, described
below.  The same kinds of comparisons arise in other functions, like
‘memq’ and friends (see List Searching).

   For all three tests, objects of different types are never equal.  So
for instance a list and a vector are not ‘equal?’, even if their
contents are the same.  Exact and inexact numbers are considered
different types too, and are hence not equal even if their values are
the same.

   ‘eq?’ tests just for the same object (essentially a pointer
comparison).  This is fast, and can be used when searching for a
particular object, or when working with symbols or keywords (which are
always unique objects).

   ‘eqv?’ extends ‘eq?’ to look at the value of numbers and characters.
It can for instance be used somewhat like ‘=’ (see Comparison) but
without an error if one operand isn't a number.

   ‘equal?’ goes further, it looks (recursively) into the contents of
lists, vectors, etc.  This is good for instance on lists that have been
read or calculated in various places and are the same, just not made up
of the same pairs.  Such lists look the same (when printed), and
‘equal?’ will consider them the same.

 -- Scheme Procedure: eq? ...
 -- C Function: scm_eq_p (x, y)
     The Scheme procedure returns ‘#t’ if all of its arguments are the
     same object, except for numbers and characters.  The C function
     does the same but takes exactly two arguments.  For example,

          (define x (vector 1 2 3))
          (define y (vector 1 2 3))

          (eq? x x)  ⇒ #t
          (eq? x y)  ⇒ #f

     Numbers and characters are not equal to any other object, but the
     problem is they're not necessarily ‘eq?’ to themselves either.
     This is even so when the number comes directly from a variable,

          (let ((n (+ 2 3)))
            (eq? n n))       ⇒ *unspecified*

     Generally ‘eqv?’ below should be used when comparing numbers or
     characters.  ‘=’ (see Comparison) or ‘char=?’ (see
     Characters) can be used too.

     It's worth noting that end-of-list ‘()’, ‘#t’, ‘#f’, a symbol of a
     given name, and a keyword of a given name, are unique objects.
     There's just one of each, so for instance no matter how ‘()’ arises
     in a program, it's the same object and can be compared with ‘eq?’,

          (define x (cdr '(123)))
          (define y (cdr '(456)))
          (eq? x y) ⇒ #t

          (define x (string->symbol "foo"))
          (eq? x 'foo) ⇒ #t

 -- C Function: int scm_is_eq (SCM x, SCM y)
     Return ‘1’ when X and Y are equal in the sense of ‘eq?’, otherwise
     return ‘0’.

     The ‘==’ operator should not be used on ‘SCM’ values, an ‘SCM’ is a
     C type which cannot necessarily be compared using ‘==’ (see The SCM Type).

 -- Scheme Procedure: eqv? ...
 -- C Function: scm_eqv_p (x, y)
     The Scheme procedure returns ‘#t’ if all of its arguments are the
     same object, or for characters and numbers the same value.  The C
     function is similar but takes exactly two arguments.

     On objects except characters and numbers, ‘eqv?’ is the same as
     ‘eq?’ above.  ‘(eqv? x y)’ is true if X and Y are the same object.

     If X and Y are numbers or characters, ‘eqv?’ compares their type
     and value.  An exact number is not ‘eqv?’ to an inexact number
     (even if their value is the same).

          (eqv? 3 (+ 1 2)) ⇒ #t
          (eqv? 1 1.0)     ⇒ #f

 -- Scheme Procedure: equal? ...
 -- C Function: scm_equal_p (x, y)
     The Scheme procedure returns ‘#t’ if all of its arguments are the
     same type, and their contents or value are equal.  The C function
     is similar, but takes exactly two arguments.

     For a pair, string, vector, array or structure, ‘equal?’ compares
     the contents, and does so using the same ‘equal?’ recursively, so a
     deep structure can be traversed.

          (equal? (list 1 2 3) (list 1 2 3))   ⇒ #t
          (equal? (list 1 2 3) (vector 1 2 3)) ⇒ #f

     For other objects, ‘equal?’ compares as per ‘eqv?’ above, which
     means characters and numbers are compared by type and value (and
     like ‘eqv?’, exact and inexact numbers are not ‘equal?’, even if
     their value is the same).

          (equal? 3 (+ 1 2)) ⇒ #t
          (equal? 1 1.0)     ⇒ #f

     Hash tables are currently only compared as per ‘eq?’, so two
     different tables are not ‘equal?’, even if their contents are the
     same.

     ‘equal?’ does not support circular data structures, it may go into
     an infinite loop if asked to compare two circular lists or similar.

     GOOPS object types (see GOOPS), including foreign object types
     (see Defining New Foreign Object Types), can have an ‘equal?’
     implementation specialized on two values of the same type.  If
     ‘equal?’ is called on two GOOPS objects of the same type, ‘equal?’
     will dispatch out to a generic function.  This lets an application
     traverse the contents or control what is considered ‘equal?’ for
     two objects of such a type.  If there's no such handler, the
     default is to just compare as per ‘eq?’.

6.9.2 Object Properties
-----------------------

It's often useful to associate a piece of additional information with a
Scheme object even though that object does not have a dedicated slot
available in which the additional information could be stored.  Object
properties allow you to do just that.

   Guile's representation of an object property is a
procedure-with-setter (see Procedures with Setters) that can be used
with the generalized form of ‘set!’ to set and retrieve that property
for any Scheme object.  So, setting a property looks like this:

     (set! (my-property obj1) value-for-obj1)
     (set! (my-property obj2) value-for-obj2)

And retrieving values of the same property looks like this:

     (my-property obj1)
     ⇒
     value-for-obj1

     (my-property obj2)
     ⇒
     value-for-obj2

   To create an object property in the first place, use the
‘make-object-property’ procedure:

     (define my-property (make-object-property))

 -- Scheme Procedure: make-object-property
     Create and return an object property.  An object property is a
     procedure-with-setter that can be called in two ways.  ‘(set!
     (PROPERTY OBJ) VAL)’ sets OBJ's PROPERTY to VAL.  ‘(PROPERTY OBJ)’
     returns the current setting of OBJ's PROPERTY.

   A single object property created by ‘make-object-property’ can
associate distinct property values with all Scheme values that are
distinguishable by ‘eq?’ (ruling out numeric values).

   Internally, object properties are implemented using a weak key hash
table.  This means that, as long as a Scheme value with property values
is protected from garbage collection, its property values are also
protected.  When the Scheme value is collected, its entry in the
property table is removed and so the (ex-) property values are no longer
protected by the table.

   Guile also implements a more traditional Lispy interface to
properties, in which each object has an list of key-value pairs
associated with it.  Properties in that list are keyed by symbols.  This
is a legacy interface; you should use weak hash tables or object
properties instead.

 -- Scheme Procedure: object-properties obj
 -- C Function: scm_object_properties (obj)
     Return OBJ's property list.

 -- Scheme Procedure: set-object-properties! obj alist
 -- C Function: scm_set_object_properties_x (obj, alist)
     Set OBJ's property list to ALIST.

 -- Scheme Procedure: object-property obj key
 -- C Function: scm_object_property (obj, key)
     Return the property of OBJ with name KEY.

 -- Scheme Procedure: set-object-property! obj key value
 -- C Function: scm_set_object_property_x (obj, key, value)
     In OBJ's property list, set the property named KEY to VALUE.

6.9.3 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’ if ITEMS is a list or vector such that, for each
     element X and the next element Y of ITEMS, ‘(LESS Y X)’ returns
     ‘#f’.  Otherwise return ‘#f’.

 -- 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 (inclusively) and ENDPOS (exclusively) delimit the range
     of the vector which gets sorted.  The return value is not
     specified.

6.9.4 Copying Deep Structures
-----------------------------

The procedures for copying lists (see Lists) only produce a flat
copy of the input list, and currently Guile does not even contain
procedures for copying vectors.  The ‘(ice-9 copy-tree)’ module contains
a ‘copy-tree’ function that can be used for this purpose, as it does not
only copy the spine of a list, but also copies any pairs in the cars of
the input lists.

     (use-modules (ice-9 copy-tree))

 -- Scheme Procedure: copy-tree obj
 -- C Function: scm_copy_tree (obj)
     Recursively copy the data tree that is bound to OBJ, and return 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.

6.9.5 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’).

6.9.6 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’.

6.9.6.1 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
     ⇒ #<hook 2 40286c90>

   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 behavior 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

6.9.6.2 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 (see 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 arg ...
 -- C Function: scm_run_hook (hook, args)
     Apply all procedures from the hook HOOK to the arguments ARG ....
     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.

6.9.6.3 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.

6.9.6.4 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 (see
     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 invoked by ‘scm_c_hook_run’
with call closure data NULL.

   The Scheme hook ‘after-gc-hook’ is particularly useful in conjunction
with guardians (see 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.

6.9.6.5 Hooks into the Guile REPL
.................................

6.10 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.

6.10.1 Top Level Variable Definitions
-------------------------------------

At the top level of a program (i.e., not nested within any other
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 in the current module, 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 (see
Local Bindings) act differently (see Internal Definitions).

   Many people end up in a development style of adding and changing
definitions at runtime, building out their program without restarting
it.  (You can do this using ‘reload-module’, the ‘reload’ REPL command,
the ‘load’ procedure, or even just pasting code into a REPL.) If you are
one of these people, you will find that sometimes there are some
variables that you _don't_ want to redefine all the time.  For these,
use ‘define-once’.

 -- Scheme Syntax: define-once name value
     Create a top level variable named NAME with value VALUE, but only
     if NAME is not already bound in the current module.

   Old Lispers probably know ‘define-once’ under its Lisp name,
‘defvar’.

6.10.2 Local Variable Bindings
------------------------------

As opposed to definitions at the top level, which creates bindings that
are visible to all code in a module, 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*’, ‘letrec’, 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 most basic local binding construct is ‘let’.

 -- 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.

     BODY is a sequence of expressions and definitions, ending in an
     expression.

     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 and definitions in BODY are evaluated in order
          (see Internal Definitions), and the values of the last
          expression are returned as the result of the ‘let’ expression.

     The INIT expressions are not allowed to refer to any of the
     VARIABLES.

   The other binding constructs are variations on the same theme: making
new values, binding them to variables, and executing a body in that new,
extended lexical context.

 -- 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

     Note that while the INIT expressions may refer to the new
     variables, they may not access their values.  For example, making
     the ‘even?’ function above creates a closure (see About Closure)
     referencing the ‘odd?’ variable.  But ‘odd?’ can't be
     called until after execution has entered the body.

 -- syntax: letrec* bindings body
     Similar to ‘letrec’, except the INIT expressions are bound to their
     variables in order.

     ‘letrec*’ thus relaxes the letrec restriction, in that later INIT
     expressions may refer to the values of previously bound variables.

          (letrec ((a 42)
                   (b (+ a 10)))  ;; Illegal access
            (* a b))
          ;; The behavior of the expression above is unspecified

          (letrec* ((a 42)
                    (b (+ a 10)))
            (* a b))
          ⇒ 2184

   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
(see Iteration)

6.10.3 Internal definitions
---------------------------

A ‘define’ form which appears inside the body of a ‘lambda’, ‘let’,
‘let*’, ‘letrec’, ‘letrec*’ or equivalent expression is called an
“internal definition”.  An internal definition differs from a top level
definition (see 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 its 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)))

   Internal definitions may be mixed with non-definition expressions.
If an expression precedes a definition, it is treated as if it were a
definition of an unreferenced variable.  So this:

     (let ()
       (define a 1)
       (foo)
       (define b 2)
       (+ a b))

is equivalent to

     (let ()
       (letrec* ((a 1) (_ (begin (foo) #f)) (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.
Whereas on the top level a second define for a given variable acts like
a ‘set!’, for internal definitions, duplicate bound identifiers signals
an error.

   As a historical note, it used to be that internal bindings were
expanded in terms of ‘letrec’, not ‘letrec*’.  This was the situation
for the R5RS report and before.  However with the R6RS, it was
recognized that sequential definition was a more intuitive expansion, as
in the following case:

     (let ()
       (define a 1)
       (define b (+ a a))
       (+ a b))

Guile decided to follow the R6RS in this regard, and now expands
internal definitions using ‘letrec*’.  Relatedly, it used to be that
internal definitions had to precede all expressions in the body; this
restriction was relaxed in Guile 3.0.

6.10.4 Querying variable bindings
---------------------------------

Guile provides a procedure for checking whether a symbol is bound in the
top level environment.

 -- Scheme Procedure: defined? sym [module]
 -- C Function: scm_defined_p (sym, module)
     Return ‘#t’ if SYM is defined in the module MODULE or the current
     module when MODULE is not specified; otherwise return ‘#f’.

6.10.5 Binding multiple return values
-------------------------------------

 -- Syntax: define-values formals expression
     The EXPRESSION is evaluated, and the FORMALS are bound to the
     return values in the same way that the formals in a ‘lambda’
     expression are matched to the arguments in a procedure call.

     (define-values (q r) (floor/ 10 3))
     (list q r) ⇒ (3 1)

     (define-values (x . y) (values 1 2 3))
     x ⇒ 1
     y ⇒ (2 3)

     (define-values x (values 1 2 3))
     x ⇒ (1 2 3)

6.11 Controlling the Flow of Program Execution
==============================================

See Control Flow for a discussion of how the more general
control flow of Scheme affects C code.

6.11.1 Sequencing and Splicing
------------------------------

As an expression, the ‘begin’ syntax is used to evaluate a sequence of
sub-expressions in order.  Consider the conditional expression below:

     (if (> x 0)
         (begin (display "greater") (newline)))

   If the test is true, we want to display "greater" to the current
output port, then display a newline.  We use ‘begin’ to form a compound
expression out of this sequence of sub-expressions.

 -- syntax: begin expr ...
     The expression(s) are evaluated in left-to-right order and the
     values of the last expression are returned as the result of the
     ‘begin’-expression.  This expression type is used when the
     expressions before the last one are evaluated for their side
     effects.

   The ‘begin’ syntax has another role in definition context (see
Internal Definitions).  A ‘begin’ form in a definition context
“splices” its subforms into its place.  For example, consider the
following procedure:

     (define (make-seal)
       (define-sealant seal open)
       (values seal open))

   Let us assume the existence of a ‘define-sealant’ macro that expands
out to some definitions wrapped in a ‘begin’, like so:

     (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))

   Here, because the ‘begin’ is in definition context, its subforms are
“spliced” into the place of the ‘begin’.  This allows the definitions
created by the macro to be visible to the following expression, the
‘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 (see 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 ‘define-sealant’ above, so Scheme abuses
the ‘begin’ form for these two tasks.

6.11.2 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 values of the evaluated branch
     (CONSEQUENT or ALTERNATE) are returned as the values of the ‘if’
     expression.

     When ALTERNATE is omitted and the TEST evaluates to ‘#f’, the value
     of the expression is not specified.

   When you go to write an ‘if’ without an alternate (a “one-armed
‘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 _effect_ of evaluating the consequent expression.  (By
convention, we use the word “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 ‘when’ and ‘unless’.  As an added
bonus, these forms take a _body_ like in a ‘let’ expression, which can
contain internal definitions and multiple statements to evaluate (see
Local Bindings).

 -- Scheme Syntax: when test body
 -- Scheme Syntax: unless test body
     The actual definitions of these forms may be their most clear
     documentation:

          (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* ...)))

     That is to say, ‘when’ evaluates its consequent statements in order
     if TEST is true.  ‘unless’ is the opposite: it evaluates the
     statements if TEST is false.

 -- syntax: cond clause1 clause2 ...
     Each ‘cond’-clause must look like this:

          (TEST BODY)

     where TEST is an 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 value, the corresponding BODY is
     evaluated to produce the result 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.

     One additional ‘cond’-clause is available as an extension to
     standard Scheme:

          (TEST GUARD => EXPRESSION)

     where GUARD and EXPRESSION must evaluate to procedures.  For this
     clause type, TEST may return multiple values, and ‘cond’ ignores
     its boolean state; instead, ‘cond’ evaluates GUARD and applies the
     resulting procedure to the value(s) of TEST, as if GUARD were the
     CONSUMER argument of ‘call-with-values’.  If the result of that
     procedure call is a true value, it evaluates EXPRESSION and applies
     the resulting procedure to the value(s) of TEST, in the same manner
     as the GUARD was called.

     The TEST of the last CLAUSE may be the symbol ‘else’.  Then, if
     none of the preceding TESTs is true, the BODY following the ‘else’
     is evaluated to produce the result of the ‘cond’-expression.

 -- syntax: case key clause1 clause2 ...
     KEY may be any expression, and the CLAUSEs must have the form

          ((DATUM1 ...) BODY)

     or

          ((DATUM1 ...) => EXPRESSION)

     and the last CLAUSE may have the form

          (else BODY)

     or

          (else => EXPRESSION)

     All DATUMs must be distinct.  First, KEY is evaluated.  The result
     of this evaluation is compared against all DATUM values using
     ‘eqv?’.  When this comparison succeeds, the BODY following the
     DATUM is evaluated to produce the result of the ‘case’ expression.

     If the KEY matches no DATUM and there is an ‘else’-clause, the BODY
     following the ‘else’ is evaluated to produce the result of the
     ‘case’ expression.  If there is no such clause, the result of the
     expression is unspecified.

     For the ‘=>’ clause types, EXPRESSION is evaluated and the
     resulting procedure is applied to the value of KEY.  The result of
     this procedure application is then the result of the
     ‘case’-expression.

6.11.3 Conditional Evaluation of a Sequence of Expressions
----------------------------------------------------------

‘and’ and ‘or’ evaluate all their arguments in order, 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.

6.11.4 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 ((variable init [step]) ...) (test expr ...) body ...
     Bind VARIABLEs and evaluate BODY until TEST is true.  The return
     value is the last EXPR after TEST, if given.  A simple example will
     illustrate the basic form,

          (do ((i 1 (1+ i)))
              ((> i 4))
            (display i))
          ⊣ 1234

     Or with two variables and a final return value,

          (do ((i 1 (1+ i))
               (p 3 (* 3 p)))
              ((> i 4)
               p)
            (format #t "3**~s is ~s\n" i p))
          ⊣
          3**1 is 3
          3**2 is 9
          3**3 is 27
          3**4 is 81
          ⇒
          243

     The VARIABLE bindings are established like a ‘let’, in that the
     expressions are all evaluated and then all bindings made.  When
     iterating, the optional STEP expressions are evaluated with the
     previous bindings in scope, then new bindings all made.

     The TEST expression is a termination condition.  Looping stops when
     the TEST is true.  It's evaluated before running the BODY each
     time, so if it's true the first time then BODY is not run at all.

     The optional EXPRs after the TEST are evaluated at the end of
     looping, with the final VARIABLE bindings available.  The last EXPR
     gives the return value, or if there are no EXPRs the return value
     is unspecified.

     Each iteration establishes bindings to fresh locations for the
     VARIABLEs, like a new ‘let’ for each iteration.  This is done for
     VARIABLEs without STEP expressions too.  The following illustrates
     this, showing how a new ‘i’ is captured by the ‘lambda’ in each
     iteration (see The Concept of Closure).

          (define lst '())
          (do ((i 1 (1+ i)))
              ((> i 4))
            (set! lst (cons (lambda () i) lst)))
          (map (lambda (proc) (proc)) lst)
          ⇒
          (4 3 2 1)

 -- syntax: while cond body ...
     Run a loop executing the BODY forms while COND is true.  COND is
     tested at the start of each iteration, so if it's ‘#f’ the first
     time then BODY is not executed at all.

     Within ‘while’, two extra bindings are provided, they can be used
     from both COND and BODY.

      -- Scheme Procedure: break break-arg ...
          Break out of the ‘while’ form.

      -- Scheme Procedure: continue
          Abandon the current iteration, go back to the start and test
          COND again, etc.

     If the loop terminates normally, by the COND evaluating to ‘#f’,
     then the ‘while’ expression as a whole evaluates to ‘#f’.  If it
     terminates by a call to ‘break’ with some number of arguments,
     those arguments are returned from the ‘while’ expression, as
     multiple values.  Otherwise if it terminates by a call to ‘break’
     with no arguments, then return value is ‘#t’.

          (while #f (error "not reached")) ⇒ #f
          (while #t (break)) ⇒ #t
          (while #t (break 1 2 3)) ⇒ 1 2 3

     Each ‘while’ form gets its own ‘break’ and ‘continue’ procedures,
     operating on that ‘while’.  This means when loops are nested the
     outer ‘break’ can be used to escape all the way out.  For example,

          (while (test1)
            (let ((outer-break break))
              (while (test2)
                (if (something)
                  (outer-break #f))
                ...)))

     Note that each ‘break’ and ‘continue’ procedure can only be used
     within the dynamic extent of its ‘while’.  Outside the ‘while’
     their behavior is unspecified.

   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’
     (see 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

6.11.5 Prompts
--------------

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.

6.11.5.1 Prompt Primitives
..........................

Guile's primitive delimited control operators are ‘call-with-prompt’ and
‘abort-to-prompt’.

 -- Scheme Procedure: call-with-prompt tag thunk handler
     Set up a prompt, and call THUNK within that prompt.

     During the dynamic extent of the call to THUNK, a prompt named TAG
     will be present in the dynamic context, such that if a user calls
     ‘abort-to-prompt’ (see below) with that tag, control rewinds back
     to the prompt, and the HANDLER is run.

     HANDLER must be a procedure.  The first argument to HANDLER will be
     the state of the computation begun when THUNK was called, and
     ending with the call to ‘abort-to-prompt’.  The remaining arguments
     to HANDLER are those passed to ‘abort-to-prompt’.

 -- 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.

 -- 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 ‘default-prompt-tag’ is actually a
     parameter, and so may be dynamically rebound using ‘parameterize’.
     See Parameters.

 -- Scheme Procedure: abort-to-prompt tag val1 val2 ...
     Unwind the dynamic and control context to the nearest prompt named
     TAG, also passing the given values.

   C programmers may recognize ‘call-with-prompt’ and ‘abort-to-prompt’
as a fancy kind of ‘setjmp’ and ‘longjmp’, respectively.  Prompts are
indeed quite useful as non-local escape mechanisms.  Guile's
‘with-exception-handler’ and ‘raise-exception’ are implemented in terms
of prompts.  Prompts are more convenient than ‘longjmp’, in that one has
the opportunity to pass multiple values to the jump target.

   Also unlike ‘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 “continuation” of the computation wrapped by
the prompt.  It is a “delimited continuation”, because it is not the
whole continuation of the program; rather, just the computation
initiated by the call to ‘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 “composable”,
because invoking a prompt-saved continuation composes that continuation
with the current one.

   Imagine you have saved a continuation via call-with-prompt:

     (define cont
       (call-with-prompt
        ;; tag
        'foo
        ;; thunk
        (lambda ()
          (+ 34 (abort-to-prompt 'foo)))
        ;; handler
        (lambda (k) k)))

   The resulting continuation is the addition of 34.  It's as if you had
written:

     (define cont
       (lambda (x)
         (+ 34 x)))

   So, if we call ‘cont’ with one numeric value, we get that number,
incremented by 34:

     (cont 8)
     ⇒ 42
     (* 2 (cont 8))
     ⇒ 84

   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 ‘(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 ‘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.

   One example where this optimization matters is “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 (see Exceptions).

   The constructs below are syntactic sugar atop prompts to simplify the
use of escape continuations.

 -- Scheme Procedure: call-with-escape-continuation proc
 -- Scheme Procedure: call/ec proc
     Call PROC with an escape continuation.

     In the example below, the RETURN continuation is used to escape the
     continuation of the call to ‘fold’.

          (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))
          ⇒ (0 1 2)

 -- Scheme Syntax: let-escape-continuation k body ...
 -- Scheme Syntax: let/ec k body ...
     Bind K within BODY to an escape continuation.

     This is equivalent to ‘(call/ec (lambda (K) BODY ...))’.

   Additionally there is another helper primitive exported by ‘(ice-9
control)’, so load up that module for ‘suspendable-continuation?’:

     (use-modules (ice-9 control))

 -- Scheme Procedure: suspendable-continuation? tag
     Return ‘#t’ if a call to ‘abort-to-prompt’ with the prompt tag 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 ‘call-with-prompt’ and the
     ‘abort-to-prompt’ recursed through C for some reason, the
     ‘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 ‘#f’.

6.11.5.2 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:

     (use-modules (ice-9 control))

   Firstly, we have a helpful abbreviation for the ‘call-with-prompt’
operator.

 -- Scheme Syntax: % expr
 -- Scheme Syntax: % expr handler
 -- Scheme Syntax: % tag expr handler
     Evaluate 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:

          (define (default-prompt-handler k proc)
            (% (default-prompt-tag)
               (proc k)
               default-prompt-handler))

     The ‘%’ symbol is chosen because it looks like a prompt.

   Likewise there is an abbreviation for ‘abort-to-prompt’, which
assumes the default prompt tag:

 -- Scheme Procedure: abort val1 val2 ...
     Abort to the default prompt tag, passing VAL1 VAL2 ... to the
     handler.

   As mentioned before, ‘(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 ‘%’.

   Still here?  So, when one implements a delimited control operator
like ‘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 “F” operator.  If
neither the continuations nor the handlers implicitly add a prompt, the
operator is known as “-F-”.  This is the case for Guile's
‘call-with-prompt’ and ‘abort-to-prompt’.

   If both continuation and handler implicitly add prompts, then the
operator is “+F+”.  ‘shift’ and ‘reset’ are such operators.

 -- Scheme Syntax: reset body1 body2 ...
     Establish a prompt, and evaluate BODY1 BODY2 ... within that
     prompt.

     The prompt handler is designed to work with ‘shift’, described
     below.

 -- Scheme Syntax: shift cont body1 body2 ...
     Abort to the nearest ‘reset’, and evaluate BODY1 BODY2 ... in a
     context in which the captured continuation is bound to CONT.

     As mentioned above, taken together, the BODY1 BODY2 ... expressions
     and the invocations of CONT implicitly establish a prompt.

   Interested readers are invited to explore Oleg Kiselyov's wonderful
web site at <http://okmij.org/ftp/>, for more information on these
operators.

6.11.6 Continuations
--------------------

A "continuation" is the code that will execute when a given function or
expression returns.  For example, consider

     (define (foo)
       (display "hello\n")
       (display (bar)) (newline)
       (exit))

   The continuation from the call to ‘bar’ comprises a ‘display’ of the
value returned, a ‘newline’ and an ‘exit’.  This can be expressed as a
function of one argument.

     (lambda (r)
       (display r) (newline)
       (exit))

   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.

 -- Scheme Procedure: call-with-current-continuation proc
 -- Scheme Procedure: call/cc proc
     Capture the current continuation and call ‘(PROC CONT)’ with it.
     The return value is the value returned by PROC, or when ‘(CONT
     VALUE)’ is later invoked, the return is the VALUE passed.

     Normally CONT should be called with one argument, but when the
     location resumed is expecting multiple values (see Multiple Values)
     then they should be passed as multiple arguments, for
     instance ‘(CONT X Y Z)’.

     CONT may only be used from the same side of a continuation barrier
     as it was created (see Continuation Barriers), and in a
     multi-threaded program only from the thread in which it was
     created.

     The call to PROC is not part of the continuation captured, it runs
     only when the continuation is created.  Often a program will want
     to store CONT somewhere for later use; this can be done in PROC.

     The ‘call’ in the name ‘call-with-current-continuation’ refers to
     the way a call to PROC gives the newly created continuation.  It's
     not related to the way a call is used later to invoke that
     continuation.

     ‘call/cc’ is an alias for ‘call-with-current-continuation’.  This
     is in common use since the latter is rather long.

Here is a simple example,

     (define kont #f)
     (format #t "the return is ~a\n"
             (call/cc (lambda (k)
                        (set! kont k)
                        1)))
     ⇒ the return is 1

     (kont 2)
     ⇒ the return is 2

   ‘call/cc’ captures a continuation in which the value returned is
going to be displayed by ‘format’.  The ‘lambda’ stores this in ‘kont’
and gives an initial return ‘1’ which is displayed.  The later
invocation of ‘kont’ resumes the captured point, but this time returning
‘2’, which is displayed.

   When Guile is run interactively, a call to ‘format’ like this has an
implicit return back to the read-eval-print loop.  ‘call/cc’ captures
that like any other return, which is why interactively ‘kont’ will come
back to read more input.

   C programmers may note that ‘call/cc’ is like ‘setjmp’ in the way it
records at runtime a point in program execution.  A call to a
continuation is like a ‘longjmp’ in that it abandons the present
location and goes to the recorded one.  Like ‘longjmp’, the value passed
to the continuation is the value returned by ‘call/cc’ on resuming
there.  However ‘longjmp’ can only go up the program stack, but the
continuation mechanism can go anywhere.

   When a continuation is invoked, ‘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.

   ‘dynamic-wind’ (see 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.

   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 ‘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 (see 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).

6.11.7 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 arg ...
 -- 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.

     For ‘scm_values’, 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 ARGS, so ARGS
     should not be modified subsequently.

 -- C Function: SCM scm_c_values (SCM *base, size_t n)
     ‘scm_c_values’ is an alternative to ‘scm_values’.  It creates a new
     values object, and copies into it the N values starting from BASE.

     Currently this creates a list and passes it to ‘scm_values’, but we
     expect that in the future we will be able to use a more efficient
     representation.

 -- C Function: size_t scm_c_nvalues (SCM obj)
     If OBJ is a multiple-values object, returns the number of values it
     contains.  Otherwise returns 1.

 -- C Function: SCM scm_c_value_ref (SCM obj, size_t idx)
     Returns the value at the position specified by IDX in OBJ.  Note
     that 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.

 -- 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.  This is in the ‘(ice-9 receive)’ and is the same as
specified by SRFI-8 (see SRFI-8).

     (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 FORMALS.  FORMALS is a list of
     symbols, like the argument list in a ‘lambda’ (see Lambda).
     After binding the variables, the BODY is evaluated to produce the
     result of the ‘receive’ expression.

     For example getting results from ‘partition’ in SRFI-1 (see
     SRFI-1),

          (receive (odds evens)
              (partition odd? '(7 4 2 8 3))
            (display odds)
            (display " and ")
            (display evens))
          ⊣ (7 3) and (4 2 8)

6.11.8 Exceptions
-----------------

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:

     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
       ...

   In this case, ‘main-loop’ can install an exception handler that would
cause any exception raised inside ‘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.

6.11.8.1 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 (see Records).

 -- Exception Type: &exception
     The base exception type.  All exception objects are composed of
     instances of subtypes of ‘&exception’.

 -- Scheme Procedure: exception-type? obj
     Return true if OBJ is an exception type.

   Exception types exist in a hierarchy.  New exception types can be
defined using ‘make-exception-type’.

 -- Scheme Procedure: make-exception-type id parent field-names
     Return a new exception type named ID, inheriting from PARENT, and
     with the fields whose names are listed in FIELD-NAMES.  FIELD-NAMES
     must be a list of symbols and must not contain names already used
     by PARENT or one of its supertypes.

   Exception type objects are record type objects, and as such, one can
use ‘record-constructor’ on an exception type to get its constructor.
The constructor will take as many arguments as the exception has fields
(including supertypes).  See Records.

   However, ‘record-predicate’ and ‘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 “compound
exceptions”.  Exception accessors should pick out the specific component
of a compound exception, and then access the field on that specific
component.

 -- Scheme Procedure: make-exception exceptions ...
     Return an exception object composed of EXCEPTIONS.

 -- Scheme Procedure: exception? obj
     Return true if OBJ is an exception object.

 -- Scheme Procedure: exception-predicate type
     Return a procedure that will return true if its argument is a
     simple exception that is an instance of TYPE, or a compound
     exception composed of such an instance.

 -- Scheme Procedure: exception-accessor rtd proc
     Return a procedure that will tail-call PROC on an instance of the
     exception type RTD, or on the component of a compound exception
     that is an instance of RTD.

   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 ‘&programming-error’, ‘&message’,
and ‘&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.  See rnrs exceptions,
for more details.

   To have access to Guile's exception type hierarchy, import the
‘(ice-9 exceptions)’ module:

     (use-modules (ice-9 exceptions))

   The following diagram gives an overview of the standard exception
type hierarchy.

     &exception
     |- &warning
     |- &message
     |- &irritants
     |- &origin
     \- &error
        |- &external-error
        \- &programming-error
           |- &assertion-failure
           |- &non-continuable
           |- &implementation-restriction
           |- &lexical
           |- &syntax
           \- &undefined-variable

 -- Exception Type: &warning
     An exception type denoting warnings.  These are usually raised
     using ‘#:continuable? #t’; see the ‘raise-exception’ documentation
     for more.
 -- Scheme Procedure: make-warning
 -- Scheme Procedure: warning? obj
     Constructor and predicate for ‘&warning’ exception objects.

 -- 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.
 -- Scheme Procedure: make-exception-with-message message
 -- Scheme Procedure: exception-with-message? obj
 -- Scheme Procedure: exception-message exn
     Constructor, predicate, and accessor for ‘&message’ exception
     objects.

 -- 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.
 -- Scheme Procedure: make-exception-with-irritants irritants
 -- Scheme Procedure: exception-with-irritants? obj
 -- Scheme Procedure: exception-irritants exn
     Constructor, predicate, and accessor for ‘&irritants’ exception
     objects.

 -- 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.
 -- Scheme Procedure: make-exception-with-origin origin
 -- Scheme Procedure: exception-with-origin? obj
 -- Scheme Procedure: exception-origin exn
     Constructor, predicate, and accessor for ‘&origin’ exception
     objects.

 -- Exception Type: &error
     An exception type denoting errors: situations that are not just
     exceptional, but wrong.
 -- Scheme Procedure: make-error
 -- Scheme Procedure: error? obj
     Constructor and predicate for ‘&error’ exception objects.

 -- 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.
 -- Scheme Procedure: make-external-error
 -- Scheme Procedure: external-error? obj
     Constructor and predicate for ‘&external-error’ exception objects.

 -- Exception Type: &programming-error
     An exception type denoting errors that proceed from inside a
     program: type mismatches and so on.
 -- Scheme Procedure: make-programming-error
 -- Scheme Procedure: programming-error? obj
     Constructor and predicate for ‘&programming-error’ exception
     objects.

 -- Exception Type: &non-continuable
     An exception type denoting errors that proceed from inside a
     program: type mismatches and so on.
 -- Scheme Procedure: make-non-continuable-error
 -- Scheme Procedure: non-continuable-error? obj
     Constructor and predicate for ‘&non-continuable’ exception objects.

 -- Exception Type: &lexical
     An exception type denoting lexical errors, for example unbalanced
     parentheses.
 -- Scheme Procedure: make-lexical-error
 -- Scheme Procedure: lexical-error? obj
     Constructor and predicate for ‘&lexical’ exception objects.

 -- Exception Type: &syntax form subform
     An exception type denoting syntax errors, for example a ‘cond’
     expression with invalid syntax.  The FORM field indicates the form
     containing the error, and SUBFORM indicates the unexpected
     subcomponent, or ‘#f’ if unavailable.
 -- Scheme Procedure: make-syntax-error form subform
 -- Scheme Procedure: syntax-error? obj
 -- Scheme Procedure: syntax-error-form exn
 -- Scheme Procedure: syntax-error-subform exn
     Constructor, predicate, and accessors for ‘&syntax’ exception
     objects.

 -- Exception Type: &undefined-variable
     An exception type denoting undefined variables.
 -- Scheme Procedure: make-undefine-variable-error
 -- Scheme Procedure: undefined-variable-error? obj
     Constructor and predicate for ‘&undefined-variable’ exception
     objects.

   Incidentally, the ‘(ice-9 exceptions)’ module also includes a
‘define-exception-type’ macro that can be used to conveniently add new
exception types to the hierarchy.

 -- Syntax: define-exception-type name parent constructor predicate
          (field accessor) ...
     Define NAME to be a new exception type, inheriting from PARENT.
     Define CONSTRUCTOR and PREDICATE to be the exception constructor
     and predicate, respectively, and define an ACCESSOR for each FIELD.

6.11.8.2 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 “raise” the exception.

 -- Scheme Procedure: raise-exception obj [#:continuable?=#f]
     Raise an exception by invoking the current exception handler on
     OBJ.  The handler is called with a continuation whose dynamic
     environment is that of the call to ‘raise’, except that the current
     exception handler is the one that was in place when the handler
     being called was installed.

     If CONTINUABLE? is true, the handler is invoked in tail position
     relative to the ‘raise-exception’ call.  Otherwise if the handler
     returns, a non-continuable exception of type ‘&non-continuable’ is
     raised in the same dynamic environment as the handler.

   As the above description notes, Guile has a notion of a “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 ‘with-exception-handler’.

 -- Scheme Procedure: with-exception-handler handler thunk
          [#:unwind?=#f] [#:unwind-for-type=#t]
     Establish HANDLER, a procedure of one argument, as the current
     exception handler during the dynamic extent of invoking THUNK.

     If ‘raise-exception’ is called during the dynamic extent of
     invoking THUNK, HANDLER will be invoked on the argument of
     ‘raise-exception’.

   There are two kinds of exception handlers: unwinding and
non-unwinding.

   By default, exception handlers are non-unwinding.  Unless
‘with-exception-handler’ was invoked with ‘#: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 ‘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 ‘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 ‘raise-exception’ call
is continuable, the exception handler needs to abort the continuation.
To support this use case, if ‘with-exception-handler’ was invoked with
‘#:unwind? #t’ is true, ‘raise-exception’ will first unwind the stack by
invoking an “escape continuation” (see ‘call/ec’),
and then invoke the handler with the continuation of the
‘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
‘stack-overflow’ or ‘out-of-memory’, where you want to immediately
shrink resource use before recovering.  See Stack Overflow.  For
this purpose, the ‘#:unwind-for-type’ keyword argument allows users to
specify the kind of exception handled by an exception handler; if ‘#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 ‘exception-kind’ will be handled.

6.11.8.3 Throw and Catch
........................

Guile only adopted ‘with-exception-handler’ and ‘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: ‘catch’, ‘with-throw-handler’, and
‘throw’.

 -- Scheme Procedure: catch key thunk handler [pre-unwind-handler]
 -- C Function: scm_catch_with_pre_unwind_handler (key, thunk, handler,
          pre_unwind_handler)
 -- C Function: scm_catch (key, thunk, handler)
     Establish an exception handler during the dynamic extent of the
     call to THUNK.  KEY is either ‘#t’, indicating that all exceptions
     should be handled, or a symbol, restricting the exceptions handled
     to those having the KEY as their ‘exception-kind’.

     If THUNK executes normally, meaning without throwing any
     exceptions, the handler procedures are not called at all and the
     result of the ‘thunk’ call is the result of the ‘catch’.  Otherwise
     if an exception is thrown that matches KEY, HANDLER is called with
     the continuation of the ‘catch’ call.

   Given the discussion from the previous section, it is most precise
and concise to specify what ‘catch’ does by expressing it in terms of
‘with-exception-handler’.  Calling ‘catch’ with the three arguments is
the same as:

     (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))

   By invoking ‘with-exception-handler’ with ‘#:unwind? #t’, ‘catch’
sets up an escape continuation that will be invoked in an exceptional
situation before the handler is called.

   If ‘catch’ is called with four arguments, then the use of THUNK
should be replaced with:

        (lambda ()
          (with-throw-handler key thunk pre-unwind-handler))

   As can be seen above, if a pre-unwind-handler is passed to ‘catch’,
it's like calling ‘with-throw-handler’ inside the body thunk.

   ‘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.

 -- Scheme Procedure: with-throw-handler key thunk handler
 -- C Function: scm_with_throw_handler (key, thunk, handler)
     Add HANDLER to the dynamic context as a throw handler for key KEY,
     then invoke THUNK.

   It's not possible to exactly express ‘with-throw-handler’ in terms of
‘with-exception-handler’, but we can get close.

     (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))

   As you can see, unlike in the case of ‘catch’, the handler for
‘with-throw-handler’ is invoked within the continuation of
‘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 ‘with-throw-handler’ that can't be shown above
is that if invoking the handler causes a ‘raise-exception’ instead of
completing normally, the exception is thrown in the _original_ dynamic
environment of the ‘raise-exception’.  Any inner exception handler will
get another shot at handling the exception.  Here is an example to
illustrate this behavior:

     (catch 'a
       (lambda ()
         (with-throw-handler 'b
           (lambda ()
             (catch 'a
               (lambda ()
                 (throw 'b))
               inner-handler))
           (lambda (key . args)
             (throw 'a))))
       outer-handler)

This code will call ‘inner-handler’ and then continue with the
continuation of the inner ‘catch’.

   Finally, we get to ‘throw’, which is the older equivalent to
‘raise-exception’.

 -- Scheme Procedure: throw key arg ...
 -- C Function: scm_throw (key, args)
     Raise an exception with kind KEY and arguments ARGS.  KEY is a
     symbol, denoting the "kind" of the exception.

   Again, we can specify what ‘throw’ does by expressing it in terms of
‘raise-exception’.

     (define (throw key . args)
       (raise-exception (make-exception-from-throw key args)))

   At this point, we should mention the primitive that manage the
relationship between structured exception objects ‘throw’.

 -- Scheme Procedure: make-exception-from-throw key args
     Create an exception object for the given KEY and ARGS passed to
     ‘throw’.  This may be a specific type of exception, for example
     ‘&programming-error’; Guile maintains a set of custom transformers
     for the various KEY values that have been used historically.

 -- Scheme Procedure: exception-kind exn
     If EXN is an exception created via ‘make-exception-from-throw’,
     return the corresponding KEY for the exception.  Otherwise, unless
     EXN is an exception of a type with a known mapping to ‘throw’,
     return the symbol ‘%exception’.

 -- Scheme Procedure: exception-args exn
     If EXN is an exception created via ‘make-exception-from-throw’,
     return the corresponding ARGS for the exception.  Otherwise, unless
     EXN is an exception of a type with a known mapping to ‘throw’,
     return ‘(list EXN)’.

6.11.8.4 Exceptions and C
.........................

There are some specific versions of Guile's original ‘catch’ and
‘with-throw-handler’ exception-handling primitives that are still widely
used in C code.

 -- 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)
 -- 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 ‘scm_catch_with_pre_unwind_handler’ and ‘scm_catch’ take
     Scheme procedures as body and handler arguments.  ‘scm_c_catch’ and
     ‘scm_internal_catch’ are equivalents taking C functions.

     BODY is called as ‘BODY (BODY_DATA)’ with a catch on exceptions of
     the given TAG type.  If an exception is caught, PRE_UNWIND_HANDLER
     and HANDLER are called as ‘HANDLER (HANDLER_DATA, KEY, ARGS)’.  KEY
     and ARGS are the ‘SCM’ key and argument list from the ‘throw’.

     BODY and HANDLER should have the following prototypes.
     ‘scm_t_catch_body’ and ‘scm_t_catch_handler’ are pointer typedefs
     for these.

          SCM body (void *data);
          SCM handler (void *data, SCM key, SCM args);

     The BODY_DATA and 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 ‘SCM’ object, care should be taken that
     it isn't garbage collected while still required.  If the ‘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
     ‘scm_remember_upto_here_1’ (see Foreign Object Memory Management).

 -- 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 ‘scm_with_throw_handler’ takes Scheme procedures as body
     (thunk) and handler arguments.  ‘scm_c_with_throw_handler’ is an
     equivalent taking C functions.  See ‘scm_c_catch’ (see Exceptions and C)
     for a description of the parameters, the behavior however
     of course follows ‘with-throw-handler’.

6.11.9 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.

 -- Scheme Procedure: error msg arg ...
     Raise an error with key ‘misc-error’ and a message constructed by
     displaying MSG and writing ARG ....

 -- Scheme Procedure: scm-error key subr message args data
 -- C Function: scm_error_scm (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; If KEY is ‘out-of-range’, ‘wrong-type-arg’, or
     ‘keyword-argument-error’, it is a list containing the bad value;
     otherwise it will usually be ‘#f’.

 -- Scheme Procedure: strerror err
 -- C Function: scm_strerror (err)
     Return the Unix error message corresponding to ERR, an integer
     ‘errno’ value.

     When ‘setlocale’ has been called (see Locales), the message is
     in the language and charset of ‘LC_MESSAGES’.  (This is done by the
     C library.)

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

6.11.10 Dynamic Wind
--------------------

For Scheme code, the fundamental procedure to react to non-local entry
and exits of dynamic contexts is ‘dynamic-wind’.  C code could use
‘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 ‘scm_dynwind_begin’ and
‘scm_dynwind_end’ to delimit a dynamic extent.  Within this dynamic
extent, which is called a “dynwind context”, you can perform various
“dynwind actions” that control what happens when the dynwind context is
entered or left.  For example, you can register a cleanup routine with
‘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.

     /* 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);
     }

 -- Scheme Procedure: dynamic-wind in_guard thunk out_guard
 -- C Function: scm_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 dynamic extent of
     the ‘dynamic-wind’ expression is escaped non-locally, OUT_GUARD is
     called.  If the dynamic extent 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

 -- C Type: scm_t_dynwind_flags
     This is an enumeration of several flags that modify the behavior of
     ‘scm_dynwind_begin’.  The flags are listed in the following table.

     ‘SCM_F_DYNWIND_REWINDABLE’
          The dynamic context is “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.

 -- C Function: void scm_dynwind_begin (scm_t_dynwind_flags flags)
     The function ‘scm_dynwind_begin’ starts a new dynamic context and
     makes it the 'current' one.

     The 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 ‘SCM_F_DYNWIND_REWINDABLE’ in 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 ‘scm_dynwind_end’.  You must make sure
     that a dynwind context is indeed ended properly.  If you fail to
     call ‘scm_dynwind_end’ for each ‘scm_dynwind_begin’, the behavior
     is undefined.

 -- C Function: void scm_dynwind_end ()
     End the current dynamic context explicitly and make the previous
     one current.

 -- C Type: scm_t_wind_flags
     This is an enumeration of several flags that modify the behavior of
     ‘scm_dynwind_unwind_handler’ and ‘scm_dynwind_rewind_handler’.  The
     flags are listed in the following table.

     ‘SCM_F_WIND_EXPLICITLY’
          The registered action is also carried out when the dynwind
          context is entered or left locally.

 -- C Function: void scm_dynwind_unwind_handler (void (*func)(void *),
          void *data, scm_t_wind_flags flags)
 -- C Function: void scm_dynwind_unwind_handler_with_scm (void
          (*func)(SCM), SCM data, scm_t_wind_flags flags)
     Arranges for FUNC to be called with DATA as its arguments when the
     current context ends implicitly.  If FLAGS contains
     ‘SCM_F_WIND_EXPLICITLY’, FUNC is also called when the context ends
     explicitly with ‘scm_dynwind_end’.

     The function ‘scm_dynwind_unwind_handler_with_scm’ takes care that
     DATA is protected from garbage collection.

 -- C Function: void scm_dynwind_rewind_handler (void (*func)(void *),
          void *data, scm_t_wind_flags flags)
 -- C Function: void scm_dynwind_rewind_handler_with_scm (void
          (*func)(SCM), SCM data, scm_t_wind_flags flags)
     Arrange for FUNC to be called with DATA as its argument when the
     current context is restarted by rewinding the stack.  When FLAGS
     contains ‘SCM_F_WIND_EXPLICITLY’, FUNC is called immediately as
     well.

     The function ‘scm_dynwind_rewind_handler_with_scm’ takes care that
     DATA is protected from garbage collection.

 -- C Function: void scm_dynwind_free (void *mem)
     Arrange for MEM to be freed automatically whenever the current
     context is exited, whether normally or non-locally.
     ‘scm_dynwind_free (mem)’ is an equivalent shorthand for
     ‘scm_dynwind_unwind_handler (free, mem, SCM_F_WIND_EXPLICITLY)’.

6.11.11 Fluids and Dynamic States
---------------------------------

A _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
‘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 (see 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
_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 ‘current-dynamic-state’ and restore it later
via ‘with-dynamic-state’ or similar procedures.  This facility is
especially useful when implementing lightweight thread-like
abstractions.

   New fluids are created with ‘make-fluid’ and ‘fluid?’ is used for
testing whether an object is actually a fluid.  The values stored in a
fluid can be accessed with ‘fluid-ref’ and ‘fluid-set!’.

   See Thread Local Variables, for further notes on fluids, threads,
parameters, and dynamic states.

 -- Scheme Procedure: make-fluid [dflt]
 -- C Function: scm_make_fluid ()
 -- C Function: scm_make_fluid_with_default (dflt)
     Return a newly created fluid, whose initial value is DFLT, or ‘#f’
     if 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.

 -- Scheme Procedure: make-unbound-fluid
 -- C Function: scm_make_unbound_fluid ()
     Return a new fluid that is initially unbound (instead of being
     implicitly bound to some definite value).

 -- Scheme Procedure: fluid? obj
 -- C Function: scm_fluid_p (obj)
     Return ‘#t’ if OBJ is a fluid; otherwise, return ‘#f’.

 -- Scheme Procedure: fluid-ref fluid
 -- C Function: scm_fluid_ref (fluid)
     Return the value associated with FLUID in the current dynamic root.
     If FLUID has not been set, then return its default value.  Calling
     ‘fluid-ref’ on an unbound fluid produces a runtime error.

 -- Scheme Procedure: fluid-set! fluid value
 -- C Function: scm_fluid_set_x (fluid, value)
     Set the value associated with FLUID in the current dynamic root.

 -- Scheme Procedure: fluid-ref* fluid depth
 -- C Function: scm_fluid_ref_star (fluid, depth)
     Return the DEPTHth oldest value associated with FLUID in the
     current thread.  If DEPTH equals or exceeds the number of values
     that have been assigned to FLUID, return the default value of the
     fluid.  ‘(fluid-ref* f 0)’ is equivalent to ‘(fluid-ref f)’.

     ‘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 ‘fluid-ref*’ instead of an explicit stack allows
     any partial continuation captured by ‘call-with-prompt’ to only
     capture the bindings made within the limits of the prompt instead
     of the entire continuation.  See Prompts, for more on delimited
     continuations.

 -- Scheme Procedure: fluid-unset! fluid
 -- C Function: scm_fluid_unset_x (fluid)
     Disassociate the given fluid from any value, making it unbound.

 -- Scheme Procedure: fluid-bound? fluid
 -- C Function: scm_fluid_bound_p (fluid)
     Returns ‘#t’ if the given fluid is bound to a value, otherwise
     ‘#f’.

   ‘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.

 -- Scheme Procedure: with-fluid* fluid value thunk
 -- C Function: scm_with_fluid (fluid, value, thunk)
     Set FLUID to VALUE temporarily, and call THUNK.  THUNK must be a
     procedure with no argument.

 -- Scheme Procedure: with-fluids* fluids values thunk
 -- C Function: scm_with_fluids (fluids, values, thunk)
     Set FLUIDS to VALUES temporary, and call THUNK.  FLUIDS must be a
     list of fluids and VALUES must be the same number of their values
     to be applied.  Each substitution is done in the order given.
     THUNK must be a procedure with no argument.  It is called inside a
     ‘dynamic-wind’ and the fluids are set/restored when control enter
     or leaves the established dynamic extent.

 -- Scheme Macro: with-fluids ((fluid value) ...) body
     Execute BODY (see Local Bindings) while each FLUID is set to
     the corresponding VALUE.  Both FLUID and VALUE are evaluated and
     FLUID must yield a fluid.  The body is executed inside a
     ‘dynamic-wind’ and the fluids are set/restored when control enter
     or leaves the established dynamic extent.

 -- C Function: SCM scm_c_with_fluids (SCM fluids, SCM vals, SCM
          (*cproc)(void *), void *data)
 -- C Function: SCM scm_c_with_fluid (SCM fluid, SCM val, SCM
          (*cproc)(void *), void *data)
     The function ‘scm_c_with_fluids’ is like ‘scm_with_fluids’ except
     that it takes a C function to call instead of a Scheme thunk.

     The function ‘scm_c_with_fluid’ is similar but only allows one
     fluid to be set instead of a list.

 -- C Function: void scm_dynwind_fluid (SCM fluid, SCM val)
     This function must be used inside a pair of calls to
     ‘scm_dynwind_begin’ and ‘scm_dynwind_end’ (see Dynamic Wind).
     During the dynwind context, the fluid FLUID is set to 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 VAL argument.

 -- Scheme Procedure: dynamic-state? obj
 -- C Function: scm_dynamic_state_p (obj)
     Return ‘#t’ if OBJ is a dynamic state object; return ‘#f’
     otherwise.

 -- C Procedure: int scm_is_dynamic_state (SCM obj)
     Return non-zero if OBJ is a dynamic state object; return zero
     otherwise.

 -- Scheme Procedure: current-dynamic-state
 -- C Function: scm_current_dynamic_state ()
     Return a snapshot of the current fluid-value associations as a
     fresh dynamic state object.

 -- Scheme Procedure: set-current-dynamic-state state
 -- C Function: scm_set_current_dynamic_state (state)
     Restore the saved fluid-value associations from STATE, replacing
     the current fluid-value associations.  Return the current
     fluid-value associations as a dynamic state object, as in
     ‘current-dynamic-state’.

 -- Scheme Procedure: with-dynamic-state state proc
 -- C Function: scm_with_dynamic_state (state, proc)
     Call PROC while the fluid bindings from STATE have been made
     current, saving the current fluid bindings.  When control leaves
     the invocation of PROC, restore the saved bindings, saving instead
     the fluid bindings from inside the call.  If control later
     re-enters PROC, restore those saved bindings, saving the current
     bindings, and so on.

 -- C Procedure: void scm_dynwind_current_dynamic_state (SCM state)
     Set the current dynamic state to STATE for the current dynwind
     context.  Like ‘with-dynamic-state’, but in terms of Guile's
     "dynwind" C API.

 -- C Procedure: void * scm_c_with_dynamic_state (SCM state, void
          *(*func)(void *), void *data)
     Like ‘scm_with_dynamic_state’, but call FUNC with DATA.

6.11.12 Parameters
------------------

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.

     (define my-param (make-parameter 123))
     (my-param) ⇒ 123
     (my-param 456)
     (my-param) ⇒ 456

   The ‘parameterize’ special form establishes new locations for
parameters, those new locations having effect within the dynamic extent
of the ‘parameterize’ body.  Leaving restores the previous locations.
Re-entering (through a saved continuation) will again use the new
locations.

     (parameterize ((my-param 789))
       (my-param)) ⇒ 789
     (my-param) ⇒ 456

   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 ‘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.

 -- Scheme Procedure: make-parameter init [converter]
     Return a new parameter object, with initial value INIT.

     If a CONVERTER is given, then a call ‘(CONVERTER val)’ is made for
     each value set, its return is the value stored.  Such a call is
     made for the INIT initial value too.

     A CONVERTER allows values to be validated, or put into a canonical
     form.  For 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) ⇒ 3/4

 -- library syntax: parameterize ((param value) ...) body1 body2 ...
     Establish a new dynamic scope with the given PARAMs bound to new
     locations and set to the given VALUEs.  BODY1 BODY2 ... is
     evaluated in that environment.  The value returned is that of last
     body form.

     Each 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 PARAM expressions and VALUE expressions are all evaluated
     before establishing the new dynamic bindings, and they're evaluated
     in an unspecified order.

     For example,

          (define prompt (make-parameter "Type something: "))
          (define (get-input)
            (display (prompt))
            ...)

          (parameterize ((prompt "Type a number: "))
            (get-input)
            ...)

   Parameter objects are implemented using fluids (see Fluids and Dynamic States),
so each dynamic state has its own parameter
locations.  That includes the separate locations when outside any
‘parameterize’ form.  When a parameter is created it gets a separate
initial location in each dynamic state, all initialized to the given
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
‘fluid->parameter’ procedure:

 -- 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 ‘parameterize’, the new value will be run through the optional
     CONV procedure, as with any parameter.  Note that unlike
     ‘make-parameter’, CONV is not applied to the initial value.

   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.

   Guile's parameters conform to SRFI-39 (see SRFI-39).

6.11.13 How to Handle Errors
----------------------------

Guile is currently in a transition from its historical ‘catch’ and
‘throw’ error handling and signaling operators to the new structured
exception facility; see Exceptions.  However in the meantime, here
is some documentation on errors and the older ‘catch’ and ‘throw’
interface.

   Errors are always thrown with a KEY and four arguments:

   • KEY: a symbol which indicates the type of error.  The symbols used
     by libguile are listed below.

   • SUBR: the name of the procedure from which the error is thrown, or
     ‘#f’.

   • MESSAGE: a string (possibly language and system dependent)
     describing the error.  The tokens ‘~A’ and ‘~S’ can be embedded
     within the message: they will be replaced with members of the ARGS
     list when the message is printed.  ‘~A’ indicates an argument
     printed using ‘display’, while ‘~S’ indicates an argument printed
     using ‘write’.  MESSAGE can also be ‘#f’, to allow it to be derived
     from the KEY by the error handler (may be useful if the KEY is to
     be thrown from both C and Scheme).

   • ARGS: a list of arguments to be used to expand ‘~A’ and ‘~S’ tokens
     in MESSAGE.  Can also be ‘#f’ if no arguments are required.

   • REST: a list of any additional objects required.  e.g., when the
     key is ‘'system-error’, this contains the C errno value.  Can also
     be ‘#f’ if no additional objects are required.

   In addition to ‘catch’ and ‘throw’, the following Scheme facilities
are available:

 -- Scheme Procedure: display-error frame port subr message args rest
 -- C Function: scm_display_error (frame, port, subr, message, args,
          rest)
     Display an error message to the output port PORT.  FRAME is the
     frame in which the error occurred, SUBR is the name of the
     procedure in which the error occurred and MESSAGE is the actual
     error message, which may contain formatting instructions.  These
     will format the arguments in the list ARGS accordingly.  REST is
     currently ignored.

   The following are the error keys defined by libguile and the
situations in which they are used:

   • ‘error-signal’: thrown after receiving an unhandled fatal signal
     such as SIGSEGV, SIGBUS, SIGFPE etc.  The REST argument in the
     throw contains the coded signal number (at present this is not the
     same as the usual Unix signal number).

   • ‘system-error’: thrown after the operating system indicates an
     error condition.  The REST argument in the throw contains the errno
     value.

   • ‘numerical-overflow’: numerical overflow.

   • ‘out-of-range’: the arguments to a procedure do not fall within the
     accepted domain.

   • ‘wrong-type-arg’: an argument to a procedure has the wrong type.

   • ‘wrong-number-of-args’: a procedure was called with the wrong
     number of arguments.

   • ‘memory-allocation-error’: memory allocation error.

   • ‘stack-overflow’: stack overflow error.

   • ‘regular-expression-syntax’: errors generated by the regular
     expression library.

   • ‘misc-error’: other errors.

6.11.13.1 C Support
...................

In the following C functions, SUBR and MESSAGE parameters can be ‘NULL’
to give the effect of ‘#f’ described above.

 -- C Function: SCM scm_error (SCM KEY, const char *SUBR, const char
          *MESSAGE, SCM ARGS, SCM REST)
     Throw an error, as per ‘scm-error’ (see Error Reporting).

 -- C Function: void scm_syserror (const char *SUBR)
 -- C Function: void scm_syserror_msg (const char *SUBR, const char
          *MESSAGE, SCM ARGS)
     Throw an error with key ‘system-error’ and supply ‘errno’ in the
     REST argument.  For ‘scm_syserror’ the message is generated using
     ‘strerror’.

     Care should be taken that any code in between the failing operation
     and the call to these routines doesn't change ‘errno’.

 -- C Function: void scm_num_overflow (const char *SUBR)
 -- C Function: void scm_out_of_range (const char *SUBR, SCM BAD_VALUE)
 -- C Function: void scm_wrong_num_args (SCM PROC)
 -- C Function: void scm_wrong_type_arg (const char *SUBR, int ARGNUM,
          SCM BAD_VALUE)
 -- C Function: void scm_wrong_type_arg_msg (const char *SUBR, int
          ARGNUM, SCM BAD_VALUE, const char *EXPECTED)
 -- C Function: void scm_misc_error (const char *SUBR, const char
          *MESSAGE, SCM ARGS)
     Throw an error with the various keys described above.

     In ‘scm_wrong_num_args’, 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 ‘scm_wrong_type_arg_msg’, EXPECTED is a C string describing the
     type of argument that was expected.

     In ‘scm_misc_error’, MESSAGE is the error message string, possibly
     containing ‘simple-format’ escapes (see Simple Output), and the
     corresponding arguments in the ARGS list.

6.11.13.2 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.

 -- Macro: void SCM_ASSERT (int TEST, SCM OBJ, unsigned int POSITION,
          const char *SUBR)
 -- Macro: void SCM_ASSERT_TYPE (int TEST, SCM OBJ, unsigned int
          POSITION, const char *SUBR, const char *EXPECTED)
     If TEST is zero, signal a "wrong type argument" error, attributed
     to the subroutine named SUBR, operating on the value OBJ, which is
     the POSITION'th argument of SUBR.

     In ‘SCM_ASSERT_TYPE’, EXPECTED is a C string describing the type of
     argument that was expected.

 -- Macro: int SCM_ARG1
 -- Macro: int SCM_ARG2
 -- Macro: int SCM_ARG3
 -- Macro: int SCM_ARG4
 -- Macro: int SCM_ARG5
 -- Macro: int SCM_ARG6
 -- Macro: int SCM_ARG7
     One of the above values can be used for POSITION to indicate the
     number of the argument of 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 ‘SCM_ARGN’ instead of
     the corresponding raw number, since it will make the code easier to
     understand.

 -- Macro: int SCM_ARGn
     Passing a value of zero or ‘SCM_ARGn’ for POSITION allows to leave
     it unspecified which argument's type is incorrect.  Again,
     ‘SCM_ARGn’ should be preferred over a raw zero constant.

6.11.14 Continuation Barriers
-----------------------------

The non-local flow of control caused by continuations might sometimes
not be wanted.  You can use ‘with-continuation-barrier’ to erect fences
that continuations can not pass.

 -- Scheme Procedure: with-continuation-barrier proc
 -- C Function: scm_with_continuation_barrier (proc)
     Call PROC and return its result.  Do not allow the invocation of
     continuations that would leave or enter the dynamic extent of the
     call to ‘with-continuation-barrier’.  Such an attempt causes an
     error to be signaled.

     Throws (such as errors) that are not caught from within PROC are
     caught by ‘with-continuation-barrier’.  In that case, a short
     message is printed to the current error port and ‘#f’ is returned.

     Thus, ‘with-continuation-barrier’ returns exactly once.

 -- C Function: void * scm_c_with_continuation_barrier (void *(*func)
          (void *), void *data)
     Like ‘scm_with_continuation_barrier’ but call FUNC on DATA.  When
     an error is caught, ‘NULL’ is returned.

6.12 Input and Output
=====================

6.12.1 Ports
------------

Ports are the way that Guile performs input and output.  Guile can read
in characters or bytes from an “input port”, or write them out to an
“output port”.  Some ports support both interfaces.

   There are a number of different port types implemented in Guile.
File ports provide input and output over files, as you might imagine.
For example, we might display a string to a file like this:

     (let ((port (open-output-file "foo.txt")))
       (display "Hello, world!\n" port)
       (close-port port))

   There are also string ports, for taking input from a string, or
collecting output to a string; bytevector ports, for doing the same but
using a bytevector as a source or sink of data; and custom ports, for
arranging to call Scheme functions to provide input or handle output.
See Port Types.

   Ports should be “closed” when they are not needed by calling
‘close-port’ on them, as in the example above.  This will make sure that
any pending output is successfully written out to disk, in the case of a
file port, or otherwise to whatever mutable store is backed by the port.
Any error that occurs while writing out that buffered data would also be
raised promptly at the ‘close-port’, and not later when the port is
closed by the garbage collector.  See Buffering, for more on
buffered output.

   Closing a port also releases any precious resource the file might
have.  Usually in Scheme a programmer doesn't have to clean up after
their data structures (see Memory Management), but most systems have
strict limits on how many files can be open, both on a per-process and a
system-wide basis.  A program that uses many files should take care not
to hit those limits.  The same applies to similar system resources such
as pipes and sockets.

   Indeed for these reasons the above example is not the most idiomatic
way to use ports.  It is more common to acquire ports via procedures
like ‘call-with-output-file’, which handle the ‘close-port’
automatically:

     (call-with-output-file "foo.txt"
       (lambda (port)
         (display "Hello, world!\n" port)))

   Finally, all ports have associated input and output buffers, as
appropriate.  Buffering is a common strategy to limit the overhead of
small reads and writes: without buffering, each character fetched from a
file would involve at least one call into the kernel, and maybe more
depending on the character and the encoding.  Instead, Guile will batch
reads and writes into internal buffers.  However, sometimes you want to
make output on a port show up immediately.  See Buffering, for more
on interfaces to control port buffering.

 -- Scheme Procedure: port? x
 -- C Function: scm_port_p (x)
     Return a boolean indicating whether X is a port.  Equivalent to
     ‘(or (input-port? X) (output-port? X))’.

 -- Scheme Procedure: input-port? x
 -- C Function: scm_input_port_p (x)
     Return ‘#t’ if X is an input port, otherwise return ‘#f’.  Any
     object satisfying this predicate also satisfies ‘port?’.

 -- Scheme Procedure: output-port? x
 -- C Function: scm_output_port_p (x)
     Return ‘#t’ if X is an output port, otherwise return ‘#f’.  Any
     object satisfying this predicate also satisfies ‘port?’.

 -- Scheme Procedure: close-port port
 -- C Function: scm_close_port (port)
     Close the specified port object.  Return ‘#t’ if it successfully
     closes a port or ‘#f’ if it was already closed.  An exception may
     be raised if an error occurs, for example when flushing buffered
     output.  See Buffering, for more on buffered output.  See
     close, for a procedure which can close
     file descriptors.

 -- Scheme Procedure: port-closed? port
 -- C Function: scm_port_closed_p (port)
     Return ‘#t’ if PORT is closed or ‘#f’ if it is open.

 -- Scheme Procedure: call-with-port port proc
     Call PROC, passing it PORT and closing PORT upon exit of PROC.
     Return the return values of PROC.

6.12.2 Binary I/O
-----------------

Guile's ports are fundamentally binary in nature: at the lowest level,
they work on bytes.  This section describes Guile's core binary I/O
operations.  See Textual I/O, for input and output of strings and
characters.

   To use these routines, first include the binary I/O module:

     (use-modules (ice-9 binary-ports))

   Note that although this module's name suggests that binary ports are
some different kind of port, that's not the case: all ports in Guile are
both binary and textual ports.

 -- Scheme Procedure: get-u8 port
 -- C Function: scm_get_u8 (port)
     Return an octet read from PORT, an input port, blocking as
     necessary, or the end-of-file object.

 -- Scheme Procedure: lookahead-u8 port
 -- C Function: scm_lookahead_u8 (port)
     Like ‘get-u8’ but does not update PORT's position to point past the
     octet.

   The end-of-file object is unlike any other kind of object: it's not a
pair, a symbol, or anything else.  To check if a value is the
end-of-file object, use the ‘eof-object?’ predicate.

 -- Scheme Procedure: eof-object? x
 -- C Function: scm_eof_object_p (x)
     Return ‘#t’ if X is an end-of-file object, or ‘#f’ otherwise.

   Note that unlike other procedures in this module, ‘eof-object?’ is
defined in the default environment.

 -- Scheme Procedure: get-bytevector-n port count
 -- C Function: scm_get_bytevector_n (port, count)
     Read COUNT octets from PORT, blocking as necessary and return a
     bytevector containing the octets read.  If fewer bytes are
     available, a bytevector smaller than COUNT is returned.

 -- Scheme Procedure: get-bytevector-n! port bv start count
 -- C Function: scm_get_bytevector_n_x (port, bv, start, count)
     Read COUNT bytes from PORT and store them in BV starting at index
     START.  Return either the number of bytes actually read or the
     end-of-file object.

 -- Scheme Procedure: get-bytevector-some port
 -- C Function: scm_get_bytevector_some (port)
     Read from PORT, blocking as necessary, until bytes are available or
     an end-of-file is reached.  Return either the end-of-file object or
     a new bytevector containing some of the available bytes (at least
     one), and update the port position to point just past these bytes.

 -- Scheme Procedure: get-bytevector-some! port bv start count
 -- C Function: scm_get_bytevector_some_x (port, bv, start, count)
     Read up to COUNT bytes from PORT, blocking as necessary until at
     least one byte is available or an end-of-file is reached.  Store
     them in BV starting at index START.  Return the number of bytes
     actually read, or an end-of-file object.

 -- Scheme Procedure: get-bytevector-all port
 -- C Function: scm_get_bytevector_all (port)
     Read from PORT, blocking as necessary, until the end-of-file is
     reached.  Return either a new bytevector containing the data read
     or the end-of-file object (if no data were available).

 -- Scheme Procedure: unget-bytevector port bv [start [count]]
 -- C Function: scm_unget_bytevector (port, bv, start, count)
     Place the contents of BV in PORT, optionally starting at index
     START and limiting to COUNT octets, so that its bytes will be read
     from left-to-right as the next bytes from PORT during subsequent
     read operations.  If called multiple times, the unread bytes will
     be read again in last-in first-out order.

   To perform binary output on a port, use ‘put-u8’ or ‘put-bytevector’.

 -- Scheme Procedure: put-u8 port octet
 -- C Function: scm_put_u8 (port, octet)
     Write OCTET, an integer in the 0-255 range, to PORT, a binary
     output port.

 -- Scheme Procedure: put-bytevector port bv [start [count]]
 -- C Function: scm_put_bytevector (port, bv, start, count)
     Write the contents of BV to PORT, optionally starting at index
     START and limiting to COUNT octets.

Binary I/O in R7RS
..................

R7RS defines the following binary I/O
procedures.  Access them with

     (use-modules (scheme base))

 -- Scheme Procedure: open-output-bytevector
     Returns a binary output port that will accumulate bytes for
     retrieval by ‘get-output-bytevector’.

 -- Scheme Procedure: write-u8 byte [out]
     Writes BYTE to the given binary output port OUT and returns an
     unspecified value.  OUT defaults to ‘(current-output-port)’.

     See also ‘put-u8’.

 -- Scheme Procedure: read-u8 [in]
     Returns the next byte available from the binary input port IN,
     updating the port to point to the following byte.  If no more bytes
     are available, an end-of-file object is returned.  IN defaults to
     ‘(current-input-port)’.

     See also ‘get-u8’.

 -- Scheme Procedure: peek-u8 [in]
     Returns the next byte available from the binary input port IN, but
     without updating the port to point to the following byte.  If no
     more bytes are available, an end-of-file object is returned.  IN
     defaults to ‘(current-input-port)’.

     See also ‘lookahead-u8’.

 -- Scheme Procedure: get-output-bytevector port
     Returns a bytevector consisting of the bytes that have been output
     to PORT so far in the order they were output.  It is an error if
     PORT was not created with ‘open-output-bytevector’.

          (define out (open-output-bytevector))
          (write-u8 1 out)
          (write-u8 2 out)
          (write-u8 3 out)
          (get-output-bytevector out) ⇒ #vu8(1 2 3)

 -- Scheme Procedure: open-input-bytevector bv
     Takes a bytevector BV and returns a binary input port that delivers
     bytes from BV.

          (define in (open-input-bytevector #vu8(1 2 3)))
          (read-u8 in) ⇒ 1
          (peek-u8 in) ⇒ 2
          (read-u8 in) ⇒ 2
          (read-u8 in) ⇒ 3
          (read-u8 in) ⇒ #<eof>

 -- Scheme Procedure: read-bytevector! bv [port [start [end]]]
     Reads the next END - START bytes, or as many as are available
     before the end of file, from the binary input port into the
     bytevector BV in left-to-right order beginning at the START
     position.  If END is not supplied, reads until the end of BV has
     been reached.  If START is not supplied, reads beginning at
     position 0.

     Returns the number of bytes read.  If no bytes are available, an
     end-of-file object is returned.

          (define in (open-input-bytevector #vu8(1 2 3)))
          (define bv (make-bytevector 5 0))
          (read-bytevector! bv in 1 3) ⇒ 2
          bv ⇒ #vu8(0 1 2 0 0 0)

 -- Scheme Procedure: read-bytevector k in
     Reads the next K bytes, or as many as are available before the end
     of file if that is less than K, from the binary input port IN into
     a newly allocated bytevector in left-to-right order, and returns
     the bytevector.  If no bytes are available before the end of file,
     an end-of-file object is returned.

          (define bv #vu8(1 2 3))
          (read-bytevector 2 (open-input-bytevector bv)) ⇒ #vu8(1 2)
          (read-bytevector 10 (open-input-bytevector bv)) ⇒ #vu8(1 2 3)

 -- Scheme Procedure: write-bytevector bv [port [start [end]]]
     Writes the bytes of bytevector BV from START to END in
     left-to-right order to the binary output PORT.  START defaults to 0
     and END defaults to the length of BV.

          (define out (open-output-bytevector))
          (write-bytevector #vu8(0 1 2 3 4) out 2 4)
          (get-output-bytevector out) ⇒ #vu8(2 3)

6.12.3 Encoding
---------------

Textual input and output on Guile ports is layered on top of binary
operations.  To this end, each port has an associated character encoding
that controls how bytes read from the port are converted to characters,
and how characters written to the port are converted to bytes.

 -- Scheme Procedure: port-encoding port
 -- C Function: scm_port_encoding (port)
     Returns, as a string, the character encoding that PORT uses to
     interpret its input and output.

 -- Scheme Procedure: set-port-encoding! port enc
 -- C Function: scm_set_port_encoding_x (port, enc)
     Sets the character encoding that will be used to interpret I/O to
     PORT.  ENC is a string containing the name of an encoding.  Valid
     encoding names are those defined by IANA
     (http://www.iana.org/assignments/character-sets), for example
     ‘"UTF-8"’ or ‘"ISO-8859-1"’.

   When ports are created, they are assigned an encoding.  The usual
process to determine the initial encoding for a port is to take the
value of the ‘%default-port-encoding’ fluid.

 -- Scheme Variable: %default-port-encoding
     A fluid containing name of the encoding to be used by default for
     newly created ports (see Fluids and Dynamic States).  As a
     special case, the value ‘#f’ is equivalent to ‘"ISO-8859-1"’.

   The ‘%default-port-encoding’ itself defaults to the encoding
appropriate for the current locale, if ‘setlocale’ has been called.
See Locales, for more on locales and when you might need to call
‘setlocale’ explicitly.

   Some port types have other ways of determining their initial locales.
String ports, for example, default to the UTF-8 encoding, in order to be
able to represent all characters regardless of the current locale.  File
ports can optionally sniff their file for a ‘coding:’ declaration; see
File Ports.  Binary ports might be initialized to the ISO-8859-1
encoding in which each codepoint between 0 and 255 corresponds to a byte
with that value.

   Currently, the ports only work with _non-modal_ encodings.  Most
encodings are non-modal, meaning that the conversion of bytes to a
string doesn't depend on its context: the same byte sequence will always
return the same string.  A couple of modal encodings are in common use,
like ISO-2022-JP and ISO-2022-KR, and they are not yet supported.

   Each port also has an associated conversion strategy, which
determines what to do when a Guile character can't be converted to the
port's encoded character representation for output.  There are three
possible strategies: to raise an error, to replace the character with a
hex escape, or to replace the character with a substitute character.
Port conversion strategies are also used when decoding characters from
an input port.

 -- Scheme Procedure: port-conversion-strategy port
 -- C Function: scm_port_conversion_strategy (port)
     Returns the behavior of the port when outputting a character that
     is not representable in the port's current encoding.

     If PORT is ‘#f’, then the current default behavior will be
     returned.  New ports will have this default behavior when they are
     created.

 -- Scheme Procedure: set-port-conversion-strategy! port sym
 -- C Function: scm_set_port_conversion_strategy_x (port, sym)
     Sets the behavior of Guile when outputting a character that is not
     representable in the port's current encoding, or when Guile
     encounters a decoding error when trying to read a character.  SYM
     can be either ‘error’, ‘substitute’, or ‘escape’.

     If PORT is an open port, the conversion error behavior is set for
     that port.  If it is ‘#f’, it is set as the default behavior for
     any future ports that get created in this thread.

   As with port encodings, there is a fluid which determines the initial
conversion strategy for a port.

 -- Scheme Variable: %default-port-conversion-strategy
     The fluid that defines the conversion strategy for newly created
     ports, and also for other conversion routines such as
     ‘scm_to_stringn’, ‘scm_from_stringn’, ‘string->pointer’, and
     ‘pointer->string’.

     Its value must be one of the symbols described above, with the same
     semantics: ‘error’, ‘substitute’, or ‘escape’.

     When Guile starts, its value is ‘substitute’.

     Note that ‘(set-port-conversion-strategy! #f SYM)’ is equivalent to
     ‘(fluid-set! %default-port-conversion-strategy SYM)’.

   As mentioned above, for an output port there are three possible port
conversion strategies.  The ‘error’ strategy will throw an error when a
nonconvertible character is encountered.  The ‘substitute’ strategy will
replace nonconvertible characters with a question mark (‘?’).  Finally
the ‘escape’ strategy will print nonconvertible characters as a hex
escape, using the escaping that is recognized by Guile's string syntax.
Note that if the port's encoding is a Unicode encoding, like ‘UTF-8’,
then encoding errors are impossible.

   For an input port, the ‘error’ strategy will cause Guile to throw an
error if it encounters an invalid encoding, such as might happen if you
tried to read ‘ISO-8859-1’ as ‘UTF-8’.  The error is thrown before
advancing the read position.  The ‘substitute’ strategy will replace the
bad bytes with a U+FFFD replacement character, in accordance with
Unicode recommendations.  When reading from an input port, the ‘escape’
strategy is treated as if it were ‘error’.

6.12.4 Textual I/O
------------------

This section describes Guile's core textual I/O operations on characters
and strings.  See Binary I/O, for input and output of bytes and
bytevectors.  See Encoding, for more on how characters relate to
bytes.  To read general S-expressions from ports, see Scheme Read.
See Scheme Write, for interfaces that write generic Scheme datums.

   To use these routines, first include the textual I/O module:

     (use-modules (ice-9 textual-ports))

   Note that although this module's name suggests that textual ports are
some different kind of port, that's not the case: all ports in Guile are
both binary and textual ports.

 -- Scheme Procedure: get-char input-port
     Reads from INPUT-PORT, blocking as necessary, until a complete
     character is available from INPUT-PORT, or until an end of file is
     reached.

     If a complete character is available before the next end of file,
     ‘get-char’ returns that character and updates the input port to
     point past the character.  If an end of file is reached before any
     character is read, ‘get-char’ returns the end-of-file object.

 -- Scheme Procedure: lookahead-char input-port
     The ‘lookahead-char’ procedure is like ‘get-char’, but it does not
     update INPUT-PORT to point past the character.

   In the same way that it's possible to "unget" a byte or bytes, it's
possible to "unget" the bytes corresponding to an encoded character.

 -- Scheme Procedure: unget-char port char
     Place character CHAR in PORT so that it will be read by the next
     read operation.  If called multiple times, the unread characters
     will be read again in last-in first-out order.

 -- Scheme Procedure: unget-string port str
     Place the string STR in PORT so that its characters will be read
     from left-to-right as the next characters from PORT during
     subsequent read operations.  If called multiple times, the unread
     characters will be read again in last-in first-out order.

   Reading in a character at a time can be inefficient.  If it's
possible to perform I/O over multiple characters at a time, via strings,
that might be faster.

 -- Scheme Procedure: get-string-n input-port count
     The ‘get-string-n’ procedure reads from INPUT-PORT, blocking as
     necessary, until COUNT characters are available, or until an end of
     file is reached.  COUNT must be an exact, non-negative integer,
     representing the number of characters to be read.

     If COUNT characters are available before end of file,
     ‘get-string-n’ returns a string consisting of those COUNT
     characters.  If fewer characters are available before an end of
     file, but one or more characters can be read, ‘get-string-n’
     returns a string containing those characters.  In either case, the
     input port is updated to point just past the characters read.  If
     no characters can be read before an end of file, the end-of-file
     object is returned.

 -- Scheme Procedure: get-string-n! input-port string start count
     The ‘get-string-n!’ procedure reads from INPUT-PORT in the same
     manner as ‘get-string-n’.  START and COUNT must be exact,
     non-negative integer objects, with COUNT representing the number of
     characters to be read.  STRING must be a string with at least
     $START + COUNT$ characters.

     If COUNT characters are available before an end of file, they are
     written into STRING starting at index START, and COUNT is returned.
     If fewer characters are available before an end of file, but one or
     more can be read, those characters are written into STRING starting
     at index START and the number of characters actually read is
     returned as an exact integer object.  If no characters can be read
     before an end of file, the end-of-file object is returned.

 -- Scheme Procedure: get-string-all input-port
     Reads from INPUT-PORT until an end of file, decoding characters in
     the same manner as ‘get-string-n’ and ‘get-string-n!’.

     If characters are available before the end of file, a string
     containing all the characters decoded from that data are returned.
     If no character precedes the end of file, the end-of-file object is
     returned.

 -- Scheme Procedure: get-line input-port
     Reads from INPUT-PORT up to and including the linefeed character or
     end of file, decoding characters in the same manner as
     ‘get-string-n’ and ‘get-string-n!’.

     If a linefeed character is read, a string containing all of the
     text up to (but not including) the linefeed character is returned,
     and the port is updated to point just past the linefeed character.
     If an end of file is encountered before any linefeed character is
     read, but some characters have been read and decoded as characters,
     a string containing those characters is returned.  If an end of
     file is encountered before any characters are read, the end-of-file
     object is returned.

   Finally, there are just two core procedures to write characters to a
port.

 -- Scheme Procedure: put-char port char
     Writes CHAR to the port.  The ‘put-char’ procedure returns an
     unspecified value.

 -- Scheme Procedure: put-string port string
 -- Scheme Procedure: put-string port string start
 -- Scheme Procedure: put-string port string start count
     Write the COUNT characters of STRING starting at index START to the
     port.

     START and COUNT must be non-negative exact integer objects.  STRING
     must have a length of at least START + COUNT.  START defaults to 0.
     COUNT defaults to ‘(string-length STRING)’ - START$.

     Calling ‘put-string’ is equivalent in all respects to calling
     ‘put-char’ on the relevant sequence of characters, except that it
     will attempt to write multiple characters to the port at a time,
     even if the port is unbuffered.

     The ‘put-string’ procedure returns an unspecified value.

   Textual ports have a textual position associated with them: a line
and a column.  Reading in characters or writing them out advances the
line and the column appropriately.

 -- Scheme Procedure: port-column port
 -- Scheme Procedure: port-line port
 -- C Function: scm_port_column (port)
 -- C Function: scm_port_line (port)
     Return the current column number or line number of PORT.

   Port lines and positions are represented as 0-origin integers, which
is to say that the first character of the first line is line 0, column
0.  However, when you display a line number, for example in an error
message, we recommend you add 1 to get 1-origin integers.  This is
because lines numbers traditionally start with 1, and that is what
non-programmers will find most natural.

 -- Scheme Procedure: set-port-column! port column
 -- Scheme Procedure: set-port-line! port line
 -- C Function: scm_set_port_column_x (port, column)
 -- C Function: scm_set_port_line_x (port, line)
     Set the current column or line number of PORT.