This manual documents Guile version 2.0.14.

   Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2009,
2010, 2011, 2012, 2013, 2014, 2015, 2016 Free Software Foundation.

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

7.4.5 Reference Documentation for ‘option-ref’
----------------------------------------------

 -- Scheme Procedure: option-ref options key default
     Search OPTIONS for a command line option named KEY and return its
     value, if found.  If the option has no value, but was given, return
     ‘#t’.  If the option was not given, return DEFAULT.  OPTIONS must
     be the result of a call to ‘getopt-long’.

   ‘option-ref’ always succeeds, either by returning the requested
option value from the command line, or the default value.

   The special key ‘'()’ can be used to get a list of all non-option
arguments.

7.5 SRFI Support Modules
========================

SRFI is an acronym for Scheme Request For Implementation.  The SRFI
documents define a lot of syntactic and procedure extensions to standard
Scheme as defined in R5RS.

   Guile has support for a number of SRFIs.  This chapter gives an
overview over the available SRFIs and some usage hints.  For complete
documentation, design rationales and further examples, we advise you to
get the relevant SRFI documents from the SRFI home page
<http://srfi.schemers.org/>.

7.5.1 About SRFI Usage
----------------------

SRFI support in Guile is currently implemented partly in the core
library, and partly as add-on modules.  That means that some SRFIs are
automatically available when the interpreter is started, whereas the
other SRFIs require you to use the appropriate support module
explicitly.

   There are several reasons for this inconsistency.  First, the feature
checking syntactic form ‘cond-expand’ (see SRFI-0) must be available
immediately, because it must be there when the user wants to check for
the Scheme implementation, that is, before she can know that it is safe
to use ‘use-modules’ to load SRFI support modules.  The second reason is
that some features defined in SRFIs had been implemented in Guile before
the developers started to add SRFI implementations as modules (for
example SRFI-13 (see SRFI-13)).  In the future, it is possible that
SRFIs in the core library might be factored out into separate modules,
requiring explicit module loading when they are needed.  So you should
be prepared to have to use ‘use-modules’ someday in the future to access
SRFI-13 bindings.  If you want, you can do that already.  We have
included the module ‘(srfi srfi-13)’ in the distribution, which
currently does nothing, but ensures that you can write future-safe code.

   Generally, support for a specific SRFI is made available by using
modules named ‘(srfi srfi-NUMBER)’, where NUMBER is the number of the
SRFI needed.  Another possibility is to use the command line option
‘--use-srfi’, which will load the necessary modules automatically (see
Invoking Guile).

7.5.2 SRFI-0 - cond-expand
--------------------------

This SRFI lets a portable Scheme program test for the presence of
certain features, and adapt itself by using different blocks of code, or
fail if the necessary features are not available.  There’s no module to
load, this is in the Guile core.

   A program designed only for Guile will generally not need this
mechanism, such a program can of course directly use the various
documented parts of Guile.

 -- syntax: cond-expand (feature body...) ...
     Expand to the BODY of the first clause whose FEATURE specification
     is satisfied.  It is an error if no FEATURE is satisfied.

     Features are symbols such as ‘srfi-1’, and a feature specification
     can use ‘and’, ‘or’ and ‘not’ forms to test combinations.  The last
     clause can be an ‘else’, to be used if no other passes.

     For example, define a private version of ‘alist-cons’ if SRFI-1 is
     not available.

          (cond-expand (srfi-1
                        )
                       (else
                        (define (alist-cons key val alist)
                          (cons (cons key val) alist))))

     Or demand a certain set of SRFIs (list operations, string ports,
     ‘receive’ and string operations), failing if they’re not available.

          (cond-expand ((and srfi-1 srfi-6 srfi-8 srfi-13)
                        ))

The Guile core has the following features,

     guile
     guile-2  ;; starting from Guile 2.x
     r5rs
     srfi-0
     srfi-4
     srfi-13
     srfi-14
     srfi-16
     srfi-23
     srfi-30
     srfi-39
     srfi-46
     srfi-55
     srfi-61
     srfi-62
     srfi-87
     srfi-105

   Other SRFI feature symbols are defined once their code has been
loaded with ‘use-modules’, since only then are their bindings available.

   The ‘--use-srfi’ command line option (see Invoking Guile) is a
good way to load SRFIs to satisfy ‘cond-expand’ when running a portable
program.

   Testing the ‘guile’ feature allows a program to adapt itself to the
Guile module system, but still run on other Scheme systems.  For example
the following demands SRFI-8 (‘receive’), but also knows how to load it
with the Guile mechanism.

     (cond-expand (srfi-8
                   )
                  (guile
                   (use-modules (srfi srfi-8))))

   Likewise, testing the ‘guile-2’ feature allows code to be portable
between Guile 2.0 and previous versions of Guile.  For instance, it
makes it possible to write code that accounts for Guile 2.0’s compiler,
yet be correctly interpreted on 1.8 and earlier versions:

     (cond-expand (guile-2 (eval-when (compile)
                             ;; This must be evaluated at compile time.
                             (fluid-set! current-reader my-reader)))
                  (guile
                           ;; Earlier versions of Guile do not have a
                           ;; separate compilation phase.
                           (fluid-set! current-reader my-reader)))

   It should be noted that ‘cond-expand’ is separate from the
‘*features*’ mechanism (see Feature Tracking), feature symbols in
one are unrelated to those in the other.

7.5.3 SRFI-1 - List library
---------------------------

The list library defined in SRFI-1 contains a lot of useful list
processing procedures for construction, examining, destructuring and
manipulating lists and pairs.

   Since SRFI-1 also defines some procedures which are already contained
in R5RS and thus are supported by the Guile core library, some list and
pair procedures which appear in the SRFI-1 document may not appear in
this section.  So when looking for a particular list/pair processing
procedure, you should also have a look at the sections Lists and
Pairs.

7.5.3.1 Constructors
....................

New lists can be constructed by calling one of the following procedures.

 -- Scheme Procedure: xcons d a
     Like ‘cons’, but with interchanged arguments.  Useful mostly when
     passed to higher-order procedures.

 -- Scheme Procedure: list-tabulate n init-proc
     Return an N-element list, where each list element is produced by
     applying the procedure INIT-PROC to the corresponding list index.
     The order in which INIT-PROC is applied to the indices is not
     specified.

 -- Scheme Procedure: list-copy lst
     Return a new list containing the elements of the list LST.

     This function differs from the core ‘list-copy’ (see List Constructors)
     in accepting improper lists too.  And if LST is not
     a pair at all then it’s treated as the final tail of an improper
     list and simply returned.

 -- Scheme Procedure: circular-list elt1 elt2 ...
     Return a circular list containing the given arguments ELT1 ELT2
     ....

 -- Scheme Procedure: iota count [start step]
     Return a list containing COUNT numbers, starting from START and
     adding STEP each time.  The default START is 0, the default STEP is
     1.  For example,

          (iota 6)        ⇒ (0 1 2 3 4 5)
          (iota 4 2.5 -2) ⇒ (2.5 0.5 -1.5 -3.5)

     This function takes its name from the corresponding primitive in
     the APL language.

7.5.3.2 Predicates
..................

The procedures in this section test specific properties of lists.

 -- Scheme Procedure: proper-list? obj
     Return ‘#t’ if OBJ is a proper list, or ‘#f’ otherwise.  This is
     the same as the core ‘list?’ (see List Predicates).

     A proper list is a list which ends with the empty list ‘()’ in the
     usual way.  The empty list ‘()’ itself is a proper list too.

          (proper-list? '(1 2 3))  ⇒ #t
          (proper-list? '())       ⇒ #t

 -- Scheme Procedure: circular-list? obj
     Return ‘#t’ if OBJ is a circular list, or ‘#f’ otherwise.

     A circular list is a list where at some point the ‘cdr’ refers back
     to a previous pair in the list (either the start or some later
     point), so that following the ‘cdr’s takes you around in a circle,
     with no end.

          (define x (list 1 2 3 4))
          (set-cdr! (last-pair x) (cddr x))
          x ⇒ (1 2 3 4 3 4 3 4 ...)
          (circular-list? x)  ⇒ #t

 -- Scheme Procedure: dotted-list? obj
     Return ‘#t’ if OBJ is a dotted list, or ‘#f’ otherwise.

     A dotted list is a list where the ‘cdr’ of the last pair is not the
     empty list ‘()’.  Any non-pair OBJ is also considered a dotted
     list, with length zero.

          (dotted-list? '(1 2 . 3))  ⇒ #t
          (dotted-list? 99)          ⇒ #t

   It will be noted that any Scheme object passes exactly one of the
above three tests ‘proper-list?’, ‘circular-list?’ and ‘dotted-list?’.
Non-lists are ‘dotted-list?’, finite lists are either ‘proper-list?’ or
‘dotted-list?’, and infinite lists are ‘circular-list?’.

 -- Scheme Procedure: null-list? lst
     Return ‘#t’ if LST is the empty list ‘()’, ‘#f’ otherwise.  If
     something else than a proper or circular list is passed as LST, an
     error is signalled.  This procedure is recommended for checking for
     the end of a list in contexts where dotted lists are not allowed.

 -- Scheme Procedure: not-pair? obj
     Return ‘#t’ is OBJ is not a pair, ‘#f’ otherwise.  This is
     shorthand notation ‘(not (pair? OBJ))’ and is supposed to be used
     for end-of-list checking in contexts where dotted lists are
     allowed.

 -- Scheme Procedure: list= elt= list1 ...
     Return ‘#t’ if all argument lists are equal, ‘#f’ otherwise.  List
     equality is determined by testing whether all lists have the same
     length and the corresponding elements are equal in the sense of the
     equality predicate ELT=.  If no or only one list is given, ‘#t’ is
     returned.

7.5.3.3 Selectors
.................

 -- Scheme Procedure: first pair
 -- Scheme Procedure: second pair
 -- Scheme Procedure: third pair
 -- Scheme Procedure: fourth pair
 -- Scheme Procedure: fifth pair
 -- Scheme Procedure: sixth pair
 -- Scheme Procedure: seventh pair
 -- Scheme Procedure: eighth pair
 -- Scheme Procedure: ninth pair
 -- Scheme Procedure: tenth pair
     These are synonyms for ‘car’, ‘cadr’, ‘caddr’, ....

 -- Scheme Procedure: car+cdr pair
     Return two values, the CAR and the CDR of PAIR.

 -- Scheme Procedure: take lst i
 -- Scheme Procedure: take! lst i
     Return a list containing the first I elements of LST.

     ‘take!’ may modify the structure of the argument list LST in order
     to produce the result.

 -- Scheme Procedure: drop lst i
     Return a list containing all but the first I elements of LST.

 -- Scheme Procedure: take-right lst i
     Return a list containing the I last elements of LST.  The return
     shares a common tail with LST.

 -- Scheme Procedure: drop-right lst i
 -- Scheme Procedure: drop-right! lst i
     Return a list containing all but the I last elements of LST.

     ‘drop-right’ always returns a new list, even when I is zero.
     ‘drop-right!’ may modify the structure of the argument list LST in
     order to produce the result.

 -- Scheme Procedure: split-at lst i
 -- Scheme Procedure: split-at! lst i
     Return two values, a list containing the first I elements of the
     list LST and a list containing the remaining elements.

     ‘split-at!’ may modify the structure of the argument list LST in
     order to produce the result.

 -- Scheme Procedure: last lst
     Return the last element of the non-empty, finite list LST.

7.5.3.4 Length, Append, Concatenate, etc.
.........................................

 -- Scheme Procedure: length+ lst
     Return the length of the argument list LST.  When LST is a circular
     list, ‘#f’ is returned.

 -- Scheme Procedure: concatenate list-of-lists
 -- Scheme Procedure: concatenate! list-of-lists
     Construct a list by appending all lists in LIST-OF-LISTS.

     ‘concatenate!’ may modify the structure of the given lists in order
     to produce the result.

     ‘concatenate’ is the same as ‘(apply append LIST-OF-LISTS)’.  It
     exists because some Scheme implementations have a limit on the
     number of arguments a function takes, which the ‘apply’ might
     exceed.  In Guile there is no such limit.

 -- Scheme Procedure: append-reverse rev-head tail
 -- Scheme Procedure: append-reverse! rev-head tail
     Reverse REV-HEAD, append TAIL to it, and return the result.  This
     is equivalent to ‘(append (reverse REV-HEAD) TAIL)’, but its
     implementation is more efficient.

          (append-reverse '(1 2 3) '(4 5 6)) ⇒ (3 2 1 4 5 6)

     ‘append-reverse!’ may modify REV-HEAD in order to produce the
     result.

 -- Scheme Procedure: zip lst1 lst2 ...
     Return a list as long as the shortest of the argument lists, where
     each element is a list.  The first list contains the first elements
     of the argument lists, the second list contains the second
     elements, and so on.

 -- Scheme Procedure: unzip1 lst
 -- Scheme Procedure: unzip2 lst
 -- Scheme Procedure: unzip3 lst
 -- Scheme Procedure: unzip4 lst
 -- Scheme Procedure: unzip5 lst
     ‘unzip1’ takes a list of lists, and returns a list containing the
     first elements of each list, ‘unzip2’ returns two lists, the first
     containing the first elements of each lists and the second
     containing the second elements of each lists, and so on.

 -- Scheme Procedure: count pred lst1 lst2 ...
     Return a count of the number of times PRED returns true when called
     on elements from the given lists.

     PRED is called with N parameters ‘(PRED ELEM1 ... ELEMN )’, each
     element being from the corresponding list.  The first call is with
     the first element of each list, the second with the second element
     from each, and so on.

     Counting stops when the end of the shortest list is reached.  At
     least one list must be non-circular.

7.5.3.5 Fold, Unfold & Map
..........................

 -- Scheme Procedure: fold proc init lst1 lst2 ...
 -- Scheme Procedure: fold-right proc init lst1 lst2 ...
     Apply PROC to the elements of LST1 LST2 ... to build a result, and
     return that result.

     Each PROC call is ‘(PROC ELEM1 ELEM2 ... PREVIOUS)’, where ELEM1 is
     from LST1, ELEM2 is from LST2, and so on.  PREVIOUS is the return
     from the previous call to PROC, or the given INIT for the first
     call.  If any list is empty, just INIT is returned.

     ‘fold’ works through the list elements from first to last.  The
     following shows a list reversal and the calls it makes,

          (fold cons '() '(1 2 3))

          (cons 1 '())
          (cons 2 '(1))
          (cons 3 '(2 1)
          ⇒ (3 2 1)

     ‘fold-right’ works through the list elements from last to first,
     ie. from the right.  So for example the following finds the longest
     string, and the last among equal longest,

          (fold-right (lambda (str prev)
                        (if (> (string-length str) (string-length prev))
                            str
                            prev))
                      ""
                      '("x" "abc" "xyz" "jk"))
          ⇒ "xyz"

     If LST1 LST2 ... have different lengths, ‘fold’ stops when the end
     of the shortest is reached; ‘fold-right’ commences at the last
     element of the shortest.  Ie. elements past the length of the
     shortest are ignored in the other LSTs.  At least one LST must be
     non-circular.

     ‘fold’ should be preferred over ‘fold-right’ if the order of
     processing doesn’t matter, or can be arranged either way, since
     ‘fold’ is a little more efficient.

     The way ‘fold’ builds a result from iterating is quite general, it
     can do more than other iterations like say ‘map’ or ‘filter’.  The
     following for example removes adjacent duplicate elements from a
     list,

          (define (delete-adjacent-duplicates lst)
            (fold-right (lambda (elem ret)
                          (if (equal? elem (first ret))
                              ret
                              (cons elem ret)))
                        (list (last lst))
                        lst))
          (delete-adjacent-duplicates '(1 2 3 3 4 4 4 5))
          ⇒ (1 2 3 4 5)

     Clearly the same sort of thing can be done with a ‘for-each’ and a
     variable in which to build the result, but a self-contained PROC
     can be re-used in multiple contexts, where a ‘for-each’ would have
     to be written out each time.

 -- Scheme Procedure: pair-fold proc init lst1 lst2 ...
 -- Scheme Procedure: pair-fold-right proc init lst1 lst2 ...
     The same as ‘fold’ and ‘fold-right’, but apply PROC to the pairs of
     the lists instead of the list elements.

 -- Scheme Procedure: reduce proc default lst
 -- Scheme Procedure: reduce-right proc default lst
     ‘reduce’ is a variant of ‘fold’, where the first call to PROC is on
     two elements from LST, rather than one element and a given initial
     value.

     If LST is empty, ‘reduce’ returns DEFAULT (this is the only use for
     DEFAULT).  If LST has just one element then that’s the return
     value.  Otherwise PROC is called on the elements of LST.

     Each PROC call is ‘(PROC ELEM PREVIOUS)’, where ELEM is from LST
     (the second and subsequent elements of LST), and PREVIOUS is the
     return from the previous call to PROC.  The first element of LST is
     the PREVIOUS for the first call to PROC.

     For example, the following adds a list of numbers, the calls made
     to ‘+’ are shown.  (Of course ‘+’ accepts multiple arguments and
     can add a list directly, with ‘apply’.)

          (reduce + 0 '(5 6 7)) ⇒ 18

          (+ 6 5)  ⇒ 11
          (+ 7 11) ⇒ 18

     ‘reduce’ can be used instead of ‘fold’ where the INIT value is an
     “identity”, meaning a value which under PROC doesn’t change the
     result, in this case 0 is an identity since ‘(+ 5 0)’ is just 5.
     ‘reduce’ avoids that unnecessary call.

     ‘reduce-right’ is a similar variation on ‘fold-right’, working from
     the end (ie. the right) of LST.  The last element of LST is the
     PREVIOUS for the first call to PROC, and the ELEM values go from
     the second last.

     ‘reduce’ should be preferred over ‘reduce-right’ if the order of
     processing doesn’t matter, or can be arranged either way, since
     ‘reduce’ is a little more efficient.

 -- Scheme Procedure: unfold p f g seed [tail-gen]
     ‘unfold’ is defined as follows:

          (unfold p f g seed) =
             (if (p seed) (tail-gen seed)
                 (cons (f seed)
                       (unfold p f g (g seed))))

     P
          Determines when to stop unfolding.

     F
          Maps each seed value to the corresponding list element.

     G
          Maps each seed value to next seed value.

     SEED
          The state value for the unfold.

     TAIL-GEN
          Creates the tail of the list; defaults to ‘(lambda (x) '())’.

     G produces a series of seed values, which are mapped to list
     elements by F.  These elements are put into a list in left-to-right
     order, and P tells when to stop unfolding.

 -- Scheme Procedure: unfold-right p f g seed [tail]
     Construct a list with the following loop.

          (let lp ((seed seed) (lis tail))
             (if (p seed) lis
                 (lp (g seed)
                     (cons (f seed) lis))))

     P
          Determines when to stop unfolding.

     F
          Maps each seed value to the corresponding list element.

     G
          Maps each seed value to next seed value.

     SEED
          The state value for the unfold.

     TAIL
          The tail of the list; defaults to ‘'()’.

 -- Scheme Procedure: map f lst1 lst2 ...
     Map the procedure over the list(s) LST1, LST2, ... and return a
     list containing the results of the procedure applications.  This
     procedure is extended with respect to R5RS, because the argument
     lists may have different lengths.  The result list will have the
     same length as the shortest argument lists.  The order in which F
     will be applied to the list element(s) is not specified.

 -- Scheme Procedure: for-each f lst1 lst2 ...
     Apply the procedure F to each pair of corresponding elements of the
     list(s) LST1, LST2, ....  The return value is not specified.  This
     procedure is extended with respect to R5RS, because the argument
     lists may have different lengths.  The shortest argument list
     determines the number of times F is called.  F will be applied to
     the list elements in left-to-right order.

 -- Scheme Procedure: append-map f lst1 lst2 ...
 -- Scheme Procedure: append-map! f lst1 lst2 ...
     Equivalent to

          (apply append (map f clist1 clist2 ...))

     and

          (apply append! (map f clist1 clist2 ...))

     Map F over the elements of the lists, just as in the ‘map’
     function.  However, the results of the applications are appended
     together to make the final result.  ‘append-map’ uses ‘append’ to
     append the results together; ‘append-map!’ uses ‘append!’.

     The dynamic order in which the various applications of F are made
     is not specified.

 -- Scheme Procedure: map! f lst1 lst2 ...
     Linear-update variant of ‘map’ – ‘map!’ is allowed, but not
     required, to alter the cons cells of LST1 to construct the result
     list.

     The dynamic order in which the various applications of F are made
     is not specified.  In the n-ary case, LST2, LST3, ... must have at
     least as many elements as LST1.

 -- Scheme Procedure: pair-for-each f lst1 lst2 ...
     Like ‘for-each’, but applies the procedure F to the pairs from
     which the argument lists are constructed, instead of the list
     elements.  The return value is not specified.

 -- Scheme Procedure: filter-map f lst1 lst2 ...
     Like ‘map’, but only results from the applications of F which are
     true are saved in the result list.

7.5.3.6 Filtering and Partitioning
..................................

Filtering means to collect all elements from a list which satisfy a
specific condition.  Partitioning a list means to make two groups of
list elements, one which contains the elements satisfying a condition,
and the other for the elements which don’t.

   The ‘filter’ and ‘filter!’ functions are implemented in the Guile
core, see List Modification.

 -- Scheme Procedure: partition pred lst
 -- Scheme Procedure: partition! pred lst
     Split LST into those elements which do and don’t satisfy the
     predicate PRED.

     The return is two values (see Multiple Values), the first being
     a list of all elements from LST which satisfy PRED, the second a
     list of those which do not.

     The elements in the result lists are in the same order as in LST
     but the order in which the calls ‘(PRED elem)’ are made on the list
     elements is unspecified.

     ‘partition’ does not change LST, but one of the returned lists may
     share a tail with it.  ‘partition!’ may modify LST to construct its
     return.

 -- Scheme Procedure: remove pred lst
 -- Scheme Procedure: remove! pred lst
     Return a list containing all elements from LST which do not satisfy
     the predicate PRED.  The elements in the result list have the same
     order as in LST.  The order in which PRED is applied to the list
     elements is not specified.

     ‘remove!’ is allowed, but not required to modify the structure of
     the input list.

7.5.3.7 Searching
.................

The procedures for searching elements in lists either accept a predicate
or a comparison object for determining which elements are to be
searched.

 -- Scheme Procedure: find pred lst
     Return the first element of LST which satisfies the predicate PRED
     and ‘#f’ if no such element is found.

 -- Scheme Procedure: find-tail pred lst
     Return the first pair of LST whose CAR satisfies the predicate PRED
     and ‘#f’ if no such element is found.

 -- Scheme Procedure: take-while pred lst
 -- Scheme Procedure: take-while! pred lst
     Return the longest initial prefix of LST whose elements all satisfy
     the predicate PRED.

     ‘take-while!’ is allowed, but not required to modify the input list
     while producing the result.

 -- Scheme Procedure: drop-while pred lst
     Drop the longest initial prefix of LST whose elements all satisfy
     the predicate PRED.

 -- Scheme Procedure: span pred lst
 -- Scheme Procedure: span! pred lst
 -- Scheme Procedure: break pred lst
 -- Scheme Procedure: break! pred lst
     ‘span’ splits the list LST into the longest initial prefix whose
     elements all satisfy the predicate PRED, and the remaining tail.
     ‘break’ inverts the sense of the predicate.

     ‘span!’ and ‘break!’ are allowed, but not required to modify the
     structure of the input list LST in order to produce the result.

     Note that the name ‘break’ conflicts with the ‘break’ binding
     established by ‘while’ (see while do).  Applications wanting to
     use ‘break’ from within a ‘while’ loop will need to make a new
     define under a different name.

 -- Scheme Procedure: any pred lst1 lst2 ...
     Test whether any set of elements from LST1 LST2 ... satisfies PRED.
     If so, the return value is the return value from the successful
     PRED call, or if not, the return value is ‘#f’.

     If there are n list arguments, then PRED must be a predicate taking
     n arguments.  Each PRED call is ‘(PRED ELEM1 ELEM2 ... )’ taking an
     element from each LST.  The calls are made successively for the
     first, second, etc.  elements of the lists, stopping when PRED
     returns non-‘#f’, or when the end of the shortest list is reached.

     The PRED call on the last set of elements (i.e., when the end of
     the shortest list has been reached), if that point is reached, is a
     tail call.

 -- Scheme Procedure: every pred lst1 lst2 ...
     Test whether every set of elements from LST1 LST2 ... satisfies
     PRED.  If so, the return value is the return from the final PRED
     call, or if not, the return value is ‘#f’.

     If there are n list arguments, then PRED must be a predicate taking
     n arguments.  Each PRED call is ‘(PRED ELEM1 ELEM2 ...)’ taking an
     element from each LST.  The calls are made successively for the
     first, second, etc.  elements of the lists, stopping if PRED
     returns ‘#f’, or when the end of any of the lists is reached.

     The PRED call on the last set of elements (i.e., when the end of
     the shortest list has been reached) is a tail call.

     If one of LST1 LST2 ...is empty then no calls to PRED are made, and
     the return value is ‘#t’.

 -- Scheme Procedure: list-index pred lst1 lst2 ...
     Return the index of the first set of elements, one from each of
     LST1 LST2 ..., which satisfies PRED.

     PRED is called as ‘(ELEM1 ELEM2 ...)’.  Searching stops when the
     end of the shortest LST is reached.  The return index starts from 0
     for the first set of elements.  If no set of elements pass, then
     the return value is ‘#f’.

          (list-index odd? '(2 4 6 9))      ⇒ 3
          (list-index = '(1 2 3) '(3 1 2))  ⇒ #f

 -- Scheme Procedure: member x lst [=]
     Return the first sublist of LST whose CAR is equal to X.  If X does
     not appear in LST, return ‘#f’.

     Equality is determined by ‘equal?’, or by the equality predicate =
     if given.  = is called ‘(= X elem)’, ie. with the given X first, so
     for example to find the first element greater than 5,

          (member 5 '(3 5 1 7 2 9) <) ⇒ (7 2 9)

     This version of ‘member’ extends the core ‘member’ (see List Searching)
     by accepting an equality predicate.

7.5.3.8 Deleting
................

 -- Scheme Procedure: delete x lst [=]
 -- Scheme Procedure: delete! x lst [=]
     Return a list containing the elements of LST but with those equal
     to X deleted.  The returned elements will be in the same order as
     they were in LST.

     Equality is determined by the = predicate, or ‘equal?’ if not
     given.  An equality call is made just once for each element, but
     the order in which the calls are made on the elements is
     unspecified.

     The equality calls are always ‘(= x elem)’, ie. the given X is
     first.  This means for instance elements greater than 5 can be
     deleted with ‘(delete 5 lst <)’.

     ‘delete’ does not modify LST, but the return might share a common
     tail with LST.  ‘delete!’ may modify the structure of LST to
     construct its return.

     These functions extend the core ‘delete’ and ‘delete!’ (see List Modification)
     in accepting an equality predicate.  See also
     ‘lset-difference’ (see SRFI-1 Set Operations) for deleting
     multiple elements from a list.

 -- Scheme Procedure: delete-duplicates lst [=]
 -- Scheme Procedure: delete-duplicates! lst [=]
     Return a list containing the elements of LST but without
     duplicates.

     When elements are equal, only the first in LST is retained.  Equal
     elements can be anywhere in LST, they don’t have to be adjacent.
     The returned list will have the retained elements in the same order
     as they were in LST.

     Equality is determined by the = predicate, or ‘equal?’ if not
     given.  Calls ‘(= x y)’ are made with element X being before Y in
     LST.  A call is made at most once for each combination, but the
     sequence of the calls across the elements is unspecified.

     ‘delete-duplicates’ does not modify LST, but the return might share
     a common tail with LST.  ‘delete-duplicates!’ may modify the
     structure of LST to construct its return.

     In the worst case, this is an O(N^2) algorithm because it must
     check each element against all those preceding it.  For long lists
     it is more efficient to sort and then compare only adjacent
     elements.

7.5.3.9 Association Lists
.........................

Association lists are described in detail in section Association Lists.
The present section only documents the additional procedures
for dealing with association lists defined by SRFI-1.

 -- Scheme Procedure: assoc key alist [=]
     Return the pair from ALIST which matches KEY.  This extends the
     core ‘assoc’ (see Retrieving Alist Entries) by taking an
     optional = comparison procedure.

     The default comparison is ‘equal?’.  If an = parameter is given
     it’s called ‘(= KEY ALISTCAR)’, i.e. the given target KEY is the
     first argument, and a ‘car’ from ALIST is second.

     For example a case-insensitive string lookup,

          (assoc "yy" '(("XX" . 1) ("YY" . 2)) string-ci=?)
          ⇒ ("YY" . 2)

 -- Scheme Procedure: alist-cons key datum alist
     Cons a new association KEY and DATUM onto ALIST and return the
     result.  This is equivalent to

          (cons (cons KEY DATUM) ALIST)

     ‘acons’ (see Adding or Setting Alist Entries) in the Guile core
     does the same thing.

 -- Scheme Procedure: alist-copy alist
     Return a newly allocated copy of ALIST, that means that the spine
     of the list as well as the pairs are copied.

 -- Scheme Procedure: alist-delete key alist [=]
 -- Scheme Procedure: alist-delete! key alist [=]
     Return a list containing the elements of ALIST but with those
     elements whose keys are equal to KEY deleted.  The returned
     elements will be in the same order as they were in ALIST.

     Equality is determined by the = predicate, or ‘equal?’ if not
     given.  The order in which elements are tested is unspecified, but
     each equality call is made ‘(= key alistkey)’, i.e. the given KEY
     parameter is first and the key from ALIST second.  This means for
     instance all associations with a key greater than 5 can be removed
     with ‘(alist-delete 5 alist <)’.

     ‘alist-delete’ does not modify ALIST, but the return might share a
     common tail with ALIST.  ‘alist-delete!’ may modify the list
     structure of ALIST to construct its return.

7.5.3.10 Set Operations on Lists
................................

Lists can be used to represent sets of objects.  The procedures in this
section operate on such lists as sets.

   Note that lists are not an efficient way to implement large sets.
The procedures here typically take time MxN when operating on M and N
element lists.  Other data structures like trees, bitsets (see Bit Vectors)
or hash tables (see Hash Tables) are faster.

   All these procedures take an equality predicate as the first
argument.  This predicate is used for testing the objects in the list
sets for sameness.  This predicate must be consistent with ‘eq?’ (see
Equality) in the sense that if two list elements are ‘eq?’ then they
must also be equal under the predicate.  This simply means a given
object must be equal to itself.

 -- Scheme Procedure: lset<= = list ...
     Return ‘#t’ if each list is a subset of the one following it.
     I.e., LIST1 is a subset of LIST2, LIST2 is a subset of LIST3, etc.,
     for as many lists as given.  If only one list or no lists are
     given, the return value is ‘#t’.

     A list X is a subset of Y if each element of X is equal to some
     element in Y.  Elements are compared using the given = procedure,
     called as ‘(= xelem yelem)’.

          (lset<= eq?)                      ⇒ #t
          (lset<= eqv? '(1 2 3) '(1))       ⇒ #f
          (lset<= eqv? '(1 3 2) '(4 3 1 2)) ⇒ #t

 -- Scheme Procedure: lset= = list ...
     Return ‘#t’ if all argument lists are set-equal.  LIST1 is compared
     to LIST2, LIST2 to LIST3, etc., for as many lists as given.  If
     only one list or no lists are given, the return value is ‘#t’.

     Two lists X and Y are set-equal if each element of X is equal to
     some element of Y and conversely each element of Y is equal to some
     element of X.  The order of the elements in the lists doesn’t
     matter.  Element equality is determined with the given = procedure,
     called as ‘(= xelem yelem)’, but exactly which calls are made is
     unspecified.

          (lset= eq?)                      ⇒ #t
          (lset= eqv? '(1 2 3) '(3 2 1))   ⇒ #t
          (lset= string-ci=? '("a" "A" "b") '("B" "b" "a")) ⇒ #t

 -- Scheme Procedure: lset-adjoin = list elem ...
     Add to LIST any of the given ELEMs not already in the list.  ELEMs
     are ‘cons’ed onto the start of LIST (so the return value shares a
     common tail with LIST), but the order that the ELEMs are added is
     unspecified.

     The given = procedure is used for comparing elements, called as ‘(=
     listelem elem)’, i.e., the second argument is one of the given ELEM
     parameters.

          (lset-adjoin eqv? '(1 2 3) 4 1 5) ⇒ (5 4 1 2 3)

 -- Scheme Procedure: lset-union = list ...
 -- Scheme Procedure: lset-union! = list ...
     Return the union of the argument list sets.  The result is built by
     taking the union of LIST1 and LIST2, then the union of that with
     LIST3, etc., for as many lists as given.  For one list argument
     that list itself is the result, for no list arguments the result is
     the empty list.

     The union of two lists X and Y is formed as follows.  If X is empty
     then the result is Y.  Otherwise start with X as the result and
     consider each Y element (from first to last).  A Y element not
     equal to something already in the result is ‘cons’ed onto the
     result.

     The given = procedure is used for comparing elements, called as ‘(=
     relem yelem)’.  The first argument is from the result accumulated
     so far, and the second is from the list being union-ed in.  But
     exactly which calls are made is otherwise unspecified.

     Notice that duplicate elements in LIST1 (or the first non-empty
     list) are preserved, but that repeated elements in subsequent lists
     are only added once.

          (lset-union eqv?)                          ⇒ ()
          (lset-union eqv? '(1 2 3))                 ⇒ (1 2 3)
          (lset-union eqv? '(1 2 1 3) '(2 4 5) '(5)) ⇒ (5 4 1 2 1 3)

     ‘lset-union’ doesn’t change the given lists but the result may
     share a tail with the first non-empty list.  ‘lset-union!’ can
     modify all of the given lists to form the result.

 -- Scheme Procedure: lset-intersection = list1 list2 ...
 -- Scheme Procedure: lset-intersection! = list1 list2 ...
     Return the intersection of LIST1 with the other argument lists,
     meaning those elements of LIST1 which are also in all of LIST2 etc.
     For one list argument, just that list is returned.

     The test for an element of LIST1 to be in the return is simply that
     it’s equal to some element in each of LIST2 etc.  Notice this means
     an element appearing twice in LIST1 but only once in each of LIST2
     etc will go into the return twice.  The return has its elements in
     the same order as they were in LIST1.

     The given = procedure is used for comparing elements, called as ‘(=
     elem1 elemN)’.  The first argument is from LIST1 and the second is
     from one of the subsequent lists.  But exactly which calls are made
     and in what order is unspecified.

          (lset-intersection eqv? '(x y))                        ⇒ (x y)
          (lset-intersection eqv? '(1 2 3) '(4 3 2))             ⇒ (2 3)
          (lset-intersection eqv? '(1 1 2 2) '(1 2) '(2 1) '(2)) ⇒ (2 2)

     The return from ‘lset-intersection’ may share a tail with LIST1.
     ‘lset-intersection!’ may modify LIST1 to form its result.

 -- Scheme Procedure: lset-difference = list1 list2 ...
 -- Scheme Procedure: lset-difference! = list1 list2 ...
     Return LIST1 with any elements in LIST2, LIST3 etc removed (ie.
     subtracted).  For one list argument, just that list is returned.

     The given = procedure is used for comparing elements, called as ‘(=
     elem1 elemN)’.  The first argument is from LIST1 and the second
     from one of the subsequent lists.  But exactly which calls are made
     and in what order is unspecified.

          (lset-difference eqv? '(x y))             ⇒ (x y)
          (lset-difference eqv? '(1 2 3) '(3 1))    ⇒ (2)
          (lset-difference eqv? '(1 2 3) '(3) '(2)) ⇒ (1)

     The return from ‘lset-difference’ may share a tail with LIST1.
     ‘lset-difference!’ may modify LIST1 to form its result.

 -- Scheme Procedure: lset-diff+intersection = list1 list2 ...
 -- Scheme Procedure: lset-diff+intersection! = list1 list2 ...
     Return two values (see Multiple Values), the difference and
     intersection of the argument lists as per ‘lset-difference’ and
     ‘lset-intersection’ above.

     For two list arguments this partitions LIST1 into those elements of
     LIST1 which are in LIST2 and not in LIST2.  (But for more than two
     arguments there can be elements of LIST1 which are neither part of
     the difference nor the intersection.)

     One of the return values from ‘lset-diff+intersection’ may share a
     tail with LIST1.  ‘lset-diff+intersection!’ may modify LIST1 to
     form its results.

 -- Scheme Procedure: lset-xor = list ...
 -- Scheme Procedure: lset-xor! = list ...
     Return an XOR of the argument lists.  For two lists this means
     those elements which are in exactly one of the lists.  For more
     than two lists it means those elements which appear in an odd
     number of the lists.

     To be precise, the XOR of two lists X and Y is formed by taking
     those elements of X not equal to any element of Y, plus those
     elements of Y not equal to any element of X.  Equality is
     determined with the given = procedure, called as ‘(= e1 e2)’.  One
     argument is from X and the other from Y, but which way around is
     unspecified.  Exactly which calls are made is also unspecified, as
     is the order of the elements in the result.

          (lset-xor eqv? '(x y))             ⇒ (x y)
          (lset-xor eqv? '(1 2 3) '(4 3 2))  ⇒ (4 1)

     The return from ‘lset-xor’ may share a tail with one of the list
     arguments.  ‘lset-xor!’ may modify LIST1 to form its result.

7.5.4 SRFI-2 - and-let*
-----------------------

The following syntax can be obtained with

     (use-modules (srfi srfi-2))

   or alternatively

     (use-modules (ice-9 and-let-star))

 -- library syntax: and-let* (clause ...) body ...
     A combination of ‘and’ and ‘let*’.

     Each CLAUSE is evaluated in turn, and if ‘#f’ is obtained then
     evaluation stops and ‘#f’ is returned.  If all are non-‘#f’ then
     BODY is evaluated and the last form gives the return value, or if
     BODY is empty then the result is ‘#t’.  Each CLAUSE should be one
     of the following,

     ‘(symbol expr)’
          Evaluate EXPR, check for ‘#f’, and bind it to SYMBOL.  Like
          ‘let*’, that binding is available to subsequent clauses.
     ‘(expr)’
          Evaluate EXPR and check for ‘#f’.
     ‘symbol’
          Get the value bound to SYMBOL and check for ‘#f’.

     Notice that ‘(expr)’ has an “extra” pair of parentheses, for
     instance ‘((eq? x y))’.  One way to remember this is to imagine the
     ‘symbol’ in ‘(symbol expr)’ is omitted.

     ‘and-let*’ is good for calculations where a ‘#f’ value means
     termination, but where a non-‘#f’ value is going to be needed in
     subsequent expressions.

     The following illustrates this, it returns text between brackets
     ‘[...]’ in a string, or ‘#f’ if there are no such brackets (ie.
     either ‘string-index’ gives ‘#f’).

          (define (extract-brackets str)
            (and-let* ((start (string-index str #\[))
                       (end   (string-index str #\] start)))
              (substring str (1+ start) end)))

     The following shows plain variables and expressions tested too.
     ‘diagnostic-levels’ is taken to be an alist associating a
     diagnostic type with a level.  ‘str’ is printed only if the type is
     known and its level is high enough.

          (define (show-diagnostic type str)
            (and-let* (want-diagnostics
                       (level (assq-ref diagnostic-levels type))
                       ((>= level current-diagnostic-level)))
              (display str)))

     The advantage of ‘and-let*’ is that an extended sequence of
     expressions and tests doesn’t require lots of nesting as would
     arise from separate ‘and’ and ‘let*’, or from ‘cond’ with ‘=>’.

7.5.5 SRFI-4 - Homogeneous numeric vector datatypes
---------------------------------------------------

SRFI-4 provides an interface to uniform numeric vectors: vectors whose
elements are all of a single numeric type.  Guile offers uniform numeric
vectors for signed and unsigned 8-bit, 16-bit, 32-bit, and 64-bit
integers, two sizes of floating point values, and, as an extension to
SRFI-4, complex floating-point numbers of these two sizes.

   The standard SRFI-4 procedures and data types may be included via
loading the appropriate module:

     (use-modules (srfi srfi-4))

   This module is currently a part of the default Guile environment, but
it is a good practice to explicitly import the module.  In the future,
using SRFI-4 procedures without importing the SRFI-4 module will cause a
deprecation message to be printed.  (Of course, one may call the C
functions at any time.  Would that C had modules!)

7.5.5.1 SRFI-4 - Overview
.........................

Uniform numeric vectors can be useful since they consume less memory
than the non-uniform, general vectors.  Also, since the types they can
store correspond directly to C types, it is easier to work with them
efficiently on a low level.  Consider image processing as an example,
where you want to apply a filter to some image.  While you could store
the pixels of an image in a general vector and write a general
convolution function, things are much more efficient with uniform
vectors: the convolution function knows that all pixels are unsigned
8-bit values (say), and can use a very tight inner loop.

   This is implemented in Scheme by having the compiler notice calls to
the SRFI-4 accessors, and inline them to appropriate compiled code.
From C you have access to the raw array; functions for efficiently
working with uniform numeric vectors from C are listed at the end of
this section.

   Uniform numeric vectors are the special case of one dimensional
uniform numeric arrays.

   There are 12 standard kinds of uniform numeric vectors, and they all
have their own complement of constructors, accessors, and so on.
Procedures that operate on a specific kind of uniform numeric vector
have a “tag” in their name, indicating the element type.

u8
     unsigned 8-bit integers

s8
     signed 8-bit integers

u16
     unsigned 16-bit integers

s16
     signed 16-bit integers

u32
     unsigned 32-bit integers

s32
     signed 32-bit integers

u64
     unsigned 64-bit integers

s64
     signed 64-bit integers

f32
     the C type ‘float’

f64
     the C type ‘double’

   In addition, Guile supports uniform arrays of complex numbers, with
the nonstandard tags:

c32
     complex numbers in rectangular form with the real and imaginary
     part being a ‘float’

c64
     complex numbers in rectangular form with the real and imaginary
     part being a ‘double’

   The external representation (ie. read syntax) for these vectors is
similar to normal Scheme vectors, but with an additional tag from the
tables above indicating the vector’s type.  For example,

     #u16(1 2 3)
     #f64(3.1415 2.71)

   Note that the read syntax for floating-point here conflicts with ‘#f’
for false.  In Standard Scheme one can write ‘(1 #f3)’ for a three
element list ‘(1 #f 3)’, but for Guile ‘(1 #f3)’ is invalid.  ‘(1 #f 3)’
is almost certainly what one should write anyway to make the intention
clear, so this is rarely a problem.

7.5.5.2 SRFI-4 - API
....................

Note that the c32 and c64 functions are only available from (srfi srfi-4
gnu).

 -- Scheme Procedure: u8vector? obj
 -- Scheme Procedure: s8vector? obj
 -- Scheme Procedure: u16vector? obj
 -- Scheme Procedure: s16vector? obj
 -- Scheme Procedure: u32vector? obj
 -- Scheme Procedure: s32vector? obj
 -- Scheme Procedure: u64vector? obj
 -- Scheme Procedure: s64vector? obj
 -- Scheme Procedure: f32vector? obj
 -- Scheme Procedure: f64vector? obj
 -- Scheme Procedure: c32vector? obj
 -- Scheme Procedure: c64vector? obj
 -- C Function: scm_u8vector_p (obj)
 -- C Function: scm_s8vector_p (obj)
 -- C Function: scm_u16vector_p (obj)
 -- C Function: scm_s16vector_p (obj)
 -- C Function: scm_u32vector_p (obj)
 -- C Function: scm_s32vector_p (obj)
 -- C Function: scm_u64vector_p (obj)
 -- C Function: scm_s64vector_p (obj)
 -- C Function: scm_f32vector_p (obj)
 -- C Function: scm_f64vector_p (obj)
 -- C Function: scm_c32vector_p (obj)
 -- C Function: scm_c64vector_p (obj)
     Return ‘#t’ if OBJ is a homogeneous numeric vector of the indicated
     type.

 -- Scheme Procedure: make-u8vector n [value]
 -- Scheme Procedure: make-s8vector n [value]
 -- Scheme Procedure: make-u16vector n [value]
 -- Scheme Procedure: make-s16vector n [value]
 -- Scheme Procedure: make-u32vector n [value]
 -- Scheme Procedure: make-s32vector n [value]
 -- Scheme Procedure: make-u64vector n [value]
 -- Scheme Procedure: make-s64vector n [value]
 -- Scheme Procedure: make-f32vector n [value]
 -- Scheme Procedure: make-f64vector n [value]
 -- Scheme Procedure: make-c32vector n [value]
 -- Scheme Procedure: make-c64vector n [value]
 -- C Function: scm_make_u8vector (n, value)
 -- C Function: scm_make_s8vector (n, value)
 -- C Function: scm_make_u16vector (n, value)
 -- C Function: scm_make_s16vector (n, value)
 -- C Function: scm_make_u32vector (n, value)
 -- C Function: scm_make_s32vector (n, value)
 -- C Function: scm_make_u64vector (n, value)
 -- C Function: scm_make_s64vector (n, value)
 -- C Function: scm_make_f32vector (n, value)
 -- C Function: scm_make_f64vector (n, value)
 -- C Function: scm_make_c32vector (n, value)
 -- C Function: scm_make_c64vector (n, value)
     Return a newly allocated homogeneous numeric vector holding N
     elements of the indicated type.  If VALUE is given, the vector is
     initialized with that value, otherwise the contents are
     unspecified.

 -- Scheme Procedure: u8vector value ...
 -- Scheme Procedure: s8vector value ...
 -- Scheme Procedure: u16vector value ...
 -- Scheme Procedure: s16vector value ...
 -- Scheme Procedure: u32vector value ...
 -- Scheme Procedure: s32vector value ...
 -- Scheme Procedure: u64vector value ...
 -- Scheme Procedure: s64vector value ...
 -- Scheme Procedure: f32vector value ...
 -- Scheme Procedure: f64vector value ...
 -- Scheme Procedure: c32vector value ...
 -- Scheme Procedure: c64vector value ...
 -- C Function: scm_u8vector (values)
 -- C Function: scm_s8vector (values)
 -- C Function: scm_u16vector (values)
 -- C Function: scm_s16vector (values)
 -- C Function: scm_u32vector (values)
 -- C Function: scm_s32vector (values)
 -- C Function: scm_u64vector (values)
 -- C Function: scm_s64vector (values)
 -- C Function: scm_f32vector (values)
 -- C Function: scm_f64vector (values)
 -- C Function: scm_c32vector (values)
 -- C Function: scm_c64vector (values)
     Return a newly allocated homogeneous numeric vector of the
     indicated type, holding the given parameter VALUEs.  The vector
     length is the number of parameters given.

 -- Scheme Procedure: u8vector-length vec
 -- Scheme Procedure: s8vector-length vec
 -- Scheme Procedure: u16vector-length vec
 -- Scheme Procedure: s16vector-length vec
 -- Scheme Procedure: u32vector-length vec
 -- Scheme Procedure: s32vector-length vec
 -- Scheme Procedure: u64vector-length vec
 -- Scheme Procedure: s64vector-length vec
 -- Scheme Procedure: f32vector-length vec
 -- Scheme Procedure: f64vector-length vec
 -- Scheme Procedure: c32vector-length vec
 -- Scheme Procedure: c64vector-length vec
 -- C Function: scm_u8vector_length (vec)
 -- C Function: scm_s8vector_length (vec)
 -- C Function: scm_u16vector_length (vec)
 -- C Function: scm_s16vector_length (vec)
 -- C Function: scm_u32vector_length (vec)
 -- C Function: scm_s32vector_length (vec)
 -- C Function: scm_u64vector_length (vec)
 -- C Function: scm_s64vector_length (vec)
 -- C Function: scm_f32vector_length (vec)
 -- C Function: scm_f64vector_length (vec)
 -- C Function: scm_c32vector_length (vec)
 -- C Function: scm_c64vector_length (vec)
     Return the number of elements in VEC.

 -- Scheme Procedure: u8vector-ref vec i
 -- Scheme Procedure: s8vector-ref vec i
 -- Scheme Procedure: u16vector-ref vec i
 -- Scheme Procedure: s16vector-ref vec i
 -- Scheme Procedure: u32vector-ref vec i
 -- Scheme Procedure: s32vector-ref vec i
 -- Scheme Procedure: u64vector-ref vec i
 -- Scheme Procedure: s64vector-ref vec i
 -- Scheme Procedure: f32vector-ref vec i
 -- Scheme Procedure: f64vector-ref vec i
 -- Scheme Procedure: c32vector-ref vec i
 -- Scheme Procedure: c64vector-ref vec i
 -- C Function: scm_u8vector_ref (vec, i)
 -- C Function: scm_s8vector_ref (vec, i)
 -- C Function: scm_u16vector_ref (vec, i)
 -- C Function: scm_s16vector_ref (vec, i)
 -- C Function: scm_u32vector_ref (vec, i)
 -- C Function: scm_s32vector_ref (vec, i)
 -- C Function: scm_u64vector_ref (vec, i)
 -- C Function: scm_s64vector_ref (vec, i)
 -- C Function: scm_f32vector_ref (vec, i)
 -- C Function: scm_f64vector_ref (vec, i)
 -- C Function: scm_c32vector_ref (vec, i)
 -- C Function: scm_c64vector_ref (vec, i)
     Return the element at index I in VEC.  The first element in VEC is
     index 0.

 -- Scheme Procedure: u8vector-set! vec i value
 -- Scheme Procedure: s8vector-set! vec i value
 -- Scheme Procedure: u16vector-set! vec i value
 -- Scheme Procedure: s16vector-set! vec i value
 -- Scheme Procedure: u32vector-set! vec i value
 -- Scheme Procedure: s32vector-set! vec i value
 -- Scheme Procedure: u64vector-set! vec i value
 -- Scheme Procedure: s64vector-set! vec i value
 -- Scheme Procedure: f32vector-set! vec i value
 -- Scheme Procedure: f64vector-set! vec i value
 -- Scheme Procedure: c32vector-set! vec i value
 -- Scheme Procedure: c64vector-set! vec i value
 -- C Function: scm_u8vector_set_x (vec, i, value)
 -- C Function: scm_s8vector_set_x (vec, i, value)
 -- C Function: scm_u16vector_set_x (vec, i, value)
 -- C Function: scm_s16vector_set_x (vec, i, value)
 -- C Function: scm_u32vector_set_x (vec, i, value)
 -- C Function: scm_s32vector_set_x (vec, i, value)
 -- C Function: scm_u64vector_set_x (vec, i, value)
 -- C Function: scm_s64vector_set_x (vec, i, value)
 -- C Function: scm_f32vector_set_x (vec, i, value)
 -- C Function: scm_f64vector_set_x (vec, i, value)
 -- C Function: scm_c32vector_set_x (vec, i, value)
 -- C Function: scm_c64vector_set_x (vec, i, value)
     Set the element at index I in VEC to VALUE.  The first element in
     VEC is index 0.  The return value is unspecified.

 -- Scheme Procedure: u8vector->list vec
 -- Scheme Procedure: s8vector->list vec
 -- Scheme Procedure: u16vector->list vec
 -- Scheme Procedure: s16vector->list vec
 -- Scheme Procedure: u32vector->list vec
 -- Scheme Procedure: s32vector->list vec
 -- Scheme Procedure: u64vector->list vec
 -- Scheme Procedure: s64vector->list vec
 -- Scheme Procedure: f32vector->list vec
 -- Scheme Procedure: f64vector->list vec
 -- Scheme Procedure: c32vector->list vec
 -- Scheme Procedure: c64vector->list vec
 -- C Function: scm_u8vector_to_list (vec)
 -- C Function: scm_s8vector_to_list (vec)
 -- C Function: scm_u16vector_to_list (vec)
 -- C Function: scm_s16vector_to_list (vec)
 -- C Function: scm_u32vector_to_list (vec)
 -- C Function: scm_s32vector_to_list (vec)
 -- C Function: scm_u64vector_to_list (vec)
 -- C Function: scm_s64vector_to_list (vec)
 -- C Function: scm_f32vector_to_list (vec)
 -- C Function: scm_f64vector_to_list (vec)
 -- C Function: scm_c32vector_to_list (vec)
 -- C Function: scm_c64vector_to_list (vec)
     Return a newly allocated list holding all elements of VEC.

 -- Scheme Procedure: list->u8vector lst
 -- Scheme Procedure: list->s8vector lst
 -- Scheme Procedure: list->u16vector lst
 -- Scheme Procedure: list->s16vector lst
 -- Scheme Procedure: list->u32vector lst
 -- Scheme Procedure: list->s32vector lst
 -- Scheme Procedure: list->u64vector lst
 -- Scheme Procedure: list->s64vector lst
 -- Scheme Procedure: list->f32vector lst
 -- Scheme Procedure: list->f64vector lst
 -- Scheme Procedure: list->c32vector lst
 -- Scheme Procedure: list->c64vector lst
 -- C Function: scm_list_to_u8vector (lst)
 -- C Function: scm_list_to_s8vector (lst)
 -- C Function: scm_list_to_u16vector (lst)
 -- C Function: scm_list_to_s16vector (lst)
 -- C Function: scm_list_to_u32vector (lst)
 -- C Function: scm_list_to_s32vector (lst)
 -- C Function: scm_list_to_u64vector (lst)
 -- C Function: scm_list_to_s64vector (lst)
 -- C Function: scm_list_to_f32vector (lst)
 -- C Function: scm_list_to_f64vector (lst)
 -- C Function: scm_list_to_c32vector (lst)
 -- C Function: scm_list_to_c64vector (lst)
     Return a newly allocated homogeneous numeric vector of the
     indicated type, initialized with the elements of the list LST.

 -- C Function: SCM scm_take_u8vector (const scm_t_uint8 *data, size_t
          len)
 -- C Function: SCM scm_take_s8vector (const scm_t_int8 *data, size_t
          len)
 -- C Function: SCM scm_take_u16vector (const scm_t_uint16 *data, size_t
          len)
 -- C Function: SCM scm_take_s16vector (const scm_t_int16 *data, size_t
          len)
 -- C Function: SCM scm_take_u32vector (const scm_t_uint32 *data, size_t
          len)
 -- C Function: SCM scm_take_s32vector (const scm_t_int32 *data, size_t
          len)
 -- C Function: SCM scm_take_u64vector (const scm_t_uint64 *data, size_t
          len)
 -- C Function: SCM scm_take_s64vector (const scm_t_int64 *data, size_t
          len)
 -- C Function: SCM scm_take_f32vector (const float *data, size_t len)
 -- C Function: SCM scm_take_f64vector (const double *data, size_t len)
 -- C Function: SCM scm_take_c32vector (const float *data, size_t len)
 -- C Function: SCM scm_take_c64vector (const double *data, size_t len)
     Return a new uniform numeric vector of the indicated type and
     length that uses the memory pointed to by DATA to store its
     elements.  This memory will eventually be freed with ‘free’.  The
     argument LEN specifies the number of elements in DATA, not its size
     in bytes.

     The ‘c32’ and ‘c64’ variants take a pointer to a C array of
     ‘float’s or ‘double’s.  The real parts of the complex numbers are
     at even indices in that array, the corresponding imaginary parts
     are at the following odd index.

 -- C Function: const scm_t_uint8 * scm_u8vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: const scm_t_int8 * scm_s8vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: const scm_t_uint16 * scm_u16vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: const scm_t_int16 * scm_s16vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: const scm_t_uint32 * scm_u32vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: const scm_t_int32 * scm_s32vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: const scm_t_uint64 * scm_u64vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: const scm_t_int64 * scm_s64vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: const float * scm_f32vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: const double * scm_f64vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: const float * scm_c32vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: const double * scm_c64vector_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
     Like ‘scm_vector_elements’ (see Vector Accessing from C), but
     returns a pointer to the elements of a uniform numeric vector of
     the indicated kind.

 -- C Function: scm_t_uint8 * scm_u8vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: scm_t_int8 * scm_s8vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: scm_t_uint16 * scm_u16vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: scm_t_int16 * scm_s16vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: scm_t_uint32 * scm_u32vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: scm_t_int32 * scm_s32vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: scm_t_uint64 * scm_u64vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: scm_t_int64 * scm_s64vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: float * scm_f32vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: double * scm_f64vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: float * scm_c32vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
 -- C Function: double * scm_c64vector_writable_elements (SCM vec,
          scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
     Like ‘scm_vector_writable_elements’ (see Vector Accessing from C),
     but returns a pointer to the elements of a uniform numeric
     vector of the indicated kind.

7.5.5.3 SRFI-4 - Relation to bytevectors
........................................

Guile implements SRFI-4 vectors using bytevectors (see Bytevectors).
Often when you have a numeric vector, you end up wanting to write its
bytes somewhere, or have access to the underlying bytes, or read in
bytes from somewhere else.  Bytevectors are very good at this sort of
thing.  But the SRFI-4 APIs are nicer to use when doing
number-crunching, because they are addressed by element and not by byte.

   So as a compromise, Guile allows all bytevector functions to operate
on numeric vectors.  They address the underlying bytes in the native
endianness, as one would expect.

   Following the same reasoning, that it’s just bytes underneath, Guile
also allows uniform vectors of a given type to be accessed as if they
were of any type.  One can fill a u32vector, and access its elements
with u8vector-ref.  One can use f64vector-ref on bytevectors.  It’s all
the same to Guile.

   In this way, uniform numeric vectors may be written to and read from
input/output ports using the procedures that operate on bytevectors.

   See Bytevectors, for more information.

7.5.5.4 SRFI-4 - Guile extensions
.................................

Guile defines some useful extensions to SRFI-4, which are not available
in the default Guile environment.  They may be imported by loading the
extensions module:

     (use-modules (srfi srfi-4 gnu))

 -- Scheme Procedure: any->u8vector obj
 -- Scheme Procedure: any->s8vector obj
 -- Scheme Procedure: any->u16vector obj
 -- Scheme Procedure: any->s16vector obj
 -- Scheme Procedure: any->u32vector obj
 -- Scheme Procedure: any->s32vector obj
 -- Scheme Procedure: any->u64vector obj
 -- Scheme Procedure: any->s64vector obj
 -- Scheme Procedure: any->f32vector obj
 -- Scheme Procedure: any->f64vector obj
 -- Scheme Procedure: any->c32vector obj
 -- Scheme Procedure: any->c64vector obj
 -- C Function: scm_any_to_u8vector (obj)
 -- C Function: scm_any_to_s8vector (obj)
 -- C Function: scm_any_to_u16vector (obj)
 -- C Function: scm_any_to_s16vector (obj)
 -- C Function: scm_any_to_u32vector (obj)
 -- C Function: scm_any_to_s32vector (obj)
 -- C Function: scm_any_to_u64vector (obj)
 -- C Function: scm_any_to_s64vector (obj)
 -- C Function: scm_any_to_f32vector (obj)
 -- C Function: scm_any_to_f64vector (obj)
 -- C Function: scm_any_to_c32vector (obj)
 -- C Function: scm_any_to_c64vector (obj)
     Return a (maybe newly allocated) uniform numeric vector of the
     indicated type, initialized with the elements of OBJ, which must be
     a list, a vector, or a uniform vector.  When OBJ is already a
     suitable uniform numeric vector, it is returned unchanged.

7.5.6 SRFI-6 - Basic String Ports
---------------------------------

SRFI-6 defines the procedures ‘open-input-string’, ‘open-output-string’
and ‘get-output-string’.

   Note that although versions of these procedures are included in the
Guile core, the core versions are not fully conformant with SRFI-6:
attempts to read or write characters that are not supported by the
current ‘%default-port-encoding’ will fail.

   We therefore recommend that you import this module, which supports
all characters:

     (use-modules (srfi srfi-6))

7.5.7 SRFI-8 - receive
----------------------

‘receive’ is a syntax for making the handling of multiple-value
procedures easier.  It is documented in Multiple Values.

7.5.8 SRFI-9 - define-record-type
---------------------------------

This SRFI is a syntax for defining new record types and creating
predicate, constructor, and field getter and setter functions.  It is
documented in the “Compound Data Types” section of the manual (see
SRFI-9 Records).

7.5.9 SRFI-10 - Hash-Comma Reader Extension
-------------------------------------------

This SRFI implements a reader extension ‘#,()’ called hash-comma.  It
allows the reader to give new kinds of objects, for use both in data and
as constants or literals in source code.  This feature is available with

     (use-modules (srfi srfi-10))

The new read syntax is of the form

     #,(TAG ARG...)

where TAG is a symbol and the ARGs are objects taken as parameters.
TAGs are registered with the following procedure.

 -- Scheme Procedure: define-reader-ctor tag proc
     Register PROC as the constructor for a hash-comma read syntax
     starting with symbol TAG, i.e. #,(TAG arg...).  PROC is called with
     the given arguments ‘(PROC arg...)’ and the object it returns is
     the result of the read.

For example, a syntax giving a list of N copies of an object.

     (define-reader-ctor 'repeat
       (lambda (obj reps)
         (make-list reps obj)))

     (display '#,(repeat 99 3))
     ⊣ (99 99 99)

   Notice the quote ’ when the #,( ) is used.  The ‘repeat’ handler
returns a list and the program must quote to use it literally, the same
as any other list.  Ie.

     (display '#,(repeat 99 3))
     ⇒
     (display '(99 99 99))

   When a handler returns an object which is self-evaluating, like a
number or a string, then there’s no need for quoting, just as there’s no
need when giving those directly as literals.  For example an addition,

     (define-reader-ctor 'sum
       (lambda (x y)
         (+ x y)))
     (display #,(sum 123 456)) ⊣ 579

   Once ‘(srfi srfi-10)’ has loaded, #,() is available globally, there’s
no need to use ‘(srfi srfi-10)’ in later modules.  Similarly the tags
registered are global and can be used anywhere once registered.

   We do not recommend #,() reader extensions, however, and for three
reasons.

   First of all, this SRFI is not modular: the tag is matched by name,
not as an identifier within a scope.  Defining a reader extension in one
part of a program can thus affect unrelated parts of a program because
the tag is not scoped.

   Secondly, reader extensions can be hard to manage from a time
perspective: when does the reader extension take effect?  See Eval When,
for more discussion.

   Finally, reader extensions can easily produce objects that can’t be
reified to an object file by the compiler.  For example if you define a
reader extension that makes a hash table (see Hash Tables), then it
will work fine when run with the interpreter, and you think you have a
neat hack.  But then if you try to compile your program, after wrangling
with the ‘eval-when’ concerns mentioned above, the compiler will carp
that it doesn’t know how to serialize a hash table to disk.

   In the specific case of hash tables, it would be possible for Guile
to know how to pack hash tables into compiled files, but this doesn’t
work in general.  What if the object you produce is an instance of a
record type?  Guile would then have to serialize the record type to disk
too, and then what happens if the program independently loads the code
that defines the record type?  Does it define the same type or a
different type?  Guile’s record types are nominal, not structural, so
the answer is not clear at all.

   For all of these reasons we recommend macros over reader extensions.
Macros fulfill many of the same needs while preserving modular
composition, and their interaction with ‘eval-when’ is well-known.  If
you need brevity, instead use ‘read-hash-extend’ and make your reader
extension expand to a macro invocation.  In that way we preserve scoping
as much as possible.  See Reader Extensions.

7.5.10 SRFI-11 - let-values
---------------------------

This module implements the binding forms for multiple values
‘let-values’ and ‘let*-values’.  These forms are similar to ‘let’ and
‘let*’ (see Local Bindings), but they support binding of the values
returned by multiple-valued expressions.

   Write ‘(use-modules (srfi srfi-11))’ to make the bindings available.

     (let-values (((x y) (values 1 2))
                  ((z f) (values 3 4)))
        (+ x y z f))
     ⇒
     10

   ‘let-values’ performs all bindings simultaneously, which means that
no expression in the binding clauses may refer to variables bound in the
same clause list.  ‘let*-values’, on the other hand, performs the
bindings sequentially, just like ‘let*’ does for single-valued
expressions.

7.5.11 SRFI-13 - String Library
-------------------------------

The SRFI-13 procedures are always available, see Strings.

7.5.12 SRFI-14 - Character-set Library
--------------------------------------

The SRFI-14 data type and procedures are always available, see
Character Sets.

7.5.13 SRFI-16 - case-lambda
----------------------------

SRFI-16 defines a variable-arity ‘lambda’ form, ‘case-lambda’.  This
form is available in the default Guile environment.  See
Case-lambda, for more information.

7.5.14 SRFI-17 - Generalized set!
---------------------------------

This SRFI implements a generalized ‘set!’, allowing some “referencing”
functions to be used as the target location of a ‘set!’.  This feature
is available from

     (use-modules (srfi srfi-17))

For example ‘vector-ref’ is extended so that

     (set! (vector-ref vec idx) new-value)

is equivalent to

     (vector-set! vec idx new-value)

   The idea is that a ‘vector-ref’ expression identifies a location,
which may be either fetched or stored.  The same form is used for the
location in both cases, encouraging visual clarity.  This is similar to
the idea of an “lvalue” in C.

   The mechanism for this kind of ‘set!’ is in the Guile core (see
Procedures with Setters).  This module adds definitions of the
following functions as procedures with setters, allowing them to be
targets of a ‘set!’,

     car, cdr, caar, cadr, cdar, cddr, caaar, caadr, cadar, caddr,
     cdaar, cdadr, cddar, cdddr, caaaar, caaadr, caadar, caaddr, cadaar,
     cadadr, caddar, cadddr, cdaaar, cdaadr, cdadar, cdaddr, cddaar,
     cddadr, cdddar, cddddr

     string-ref, vector-ref

   The SRFI specifies ‘setter’ (see Procedures with Setters) as a
procedure with setter, allowing the setter for a procedure to be
changed, eg. ‘(set! (setter foo) my-new-setter-handler)’.  Currently
Guile does not implement this, a setter can only be specified on
creation (‘getter-with-setter’ below).

 -- Function: getter-with-setter
     The same as the Guile core ‘make-procedure-with-setter’ (see
     Procedures with Setters).

7.5.15 SRFI-18 - Multithreading support
---------------------------------------

This is an implementation of the SRFI-18 threading and synchronization
library.  The functions and variables described here are provided by

     (use-modules (srfi srfi-18))

   As a general rule, the data types and functions in this SRFI-18
implementation are compatible with the types and functions in Guile’s
core threading code.  For example, mutexes created with the SRFI-18
‘make-mutex’ function can be passed to the built-in Guile function
‘lock-mutex’ (see Mutexes and Condition Variables), and mutexes
created with the built-in Guile function ‘make-mutex’ can be passed to
the SRFI-18 function ‘mutex-lock!’.  Cases in which this does not hold
true are noted in the following sections.

7.5.15.1 SRFI-18 Threads
........................

Threads created by SRFI-18 differ in two ways from threads created by
Guile’s built-in thread functions.  First, a thread created by SRFI-18
‘make-thread’ begins in a blocked state and will not start execution
until ‘thread-start!’ is called on it.  Second, SRFI-18 threads are
constructed with a top-level exception handler that captures any
exceptions that are thrown on thread exit.  In all other regards,
SRFI-18 threads are identical to normal Guile threads.

 -- Function: current-thread
     Returns the thread that called this function.  This is the same
     procedure as the same-named built-in procedure ‘current-thread’
     (see Threads).

 -- Function: thread? obj
     Returns ‘#t’ if OBJ is a thread, ‘#f’ otherwise.  This is the same
     procedure as the same-named built-in procedure ‘thread?’ (see
     Threads).

 -- Function: make-thread thunk [name]
     Call ‘thunk’ in a new thread and with a new dynamic state,
     returning the new thread and optionally assigning it the object
     name NAME, which may be any Scheme object.

     Note that the name ‘make-thread’ conflicts with the ‘(ice-9
     threads)’ function ‘make-thread’.  Applications wanting to use both
     of these functions will need to refer to them by different names.

 -- Function: thread-name thread
     Returns the name assigned to THREAD at the time of its creation, or
     ‘#f’ if it was not given a name.

 -- Function: thread-specific thread
 -- Function: thread-specific-set! thread obj
     Get or set the “object-specific” property of THREAD.  In Guile’s
     implementation of SRFI-18, this value is stored as an object
     property, and will be ‘#f’ if not set.

 -- Function: thread-start! thread
     Unblocks THREAD and allows it to begin execution if it has not done
     so already.

 -- Function: thread-yield!
     If one or more threads are waiting to execute, calling
     ‘thread-yield!’ forces an immediate context switch to one of them.
     Otherwise, ‘thread-yield!’ has no effect.  ‘thread-yield!’ behaves
     identically to the Guile built-in function ‘yield’.

 -- Function: thread-sleep! timeout
     The current thread waits until the point specified by the time
     object TIMEOUT is reached (see SRFI-18 Time).  This blocks the
     thread only if TIMEOUT represents a point in the future.  it is an
     error for TIMEOUT to be ‘#f’.

 -- Function: thread-terminate! thread
     Causes an abnormal termination of THREAD.  If THREAD is not already
     terminated, all mutexes owned by THREAD become unlocked/abandoned.
     If THREAD is the current thread, ‘thread-terminate!’ does not
     return.  Otherwise ‘thread-terminate!’ returns an unspecified
     value; the termination of THREAD will occur before
     ‘thread-terminate!’ returns.  Subsequent attempts to join on THREAD
     will cause a “terminated thread exception” to be raised.

     ‘thread-terminate!’ is compatible with the thread cancellation
     procedures in the core threads API (see Threads) in that if a
     cleanup handler has been installed for the target thread, it will
     be called before the thread exits and its return value (or
     exception, if any) will be stored for later retrieval via a call to
     ‘thread-join!’.

 -- Function: thread-join! thread [timeout [timeout-val]]
     Wait for THREAD to terminate and return its exit value.  When a
     time value TIMEOUT is given, it specifies a point in time where the
     waiting should be aborted.  When the waiting is aborted,
     TIMEOUT-VAL is returned if it is specified; otherwise, a
     ‘join-timeout-exception’ exception is raised (see SRFI-18 Exceptions).
     Exceptions may also be raised if the thread was
     terminated by a call to ‘thread-terminate!’
     (‘terminated-thread-exception’ will be raised) or if the thread
     exited by raising an exception that was handled by the top-level
     exception handler (‘uncaught-exception’ will be raised; the
     original exception can be retrieved using
     ‘uncaught-exception-reason’).

7.5.15.2 SRFI-18 Mutexes
........................

The behavior of Guile’s built-in mutexes is parameterized via a set of
flags passed to the ‘make-mutex’ procedure in the core (see Mutexes and Condition Variables).
To satisfy the requirements for mutexes
specified by SRFI-18, the ‘make-mutex’ procedure described below sets
the following flags:
   • ‘recursive’: the mutex can be locked recursively
   • ‘unchecked-unlock’: attempts to unlock a mutex that is already
     unlocked will not raise an exception
   • ‘allow-external-unlock’: the mutex can be unlocked by any thread,
     not just the thread that locked it originally

 -- Function: make-mutex [name]
     Returns a new mutex, optionally assigning it the object name NAME,
     which may be any Scheme object.  The returned mutex will be created
     with the configuration described above.  Note that the name
     ‘make-mutex’ conflicts with Guile core function ‘make-mutex’.
     Applications wanting to use both of these functions will need to
     refer to them by different names.

 -- Function: mutex-name mutex
     Returns the name assigned to MUTEX at the time of its creation, or
     ‘#f’ if it was not given a name.

 -- Function: mutex-specific mutex
 -- Function: mutex-specific-set! mutex obj
     Get or set the “object-specific” property of MUTEX.  In Guile’s
     implementation of SRFI-18, this value is stored as an object
     property, and will be ‘#f’ if not set.

 -- Function: mutex-state mutex
     Returns information about the state of MUTEX.  Possible values are:
        • thread ‘T’: the mutex is in the locked/owned state and thread
          T is the owner of the mutex
        • symbol ‘not-owned’: the mutex is in the locked/not-owned state
        • symbol ‘abandoned’: the mutex is in the unlocked/abandoned
          state
        • symbol ‘not-abandoned’: the mutex is in the
          unlocked/not-abandoned state

 -- Function: mutex-lock! mutex [timeout [thread]]
     Lock MUTEX, optionally specifying a time object TIMEOUT after which
     to abort the lock attempt and a thread THREAD giving a new owner
     for MUTEX different than the current thread.  This procedure has
     the same behavior as the ‘lock-mutex’ procedure in the core
     library.

 -- Function: mutex-unlock! mutex [condition-variable [timeout]]
     Unlock MUTEX, optionally specifying a condition variable
     CONDITION-VARIABLE on which to wait, either indefinitely or,
     optionally, until the time object TIMEOUT has passed, to be
     signalled.  This procedure has the same behavior as the
     ‘unlock-mutex’ procedure in the core library.

7.5.15.3 SRFI-18 Condition variables
....................................

SRFI-18 does not specify a “wait” function for condition variables.
Waiting on a condition variable can be simulated using the SRFI-18
‘mutex-unlock!’ function described in the previous section, or Guile’s
built-in ‘wait-condition-variable’ procedure can be used.

 -- Function: condition-variable? obj
     Returns ‘#t’ if OBJ is a condition variable, ‘#f’ otherwise.  This
     is the same procedure as the same-named built-in procedure (see
     ‘condition-variable?’).

 -- Function: make-condition-variable [name]
     Returns a new condition variable, optionally assigning it the
     object name NAME, which may be any Scheme object.  This procedure
     replaces a procedure of the same name in the core library.

 -- Function: condition-variable-name condition-variable
     Returns the name assigned to CONDITION-VARIABLE at the time of its
     creation, or ‘#f’ if it was not given a name.

 -- Function: condition-variable-specific condition-variable
 -- Function: condition-variable-specific-set! condition-variable obj
     Get or set the “object-specific” property of CONDITION-VARIABLE.
     In Guile’s implementation of SRFI-18, this value is stored as an
     object property, and will be ‘#f’ if not set.

 -- Function: condition-variable-signal! condition-variable
 -- Function: condition-variable-broadcast! condition-variable
     Wake up one thread that is waiting for CONDITION-VARIABLE, in the
     case of ‘condition-variable-signal!’, or all threads waiting for
     it, in the case of ‘condition-variable-broadcast!’.  The behavior
     of these procedures is equivalent to that of the procedures
     ‘signal-condition-variable’ and ‘broadcast-condition-variable’ in
     the core library.

7.5.15.4 SRFI-18 Time
.....................

The SRFI-18 time functions manipulate time in two formats: a “time
object” type that represents an absolute point in time in some
implementation-specific way; and the number of seconds since some
unspecified “epoch”.  In Guile’s implementation, the epoch is the Unix
epoch, 00:00:00 UTC, January 1, 1970.

 -- Function: current-time
     Return the current time as a time object.  This procedure replaces
     the procedure of the same name in the core library, which returns
     the current time in seconds since the epoch.

 -- Function: time? obj
     Returns ‘#t’ if OBJ is a time object, ‘#f’ otherwise.

 -- Function: time->seconds time
 -- Function: seconds->time seconds
     Convert between time objects and numerical values representing the
     number of seconds since the epoch.  When converting from a time
     object to seconds, the return value is the number of seconds
     between TIME and the epoch.  When converting from seconds to a time
     object, the return value is a time object that represents a time
     SECONDS seconds after the epoch.

7.5.15.5 SRFI-18 Exceptions
...........................

SRFI-18 exceptions are identical to the exceptions provided by Guile’s
implementation of SRFI-34.  The behavior of exception handlers invoked
to handle exceptions thrown from SRFI-18 functions, however, differs
from the conventional behavior of SRFI-34 in that the continuation of
the handler is the same as that of the call to the function.  Handlers
are called in a tail-recursive manner; the exceptions do not “bubble
up”.

 -- Function: current-exception-handler
     Returns the current exception handler.

 -- Function: with-exception-handler handler thunk
     Installs HANDLER as the current exception handler and calls the
     procedure THUNK with no arguments, returning its value as the value
     of the exception.  HANDLER must be a procedure that accepts a
     single argument.  The current exception handler at the time this
     procedure is called will be restored after the call returns.

 -- Function: raise obj
     Raise OBJ as an exception.  This is the same procedure as the
     same-named procedure defined in SRFI 34.

 -- Function: join-timeout-exception? obj
     Returns ‘#t’ if OBJ is an exception raised as the result of
     performing a timed join on a thread that does not exit within the
     specified timeout, ‘#f’ otherwise.

 -- Function: abandoned-mutex-exception? obj
     Returns ‘#t’ if OBJ is an exception raised as the result of
     attempting to lock a mutex that has been abandoned by its owner
     thread, ‘#f’ otherwise.

 -- Function: terminated-thread-exception? obj
     Returns ‘#t’ if OBJ is an exception raised as the result of joining
     on a thread that exited as the result of a call to
     ‘thread-terminate!’.

 -- Function: uncaught-exception? obj
 -- Function: uncaught-exception-reason exc
     ‘uncaught-exception?’ returns ‘#t’ if OBJ is an exception thrown as
     the result of joining a thread that exited by raising an exception
     that was handled by the top-level exception handler installed by
     ‘make-thread’.  When this occurs, the original exception is
     preserved as part of the exception thrown by ‘thread-join!’ and can
     be accessed by calling ‘uncaught-exception-reason’ on that
     exception.  Note that because this exception-preservation mechanism
     is a side-effect of ‘make-thread’, joining on threads that exited
     as described above but were created by other means will not raise
     this ‘uncaught-exception’ error.

7.5.16 SRFI-19 - Time/Date Library
----------------------------------

This is an implementation of the SRFI-19 time/date library.  The
functions and variables described here are provided by

     (use-modules (srfi srfi-19))

   *Caution*: The current code in this module incorrectly extends the
Gregorian calendar leap year rule back prior to the introduction of
those reforms in 1582 (or the appropriate year in various countries).
The Julian calendar was used prior to 1582, and there were 10 days
skipped for the reform, but the code doesn’t implement that.

   This will be fixed some time.  Until then calculations for 1583
onwards are correct, but prior to that any day/month/year and day of the
week calculations are wrong.

7.5.16.1 SRFI-19 Introduction
.............................

This module implements time and date representations and calculations,
in various time systems, including universal time (UTC) and atomic time
(TAI).

   For those not familiar with these time systems, TAI is based on a
fixed length second derived from oscillations of certain atoms.  UTC
differs from TAI by an integral number of seconds, which is increased or
decreased at announced times to keep UTC aligned to a mean solar day
(the orbit and rotation of the earth are not quite constant).

   So far, only increases in the TAI <-> UTC difference have been
needed.  Such an increase is a “leap second”, an extra second of TAI
introduced at the end of a UTC day.  When working entirely within UTC
this is never seen, every day simply has 86400 seconds.  But when
converting from TAI to a UTC date, an extra 23:59:60 is present, where
normally a day would end at 23:59:59.  Effectively the UTC second from
23:59:59 to 00:00:00 has taken two TAI seconds.

   In the current implementation, the system clock is assumed to be UTC,
and a table of leap seconds in the code converts to TAI. See comments in
‘srfi-19.scm’ for how to update this table.

   Also, for those not familiar with the terminology, a “Julian Day” is
a real number which is a count of days and fraction of a day, in UTC,
starting from -4713-01-01T12:00:00Z, ie. midday Monday 1 Jan 4713 B.C. A
“Modified Julian Day” is the same, but starting from
1858-11-17T00:00:00Z, ie. midnight 17 November 1858 UTC. That time is
julian day 2400000.5.

7.5.16.2 SRFI-19 Time
.....................

A “time” object has type, seconds and nanoseconds fields representing a
point in time starting from some epoch.  This is an arbitrary point in
time, not just a time of day.  Although times are represented in
nanoseconds, the actual resolution may be lower.

   The following variables hold the possible time types.  For instance
‘(current-time time-process)’ would give the current CPU process time.

 -- Variable: time-utc
     Universal Coordinated Time (UTC).

 -- Variable: time-tai
     International Atomic Time (TAI).

 -- Variable: time-monotonic
     Monotonic time, meaning a monotonically increasing time starting
     from an unspecified epoch.

     Note that in the current implementation ‘time-monotonic’ is the
     same as ‘time-tai’, and unfortunately is therefore affected by
     adjustments to the system clock.  Perhaps this will change in the
     future.

 -- Variable: time-duration
     A duration, meaning simply a difference between two times.

 -- Variable: time-process
     CPU time spent in the current process, starting from when the
     process began.

 -- Variable: time-thread
     CPU time spent in the current thread.  Not currently implemented.

 -- Function: time? obj
     Return ‘#t’ if OBJ is a time object, or ‘#f’ if not.

 -- Function: make-time type nanoseconds seconds
     Create a time object with the given TYPE, SECONDS and NANOSECONDS.

 -- Function: time-type time
 -- Function: time-nanosecond time
 -- Function: time-second time
 -- Function: set-time-type! time type
 -- Function: set-time-nanosecond! time nsec
 -- Function: set-time-second! time sec
     Get or set the type, seconds or nanoseconds fields of a time
     object.

     ‘set-time-type!’ merely changes the field, it doesn’t convert the
     time value.  For conversions, see SRFI-19 Time/Date conversions.

 -- Function: copy-time time
     Return a new time object, which is a copy of the given TIME.

 -- Function: current-time [type]
     Return the current time of the given TYPE.  The default TYPE is
     ‘time-utc’.

     Note that the name ‘current-time’ conflicts with the Guile core
     ‘current-time’ function (see Time) as well as the SRFI-18
     ‘current-time’ function (see SRFI-18 Time).  Applications
     wanting to use more than one of these functions will need to refer
     to them by different names.

 -- Function: time-resolution [type]
     Return the resolution, in nanoseconds, of the given time TYPE.  The
     default TYPE is ‘time-utc’.

 -- Function: time<=? t1 t2
 -- Function: time<? t1 t2
 -- Function: time=? t1 t2
 -- Function: time>=? t1 t2
 -- Function: time>? t1 t2
     Return ‘#t’ or ‘#f’ according to the respective relation between
     time objects T1 and T2.  T1 and T2 must be the same time type.

 -- Function: time-difference t1 t2
 -- Function: time-difference! t1 t2
     Return a time object of type ‘time-duration’ representing the
     period between T1 and T2.  T1 and T2 must be the same time type.

     ‘time-difference’ returns a new time object, ‘time-difference!’ may
     modify T1 to form its return.

 -- Function: add-duration time duration
 -- Function: add-duration! time duration
 -- Function: subtract-duration time duration
 -- Function: subtract-duration! time duration
     Return a time object which is TIME with the given DURATION added or
     subtracted.  DURATION must be a time object of type
     ‘time-duration’.

     ‘add-duration’ and ‘subtract-duration’ return a new time object.
     ‘add-duration!’ and ‘subtract-duration!’ may modify the given TIME
     to form their return.

7.5.16.3 SRFI-19 Date
.....................

A “date” object represents a date in the Gregorian calendar and a time
of day on that date in some timezone.

   The fields are year, month, day, hour, minute, second, nanoseconds
and timezone.  A date object is immutable, its fields can be read but
they cannot be modified once the object is created.

 -- Function: date? obj
     Return ‘#t’ if OBJ is a date object, or ‘#f’ if not.

 -- Function: make-date nsecs seconds minutes hours date month year
          zone-offset
     Create a new date object.

 -- Function: date-nanosecond date
     Nanoseconds, 0 to 999999999.

 -- Function: date-second date
     Seconds, 0 to 59, or 60 for a leap second.  60 is never seen when
     working entirely within UTC, it’s only when converting to or from
     TAI.

 -- Function: date-minute date
     Minutes, 0 to 59.

 -- Function: date-hour date
     Hour, 0 to 23.

 -- Function: date-day date
     Day of the month, 1 to 31 (or less, according to the month).

 -- Function: date-month date
     Month, 1 to 12.

 -- Function: date-year date
     Year, eg. 2003.  Dates B.C. are negative, eg. -46 is 46 B.C. There
     is no year 0, year -1 is followed by year 1.

 -- Function: date-zone-offset date
     Time zone, an integer number of seconds east of Greenwich.

 -- Function: date-year-day date
     Day of the year, starting from 1 for 1st January.

 -- Function: date-week-day date
     Day of the week, starting from 0 for Sunday.

 -- Function: date-week-number date dstartw
     Week of the year, ignoring a first partial week.  DSTARTW is the
     day of the week which is taken to start a week, 0 for Sunday, 1 for
     Monday, etc.

 -- Function: current-date [tz-offset]
     Return a date object representing the current date/time, in UTC
     offset by TZ-OFFSET.  TZ-OFFSET is seconds east of Greenwich and
     defaults to the local timezone.

 -- Function: current-julian-day
     Return the current Julian Day.

 -- Function: current-modified-julian-day
     Return the current Modified Julian Day.

7.5.16.4 SRFI-19 Time/Date conversions
......................................

 -- Function: date->julian-day date
 -- Function: date->modified-julian-day date
 -- Function: date->time-monotonic date
 -- Function: date->time-tai date
 -- Function: date->time-utc date
 -- Function: julian-day->date jdn [tz-offset]
 -- Function: julian-day->time-monotonic jdn
 -- Function: julian-day->time-tai jdn
 -- Function: julian-day->time-utc jdn
 -- Function: modified-julian-day->date jdn [tz-offset]
 -- Function: modified-julian-day->time-monotonic jdn
 -- Function: modified-julian-day->time-tai jdn
 -- Function: modified-julian-day->time-utc jdn
 -- Function: time-monotonic->date time [tz-offset]
 -- Function: time-monotonic->time-tai time
 -- Function: time-monotonic->time-tai! time
 -- Function: time-monotonic->time-utc time
 -- Function: time-monotonic->time-utc! time
 -- Function: time-tai->date time [tz-offset]
 -- Function: time-tai->julian-day time
 -- Function: time-tai->modified-julian-day time
 -- Function: time-tai->time-monotonic time
 -- Function: time-tai->time-monotonic! time
 -- Function: time-tai->time-utc time
 -- Function: time-tai->time-utc! time
 -- Function: time-utc->date time [tz-offset]
 -- Function: time-utc->julian-day time
 -- Function: time-utc->modified-julian-day time
 -- Function: time-utc->time-monotonic time
 -- Function: time-utc->time-monotonic! time
 -- Function: time-utc->time-tai time
 -- Function: time-utc->time-tai! time

     Convert between dates, times and days of the respective types.  For
     instance ‘time-tai->time-utc’ accepts a TIME object of type
     ‘time-tai’ and returns an object of type ‘time-utc’.

     The ‘!’ variants may modify their TIME argument to form their
     return.  The plain functions create a new object.

     For conversions to dates, TZ-OFFSET is seconds east of Greenwich.
     The default is the local timezone, at the given time, as provided
     by the system, using ‘localtime’ (see Time).

     On 32-bit systems, ‘localtime’ is limited to a 32-bit ‘time_t’, so
     a default TZ-OFFSET is only available for times between Dec 1901
     and Jan 2038.  For prior dates an application might like to use the
     value in 1902, though some locations have zone changes prior to
     that.  For future dates an application might like to assume today’s
     rules extend indefinitely.  But for correct daylight savings
     transitions it will be necessary to take an offset for the same day
     and time but a year in range and which has the same starting
     weekday and same leap/non-leap (to support rules like last Sunday
     in October).

7.5.16.5 SRFI-19 Date to string
...............................

 -- Function: date->string date [format]
     Convert a date to a string under the control of a format.  FORMAT
     should be a string containing ‘~’ escapes, which will be expanded
     as per the following conversion table.  The default FORMAT is ‘~c’,
     a locale-dependent date and time.

     Many of these conversion characters are the same as POSIX
     ‘strftime’ (see Time), but there are some extras and some
     variations.

     ~~     literal ~
     ~a     locale abbreviated weekday, eg. ‘Sun’
     ~A     locale full weekday, eg. ‘Sunday’
     ~b     locale abbreviated month, eg. ‘Jan’
     ~B     locale full month, eg. ‘January’
     ~c     locale date and time, eg.
            ‘Fri Jul 14 20:28:42-0400 2000’
     ~d     day of month, zero padded, ‘01’ to ‘31’

     ~e     day of month, blank padded, ‘ 1’ to ‘31’
     ~f     seconds and fractional seconds, with locale
            decimal point, eg. ‘5.2’
     ~h     same as ~b
     ~H     hour, 24-hour clock, zero padded, ‘00’ to ‘23’
     ~I     hour, 12-hour clock, zero padded, ‘01’ to ‘12’
     ~j     day of year, zero padded, ‘001’ to ‘366’
     ~k     hour, 24-hour clock, blank padded, ‘ 0’ to ‘23’
     ~l     hour, 12-hour clock, blank padded, ‘ 1’ to ‘12’
     ~m     month, zero padded, ‘01’ to ‘12’
     ~M     minute, zero padded, ‘00’ to ‘59’
     ~n     newline
     ~N     nanosecond, zero padded, ‘000000000’ to
            ‘999999999’
     ~p     locale AM or PM
     ~r     time, 12 hour clock, ‘~I:~M:~S ~p’
     ~s     number of full seconds since “the epoch” in UTC
     ~S     second, zero padded ‘00’ to ‘60’
            (usual limit is 59, 60 is a leap second)
     ~t     horizontal tab character
     ~T     time, 24 hour clock, ‘~H:~M:~S’
     ~U     week of year, Sunday first day of week, ‘00’ to
            ‘52’
     ~V     week of year, Monday first day of week, ‘01’ to
            ‘53’
     ~w     day of week, 0 for Sunday, ‘0’ to ‘6’
     ~W     week of year, Monday first day of week, ‘00’ to
            ‘52’

     ~y     year, two digits, ‘00’ to ‘99’
     ~Y     year, full, eg. ‘2003’
     ~z     time zone, RFC-822 style
     ~Z     time zone symbol (not currently implemented)
     ~1     ISO-8601 date, ‘~Y-~m-~d’
     ~2     ISO-8601 time+zone, ‘~H:~M:~S~z’
     ~3     ISO-8601 time, ‘~H:~M:~S’
     ~4     ISO-8601 date/time+zone, ‘~Y-~m-~dT~H:~M:~S~z’
     ~5     ISO-8601 date/time, ‘~Y-~m-~dT~H:~M:~S’

   Conversions ‘~D’, ‘~x’ and ‘~X’ are not currently described here,
since the specification and reference implementation differ.

   Conversion is locale-dependent on systems that support it (see
Accessing Locale Information).  See ‘setlocale’, for
information on how to change the current locale.

7.5.16.6 SRFI-19 String to date
...............................

 -- Function: string->date input template
     Convert an INPUT string to a date under the control of a TEMPLATE
     string.  Return a newly created date object.

     Literal characters in TEMPLATE must match characters in INPUT and
     ‘~’ escapes must match the input forms described in the table
     below.  “Skip to” means characters up to one of the given type are
     ignored, or “no skip” for no skipping.  “Read” is what’s then read,
     and “Set” is the field affected in the date object.

     For example ‘~Y’ skips input characters until a digit is reached,
     at which point it expects a year and stores that to the year field
     of the date.

            Skip to            Read                        Set

     ~~     no skip            literal ~                   nothing

     ~a     char-alphabetic?   locale abbreviated          nothing
                               weekday name
     ~A     char-alphabetic?   locale full weekday name    nothing

     ~b     char-alphabetic?   locale abbreviated month    date-month
                               name
     ~B     char-alphabetic?   locale full month name      date-month

     ~d     char-numeric?      day of month                date-day

     ~e     no skip            day of month, blank         date-day
                               padded
     ~h     same as ‘~b’

     ~H     char-numeric?      hour                        date-hour

     ~k     no skip            hour, blank padded          date-hour

     ~m     char-numeric?      month                       date-month

     ~M     char-numeric?      minute                      date-minute

     ~S     char-numeric?      second                      date-second

     ~y     no skip            2-digit year                date-year within
                                                           50 years

     ~Y     char-numeric?      year                        date-year

     ~z     no skip            time zone                   date-zone-offset

     Notice that the weekday matching forms don’t affect the date object
     returned, instead the weekday will be derived from the day, month
     and year.

     Conversion is locale-dependent on systems that support it (see
     Accessing Locale Information).  See ‘setlocale’, for
     information on how to change the current locale.

7.5.17 SRFI-23 - Error Reporting
--------------------------------

The SRFI-23 ‘error’ procedure is always available.

7.5.18 SRFI-26 - specializing parameters
----------------------------------------

This SRFI provides a syntax for conveniently specializing selected
parameters of a function.  It can be used with,

     (use-modules (srfi srfi-26))

 -- library syntax: cut slot1 slot2 ...
 -- library syntax: cute slot1 slot2 ...
     Return a new procedure which will make a call (SLOT1 SLOT2 ...) but
     with selected parameters specialized to given expressions.

     An example will illustrate the idea.  The following is a
     specialization of ‘write’, sending output to ‘my-output-port’,

          (cut write <> my-output-port)
          ⇒
          (lambda (obj) (write obj my-output-port))

     The special symbol ‘<>’ indicates a slot to be filled by an
     argument to the new procedure.  ‘my-output-port’ on the other hand
     is an expression to be evaluated and passed, ie. it specializes the
     behaviour of ‘write’.

     <>
          A slot to be filled by an argument from the created procedure.
          Arguments are assigned to ‘<>’ slots in the order they appear
          in the ‘cut’ form, there’s no way to re-arrange arguments.

          The first argument to ‘cut’ is usually a procedure (or
          expression giving a procedure), but ‘<>’ is allowed there too.
          For example,

               (cut <> 1 2 3)
               ⇒
               (lambda (proc) (proc 1 2 3))

     <...>
          A slot to be filled by all remaining arguments from the new
          procedure.  This can only occur at the end of a ‘cut’ form.

          For example, a procedure taking a variable number of arguments
          like ‘max’ but in addition enforcing a lower bound,

               (define my-lower-bound 123)

               (cut max my-lower-bound <...>)
               ⇒
               (lambda arglist (apply max my-lower-bound arglist))

     For ‘cut’ the specializing expressions are evaluated each time the
     new procedure is called.  For ‘cute’ they’re evaluated just once,
     when the new procedure is created.  The name ‘cute’ stands for
     “‘cut’ with evaluated arguments”.  In all cases the evaluations
     take place in an unspecified order.

     The following illustrates the difference between ‘cut’ and ‘cute’,

          (cut format <> "the time is ~s" (current-time))
          ⇒
          (lambda (port) (format port "the time is ~s" (current-time)))

          (cute format <> "the time is ~s" (current-time))
          ⇒
          (let ((val (current-time)))
            (lambda (port) (format port "the time is ~s" val))

     (There’s no provision for a mixture of ‘cut’ and ‘cute’ where some
     expressions would be evaluated every time but others evaluated only
     once.)

     ‘cut’ is really just a shorthand for the sort of ‘lambda’ forms
     shown in the above examples.  But notice ‘cut’ avoids the need to
     name unspecialized parameters, and is more compact.  Use in
     functional programming style or just with ‘map’, ‘for-each’ or
     similar is typical.

          (map (cut * 2 <>) '(1 2 3 4))

          (for-each (cut write <> my-port) my-list)

7.5.19 SRFI-27 - Sources of Random Bits
---------------------------------------

This subsection is based on the specification of SRFI-27
(http://srfi.schemers.org/srfi-27/srfi-27.html) written by Sebastian
Egner.

   This SRFI provides access to a (pseudo) random number generator; for
Guile’s built-in random number facilities, which SRFI-27 is implemented
upon, see Random.  With SRFI-27, random numbers are obtained from a
_random source_, which encapsulates a random number generation algorithm
and its state.

7.5.19.1 The Default Random Source
..................................

 -- Function: random-integer n
     Return a random number between zero (inclusive) and N (exclusive),
     using the default random source.  The numbers returned have a
     uniform distribution.

 -- Function: random-real
     Return a random number in (0,1), using the default random source.
     The numbers returned have a uniform distribution.

 -- Function: default-random-source
     A random source from which ‘random-integer’ and ‘random-real’ have
     been derived using ‘random-source-make-integers’ and
     ‘random-source-make-reals’ (see SRFI-27 Random Number Generators
     for those procedures).  Note that an assignment to
     ‘default-random-source’ does not change ‘random-integer’ or
     ‘random-real’; it is also strongly recommended not to assign a new
     value.

7.5.19.2 Random Sources
.......................

 -- Function: make-random-source
     Create a new random source.  The stream of random numbers obtained
     from each random source created by this procedure will be
     identical, unless its state is changed by one of the procedures
     below.

 -- Function: random-source? object
     Tests whether OBJECT is a random source.  Random sources are a
     disjoint type.

 -- Function: random-source-randomize! source
     Attempt to set the state of the random source to a truly random
     value.  The current implementation uses a seed based on the current
     system time.

 -- Function: random-source-pseudo-randomize! source i j
     Changes the state of the random source s into the initial state of
     the (I, J)-th independent random source, where I and J are
     non-negative integers.  This procedure provides a mechanism to
     obtain a large number of independent random sources (usually all
     derived from the same backbone generator), indexed by two integers.
     In contrast to ‘random-source-randomize!’, this procedure is
     entirely deterministic.

   The state associated with a random state can be obtained an
reinstated with the following procedures:

 -- Function: random-source-state-ref source
 -- Function: random-source-state-set! source state
     Get and set the state of a random source.  No assumptions should be
     made about the nature of the state object, besides it having an
     external representation (i.e. it can be passed to ‘write’ and
     subsequently ‘read’ back).

7.5.19.3 Obtaining random number generator procedures
.....................................................

 -- Function: random-source-make-integers source
     Obtains a procedure to generate random integers using the random
     source SOURCE.  The returned procedure takes a single argument N,
     which must be a positive integer, and returns the next uniformly
     distributed random integer from the interval {0, ..., N-1} by
     advancing the state of SOURCE.

     If an application obtains and uses several generators for the same
     random source SOURCE, a call to any of these generators advances
     the state of SOURCE.  Hence, the generators do not produce the same
     sequence of random integers each but rather share a state.  This
     also holds for all other types of generators derived from a fixed
     random sources.

     While the SRFI text specifies that “Implementations that support
     concurrency make sure that the state of a generator is properly
     advanced”, this is currently not the case in Guile’s implementation
     of SRFI-27, as it would cause a severe performance penalty.  So in
     multi-threaded programs, you either must perform locking on random
     sources shared between threads yourself, or use different random
     sources for multiple threads.

 -- Function: random-source-make-reals source
 -- Function: random-source-make-reals source unit
     Obtains a procedure to generate random real numbers 0 < x < 1 using
     the random source SOURCE.  The procedure rand is called without
     arguments.

     The optional parameter UNIT determines the type of numbers being
     produced by the returned procedure and the quantization of the
     output.  UNIT must be a number such that 0 < UNIT < 1.  The numbers
     created by the returned procedure are of the same numerical type as
     UNIT and the potential output values are spaced by at most UNIT.
     One can imagine rand to create numbers as X * UNIT where X is a
     random integer in {1, ..., floor(1/unit)-1}.  Note, however, that
     this need not be the way the values are actually created and that
     the actual resolution of rand can be much higher than unit.  In
     case UNIT is absent it defaults to a reasonably small value
     (related to the width of the mantissa of an efficient number
     format).

7.5.20 SRFI-28 - Basic Format Strings
-------------------------------------

SRFI-28 provides a basic ‘format’ procedure that provides only the ‘~a’,
‘~s’, ‘~%’, and ‘~~’ format specifiers.  You can import this procedure
by using:

     (use-modules (srfi srfi-28))

 -- Scheme Procedure: format message arg ...
     Returns a formatted message, using MESSAGE as the format string,
     which can contain the following format specifiers:

     ‘~a’
          Insert the textual representation of the next ARG, as if
          printed by ‘display’.

     ‘~s’
          Insert the textual representation of the next ARG, as if
          printed by ‘write’.

     ‘~%’
          Insert a newline.

     ‘~~’
          Insert a tilde.

     This procedure is the same as calling ‘simple-format’ (see
     Writing) with ‘#f’ as the destination.

7.5.21 SRFI-30 - Nested Multi-line Comments
-------------------------------------------

Starting from version 2.0, Guile’s ‘read’ supports SRFI-30/R6RS nested
multi-line comments by default, see Block Comments.

7.5.22 SRFI-31 - A special form ‘rec’ for recursive evaluation
--------------------------------------------------------------

SRFI-31 defines a special form that can be used to create
self-referential expressions more conveniently.  The syntax is as
follows:

     <rec expression> --> (rec <variable> <expression>)
     <rec expression> --> (rec (<variable>+) <body>)

   The first syntax can be used to create self-referential expressions,
for example:

       guile> (define tmp (rec ones (cons 1 (delay ones))))

   The second syntax can be used to create anonymous recursive
functions:

       guile> (define tmp (rec (display-n item n)
                            (if (positive? n)
                                (begin (display n) (display-n (- n 1))))))
       guile> (tmp 42 3)
       424242
       guile>

7.5.23 SRFI-34 - Exception handling for programs
------------------------------------------------

Guile provides an implementation of SRFI-34’s exception handling
mechanisms (http://srfi.schemers.org/srfi-34/srfi-34.html) as an
alternative to its own built-in mechanisms (see Exceptions).  It can
be made available as follows:

     (use-modules (srfi srfi-34))

7.5.24 SRFI-35 - Conditions
---------------------------

SRFI-35 (http://srfi.schemers.org/srfi-35/srfi-35.html) implements
“conditions”, a data structure akin to records designed to convey
information about exceptional conditions between parts of a program.  It
is normally used in conjunction with SRFI-34’s ‘raise’:

     (raise (condition (&message
                         (message "An error occurred"))))

   Users can define “condition types” containing arbitrary information.
Condition types may inherit from one another.  This allows the part of
the program that handles (or “catches”) conditions to get accurate
information about the exceptional condition that arose.

   SRFI-35 conditions are made available using:

     (use-modules (srfi srfi-35))

   The procedures available to manipulate condition types are the
following:

 -- Scheme Procedure: make-condition-type id parent field-names
     Return a new condition 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.

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

   Conditions can be created and accessed with the following procedures:

 -- Scheme Procedure: make-condition type . field+value
     Return a new condition of type TYPE with fields initialized as
     specified by FIELD+VALUE, a sequence of field names (symbols) and
     values as in the following example:

          (let ((&ct (make-condition-type 'foo &condition '(a b c))))
            (make-condition &ct 'a 1 'b 2 'c 3))

     Note that all fields of TYPE and its supertypes must be specified.

 -- Scheme Procedure: make-compound-condition condition1 condition2 ...
     Return a new compound condition composed of CONDITION1 CONDITION2
     ....  The returned condition has the type of each condition of
     condition1 condition2 ... (per ‘condition-has-type?’).

 -- Scheme Procedure: condition-has-type? c type
     Return true if condition C has type TYPE.

 -- Scheme Procedure: condition-ref c field-name
     Return the value of the field named FIELD-NAME from condition C.

     If C is a compound condition and several underlying condition types
     contain a field named FIELD-NAME, then the value of the first such
     field is returned, using the order in which conditions were passed
     to ‘make-compound-condition’.

 -- Scheme Procedure: extract-condition c type
     Return a condition of condition type TYPE with the field values
     specified by C.

     If C is a compound condition, extract the field values from the
     subcondition belonging to TYPE that appeared first in the call to
     ‘make-compound-condition’ that created the condition.

   Convenience macros are also available to create condition types and
conditions.

 -- library syntax: define-condition-type type supertype predicate
          field-spec...
     Define a new condition type named TYPE that inherits from
     SUPERTYPE.  In addition, bind PREDICATE to a type predicate that
     returns true when passed a condition of type TYPE or any of its
     subtypes.  FIELD-SPEC must have the form ‘(field accessor)’ where
     FIELD is the name of field of TYPE and ACCESSOR is the name of a
     procedure to access field FIELD in conditions of type TYPE.

     The example below defines condition type ‘&foo’, inheriting from
     ‘&condition’ with fields ‘a’, ‘b’ and ‘c’:

          (define-condition-type &foo &condition
            foo-condition?
            (a  foo-a)
            (b  foo-b)
            (c  foo-c))

 -- library syntax: condition type-field-binding1 type-field-binding2
          ...
     Return a new condition or compound condition, initialized according
     to TYPE-FIELD-BINDING1 TYPE-FIELD-BINDING2 ....  Each
     TYPE-FIELD-BINDING must have the form ‘(type field-specs...)’,
     where TYPE is the name of a variable bound to a condition type;
     each FIELD-SPEC must have the form ‘(field-name value)’ where
     FIELD-NAME is a symbol denoting the field being initialized to
     VALUE.  As for ‘make-condition’, all fields must be specified.

     The following example returns a simple condition:

          (condition (&message (message "An error occurred")))

     The one below returns a compound condition:

          (condition (&message (message "An error occurred"))
                     (&serious))

   Finally, SRFI-35 defines a several standard condition types.

 -- Variable: &condition
     This condition type is the root of all condition types.  It has no
     fields.

 -- Variable: &message
     A condition type that carries a message describing the nature of
     the condition to humans.

 -- Scheme Procedure: message-condition? c
     Return true if C is of type ‘&message’ or one of its subtypes.

 -- Scheme Procedure: condition-message c
     Return the message associated with message condition C.

 -- Variable: &serious
     This type describes conditions serious enough that they cannot
     safely be ignored.  It has no fields.

 -- Scheme Procedure: serious-condition? c
     Return true if C is of type ‘&serious’ or one of its subtypes.

 -- Variable: &error
     This condition describes errors, typically caused by something that
     has gone wrong in the interaction of the program with the external
     world or the user.

 -- Scheme Procedure: error? c
     Return true if C is of type ‘&error’ or one of its subtypes.

7.5.25 SRFI-37 - args-fold
--------------------------

This is a processor for GNU ‘getopt_long’-style program arguments.  It
provides an alternative, less declarative interface than ‘getopt-long’
in ‘(ice-9 getopt-long)’ (see The (ice-9 getopt-long) Module).
Unlike ‘getopt-long’, it supports repeated options and
any number of short and long names per option.  Access it with:

     (use-modules (srfi srfi-37))

   SRFI-37 principally provides an ‘option’ type and the ‘args-fold’
function.  To use the library, create a set of options with ‘option’ and
use it as a specification for invoking ‘args-fold’.

   Here is an example of a simple argument processor for the typical
‘--version’ and ‘--help’ options, which returns a backwards list of
files given on the command line:

     (args-fold (cdr (program-arguments))
                (let ((display-and-exit-proc
                       (lambda (msg)
                         (lambda (opt name arg loads)
                           (display msg) (quit)))))
                  (list (option '(#\v "version") #f #f
                                (display-and-exit-proc "Foo version 42.0\n"))
                        (option '(#\h "help") #f #f
                                (display-and-exit-proc
                                 "Usage: foo scheme-file ..."))))
                (lambda (opt name arg loads)
                  (error "Unrecognized option `~A'" name))
                (lambda (op loads) (cons op loads))
                '())

 -- Scheme Procedure: option names required-arg? optional-arg? processor
     Return an object that specifies a single kind of program option.

     NAMES is a list of command-line option names, and should consist of
     characters for traditional ‘getopt’ short options and strings for
     ‘getopt_long’-style long options.

     REQUIRED-ARG? and OPTIONAL-ARG? are mutually exclusive; one or both
     must be ‘#f’.  If REQUIRED-ARG?, the option must be followed by an
     argument on the command line, such as ‘--opt=value’ for long
     options, or an error will be signalled.  If OPTIONAL-ARG?, an
     argument will be taken if available.

     PROCESSOR is a procedure that takes at least 3 arguments, called
     when ‘args-fold’ encounters the option: the containing option
     object, the name used on the command line, and the argument given
     for the option (or ‘#f’ if none).  The rest of the arguments are
     ‘args-fold’ “seeds”, and the PROCESSOR should return seeds as well.

 -- Scheme Procedure: option-names opt
 -- Scheme Procedure: option-required-arg? opt
 -- Scheme Procedure: option-optional-arg? opt
 -- Scheme Procedure: option-processor opt
     Return the specified field of OPT, an option object, as described
     above for ‘option’.

 -- Scheme Procedure: args-fold args options unrecognized-option-proc
          operand-proc seed ...
     Process ARGS, a list of program arguments such as that returned by
     ‘(cdr (program-arguments))’, in order against OPTIONS, a list of
     option objects as described above.  All functions called take the
     “seeds”, or the last multiple-values as multiple arguments,
     starting with SEED ..., and must return the new seeds.  Return the
     final seeds.

     Call ‘unrecognized-option-proc’, which is like an option object’s
     processor, for any options not found in OPTIONS.

     Call ‘operand-proc’ with any items on the command line that are not
     named options.  This includes arguments after ‘--’.  It is called
     with the argument in question, as well as the seeds.

7.5.26 SRFI-38 - External Representation for Data With Shared Structure
-----------------------------------------------------------------------

This subsection is based on the specification of SRFI-38
(http://srfi.schemers.org/srfi-38/srfi-38.html) written by Ray
Dillinger.

   This SRFI creates an alternative external representation for data
written and read using ‘write-with-shared-structure’ and
‘read-with-shared-structure’.  It is identical to the grammar for
external representation for data written and read with ‘write’ and
‘read’ given in section 7 of R5RS, except that the single production

     <datum> --> <simple datum> | <compound datum>

   is replaced by the following five productions:

     <datum> --> <defining datum> | <nondefining datum> | <defined datum>
     <defining datum> -->  #<indexnum>=<nondefining datum>
     <defined datum> --> #<indexnum>#
     <nondefining datum> --> <simple datum> | <compound datum>
     <indexnum> --> <digit 10>+

 -- Scheme procedure: write-with-shared-structure obj
 -- Scheme procedure: write-with-shared-structure obj port
 -- Scheme procedure: write-with-shared-structure obj port optarg

     Writes an external representation of OBJ to the given port.
     Strings that appear in the written representation are enclosed in
     doublequotes, and within those strings backslash and doublequote
     characters are escaped by backslashes.  Character objects are
     written using the ‘#\’ notation.

     Objects which denote locations rather than values (cons cells,
     vectors, and non-zero-length strings in R5RS scheme; also Guile’s
     structs, bytevectors and ports and hash-tables), if they appear at
     more than one point in the data being written, are preceded by
     ‘#N=’ the first time they are written and replaced by ‘#N#’ all
     subsequent times they are written, where N is a natural number used
     to identify that particular object.  If objects which denote
     locations occur only once in the structure, then
     ‘write-with-shared-structure’ must produce the same external
     representation for those objects as ‘write’.

     ‘write-with-shared-structure’ terminates in finite time and
     produces a finite representation when writing finite data.

     ‘write-with-shared-structure’ returns an unspecified value.  The
     PORT argument may be omitted, in which case it defaults to the
     value returned by ‘(current-output-port)’.  The OPTARG argument may
     also be omitted.  If present, its effects on the output and return
     value are unspecified but ‘write-with-shared-structure’ must still
     write a representation that can be read by
     ‘read-with-shared-structure’.  Some implementations may wish to use
     OPTARG to specify formatting conventions, numeric radixes, or
     return values.  Guile’s implementation ignores OPTARG.

     For example, the code

          (begin (define a (cons 'val1 'val2))
                 (set-cdr! a a)
                 (write-with-shared-structure a))

     should produce the output ‘#1=(val1 . #1#)’.  This shows a cons
     cell whose ‘cdr’ contains itself.

 -- Scheme procedure: read-with-shared-structure
 -- Scheme procedure: read-with-shared-structure port

     ‘read-with-shared-structure’ converts the external representations
     of Scheme objects produced by ‘write-with-shared-structure’ into
     Scheme objects.  That is, it is a parser for the nonterminal
     ‘<datum>’ in the augmented external representation grammar defined
     above.  ‘read-with-shared-structure’ returns the next object
     parsable from the given input port, updating PORT to point to the
     first character past the end of the external representation of the
     object.

     If an end-of-file is encountered in the input before any characters
     are found that can begin an object, then an end-of-file object is
     returned.  The port remains open, and further attempts to read it
     (by ‘read-with-shared-structure’ or ‘read’ will also return an
     end-of-file object.  If an end of file is encountered after the
     beginning of an object’s external representation, but the external
     representation is incomplete and therefore not parsable, an error
     is signalled.

     The PORT argument may be omitted, in which case it defaults to the
     value returned by ‘(current-input-port)’.  It is an error to read
     from a closed port.

7.5.27 SRFI-39 - Parameters
---------------------------

This SRFI adds support for dynamically-scoped parameters.  SRFI 39 is
implemented in the Guile core; there’s no module needed to get SRFI-39
itself.  Parameters are documented in Parameters.

   This module does export one extra function: ‘with-parameters*’.  This
is a Guile-specific addition to the SRFI, similar to the core
‘with-fluids*’ (see Fluids and Dynamic States).

 -- Function: with-parameters* param-list value-list thunk
     Establish a new dynamic scope, as per ‘parameterize’ above, taking
     parameters from PARAM-LIST and corresponding values from
     VALUE-LIST.  A call ‘(THUNK)’ is made in the new scope and the
     result from that THUNK is the return from ‘with-parameters*’.

7.5.28 SRFI-41 - Streams
------------------------

This subsection is based on the specification of SRFI-41
(http://srfi.schemers.org/srfi-41/srfi-41.html) by Philip L. Bewig.

This SRFI implements streams, sometimes called lazy lists, a sequential
data structure containing elements computed only on demand.  A stream is
either null or is a pair with a stream in its cdr.  Since elements of a
stream are computed only when accessed, streams can be infinite.  Once
computed, the value of a stream element is cached in case it is needed
again.  SRFI-41 can be made available with:

     (use-modules (srfi srfi-41))

7.5.28.1 SRFI-41 Stream Fundamentals
....................................

SRFI-41 Streams are based on two mutually-recursive abstract data types:
An object of the ‘stream’ abstract data type is a promise that, when
forced, is either ‘stream-null’ or is an object of type ‘stream-pair’.
An object of the ‘stream-pair’ abstract data type contains a
‘stream-car’ and a ‘stream-cdr’, which must be a ‘stream’.  The
essential feature of streams is the systematic suspensions of the
recursive promises between the two data types.

   The object stored in the ‘stream-car’ of a ‘stream-pair’ is a promise
that is forced the first time the ‘stream-car’ is accessed; its value is
cached in case it is needed again.  The object may have any type, and
different stream elements may have different types.  If the ‘stream-car’
is never accessed, the object stored there is never evaluated.
Likewise, the ‘stream-cdr’ is a promise to return a stream, and is only
forced on demand.

7.5.28.2 SRFI-41 Stream Primitives
..................................

This library provides eight operators: constructors for ‘stream-null’
and ‘stream-pair’s, type predicates for streams and the two kinds of
streams, accessors for both fields of a ‘stream-pair’, and a lambda that
creates procedures that return streams.

 -- Scheme Variable: stream-null
     A promise that, when forced, is a single object, distinguishable
     from all other objects, that represents the null stream.
     ‘stream-null’ is immutable and unique.

 -- Scheme Syntax: stream-cons object-expr stream-expr
     Creates a newly-allocated stream containing a promise that, when
     forced, is a ‘stream-pair’ with OBJECT-EXPR in its ‘stream-car’ and
     STREAM-EXPR in its ‘stream-cdr’.  Neither OBJECT-EXPR nor
     STREAM-EXPR is evaluated when ‘stream-cons’ is called.

     Once created, a ‘stream-pair’ is immutable; there is no
     ‘stream-set-car!’ or ‘stream-set-cdr!’ that modifies an existing
     stream-pair.  There is no dotted-pair or improper stream as with
     lists.

 -- Scheme Procedure: stream? object
     Returns true if OBJECT is a stream, otherwise returns false.  If
     OBJECT is a stream, its promise will not be forced.  If ‘(stream?
     obj)’ returns true, then one of ‘(stream-null? obj)’ or
     ‘(stream-pair? obj)’ will return true and the other will return
     false.

 -- Scheme Procedure: stream-null? object
     Returns true if OBJECT is the distinguished null stream, otherwise
     returns false.  If OBJECT is a stream, its promise will be forced.

 -- Scheme Procedure: stream-pair? object
     Returns true if OBJECT is a ‘stream-pair’ constructed by
     ‘stream-cons’, otherwise returns false.  If OBJECT is a stream, its
     promise will be forced.

 -- Scheme Procedure: stream-car stream
     Returns the object stored in the ‘stream-car’ of STREAM.  An error
     is signalled if the argument is not a ‘stream-pair’.  This causes
     the OBJECT-EXPR passed to ‘stream-cons’ to be evaluated if it had
     not yet been; the value is cached in case it is needed again.

 -- Scheme Procedure: stream-cdr stream
     Returns the stream stored in the ‘stream-cdr’ of STREAM.  An error
     is signalled if the argument is not a ‘stream-pair’.

 -- Scheme Syntax: stream-lambda formals body ...
     Creates a procedure that returns a promise to evaluate the BODY of
     the procedure.  The last BODY expression to be evaluated must yield
     a stream.  As with normal ‘lambda’, FORMALS may be a single
     variable name, in which case all the formal arguments are collected
     into a single list, or a list of variable names, which may be null
     if there are no arguments, proper if there are an exact number of
     arguments, or dotted if a fixed number of arguments is to be
     followed by zero or more arguments collected into a list.  BODY
     must contain at least one expression, and may contain internal
     definitions preceding any expressions to be evaluated.

     (define strm123
       (stream-cons 1
         (stream-cons 2
           (stream-cons 3
             stream-null))))

     (stream-car strm123) ⇒ 1
     (stream-car (stream-cdr strm123) ⇒ 2

     (stream-pair?
       (stream-cdr
         (stream-cons (/ 1 0) stream-null))) ⇒ #f

     (stream? (list 1 2 3)) ⇒ #f

     (define iter
       (stream-lambda (f x)
         (stream-cons x (iter f (f x)))))

     (define nats (iter (lambda (x) (+ x 1)) 0))

     (stream-car (stream-cdr nats)) ⇒ 1

     (define stream-add
       (stream-lambda (s1 s2)
         (stream-cons
           (+ (stream-car s1) (stream-car s2))
           (stream-add (stream-cdr s1)
                       (stream-cdr s2)))))

     (define evens (stream-add nats nats))

     (stream-car evens) ⇒ 0
     (stream-car (stream-cdr evens)) ⇒ 2
     (stream-car (stream-cdr (stream-cdr evens))) ⇒ 4

7.5.28.3 SRFI-41 Stream Library
...............................

 -- Scheme Syntax: define-stream (name args ...) body ...
     Creates a procedure that returns a stream, and may appear anywhere
     a normal ‘define’ may appear, including as an internal definition.
     It may contain internal definitions of its own.  The defined
     procedure takes arguments in the same way as ‘stream-lambda’.
     ‘define-stream’ is syntactic sugar on ‘stream-lambda’; see also
     ‘stream-let’, which is also a sugaring of ‘stream-lambda’.

     A simple version of ‘stream-map’ that takes only a single input
     stream calls itself recursively:

          (define-stream (stream-map proc strm)
            (if (stream-null? strm)
                stream-null
                (stream-cons
                  (proc (stream-car strm))
                  (stream-map proc (stream-cdr strm))))))

 -- Scheme Procedure: list->stream list
     Returns a newly-allocated stream containing the elements from LIST.

 -- Scheme Procedure: port->stream [port]
     Returns a newly-allocated stream containing in its elements the
     characters on the port.  If PORT is not given it defaults to the
     current input port.  The returned stream has finite length and is
     terminated by ‘stream-null’.

     It looks like one use of ‘port->stream’ would be this:

          (define s ;wrong!
            (with-input-from-file filename
              (lambda () (port->stream))))

     But that fails, because ‘with-input-from-file’ is eager, and closes
     the input port prematurely, before the first character is read.  To
     read a file into a stream, say:

          (define-stream (file->stream filename)
            (let ((p (open-input-file filename)))
              (stream-let loop ((c (read-char p)))
                (if (eof-object? c)
                    (begin (close-input-port p)
                           stream-null)
                    (stream-cons c
                      (loop (read-char p)))))))

 -- Scheme Syntax: stream object-expr ...
     Creates a newly-allocated stream containing in its elements the
     objects, in order.  The OBJECT-EXPRs are evaluated when they are
     accessed, not when the stream is created.  If no objects are given,
     as in (stream), the null stream is returned.  See also
     ‘list->stream’.

          (define strm123 (stream 1 2 3))

          ; (/ 1 0) not evaluated when stream is created
          (define s (stream 1 (/ 1 0) -1))

 -- Scheme Procedure: stream->list [n] stream
     Returns a newly-allocated list containing in its elements the first
     N items in STREAM.  If STREAM has less than N items, all the items
     in the stream will be included in the returned list.  If N is not
     given it defaults to infinity, which means that unless STREAM is
     finite ‘stream->list’ will never return.

          (stream->list 10
            (stream-map (lambda (x) (* x x))
              (stream-from 0)))
            ⇒ (0 1 4 9 16 25 36 49 64 81)

 -- Scheme Procedure: stream-append stream ...
     Returns a newly-allocated stream containing in its elements those
     elements contained in its input STREAMs, in order of input.  If any
     of the input streams is infinite, no elements of any of the
     succeeding input streams will appear in the output stream.  See
     also ‘stream-concat’.

 -- Scheme Procedure: stream-concat stream
     Takes a STREAM consisting of one or more streams and returns a
     newly-allocated stream containing all the elements of the input
     streams.  If any of the streams in the input STREAM is infinite,
     any remaining streams in the input stream will never appear in the
     output stream.  See also ‘stream-append’.

 -- Scheme Procedure: stream-constant object ...
     Returns a newly-allocated stream containing in its elements the
     OBJECTs, repeating in succession forever.

          (stream-constant 1) ⇒ 1 1 1 ...
          (stream-constant #t #f) ⇒ #t #f #t #f #t #f ...

 -- Scheme Procedure: stream-drop n stream
     Returns the suffix of the input STREAM that starts at the next
     element after the first N elements.  The output stream shares
     structure with the input STREAM; thus, promises forced in one
     instance of the stream are also forced in the other instance of the
     stream.  If the input STREAM has less than N elements,
     ‘stream-drop’ returns the null stream.  See also ‘stream-take’.

 -- Scheme Procedure: stream-drop-while pred stream
     Returns the suffix of the input STREAM that starts at the first
     element X for which ‘(pred x)’ returns false.  The output stream
     shares structure with the input STREAM.  See also
     ‘stream-take-while’.

 -- Scheme Procedure: stream-filter pred stream
     Returns a newly-allocated stream that contains only those elements
     X of the input STREAM which satisfy the predicate ‘pred’.

          (stream-filter odd? (stream-from 0))
             ⇒ 1 3 5 7 9 ...

 -- Scheme Procedure: stream-fold proc base stream
     Applies a binary procedure PROC to BASE and the first element of
     STREAM to compute a new BASE, then applies the procedure to the new
     BASE and the next element of STREAM to compute a succeeding BASE,
     and so on, accumulating a value that is finally returned as the
     value of ‘stream-fold’ when the end of the stream is reached.
     STREAM must be finite, or ‘stream-fold’ will enter an infinite
     loop.  See also ‘stream-scan’, which is similar to ‘stream-fold’,
     but useful for infinite streams.  For readers familiar with other
     functional languages, this is a left-fold; there is no
     corresponding right-fold, since right-fold relies on finite streams
     that are fully-evaluated, in which case they may as well be
     converted to a list.

 -- Scheme Procedure: stream-for-each proc stream ...
     Applies PROC element-wise to corresponding elements of the input
     STREAMs for side-effects; it returns nothing.  ‘stream-for-each’
     stops as soon as any of its input streams is exhausted.

 -- Scheme Procedure: stream-from first [step]
     Creates a newly-allocated stream that contains FIRST as its first
     element and increments each succeeding element by STEP.  If STEP is
     not given it defaults to 1.  FIRST and STEP may be of any numeric
     type.  ‘stream-from’ is frequently useful as a generator in
     ‘stream-of’ expressions.  See also ‘stream-range’ for a similar
     procedure that creates finite streams.

 -- Scheme Procedure: stream-iterate proc base
     Creates a newly-allocated stream containing BASE in its first
     element and applies PROC to each element in turn to determine the
     succeeding element.  See also ‘stream-unfold’ and ‘stream-unfolds’.

 -- Scheme Procedure: stream-length stream
     Returns the number of elements in the STREAM; it does not evaluate
     its elements.  ‘stream-length’ may only be used on finite streams;
     it enters an infinite loop with infinite streams.

 -- Scheme Syntax: stream-let tag ((var expr) ...) body ...
     Creates a local scope that binds each variable to the value of its
     corresponding expression.  It additionally binds TAG to a procedure
     which takes the bound variables as arguments and BODY as its
     defining expressions, binding the TAG with ‘stream-lambda’.  TAG is
     in scope within body, and may be called recursively.  When the
     expanded expression defined by the ‘stream-let’ is evaluated,
     ‘stream-let’ evaluates the expressions in its BODY in an
     environment containing the newly-bound variables, returning the
     value of the last expression evaluated, which must yield a stream.

     ‘stream-let’ provides syntactic sugar on ‘stream-lambda’, in the
     same manner as normal ‘let’ provides syntactic sugar on normal
     ‘lambda’.  However, unlike normal ‘let’, the TAG is required, not
     optional, because unnamed ‘stream-let’ is meaningless.

     For example, ‘stream-member’ returns the first ‘stream-pair’ of the
     input STRM with a ‘stream-car’ X that satisfies ‘(eql? obj x)’, or
     the null stream if X is not present in STRM.

          (define-stream (stream-member eql? obj strm)
            (stream-let loop ((strm strm))
              (cond ((stream-null? strm) strm)
                    ((eql? obj (stream-car strm)) strm)
                    (else (loop (stream-cdr strm))))))

 -- Scheme Procedure: stream-map proc stream ...
     Applies PROC element-wise to corresponding elements of the input
     STREAMs, returning a newly-allocated stream containing elements
     that are the results of those procedure applications.  The output
     stream has as many elements as the minimum-length input stream, and
     may be infinite.

 -- Scheme Syntax: stream-match stream clause ...
     Provides pattern-matching for streams.  The input STREAM is an
     expression that evaluates to a stream.  Clauses are of the form
     ‘(pattern [fender] expression)’, consisting of a PATTERN that
     matches a stream of a particular shape, an optional FENDER that
     must succeed if the pattern is to match, and an EXPRESSION that is
     evaluated if the pattern matches.  There are four types of
     patterns:

        • () matches the null stream.

        • (PAT0 PAT1 ...) matches a finite stream with length exactly
          equal to the number of pattern elements.

        • (PAT0 PAT1 ... ‘.’  PAT-REST) matches an infinite stream, or a
          finite stream with length at least as great as the number of
          pattern elements before the literal dot.

        • PAT matches an entire stream.  Should always appear last in
          the list of clauses; it’s not an error to appear elsewhere,
          but subsequent clauses could never match.

     Each pattern element may be either:

        • An identifier, which matches any stream element.
          Additionally, the value of the stream element is bound to the
          variable named by the identifier, which is in scope in the
          FENDER and EXPRESSION of the corresponding CLAUSE.  Each
          identifier in a single pattern must be unique.

        • A literal underscore (‘_’), which matches any stream element
          but creates no bindings.

     The PATTERNs are tested in order, left-to-right, until a matching
     pattern is found; if FENDER is present, it must evaluate to a true
     value for the match to be successful.  Pattern variables are bound
     in the corresponding FENDER and EXPRESSION.  Once the matching
     PATTERN is found, the corresponding EXPRESSION is evaluated and
     returned as the result of the match.  An error is signaled if no
     pattern matches the input STREAM.

     ‘stream-match’ is often used to distinguish null streams from
     non-null streams, binding HEAD and TAIL:

          (define (len strm)
            (stream-match strm
              (() 0)
              ((head . tail) (+ 1 (len tail)))))

     Fenders can test the common case where two stream elements must be
     identical; the ‘else’ pattern is an identifier bound to the entire
     stream, not a keyword as in ‘cond’.

          (stream-match strm
            ((x y . _) (equal? x y) 'ok)
            (else 'error))

     A more complex example uses two nested matchers to match two
     different stream arguments; ‘(stream-merge lt? . strms)’ stably
     merges two or more streams ordered by the ‘lt?’ predicate:

          (define-stream (stream-merge lt? . strms)
            (define-stream (merge xx yy)
              (stream-match xx (() yy) ((x . xs)
                (stream-match yy (() xx) ((y . ys)
                  (if (lt? y x)
                      (stream-cons y (merge xx ys))
                      (stream-cons x (merge xs yy))))))))
            (stream-let loop ((strms strms))
              (cond ((null? strms) stream-null)
                    ((null? (cdr strms)) (car strms))
                    (else (merge (car strms)
                                 (apply stream-merge lt?
                                   (cdr strms)))))))

 -- Scheme Syntax: stream-of expr clause ...
     Provides the syntax of stream comprehensions, which generate
     streams by means of looping expressions.  The result is a stream of
     objects of the type returned by EXPR.  There are four types of
     clauses:

        • (VAR ‘in’ STREAM-EXPR) loops over the elements of STREAM-EXPR,
          in order from the start of the stream, binding each element of
          the stream in turn to VAR.  ‘stream-from’ and ‘stream-range’
          are frequently useful as generators for STREAM-EXPR.

        • (VAR ‘is’ EXPR) binds VAR to the value obtained by evaluating
          EXPR.

        • (PRED EXPR) includes in the output stream only those elements
          X which satisfy the predicate PRED.

     The scope of variables bound in the stream comprehension is the
     clauses to the right of the binding clause (but not the binding
     clause itself) plus the result expression.

     When two or more generators are present, the loops are processed as
     if they are nested from left to right; that is, the rightmost
     generator varies fastest.  A consequence of this is that only the
     first generator may be infinite and all subsequent generators must
     be finite.  If no generators are present, the result of a stream
     comprehension is a stream containing the result expression; thus,
     ‘(stream-of 1)’ produces a finite stream containing only the
     element 1.

          (stream-of (* x x)
            (x in (stream-range 0 10))
            (even? x))
            ⇒ 0 4 16 36 64

          (stream-of (list a b)
            (a in (stream-range 1 4))
            (b in (stream-range 1 3)))
            ⇒ (1 1) (1 2) (2 1) (2 2) (3 1) (3 2)

          (stream-of (list i j)
            (i in (stream-range 1 5))
            (j in (stream-range (+ i 1) 5)))
            ⇒ (1 2) (1 3) (1 4) (2 3) (2 4) (3 4)

 -- Scheme Procedure: stream-range first past [step]
     Creates a newly-allocated stream that contains FIRST as its first
     element and increments each succeeding element by STEP.  The stream
     is finite and ends before PAST, which is not an element of the
     stream.  If STEP is not given it defaults to 1 if FIRST is less
     than past and -1 otherwise.  FIRST, PAST and STEP may be of any
     real numeric type.  ‘stream-range’ is frequently useful as a
     generator in ‘stream-of’ expressions.  See also ‘stream-from’ for a
     similar procedure that creates infinite streams.

          (stream-range 0 10) ⇒ 0 1 2 3 4 5 6 7 8 9
          (stream-range 0 10 2) ⇒ 0 2 4 6 8

     Successive elements of the stream are calculated by adding STEP to
     FIRST, so if any of FIRST, PAST or STEP are inexact, the length of
     the output stream may differ from ‘(ceiling (- (/ (- past first)
     step) 1)’.

 -- Scheme Procedure: stream-ref stream n
     Returns the Nth element of stream, counting from zero.  An error is
     signaled if N is greater than or equal to the length of stream.

          (define (fact n)
            (stream-ref
              (stream-scan * 1 (stream-from 1))
              n))

 -- Scheme Procedure: stream-reverse stream
     Returns a newly-allocated stream containing the elements of the
     input STREAM but in reverse order.  ‘stream-reverse’ may only be
     used with finite streams; it enters an infinite loop with infinite
     streams.  ‘stream-reverse’ does not force evaluation of the
     elements of the stream.

 -- Scheme Procedure: stream-scan proc base stream
     Accumulates the partial folds of an input STREAM into a
     newly-allocated output stream.  The output stream is the BASE
     followed by ‘(stream-fold proc base (stream-take i stream))’ for
     each of the first I elements of STREAM.

          (stream-scan + 0 (stream-from 1))
            ⇒ (stream 0 1 3 6 10 15 ...)

          (stream-scan * 1 (stream-from 1))
            ⇒ (stream 1 1 2 6 24 120 ...)

 -- Scheme Procedure: stream-take n stream
     Returns a newly-allocated stream containing the first N elements of
     the input STREAM.  If the input STREAM has less than N elements, so
     does the output stream.  See also ‘stream-drop’.

 -- Scheme Procedure: stream-take-while pred stream
     Takes a predicate and a ‘stream’ and returns a newly-allocated
     stream containing those elements ‘x’ that form the maximal prefix
     of the input stream which satisfy PRED.  See also
     ‘stream-drop-while’.

 -- Scheme Procedure: stream-unfold map pred gen base
     The fundamental recursive stream constructor.  It constructs a
     stream by repeatedly applying GEN to successive values of BASE, in
     the manner of ‘stream-iterate’, then applying MAP to each of the
     values so generated, appending each of the mapped values to the
     output stream as long as ‘(pred? base)’ returns a true value.  See
     also ‘stream-iterate’ and ‘stream-unfolds’.

     The expression below creates the finite stream ‘0 1 4 9 16 25 36 49
     64 81’.  Initially the BASE is 0, which is less than 10, so MAP
     squares the BASE and the mapped value becomes the first element of
     the output stream.  Then GEN increments the BASE by 1, so it
     becomes 1; this is less than 10, so MAP squares the new BASE and 1
     becomes the second element of the output stream.  And so on, until
     the base becomes 10, when PRED stops the recursion and stream-null
     ends the output stream.

          (stream-unfold
            (lambda (x) (expt x 2)) ; map
            (lambda (x) (< x 10))   ; pred?
            (lambda (x) (+ x 1))    ; gen
            0)                      ; base

 -- Scheme Procedure: stream-unfolds proc seed
     Returns N newly-allocated streams containing those elements
     produced by successive calls to the generator PROC, which takes the
     current SEED as its argument and returns N+1 values

     (PROC SEED) ⇒ SEED RESULT_0 ... RESULT_N-1

     where the returned SEED is the input SEED to the next call to the
     generator and RESULT_I indicates how to produce the next element of
     the Ith result stream:

        • (VALUE): VALUE is the next car of the result stream.

        • ‘#f’: no value produced by this iteration of the generator
          PROC for the result stream.

        • (): the end of the result stream.

     It may require multiple calls of PROC to produce the next element
     of any particular result stream.  See also ‘stream-iterate’ and
     ‘stream-unfold’.

          (define (stream-partition pred? strm)
            (stream-unfolds
              (lambda (s)
                (if (stream-null? s)
                    (values s '() '())
                    (let ((a (stream-car s))
                          (d (stream-cdr s)))
                      (if (pred? a)
                          (values d (list a) #f)
                          (values d #f (list a))))))
              strm))

          (call-with-values
            (lambda ()
              (stream-partition odd?
                (stream-range 1 6)))
            (lambda (odds evens)
              (list (stream->list odds)
                    (stream->list evens))))
            ⇒ ((1 3 5) (2 4))

 -- Scheme Procedure: stream-zip stream ...
     Returns a newly-allocated stream in which each element is a list
     (not a stream) of the corresponding elements of the input STREAMs.
     The output stream is as long as the shortest input STREAM, if any
     of the input STREAMs is finite, or is infinite if all the input
     STREAMs are infinite.

7.5.29 SRFI-42 - Eager Comprehensions
-------------------------------------

See the specification of SRFI-42
(http://srfi.schemers.org/srfi-42/srfi-42.html).

7.5.30 SRFI-43 - Vector Library
-------------------------------

This subsection is based on the specification of SRFI-43
(http://srfi.schemers.org/srfi-43/srfi-43.html) by Taylor Campbell.

SRFI-43 implements a comprehensive library of vector operations.  It can
be made available with:

     (use-modules (srfi srfi-43))

7.5.30.1 SRFI-43 Constructors
.............................

 -- Scheme Procedure: make-vector size [fill]
     Create and return a vector of size SIZE, optionally filling it with
     FILL.  The default value of FILL is unspecified.

          (make-vector 5 3) ⇒ #(3 3 3 3 3)

 -- Scheme Procedure: vector x ...
     Create and return a vector whose elements are X ....

          (vector 0 1 2 3 4) ⇒ #(0 1 2 3 4)

 -- Scheme Procedure: vector-unfold f length initial-seed ...
     The fundamental vector constructor.  Create a vector whose length
     is LENGTH and iterates across each index k from 0 up to LENGTH - 1,
     applying F at each iteration to the current index and current
     seeds, in that order, to receive n + 1 values: the element to put
     in the kth slot of the new vector, and n new seeds for the next
     iteration.  It is an error for the number of seeds to vary between
     iterations.

          (vector-unfold (lambda (i x) (values x (- x 1)))
                         10 0)
          ⇒ #(0 -1 -2 -3 -4 -5 -6 -7 -8 -9)

          (vector-unfold values 10)
          ⇒ #(0 1 2 3 4 5 6 7 8 9)

 -- Scheme Procedure: vector-unfold-right f length initial-seed ...
     Like ‘vector-unfold’, but it uses F to generate elements from
     right-to-left, rather than left-to-right.

          (vector-unfold-right (lambda (i x) (values x (+ x 1)))
                               10 0)
          ⇒ #(9 8 7 6 5 4 3 2 1 0)

 -- Scheme Procedure: vector-copy vec [start [end [fill]]]
     Allocate a new vector whose length is END - START and fills it with
     elements from VEC, taking elements from VEC starting at index START
     and stopping at index END.  START defaults to 0 and END defaults to
     the value of ‘(vector-length vec)’.  If END extends beyond the
     length of VEC, the slots in the new vector that obviously cannot be
     filled by elements from VEC are filled with FILL, whose default
     value is unspecified.

          (vector-copy '#(a b c d e f g h i))
          ⇒ #(a b c d e f g h i)

          (vector-copy '#(a b c d e f g h i) 6)
          ⇒ #(g h i)

          (vector-copy '#(a b c d e f g h i) 3 6)
          ⇒ #(d e f)

          (vector-copy '#(a b c d e f g h i) 6 12 'x)
          ⇒ #(g h i x x x)

 -- Scheme Procedure: vector-reverse-copy vec [start [end]]
     Like ‘vector-copy’, but it copies the elements in the reverse order
     from VEC.

          (vector-reverse-copy '#(5 4 3 2 1 0) 1 5)
          ⇒ #(1 2 3 4)

 -- Scheme Procedure: vector-append vec ...
     Return a newly allocated vector that contains all elements in order
     from the subsequent locations in VEC ....

          (vector-append '#(a) '#(b c d))
          ⇒ #(a b c d)

 -- Scheme Procedure: vector-concatenate list-of-vectors
     Append each vector in LIST-OF-VECTORS.  Equivalent to ‘(apply
     vector-append list-of-vectors)’.

          (vector-concatenate '(#(a b) #(c d)))
          ⇒ #(a b c d)

7.5.30.2 SRFI-43 Predicates
...........................

 -- Scheme Procedure: vector? obj
     Return true if OBJ is a vector, else return false.

 -- Scheme Procedure: vector-empty? vec
     Return true if VEC is empty, i.e.  its length is 0, else return
     false.

 -- Scheme Procedure: vector= elt=? vec ...
     Return true if the vectors VEC ... have equal lengths and equal
     elements according to ELT=?.  ELT=? is always applied to two
     arguments.  Element comparison must be consistent with ‘eq?’ in the
     following sense: if ‘(eq? a b)’ returns true, then ‘(elt=? a b)’
     must also return true.  The order in which comparisons are
     performed is unspecified.

7.5.30.3 SRFI-43 Selectors
..........................

 -- Scheme Procedure: vector-ref vec i
     Return the element at index I in VEC.  Indexing is based on zero.

 -- Scheme Procedure: vector-length vec
     Return the length of VEC.

7.5.30.4 SRFI-43 Iteration
..........................

 -- Scheme Procedure: vector-fold kons knil vec1 vec2 ...
     The fundamental vector iterator.  KONS is iterated over each index
     in all of the vectors, stopping at the end of the shortest; KONS is
     applied as
          (kons i state (vector-ref vec1 i) (vector-ref vec2 i) ...)
     where STATE is the current state value, and I is the current index.
     The current state value begins with KNIL, and becomes whatever KONS
     returned at the respective iteration.  The iteration is strictly
     left-to-right.

 -- Scheme Procedure: vector-fold-right kons knil vec1 vec2 ...
     Similar to ‘vector-fold’, but it iterates right-to-left instead of
     left-to-right.

 -- Scheme Procedure: vector-map f vec1 vec2 ...
     Return a new vector of the shortest size of the vector arguments.
     Each element at index i of the new vector is mapped from the old
     vectors by
          (f i (vector-ref vec1 i) (vector-ref vec2 i) ...)
     The dynamic order of application of F is unspecified.

 -- Scheme Procedure: vector-map! f vec1 vec2 ...
     Similar to ‘vector-map’, but rather than mapping the new elements
     into a new vector, the new mapped elements are destructively
     inserted into VEC1.  The dynamic order of application of F is
     unspecified.

 -- Scheme Procedure: vector-for-each f vec1 vec2 ...
     Call ‘(f i (vector-ref vec1 i) (vector-ref vec2 i) ...)’ for each
     index i less than the length of the shortest vector passed.  The
     iteration is strictly left-to-right.

 -- Scheme Procedure: vector-count pred? vec1 vec2 ...
     Count the number of parallel elements in the vectors that satisfy
     PRED?, which is applied, for each index i less than the length of
     the smallest vector, to i and each parallel element in the vectors
     at that index, in order.

          (vector-count (lambda (i elt) (even? elt))
                        '#(3 1 4 1 5 9 2 5 6))
          ⇒ 3
          (vector-count (lambda (i x y) (< x y))
                        '#(1 3 6 9) '#(2 4 6 8 10 12))
          ⇒ 2

7.5.30.5 SRFI-43 Searching
..........................

 -- Scheme Procedure: vector-index pred? vec1 vec2 ...
     Find and return the index of the first elements in VEC1 VEC2 ...
     that satisfy PRED?.  If no matching element is found by the end of
     the shortest vector, return ‘#f’.

          (vector-index even? '#(3 1 4 1 5 9))
          ⇒ 2
          (vector-index < '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))
          ⇒ 1
          (vector-index = '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))
          ⇒ #f

 -- Scheme Procedure: vector-index-right pred? vec1 vec2 ...
     Like ‘vector-index’, but it searches right-to-left, rather than
     left-to-right.  Note that the SRFI 43 specification requires that
     all the vectors must have the same length, but both the SRFI 43
     reference implementation and Guile’s implementation allow vectors
     with unequal lengths, and start searching from the last index of
     the shortest vector.

 -- Scheme Procedure: vector-skip pred? vec1 vec2 ...
     Find and return the index of the first elements in VEC1 VEC2 ...
     that do not satisfy PRED?.  If no matching element is found by the
     end of the shortest vector, return ‘#f’.  Equivalent to
     ‘vector-index’ but with the predicate inverted.

          (vector-skip number? '#(1 2 a b 3 4 c d)) ⇒ 2

 -- Scheme Procedure: vector-skip-right pred? vec1 vec2 ...
     Like ‘vector-skip’, but it searches for a non-matching element
     right-to-left, rather than left-to-right.  Note that the SRFI 43
     specification requires that all the vectors must have the same
     length, but both the SRFI 43 reference implementation and Guile’s
     implementation allow vectors with unequal lengths, and start
     searching from the last index of the shortest vector.

 -- Scheme Procedure: vector-binary-search vec value cmp [start [end]]
     Find and return an index of VEC between START and END whose value
     is VALUE using a binary search.  If no matching element is found,
     return ‘#f’.  The default START is 0 and the default END is the
     length of VEC.

     CMP must be a procedure of two arguments such that ‘(cmp a b)’
     returns a negative integer if a < b, a positive integer if a > b,
     or zero if a = b.  The elements of VEC must be sorted in
     non-decreasing order according to CMP.

     Note that SRFI 43 does not document the START and END arguments,
     but both its reference implementation and Guile’s implementation
     support them.

          (define (char-cmp c1 c2)
            (cond ((char<? c1 c2) -1)
                  ((char>? c1 c2) 1)
                  (else 0)))

          (vector-binary-search '#(#\a #\b #\c #\d #\e #\f #\g #\h)
                                #\g
                                char-cmp)
          ⇒ 6

 -- Scheme Procedure: vector-any pred? vec1 vec2 ...
     Find the first parallel set of elements from VEC1 VEC2 ... for
     which PRED? returns a true value.  If such a parallel set of
     elements exists, ‘vector-any’ returns the value that PRED? returned
     for that set of elements.  The iteration is strictly left-to-right.

 -- Scheme Procedure: vector-every pred? vec1 vec2 ...
     If, for every index i between 0 and the length of the shortest
     vector argument, the set of elements ‘(vector-ref vec1 i)’
     ‘(vector-ref vec2 i)’ ... satisfies PRED?, ‘vector-every’ returns
     the value that PRED? returned for the last set of elements, at the
     last index of the shortest vector.  Otherwise it returns ‘#f’.  The
     iteration is strictly left-to-right.

7.5.30.6 SRFI-43 Mutators
.........................

 -- Scheme Procedure: vector-set! vec i value
     Assign the contents of the location at I in VEC to VALUE.

 -- Scheme Procedure: vector-swap! vec i j
     Swap the values of the locations in VEC at I and J.

 -- Scheme Procedure: vector-fill! vec fill [start [end]]
     Assign the value of every location in VEC between START and END to
     FILL.  START defaults to 0 and END defaults to the length of VEC.

 -- Scheme Procedure: vector-reverse! vec [start [end]]
     Destructively reverse the contents of VEC between START and END.
     START defaults to 0 and END defaults to the length of VEC.

 -- Scheme Procedure: vector-copy! target tstart source [sstart [send]]
     Copy a block of elements from SOURCE to TARGET, both of which must
     be vectors, starting in TARGET at TSTART and starting in SOURCE at
     SSTART, ending when (SEND - SSTART) elements have been copied.  It
     is an error for TARGET to have a length less than (TSTART + SEND -
     SSTART).  SSTART defaults to 0 and SEND defaults to the length of
     SOURCE.

 -- Scheme Procedure: vector-reverse-copy! target tstart source [sstart
          [send]]
     Like ‘vector-copy!’, but this copies the elements in the reverse
     order.  It is an error if TARGET and SOURCE are identical vectors
     and the TARGET and SOURCE ranges overlap; however, if TSTART =
     SSTART, ‘vector-reverse-copy!’ behaves as ‘(vector-reverse! target
     tstart send)’ would.

7.5.30.7 SRFI-43 Conversion
...........................

 -- Scheme Procedure: vector->list vec [start [end]]
     Return a newly allocated list containing the elements in VEC
     between START and END.  START defaults to 0 and END defaults to the
     length of VEC.

 -- Scheme Procedure: reverse-vector->list vec [start [end]]
     Like ‘vector->list’, but the resulting list contains the specified
     range of elements of VEC in reverse order.

 -- Scheme Procedure: list->vector proper-list [start [end]]
     Return a newly allocated vector of the elements from PROPER-LIST
     with indices between START and END.  START defaults to 0 and END
     defaults to the length of PROPER-LIST.  Note that SRFI 43 does not
     document the START and END arguments, but both its reference
     implementation and Guile’s implementation support them.

 -- Scheme Procedure: reverse-list->vector proper-list [start [end]]
     Like ‘list->vector’, but the resulting vector contains the
     specified range of elements of PROPER-LIST in reverse order.  Note
     that SRFI 43 does not document the START and END arguments, but
     both its reference implementation and Guile’s implementation
     support them.

7.5.31 SRFI-45 - Primitives for Expressing Iterative Lazy Algorithms
--------------------------------------------------------------------

This subsection is based on the specification of SRFI-45
(http://srfi.schemers.org/srfi-45/srfi-45.html) written by André van
Tonder.

   Lazy evaluation is traditionally simulated in Scheme using ‘delay’
and ‘force’.  However, these primitives are not powerful enough to
express a large class of lazy algorithms that are iterative.  Indeed, it
is folklore in the Scheme community that typical iterative lazy
algorithms written using delay and force will often require unbounded
memory.

   This SRFI provides set of three operations: {‘lazy’, ‘delay’,
‘force’}, which allow the programmer to succinctly express lazy
algorithms while retaining bounded space behavior in cases that are
properly tail-recursive.  A general recipe for using these primitives is
provided.  An additional procedure ‘eager’ is provided for the
construction of eager promises in cases where efficiency is a concern.

   Although this SRFI redefines ‘delay’ and ‘force’, the extension is
conservative in the sense that the semantics of the subset {‘delay’,
‘force’} in isolation (i.e., as long as the program does not use ‘lazy’)
agrees with that in R5RS. In other words, no program that uses the R5RS
definitions of delay and force will break if those definition are
replaced by the SRFI-45 definitions of delay and force.

   Guile also adds ‘promise?’ to the list of exports, which is not part
of the official SRFI-45.

 -- Scheme Procedure: promise? obj
     Return true if OBJ is an SRFI-45 promise, otherwise return false.

 -- Scheme Syntax: delay expression
     Takes an expression of arbitrary type A and returns a promise of
     type ‘(Promise A)’ which at some point in the future may be asked
     (by the ‘force’ procedure) to evaluate the expression and deliver
     the resulting value.

 -- Scheme Syntax: lazy expression
     Takes an expression of type ‘(Promise A)’ and returns a promise of
     type ‘(Promise A)’ which at some point in the future may be asked
     (by the ‘force’ procedure) to evaluate the expression and deliver
     the resulting promise.

 -- Scheme Procedure: force expression
     Takes an argument of type ‘(Promise A)’ and returns a value of type
     A as follows: If a value of type A has been computed for the
     promise, this value is returned.  Otherwise, the promise is first
     evaluated, then overwritten by the obtained promise or value, and
     then force is again applied (iteratively) to the promise.

 -- Scheme Procedure: eager expression
     Takes an argument of type A and returns a value of type ‘(Promise
     A)’.  As opposed to ‘delay’, the argument is evaluated eagerly.
     Semantically, writing ‘(eager expression)’ is equivalent to writing

          (let ((value expression)) (delay value)).

     However, the former is more efficient since it does not require
     unnecessary creation and evaluation of thunks.  We also have the
     equivalence

          (delay expression) = (lazy (eager expression))

   The following reduction rules may be helpful for reasoning about
these primitives.  However, they do not express the memoization and
memory usage semantics specified above:

     (force (delay expression)) -> expression
     (force (lazy  expression)) -> (force expression)
     (force (eager value))      -> value

Correct usage
.............

We now provide a general recipe for using the primitives {‘lazy’,
‘delay’, ‘force’} to express lazy algorithms in Scheme.  The
transformation is best described by way of an example: Consider the
stream-filter algorithm, expressed in a hypothetical lazy language as

     (define (stream-filter p? s)
       (if (null? s) '()
           (let ((h (car s))
                 (t (cdr s)))
             (if (p? h)
                 (cons h (stream-filter p? t))
                 (stream-filter p? t)))))

   This algorithm can be expressed as follows in Scheme:

     (define (stream-filter p? s)
       (lazy
          (if (null? (force s)) (delay '())
              (let ((h (car (force s)))
                    (t (cdr (force s))))
                (if (p? h)
                    (delay (cons h (stream-filter p? t)))
                    (stream-filter p? t))))))

   In other words, we

   • wrap all constructors (e.g., ‘'()’, ‘cons’) with ‘delay’,
   • apply ‘force’ to arguments of deconstructors (e.g., ‘car’, ‘cdr’
     and ‘null?’),
   • wrap procedure bodies with ‘(lazy ...)’.

7.5.32 SRFI-46 Basic syntax-rules Extensions
--------------------------------------------

Guile’s core ‘syntax-rules’ supports the extensions specified by
SRFI-46/R7RS. Tail patterns have been supported since at least Guile
2.0, and custom ellipsis identifiers have been supported since Guile
2.0.10.  See Syntax Rules.

7.5.33 SRFI-55 - Requiring Features
-----------------------------------

SRFI-55 provides ‘require-extension’ which is a portable mechanism to
load selected SRFI modules.  This is implemented in the Guile core,
there’s no module needed to get SRFI-55 itself.

 -- library syntax: require-extension clause1 clause2 ...
     Require the features of CLAUSE1 CLAUSE2 ... , throwing an error if
     any are unavailable.

     A CLAUSE is of the form ‘(IDENTIFIER arg...)’.  The only IDENTIFIER
     currently supported is ‘srfi’ and the arguments are SRFI numbers.
     For example to get SRFI-1 and SRFI-6,

          (require-extension (srfi 1 6))

     ‘require-extension’ can only be used at the top-level.

     A Guile-specific program can simply ‘use-modules’ to load SRFIs not
     already in the core, ‘require-extension’ is for programs designed
     to be portable to other Scheme implementations.

7.5.34 SRFI-60 - Integers as Bits
---------------------------------

This SRFI provides various functions for treating integers as bits and
for bitwise manipulations.  These functions can be obtained with,

     (use-modules (srfi srfi-60))

   Integers are treated as infinite precision twos-complement, the same
as in the core logical functions (see Bitwise Operations).  And
likewise bit indexes start from 0 for the least significant bit.  The
following functions in this SRFI are already in the Guile core,

     ‘logand’, ‘logior’, ‘logxor’, ‘lognot’, ‘logtest’, ‘logcount’,
     ‘integer-length’, ‘logbit?’, ‘ash’

 -- Function: bitwise-and n1 ...
 -- Function: bitwise-ior n1 ...
 -- Function: bitwise-xor n1 ...
 -- Function: bitwise-not n
 -- Function: any-bits-set? j k
 -- Function: bit-set? index n
 -- Function: arithmetic-shift n count
 -- Function: bit-field n start end
 -- Function: bit-count n
     Aliases for ‘logand’, ‘logior’, ‘logxor’, ‘lognot’, ‘logtest’,
     ‘logbit?’, ‘ash’, ‘bit-extract’ and ‘logcount’ respectively.

     Note that the name ‘bit-count’ conflicts with ‘bit-count’ in the
     core (see Bit Vectors).

 -- Function: bitwise-if mask n1 n0
 -- Function: bitwise-merge mask n1 n0
     Return an integer with bits selected from N1 and N0 according to
     MASK.  Those bits where MASK has 1s are taken from N1, and those
     where MASK has 0s are taken from N0.

          (bitwise-if 3 #b0101 #b1010) ⇒ 9

 -- Function: log2-binary-factors n
 -- Function: first-set-bit n
     Return a count of how many factors of 2 are present in N.  This is
     also the bit index of the lowest 1 bit in N.  If N is 0, the return
     is -1.

          (log2-binary-factors 6) ⇒ 1
          (log2-binary-factors -8) ⇒ 3

 -- Function: copy-bit index n newbit
     Return N with the bit at INDEX set according to NEWBIT.  NEWBIT
     should be ‘#t’ to set the bit to 1, or ‘#f’ to set it to 0.  Bits
     other than at INDEX are unchanged in the return.

          (copy-bit 1 #b0101 #t) ⇒ 7

 -- Function: copy-bit-field n newbits start end
     Return N with the bits from START (inclusive) to END (exclusive)
     changed to the value NEWBITS.

     The least significant bit in NEWBITS goes to START, the next to
     START+1, etc.  Anything in NEWBITS past the END given is ignored.

          (copy-bit-field #b10000 #b11 1 3) ⇒ #b10110

 -- Function: rotate-bit-field n count start end
     Return N with the bit field from START (inclusive) to END
     (exclusive) rotated upwards by COUNT bits.

     COUNT can be positive or negative, and it can be more than the
     field width (it’ll be reduced modulo the width).

          (rotate-bit-field #b0110 2 1 4) ⇒ #b1010

 -- Function: reverse-bit-field n start end
     Return N with the bits from START (inclusive) to END (exclusive)
     reversed.

          (reverse-bit-field #b101001 2 4) ⇒ #b100101

 -- Function: integer->list n [len]
     Return bits from N in the form of a list of ‘#t’ for 1 and ‘#f’ for
     0.  The least significant LEN bits are returned, and the first list
     element is the most significant of those bits.  If LEN is not
     given, the default is ‘(integer-length N)’ (see Bitwise Operations).

          (integer->list 6)   ⇒ (#t #t #f)
          (integer->list 1 4) ⇒ (#f #f #f #t)

 -- Function: list->integer lst
 -- Function: booleans->integer bool...
     Return an integer formed bitwise from the given LST list of
     booleans, or for ‘booleans->integer’ from the BOOL arguments.

     Each boolean is ‘#t’ for a 1 and ‘#f’ for a 0.  The first element
     becomes the most significant bit in the return.

          (list->integer '(#t #f #t #f)) ⇒ 10

7.5.35 SRFI-61 - A more general ‘cond’ clause
---------------------------------------------

This SRFI extends RnRS ‘cond’ to support test expressions that return
multiple values, as well as arbitrary definitions of test success.  SRFI
61 is implemented in the Guile core; there’s no module needed to get
SRFI-61 itself.  Extended ‘cond’ is documented in Simple Conditional Evaluation.

7.5.36 SRFI-62 - S-expression comments.
---------------------------------------

Starting from version 2.0, Guile’s ‘read’ supports SRFI-62/R7RS
S-expression comments by default.

7.5.37 SRFI-64 - A Scheme API for test suites.
----------------------------------------------

See the specification of SRFI-64
(http://srfi.schemers.org/srfi-64/srfi-64.html).

7.5.38 SRFI-67 - Compare procedures
-----------------------------------

See the specification of SRFI-67
(http://srfi.schemers.org/srfi-67/srfi-67.html).

7.5.39 SRFI-69 - Basic hash tables
----------------------------------

This is a portable wrapper around Guile’s built-in hash table and weak
table support.  See Hash Tables, for information on that built-in
support.  Above that, this hash-table interface provides association of
equality and hash functions with tables at creation time, so variants of
each function are not required, as well as a procedure that takes care
of most uses for Guile hash table handles, which this SRFI does not
provide as such.

   Access it with:

     (use-modules (srfi srfi-69))

7.5.39.1 Creating hash tables
.............................

 -- Scheme Procedure: make-hash-table [equal-proc hash-proc #:weak
          weakness start-size]
     Create and answer a new hash table with EQUAL-PROC as the equality
     function and HASH-PROC as the hashing function.

     By default, EQUAL-PROC is ‘equal?’.  It can be any two-argument
     procedure, and should answer whether two keys are the same for this
     table’s purposes.

     My default HASH-PROC assumes that ‘equal-proc’ is no coarser than
     ‘equal?’ unless it is literally ‘string-ci=?’.  If provided,
     HASH-PROC should be a two-argument procedure that takes a key and
     the current table size, and answers a reasonably good hash integer
     between 0 (inclusive) and the size (exclusive).

     WEAKNESS should be ‘#f’ or a symbol indicating how “weak” the hash
     table is:

     ‘#f’
          An ordinary non-weak hash table.  This is the default.

     ‘key’
          When the key has no more non-weak references at GC, remove
          that entry.

     ‘value’
          When the value has no more non-weak references at GC, remove
          that entry.

     ‘key-or-value’
          When either has no more non-weak references at GC, remove the
          association.

     As a legacy of the time when Guile couldn’t grow hash tables,
     START-SIZE is an optional integer argument that specifies the
     approximate starting size for the hash table, which will be rounded
     to an algorithmically-sounder number.

   By “coarser” than ‘equal?’, we mean that for all X and Y values where
‘(EQUAL-PROC X Y)’, ‘(equal? X Y)’ as well.  If that does not hold for
your EQUAL-PROC, you must provide a HASH-PROC.

   In the case of weak tables, remember that “references” above always
refers to ‘eq?’-wise references.  Just because you have a reference to
some string ‘"foo"’ doesn’t mean that an association with key ‘"foo"’ in
a weak-key table _won’t_ be collected; it only counts as a reference if
the two ‘"foo"’s are ‘eq?’, regardless of EQUAL-PROC.  As such, it is
usually only sensible to use ‘eq?’ and ‘hashq’ as the equivalence and
hash functions for a weak table.  See Weak References, for more
information on Guile’s built-in weak table support.

 -- Scheme Procedure: alist->hash-table alist [equal-proc hash-proc
          #:weak weakness start-size]
     As with ‘make-hash-table’, but initialize it with the associations
     in ALIST.  Where keys are repeated in ALIST, the leftmost
     association takes precedence.

7.5.39.2 Accessing table items
..............................

 -- Scheme Procedure: hash-table-ref table key [default-thunk]
 -- Scheme Procedure: hash-table-ref/default table key default
     Answer the value associated with KEY in TABLE.  If KEY is not
     present, answer the result of invoking the thunk DEFAULT-THUNK,
     which signals an error instead by default.

     ‘hash-table-ref/default’ is a variant that requires a third
     argument, DEFAULT, and answers DEFAULT itself instead of invoking
     it.

 -- Scheme Procedure: hash-table-set! table key new-value
     Set KEY to NEW-VALUE in TABLE.

 -- Scheme Procedure: hash-table-delete! table key
     Remove the association of KEY in TABLE, if present.  If absent, do
     nothing.

 -- Scheme Procedure: hash-table-exists? table key
     Answer whether KEY has an association in TABLE.

 -- Scheme Procedure: hash-table-update! table key modifier
          [default-thunk]
 -- Scheme Procedure: hash-table-update!/default table key modifier
          default
     Replace KEY’s associated value in TABLE by invoking MODIFIER with
     one argument, the old value.

     If KEY is not present, and DEFAULT-THUNK is provided, invoke it
     with no arguments to get the “old value” to be passed to MODIFIER
     as above.  If DEFAULT-THUNK is not provided in such a case, signal
     an error.

     ‘hash-table-update!/default’ is a variant that requires the fourth
     argument, which is used directly as the “old value” rather than as
     a thunk to be invoked to retrieve the “old value”.

7.5.39.3 Table properties
.........................

 -- Scheme Procedure: hash-table-size table
     Answer the number of associations in TABLE.  This is guaranteed to
     run in constant time for non-weak tables.

 -- Scheme Procedure: hash-table-keys table
     Answer an unordered list of the keys in TABLE.

 -- Scheme Procedure: hash-table-values table
     Answer an unordered list of the values in TABLE.

 -- Scheme Procedure: hash-table-walk table proc
     Invoke PROC once for each association in TABLE, passing the key and
     value as arguments.

 -- Scheme Procedure: hash-table-fold table proc init
     Invoke ‘(PROC KEY VALUE PREVIOUS)’ for each KEY and VALUE in TABLE,
     where PREVIOUS is the result of the previous invocation, using INIT
     as the first PREVIOUS value.  Answer the final PROC result.

 -- Scheme Procedure: hash-table->alist table
     Answer an alist where each association in TABLE is an association
     in the result.

7.5.39.4 Hash table algorithms
..............................

Each hash table carries an “equivalence function” and a “hash function”,
used to implement key lookups.  Beginning users should follow the rules
for consistency of the default HASH-PROC specified above.  Advanced
users can use these to implement their own equivalence and hash
functions for specialized lookup semantics.

 -- Scheme Procedure: hash-table-equivalence-function hash-table
 -- Scheme Procedure: hash-table-hash-function hash-table
     Answer the equivalence and hash function of HASH-TABLE,
     respectively.

 -- Scheme Procedure: hash obj [size]
 -- Scheme Procedure: string-hash obj [size]
 -- Scheme Procedure: string-ci-hash obj [size]
 -- Scheme Procedure: hash-by-identity obj [size]
     Answer a hash value appropriate for equality predicate ‘equal?’,
     ‘string=?’, ‘string-ci=?’, and ‘eq?’, respectively.

   ‘hash’ is a backwards-compatible replacement for Guile’s built-in
‘hash’.

7.5.40 SRFI-87 => in case clauses
---------------------------------

Starting from version 2.0.6, Guile’s core ‘case’ syntax supports ‘=>’ in
clauses, as specified by SRFI-87/R7RS. See Conditionals.

7.5.41 SRFI-88 Keyword Objects
------------------------------

SRFI-88 (http://srfi.schemers.org/srfi-88/srfi-88.html) provides
“keyword objects”, which are equivalent to Guile’s keywords (see
Keywords).  SRFI-88 keywords can be entered using the “postfix keyword
syntax”, which consists of an identifier followed by ‘:’ (see
‘postfix’ keyword syntax).  SRFI-88 can be made available
with:

     (use-modules (srfi srfi-88))

   Doing so installs the right reader option for keyword syntax, using
‘(read-set! keywords 'postfix)’.  It also provides the procedures
described below.

 -- Scheme Procedure: keyword? obj
     Return ‘#t’ if OBJ is a keyword.  This is the same procedure as the
     same-named built-in procedure (see ‘keyword?’).

          (keyword? foo:)         ⇒ #t
          (keyword? 'foo:)        ⇒ #t
          (keyword? "foo")        ⇒ #f

 -- Scheme Procedure: keyword->string kw
     Return the name of KW as a string, i.e., without the trailing
     colon.  The returned string may not be modified, e.g., with
     ‘string-set!’.

          (keyword->string foo:)  ⇒ "foo"

 -- Scheme Procedure: string->keyword str
     Return the keyword object whose name is STR.

          (keyword->string (string->keyword "a b c"))     ⇒ "a b c"

7.5.42 SRFI-98 Accessing environment variables.
-----------------------------------------------

This is a portable wrapper around Guile’s built-in support for
interacting with the current environment, see Runtime Environment.

 -- Scheme Procedure: get-environment-variable name
     Returns a string containing the value of the environment variable
     given by the string ‘name’, or ‘#f’ if the named environment
     variable is not found.  This is equivalent to ‘(getenv name)’.

 -- Scheme Procedure: get-environment-variables
     Returns the names and values of all the environment variables as an
     association list in which both the keys and the values are strings.

7.5.43 SRFI-105 Curly-infix expressions.
----------------------------------------

Guile’s built-in reader includes support for SRFI-105 curly-infix
expressions.  See the specification of SRFI-105
(http://srfi.schemers.org/srfi-105/srfi-105.html).  Some examples:

     {n <= 5}                ⇒  (<= n 5)
     {a + b + c}             ⇒  (+ a b c)
     {a * {b + c}}           ⇒  (* a (+ b c))
     {(- a) / b}             ⇒  (/ (- a) b)
     {-(a) / b}              ⇒  (/ (- a) b) as well
     {(f a b) + (g h)}       ⇒  (+ (f a b) (g h))
     {f(a b) + g(h)}         ⇒  (+ (f a b) (g h)) as well
     {f[a b] + g(h)}         ⇒  (+ ($bracket-apply$ f a b) (g h))
     '{a + f(b) + x}         ⇒  '(+ a (f b) x)
     {length(x) >= 6}        ⇒  (>= (length x) 6)
     {n-1 + n-2}             ⇒  (+ n-1 n-2)
     {n * factorial{n - 1}}  ⇒  (* n (factorial (- n 1)))
     {{a > 0} and {b >= 1}}  ⇒  (and (> a 0) (>= b 1))
     {f{n - 1}(x)}           ⇒  ((f (- n 1)) x)
     {a . z}                 ⇒  ($nfx$ a . z)
     {a + b - c}             ⇒  ($nfx$ a + b - c)

   To enable curly-infix expressions within a file, place the reader
directive ‘#!curly-infix’ before the first use of curly-infix notation.
To globally enable curly-infix expressions in Guile’s reader, set the
‘curly-infix’ read option.

   Guile also implements the following non-standard extension to
SRFI-105: if ‘curly-infix’ is enabled and there is no other meaning
assigned to square brackets (i.e.  the ‘square-brackets’ read option is
turned off), then lists within square brackets are read as normal lists
but with the special symbol ‘$bracket-list$’ added to the front.  To
enable this combination of read options within a file, use the reader
directive ‘#!curly-infix-and-bracket-lists’.  For example:

     [a b]    ⇒  ($bracket-list$ a b)
     [a . b]  ⇒  ($bracket-list$ a . b)

   For more information on reader options, see Scheme Read.

7.5.44 SRFI-111 Boxes.
----------------------

SRFI-111 (http://srfi.schemers.org/srfi-111/srfi-111.html) provides
boxes: objects with a single mutable cell.

 -- Scheme Procedure: box value
     Return a newly allocated box whose contents is initialized to
     VALUE.

 -- Scheme Procedure: box? obj
     Return true if OBJ is a box, otherwise return false.

 -- Scheme Procedure: unbox box
     Return the current contents of BOX.

 -- Scheme Procedure: set-box! box value
     Set the contents of BOX to VALUE.

7.6 R6RS Support
================

See R6RS Libraries, for more information on how to define R6RS
libraries, and their integration with Guile modules.

7.6.1 Incompatibilities with the R6RS
-------------------------------------

There are some incompatibilities between Guile and the R6RS. Some of
them are intentional, some of them are bugs, and some are simply
unimplemented features.  Please let the Guile developers know if you
find one that is not on this list.

   • The R6RS specifies many situations in which a conforming
     implementation must signal a specific error.  Guile doesn’t really
     care about that too much—if a correct R6RS program would not hit
     that error, we don’t bother checking for it.

   • Multiple ‘library’ forms in one file are not yet supported.  This
     is because the expansion of ‘library’ sets the current module, but
     does not restore it.  This is a bug.

   • R6RS unicode escapes within strings are disabled by default,
     because they conflict with Guile’s already-existing escapes.  The
     same is the case for R6RS treatment of escaped newlines in strings.

     R6RS behavior can be turned on via a reader option.  See String Syntax,
     for more information.

   • A ‘set!’ to a variable transformer may only expand to an
     expression, not a definition—even if the original ‘set!’ expression
     was in definition context.

   • Instead of using the algorithm detailed in chapter 10 of the R6RS,
     expansion of toplevel forms happens sequentially.

     For example, while the expansion of the following set of toplevel
     definitions does the correct thing:

          (begin
           (define even?
             (lambda (x)
               (or (= x 0) (odd? (- x 1)))))
           (define-syntax odd?
             (syntax-rules ()
               ((odd? x) (not (even? x)))))
           (even? 10))
          ⇒ #t

     The same definitions outside of the ‘begin’ wrapper do not:

          (define even?
            (lambda (x)
              (or (= x 0) (odd? (- x 1)))))
          (define-syntax odd?
            (syntax-rules ()
              ((odd? x) (not (even? x)))))
          (even? 10)
          <unnamed port>:4:18: In procedure even?:
          <unnamed port>:4:18: Wrong type to apply: #<syntax-transformer odd?>

     This is because when expanding the right-hand-side of ‘even?’, the
     reference to ‘odd?’ is not yet marked as a syntax transformer, so
     it is assumed to be a function.

     This bug will only affect top-level programs, not code in ‘library’
     forms.  Fixing it for toplevel forms seems doable, but tricky to
     implement in a backward-compatible way.  Suggestions and/or patches
     would be appreciated.

   • The ‘(rnrs io ports)’ module is incomplete.  Work is ongoing to fix
     this.

   • Guile does not prevent use of textual I/O procedures on binary
     ports.  More generally, it does not make a sharp distinction
     between binary and textual ports (see binary-port?).

   • Guile’s implementation of ‘equal?’ may fail to terminate when
     applied to arguments containing cycles.

7.6.2 R6RS Standard Libraries
-----------------------------

In contrast with earlier versions of the Revised Report, the R6RS
organizes the procedures and syntactic forms required of conforming
implementations into a set of “standard libraries” which can be imported
as necessary by user programs and libraries.  Here we briefly list the
libraries that have been implemented for Guile.

   We do not attempt to document these libraries fully here, as most of
their functionality is already available in Guile itself.  The
expectation is that most Guile users will use the well-known and
well-documented Guile modules.  These R6RS libraries are mostly useful
to users who want to port their code to other R6RS systems.

   The documentation in the following sections reproduces some of the
content of the library section of the Report, but is mostly intended to
provide supplementary information about Guile’s implementation of the
R6RS standard libraries.  For complete documentation, design rationales
and further examples, we advise you to consult the “Standard Libraries”
section of the Report (see R6RS Standard Libraries (r6rs)).

7.6.2.1 Library Usage
.....................

Guile implements the R6RS ‘library’ form as a transformation to a native
Guile module definition.  As a consequence of this, all of the libraries
described in the following subsections, in addition to being available
for use by R6RS libraries and top-level programs, can also be imported
as if they were normal Guile modules—via a ‘use-modules’ form, say.  For
example, the R6RS “composite” library can be imported by:

       (import (rnrs (6)))

       (use-modules ((rnrs) :version (6)))

   For more information on Guile’s library implementation, see (see
R6RS Libraries).

7.6.2.2 rnrs base
.................

The ‘(rnrs base (6))’ library exports the procedures and syntactic forms
described in the main section of the Report (see R6RS Base library (r6rs)).
They are grouped below by the existing manual
sections to which they correspond.

 -- Scheme Procedure: boolean? obj
 -- Scheme Procedure: not x
     See Booleans, for documentation.

 -- Scheme Procedure: symbol? obj
 -- Scheme Procedure: symbol->string sym
 -- Scheme Procedure: string->symbol str
     See Symbol Primitives, for documentation.

 -- Scheme Procedure: char? obj
 -- Scheme Procedure: char=?
 -- Scheme Procedure: char<?
 -- Scheme Procedure: char>?
 -- Scheme Procedure: char<=?
 -- Scheme Procedure: char>=?
 -- Scheme Procedure: integer->char n
 -- Scheme Procedure: char->integer chr
     See Characters, for documentation.

 -- Scheme Procedure: list? x
 -- Scheme Procedure: null? x
     See List Predicates, for documentation.

 -- Scheme Procedure: pair? x
 -- Scheme Procedure: cons x y
 -- Scheme Procedure: car pair
 -- Scheme Procedure: cdr pair
 -- Scheme Procedure: caar pair
 -- Scheme Procedure: cadr pair
 -- Scheme Procedure: cdar pair
 -- Scheme Procedure: cddr pair
 -- Scheme Procedure: caaar pair
 -- Scheme Procedure: caadr pair
 -- Scheme Procedure: cadar pair
 -- Scheme Procedure: cdaar pair
 -- Scheme Procedure: caddr pair
 -- Scheme Procedure: cdadr pair
 -- Scheme Procedure: cddar pair
 -- Scheme Procedure: cdddr pair
 -- Scheme Procedure: caaaar pair
 -- Scheme Procedure: caaadr pair
 -- Scheme Procedure: caadar pair
 -- Scheme Procedure: cadaar pair
 -- Scheme Procedure: cdaaar pair
 -- Scheme Procedure: cddaar pair
 -- Scheme Procedure: cdadar pair
 -- Scheme Procedure: cdaadr pair
 -- Scheme Procedure: cadadr pair
 -- Scheme Procedure: caaddr pair
 -- Scheme Procedure: caddar pair
 -- Scheme Procedure: cadddr pair
 -- Scheme Procedure: cdaddr pair
 -- Scheme Procedure: cddadr pair
 -- Scheme Procedure: cdddar pair
 -- Scheme Procedure: cddddr pair
     See Pairs, for documentation.

 -- Scheme Procedure: number? obj
     See Numerical Tower, for documentation.

 -- Scheme Procedure: string? obj
     See String Predicates, for documentation.

 -- Scheme Procedure: procedure? obj
     See Procedure Properties, for documentation.

 -- Scheme Syntax: define name value
 -- Scheme Syntax: set! variable-name value
     See Definition, for documentation.

 -- Scheme Syntax: define-syntax keyword expression
 -- Scheme Syntax: let-syntax ((keyword transformer) ...) exp1 exp2 ...
 -- Scheme Syntax: letrec-syntax ((keyword transformer) ...) exp1 exp2
          ...
     See Defining Macros, for documentation.

 -- Scheme Syntax: identifier-syntax exp
     See Identifier Macros, for documentation.

 -- Scheme Syntax: syntax-rules literals (pattern template) ...
     See Syntax Rules, for documentation.

 -- Scheme Syntax: lambda formals body
     See Lambda, for documentation.

 -- Scheme Syntax: let bindings body
 -- Scheme Syntax: let* bindings body
 -- Scheme Syntax: letrec bindings body
 -- Scheme Syntax: letrec* bindings body
     See Local Bindings, for documentation.

 -- Scheme Syntax: let-values bindings body
 -- Scheme Syntax: let*-values bindings body
     See SRFI-11, for documentation.

 -- Scheme Syntax: begin expr1 expr2 ...
     See begin, for documentation.

 -- Scheme Syntax: quote expr
 -- Scheme Syntax: quasiquote expr
 -- Scheme Syntax: unquote expr
 -- Scheme Syntax: unquote-splicing expr
     See Expression Syntax, for documentation.

 -- Scheme Syntax: if test consequence [alternate]
 -- Scheme Syntax: cond clause1 clause2 ...
 -- Scheme Syntax: case key clause1 clause2 ...
     See Conditionals, for documentation.

 -- Scheme Syntax: and expr ...
 -- Scheme Syntax: or expr ...
     See and or, for documentation.

 -- Scheme Procedure: eq? x y
 -- Scheme Procedure: eqv? x y
 -- Scheme Procedure: equal? x y
 -- Scheme Procedure: symbol=? symbol1 symbol2 ...
     See Equality, for documentation.

     ‘symbol=?’ is identical to ‘eq?’.

 -- Scheme Procedure: complex? z
     See Complex Numbers, for documentation.

 -- Scheme Procedure: real-part z
 -- Scheme Procedure: imag-part z
 -- Scheme Procedure: make-rectangular real_part imaginary_part
 -- Scheme Procedure: make-polar x y
 -- Scheme Procedure: magnitude z
 -- Scheme Procedure: angle z
     See Complex, for documentation.

 -- Scheme Procedure: sqrt z
 -- Scheme Procedure: exp z
 -- Scheme Procedure: expt z1 z2
 -- Scheme Procedure: log z
 -- Scheme Procedure: sin z
 -- Scheme Procedure: cos z
 -- Scheme Procedure: tan z
 -- Scheme Procedure: asin z
 -- Scheme Procedure: acos z
 -- Scheme Procedure: atan z
     See Scientific, for documentation.

 -- Scheme Procedure: real? x
 -- Scheme Procedure: rational? x
 -- Scheme Procedure: numerator x
 -- Scheme Procedure: denominator x
 -- Scheme Procedure: rationalize x eps
     See Reals and Rationals, for documentation.

 -- Scheme Procedure: exact? x
 -- Scheme Procedure: inexact? x
 -- Scheme Procedure: exact z
 -- Scheme Procedure: inexact z
     See Exactness, for documentation.  The ‘exact’ and ‘inexact’
     procedures are identical to the ‘inexact->exact’ and
     ‘exact->inexact’ procedures provided by Guile’s code library.

 -- Scheme Procedure: integer? x
     See Integers, for documentation.

 -- Scheme Procedure: odd? n
 -- Scheme Procedure: even? n
 -- Scheme Procedure: gcd x ...
 -- Scheme Procedure: lcm x ...
 -- Scheme Procedure: exact-integer-sqrt k
     See Integer Operations, for documentation.

 -- Scheme Procedure: =
 -- Scheme Procedure: <
 -- Scheme Procedure: >
 -- Scheme Procedure: <=
 -- Scheme Procedure: >=
 -- Scheme Procedure: zero? x
 -- Scheme Procedure: positive? x
 -- Scheme Procedure: negative? x
     See Comparison, for documentation.

 -- Scheme Procedure: for-each f lst1 lst2 ...
     See SRFI-1 Fold and Map, for documentation.

 -- Scheme Procedure: list elem ...
     See List Constructors, for documentation.

 -- Scheme Procedure: length lst
 -- Scheme Procedure: list-ref lst k
 -- Scheme Procedure: list-tail lst k
     See List Selection, for documentation.

 -- Scheme Procedure: append lst ... obj
 -- Scheme Procedure: append
 -- Scheme Procedure: reverse lst
     See Append/Reverse, for documentation.

 -- Scheme Procedure: number->string n [radix]
 -- Scheme Procedure: string->number str [radix]
     See Conversion, for documentation.

 -- Scheme Procedure: string char ...
 -- Scheme Procedure: make-string k [chr]
 -- Scheme Procedure: list->string lst
     See String Constructors, for documentation.

 -- Scheme Procedure: string->list str [start [end]]
     See List/String Conversion, for documentation.

 -- Scheme Procedure: string-length str
 -- Scheme Procedure: string-ref str k
 -- Scheme Procedure: string-copy str [start [end]]
 -- Scheme Procedure: substring str start [end]
     See String Selection, for documentation.

 -- Scheme Procedure: string=? s1 s2 s3 ...
 -- Scheme Procedure: string<? s1 s2 s3 ...
 -- Scheme Procedure: string>? s1 s2 s3 ...
 -- Scheme Procedure: string<=? s1 s2 s3 ...
 -- Scheme Procedure: string>=? s1 s2 s3 ...
     See String Comparison, for documentation.

 -- Scheme Procedure: string-append arg ...
     See Reversing and Appending Strings, for documentation.

 -- Scheme Procedure: string-for-each proc s [start [end]]
     See Mapping Folding and Unfolding, for documentation.

 -- Scheme Procedure: + z1 ...
 -- Scheme Procedure: - z1 z2 ...
 -- Scheme Procedure: * z1 ...
 -- Scheme Procedure: / z1 z2 ...
 -- Scheme Procedure: max x1 x2 ...
 -- Scheme Procedure: min x1 x2 ...
 -- Scheme Procedure: abs x
 -- Scheme Procedure: truncate x
 -- Scheme Procedure: floor x
 -- Scheme Procedure: ceiling x
 -- Scheme Procedure: round x
     See Arithmetic, for documentation.

 -- Scheme Procedure: div x y
 -- Scheme Procedure: mod x y
 -- Scheme Procedure: div-and-mod x y
     These procedures accept two real numbers X and Y, where the divisor
     Y must be non-zero.  ‘div’ returns the integer Q and ‘mod’ returns
     the real number R such that X = Q*Y + R and 0 <= R < abs(Y).
     ‘div-and-mod’ returns both Q and R, and is more efficient than
     computing each separately.  Note that when Y > 0, ‘div’ returns
     floor(X/Y), otherwise it returns ceiling(X/Y).

          (div 123 10) ⇒ 12
          (mod 123 10) ⇒ 3
          (div-and-mod 123 10) ⇒ 12 and 3
          (div-and-mod 123 -10) ⇒ -12 and 3
          (div-and-mod -123 10) ⇒ -13 and 7
          (div-and-mod -123 -10) ⇒ 13 and 7
          (div-and-mod -123.2 -63.5) ⇒ 2.0 and 3.8
          (div-and-mod 16/3 -10/7) ⇒ -3 and 22/21

 -- Scheme Procedure: div0 x y
 -- Scheme Procedure: mod0 x y
 -- Scheme Procedure: div0-and-mod0 x y
     These procedures accept two real numbers X and Y, where the divisor
     Y must be non-zero.  ‘div0’ returns the integer Q and ‘mod0’
     returns the real number R such that X = Q*Y + R and -abs(Y/2) <= R
     < abs(Y/2).  ‘div0-and-mod0’ returns both Q and R, and is more
     efficient than computing each separately.

     Note that ‘div0’ returns X/Y rounded to the nearest integer.  When
     X/Y lies exactly half-way between two integers, the tie is broken
     according to the sign of Y.  If Y > 0, ties are rounded toward
     positive infinity, otherwise they are rounded toward negative
     infinity.  This is a consequence of the requirement that -abs(Y/2)
     <= R < abs(Y/2).

          (div0 123 10) ⇒ 12
          (mod0 123 10) ⇒ 3
          (div0-and-mod0 123 10) ⇒ 12 and 3
          (div0-and-mod0 123 -10) ⇒ -12 and 3
          (div0-and-mod0 -123 10) ⇒ -12 and -3
          (div0-and-mod0 -123 -10) ⇒ 12 and -3
          (div0-and-mod0 -123.2 -63.5) ⇒ 2.0 and 3.8
          (div0-and-mod0 16/3 -10/7) ⇒ -4 and -8/21

 -- Scheme Procedure: real-valued? obj
 -- Scheme Procedure: rational-valued? obj
 -- Scheme Procedure: integer-valued? obj
     These procedures return ‘#t’ if and only if their arguments can,
     respectively, be coerced to a real, rational, or integer value
     without a loss of numerical precision.

     ‘real-valued?’ will return ‘#t’ for complex numbers whose imaginary
     parts are zero.

 -- Scheme Procedure: nan? x
 -- Scheme Procedure: infinite? x
 -- Scheme Procedure: finite? x
     ‘nan?’ returns ‘#t’ if X is a NaN value, ‘#f’ otherwise.
     ‘infinite?’ returns ‘#t’ if X is an infinite value, ‘#f’ otherwise.
     ‘finite?’ returns ‘#t’ if X is neither infinite nor a NaN value,
     otherwise it returns ‘#f’.  Every real number satisfies exactly one
     of these predicates.  An exception is raised if X is not real.

 -- Scheme Syntax: assert expr
     Raises an ‘&assertion’ condition if EXPR evaluates to ‘#f’;
     otherwise evaluates to the value of EXPR.

 -- Scheme Procedure: error who message irritant1 ...
 -- Scheme Procedure: assertion-violation who message irritant1 ...
     These procedures raise compound conditions based on their
     arguments: If WHO is not ‘#f’, the condition will include a ‘&who’
     condition whose ‘who’ field is set to WHO; a ‘&message’ condition
     will be included with a ‘message’ field equal to MESSAGE; an
     ‘&irritants’ condition will be included with its ‘irritants’ list
     given by ‘irritant1 ...’.

     ‘error’ produces a compound condition with the simple conditions
     described above, as well as an ‘&error’ condition;
     ‘assertion-violation’ produces one that includes an ‘&assertion’
     condition.

 -- Scheme Procedure: vector-map proc v
 -- Scheme Procedure: vector-for-each proc v
     These procedures implement the ‘map’ and ‘for-each’ contracts over
     vectors.

 -- Scheme Procedure: vector arg ...
 -- Scheme Procedure: vector? obj
 -- Scheme Procedure: make-vector len
 -- Scheme Procedure: make-vector len fill
 -- Scheme Procedure: list->vector l
 -- Scheme Procedure: vector->list v
     See Vector Creation, for documentation.

 -- Scheme Procedure: vector-length vector
 -- Scheme Procedure: vector-ref vector k
 -- Scheme Procedure: vector-set! vector k obj
 -- Scheme Procedure: vector-fill! v fill
     See Vector Accessors, for documentation.

 -- Scheme Procedure: call-with-current-continuation proc
 -- Scheme Procedure: call/cc proc
     See Continuations, for documentation.

 -- Scheme Procedure: values arg ...
 -- Scheme Procedure: call-with-values producer consumer
     See Multiple Values, for documentation.

 -- Scheme Procedure: dynamic-wind in_guard thunk out_guard
     See Dynamic Wind, for documentation.

 -- Scheme Procedure: apply proc arg ... arglst
     See Fly Evaluation, for documentation.

7.6.2.3 rnrs unicode
....................

The ‘(rnrs unicode (6))’ library provides procedures for manipulating
Unicode characters and strings.

 -- Scheme Procedure: char-upcase char
 -- Scheme Procedure: char-downcase char
 -- Scheme Procedure: char-titlecase char
 -- Scheme Procedure: char-foldcase char
     These procedures translate their arguments from one Unicode
     character set to another.  ‘char-upcase’, ‘char-downcase’, and
     ‘char-titlecase’ are identical to their counterparts in the Guile
     core library; see Characters, for documentation.

     ‘char-foldcase’ returns the result of applying ‘char-upcase’ to its
     argument, followed by ‘char-downcase’—except in the case of the
     Turkic characters ‘U+0130’ and ‘U+0131’, for which the procedure
     acts as the identity function.

 -- Scheme Procedure: char-ci=? char1 char2 char3 ...
 -- Scheme Procedure: char-ci<? char1 char2 char3 ...
 -- Scheme Procedure: char-ci>? char1 char2 char3 ...
 -- Scheme Procedure: char-ci<=? char1 char2 char3 ...
 -- Scheme Procedure: char-ci>=? char1 char2 char3 ...
     These procedures facilitate case-insensitive comparison of Unicode
     characters.  They are identical to the procedures provided by
     Guile’s core library.  See Characters, for documentation.

 -- Scheme Procedure: char-alphabetic? char
 -- Scheme Procedure: char-numeric? char
 -- Scheme Procedure: char-whitespace? char
 -- Scheme Procedure: char-upper-case? char
 -- Scheme Procedure: char-lower-case? char
 -- Scheme Procedure: char-title-case? char
     These procedures implement various Unicode character set
     predicates.  They are identical to the procedures provided by
     Guile’s core library.  See Characters, for documentation.

 -- Scheme Procedure: char-general-category char
     See Characters, for documentation.

 -- Scheme Procedure: string-upcase string
 -- Scheme Procedure: string-downcase string
 -- Scheme Procedure: string-titlecase string
 -- Scheme Procedure: string-foldcase string
     These procedures perform Unicode case folding operations on their
     input.  See Alphabetic Case Mapping, for documentation.

 -- Scheme Procedure: string-ci=? string1 string2 string3 ...
 -- Scheme Procedure: string-ci<? string1 string2 string3 ...
 -- Scheme Procedure: string-ci>? string1 string2 string3 ...
 -- Scheme Procedure: string-ci<=? string1 string2 string3 ...
 -- Scheme Procedure: string-ci>=? string1 string2 string3 ...
     These procedures perform case-insensitive comparison on their
     input.  See String Comparison, for documentation.

 -- Scheme Procedure: string-normalize-nfd string
 -- Scheme Procedure: string-normalize-nfkd string
 -- Scheme Procedure: string-normalize-nfc string
 -- Scheme Procedure: string-normalize-nfkc string
     These procedures perform Unicode string normalization operations on
     their input.  See String Comparison, for documentation.

7.6.2.4 rnrs bytevectors
........................

The ‘(rnrs bytevectors (6))’ library provides procedures for working
with blocks of binary data.  This functionality is documented in its own
section of the manual; see Bytevectors.

7.6.2.5 rnrs lists
..................

The ‘(rnrs lists (6))’ library provides procedures additional procedures
for working with lists.

 -- Scheme Procedure: find proc list
     This procedure is identical to the one defined in Guile’s SRFI-1
     implementation.  See SRFI-1 Searching, for documentation.

 -- Scheme Procedure: for-all proc list1 list2 ...
 -- Scheme Procedure: exists proc list1 list2 ...

     The ‘for-all’ procedure is identical to the ‘every’ procedure
     defined by SRFI-1; the ‘exists’ procedure is identical to SRFI-1’s
     ‘any’.  See SRFI-1 Searching, for documentation.

 -- Scheme Procedure: filter proc list
 -- Scheme Procedure: partition proc list
     These procedures are identical to the ones provided by SRFI-1.
     See List Modification, for a description of ‘filter’; see
     SRFI-1 Filtering and Partitioning, for ‘partition’.

 -- Scheme Procedure: fold-right combine nil list1 list2 ...
     This procedure is identical the ‘fold-right’ procedure provided by
     SRFI-1.  See SRFI-1 Fold and Map, for documentation.

 -- Scheme Procedure: fold-left combine nil list1 list2 ...
     This procedure is like ‘fold’ from SRFI-1, but COMBINE is called
     with the seed as the first argument.  See SRFI-1 Fold and Map,
     for documentation.

 -- Scheme Procedure: remp proc list
 -- Scheme Procedure: remove obj list
 -- Scheme Procedure: remv obj list
 -- Scheme Procedure: remq obj list
     ‘remove’, ‘remv’, and ‘remq’ are identical to the ‘delete’, ‘delv’,
     and ‘delq’ procedures provided by Guile’s core library, (see List Modification).
     ‘remp’ is identical to the alternate ‘remove’
     procedure provided by SRFI-1; see SRFI-1 Deleting.

 -- Scheme Procedure: memp proc list
 -- Scheme Procedure: member obj list
 -- Scheme Procedure: memv obj list
 -- Scheme Procedure: memq obj list
     ‘member’, ‘memv’, and ‘memq’ are identical to the procedures
     provided by Guile’s core library; see List Searching, for their
     documentation.  ‘memp’ uses the specified predicate function ‘proc’
     to test elements of the list LIST—it behaves similarly to ‘find’,
     except that it returns the first sublist of LIST whose ‘car’
     satisfies PROC.

 -- Scheme Procedure: assp proc alist
 -- Scheme Procedure: assoc obj alist
 -- Scheme Procedure: assv obj alist
 -- Scheme Procedure: assq obj alist
     ‘assoc’, ‘assv’, and ‘assq’ are identical to the procedures
     provided by Guile’s core library; see Alist Key Equality, for
     their documentation.  ‘assp’ uses the specified predicate function
     ‘proc’ to test keys in the association list ALIST.

 -- Scheme Procedure: cons* obj1 ... obj
 -- Scheme Procedure: cons* obj
     This procedure is identical to the one exported by Guile’s core
     library.  See List Constructors, for documentation.

7.6.2.6 rnrs sorting
....................

The ‘(rnrs sorting (6))’ library provides procedures for sorting lists
and vectors.

 -- Scheme Procedure: list-sort proc list
 -- Scheme Procedure: vector-sort proc vector
     These procedures return their input sorted in ascending order,
     without modifying the original data.  PROC must be a procedure that
     takes two elements from the input list or vector as arguments, and
     returns a true value if the first is “less” than the second, ‘#f’
     otherwise.  ‘list-sort’ returns a list; ‘vector-sort’ returns a
     vector.

     Both ‘list-sort’ and ‘vector-sort’ are implemented in terms of the
     ‘stable-sort’ procedure from Guile’s core library.  See
     Sorting, for a discussion of the behavior of that procedure.

 -- Scheme Procedure: vector-sort! proc vector
     Performs a destructive, “in-place” sort of VECTOR, using PROC as
     described above to determine an ascending ordering of elements.
     ‘vector-sort!’ returns an unspecified value.

     This procedure is implemented in terms of the ‘sort!’ procedure
     from Guile’s core library.  See Sorting, for more information.

7.6.2.7 rnrs control
....................

The ‘(rnrs control (6))’ library provides syntactic forms useful for
constructing conditional expressions and controlling the flow of
execution.

 -- Scheme Syntax: when test expression1 expression2 ...
 -- Scheme Syntax: unless test expression1 expression2 ...
     The ‘when’ form is evaluated by evaluating the specified TEST
     expression; if the result is a true value, the EXPRESSIONs that
     follow it are evaluated in order, and the value of the final
     EXPRESSION becomes the value of the entire ‘when’ expression.

     The ‘unless’ form behaves similarly, with the exception that the
     specified EXPRESSIONs are only evaluated if the value of TEST is
     false.

 -- Scheme Syntax: do ((variable init step) ...) (test expression ...)
          command ...
     This form is identical to the one provided by Guile’s core library.
     See while do, for documentation.

 -- Scheme Syntax: case-lambda clause ...
     This form is identical to the one provided by Guile’s core library.
     See Case-lambda, for documentation.

7.6.2.8 R6RS Records
....................

The manual sections below describe Guile’s implementation of R6RS
records, which provide support for user-defined data types.  The R6RS
records API provides a superset of the features provided by Guile’s
“native” records, as well as those of the SRFI-9 records API; see
Records, and SRFI-9 Records, for a description of those
interfaces.

   As with SRFI-9 and Guile’s native records, R6RS records are
constructed using a record-type descriptor that specifies attributes
like the record’s name, its fields, and the mutability of those fields.

   R6RS records extend this framework to support single inheritance via
the specification of a “parent” type for a record type at definition
time.  Accessors and mutator procedures for the fields of a parent type
may be applied to records of a subtype of this parent.  A record type
may be “sealed”, in which case it cannot be used as the parent of
another record type.

   The inheritance mechanism for record types also informs the process
of initializing the fields of a record and its parents.  Constructor
procedures that generate new instances of a record type are obtained
from a record constructor descriptor, which encapsulates the record-type
descriptor of the record to be constructed along with a “protocol”
procedure that defines how constructors for record subtypes delegate to
the constructors of their parent types.

   A protocol is a procedure used by the record system at construction
time to bind arguments to the fields of the record being constructed.
The protocol procedure is passed a procedure N that accepts the
arguments required to construct the record’s parent type; this
procedure, when invoked, will return a procedure P that accepts the
arguments required to construct a new instance of the record type itself
and returns a new instance of the record type.

   The protocol should in turn return a procedure that uses N and P to
initialize the fields of the record type and its parent type(s).  This
procedure will be the constructor returned by

   As a trivial example, consider the hypothetical record type ‘pixel’,
which encapsulates an x-y location on a screen, and ‘voxel’, which has
‘pixel’ as its parent type and stores an additional coordinate.  The
following protocol produces a constructor procedure that accepts all
three coordinates, uses the first two to initialize the fields of
‘pixel’, and binds the third to the single field of ‘voxel’.

       (lambda (n)
         (lambda (x y z)
           (let ((p (n x y)))
             (p z))))

   It may be helpful to think of protocols as “constructor factories”
that produce chains of delegating constructors glued together by the
helper procedure N.

   An R6RS record type may be declared to be “nongenerative” via the use
of a unique generated or user-supplied symbol—or “uid”—such that
subsequent record type declarations with the same uid and attributes
will return the previously-declared record-type descriptor.

   R6RS record types may also be declared to be “opaque”, in which case
the various predicates and introspection procedures defined in ‘(rnrs
records introspection)’ will behave as if records of this type are not
records at all.

   Note that while the R6RS records API shares much of its namespace
with both the SRFI-9 and native Guile records APIs, it is not currently
compatible with either.

7.6.2.9 rnrs records syntactic
..............................

The ‘(rnrs records syntactic (6))’ library exports the syntactic API for
working with R6RS records.

 -- Scheme Syntax: define-record-type name-spec record-clause ...
     Defines a new record type, introducing bindings for a record-type
     descriptor, a record constructor descriptor, a constructor
     procedure, a record predicate, and accessor and mutator procedures
     for the new record type’s fields.

     NAME-SPEC must either be an identifier or must take the form
     ‘(record-name constructor-name predicate-name)’, where RECORD-NAME,
     CONSTRUCTOR-NAME, and PREDICATE-NAME are all identifiers and
     specify the names to which, respectively, the record-type
     descriptor, constructor, and predicate procedures will be bound.
     If NAME-SPEC is only an identifier, it specifies the name to which
     the generated record-type descriptor will be bound.

     Each RECORD-CLAUSE must be one of the following:

        • ‘(fields field-spec*)’, where each FIELD-SPEC specifies a
          field of the new record type and takes one of the following
          forms:
             • ‘(immutable field-name accessor-name)’, which specifies
               an immutable field with the name FIELD-NAME and binds an
               accessor procedure for it to the name given by
               ACCESSOR-NAME
             • ‘(mutable field-name accessor-name mutator-name)’, which
               specifies a mutable field with the name FIELD-NAME and
               binds accessor and mutator procedures to ACCESSOR-NAME
               and MUTATOR-NAME, respectively
             • ‘(immutable field-name)’, which specifies an immutable
               field with the name FIELD-NAME; an accessor procedure for
               it will be created and named by appending record name and
               FIELD-NAME with a hyphen separator
             • ‘(mutable field-name’), which specifies a mutable field
               with the name FIELD-NAME; an accessor procedure for it
               will be created and named as described above; a mutator
               procedure will also be created and named by appending
               ‘-set!’ to the accessor name
             • ‘field-name’, which specifies an immutable field with the
               name FIELD-NAME; an access procedure for it will be
               created and named as described above
        • ‘(parent parent-name)’, where PARENT-NAME is a symbol giving
          the name of the record type to be used as the parent of the
          new record type
        • ‘(protocol expression)’, where EXPRESSION evaluates to a
          protocol procedure which behaves as described above, and is
          used to create a record constructor descriptor for the new
          record type
        • ‘(sealed sealed?)’, where SEALED? is a boolean value that
          specifies whether or not the new record type is sealed
        • ‘(opaque opaque?)’, where OPAQUE? is a boolean value that
          specifies whether or not the new record type is opaque
        • ‘(nongenerative [uid])’, which specifies that the record type
          is nongenerative via the optional uid UID.  If UID is not
          specified, a unique uid will be generated at expansion time
        • ‘(parent-rtd parent-rtd parent-cd)’, a more explicit form of
          the ‘parent’ form above; PARENT-RTD and PARENT-CD should
          evaluate to a record-type descriptor and a record constructor
          descriptor, respectively

 -- Scheme Syntax: record-type-descriptor record-name
     Evaluates to the record-type descriptor associated with the type
     specified by RECORD-NAME.

 -- Scheme Syntax: record-constructor-descriptor record-name
     Evaluates to the record-constructor descriptor associated with the
     type specified by RECORD-NAME.

7.6.2.10 rnrs records procedural
................................

The ‘(rnrs records procedural (6))’ library exports the procedural API
for working with R6RS records.

 -- Scheme Procedure: make-record-type-descriptor name parent uid
          sealed? opaque? fields
     Returns a new record-type descriptor with the specified
     characteristics: NAME must be a symbol giving the name of the new
     record type; PARENT must be either ‘#f’ or a non-sealed record-type
     descriptor for the returned record type to extend; UID must be
     either ‘#f’, indicating that the record type is generative, or a
     symbol giving the type’s nongenerative uid; SEALED? and OPAQUE?
     must be boolean values that specify the sealedness and opaqueness
     of the record type; FIELDS must be a vector of zero or more field
     specifiers of the form ‘(mutable name)’ or ‘(immutable name)’,
     where name is a symbol giving a name for the field.

     If UID is not ‘#f’, it must be a symbol

 -- Scheme Procedure: record-type-descriptor? obj
     Returns ‘#t’ if OBJ is a record-type descriptor, ‘#f’ otherwise.

 -- Scheme Procedure: make-record-constructor-descriptor rtd
          parent-constructor-descriptor protocol
     Returns a new record constructor descriptor that can be used to
     produce constructors for the record type specified by the
     record-type descriptor RTD and whose delegation and binding
     behavior are specified by the protocol procedure PROTOCOL.

     PARENT-CONSTRUCTOR-DESCRIPTOR specifies a record constructor
     descriptor for the parent type of RTD, if one exists.  If RTD
     represents a base type, then PARENT-CONSTRUCTOR-DESCRIPTOR must be
     ‘#f’.  If RTD is an extension of another type,
     PARENT-CONSTRUCTOR-DESCRIPTOR may still be ‘#f’, but protocol must
     also be ‘#f’ in this case.

 -- Scheme Procedure: record-constructor rcd
     Returns a record constructor procedure by invoking the protocol
     defined by the record-constructor descriptor RCD.

 -- Scheme Procedure: record-predicate rtd
     Returns the record predicate procedure for the record-type
     descriptor RTD.

 -- Scheme Procedure: record-accessor rtd k
     Returns the record field accessor procedure for the Kth field of
     the record-type descriptor RTD.

 -- Scheme Procedure: record-mutator rtd k
     Returns the record field mutator procedure for the Kth field of the
     record-type descriptor RTD.  An ‘&assertion’ condition will be
     raised if this field is not mutable.

7.6.2.11 rnrs records inspection
................................

The ‘(rnrs records inspection (6))’ library provides procedures useful
for accessing metadata about R6RS records.

 -- Scheme Procedure: record? obj
     Return ‘#t’ if the specified object is a non-opaque R6RS record,
     ‘#f’ otherwise.

 -- Scheme Procedure: record-rtd record
     Returns the record-type descriptor for RECORD.  An ‘&assertion’ is
     raised if RECORD is opaque.

 -- Scheme Procedure: record-type-name rtd
     Returns the name of the record-type descriptor RTD.

 -- Scheme Procedure: record-type-parent rtd
     Returns the parent of the record-type descriptor RTD, or ‘#f’ if it
     has none.

 -- Scheme Procedure: record-type-uid rtd
     Returns the uid of the record-type descriptor RTD, or ‘#f’ if it
     has none.

 -- Scheme Procedure: record-type-generative? rtd
     Returns ‘#t’ if the record-type descriptor RTD is generative, ‘#f’
     otherwise.

 -- Scheme Procedure: record-type-sealed? rtd
     Returns ‘#t’ if the record-type descriptor RTD is sealed, ‘#f’
     otherwise.

 -- Scheme Procedure: record-type-opaque? rtd
     Returns ‘#t’ if the record-type descriptor RTD is opaque, ‘#f’
     otherwise.

 -- Scheme Procedure: record-type-field-names rtd
     Returns a vector of symbols giving the names of the fields defined
     by the record-type descriptor RTD (and not any of its sub- or
     supertypes).

 -- Scheme Procedure: record-field-mutable? rtd k
     Returns ‘#t’ if the field at index K of the record-type descriptor
     RTD (and not any of its sub- or supertypes) is mutable.

7.6.2.12 rnrs exceptions
........................

The ‘(rnrs exceptions (6))’ library provides functionality related to
signaling and handling exceptional situations.  This functionality is
similar to the exception handling systems provided by Guile’s core
library Exceptions, and by the SRFI-18 and SRFI-34 modules—see
SRFI-18 Exceptions, and SRFI-34, respectively—but there are
some key differences in concepts and behavior.

   A raised exception may be “continuable” or “non-continuable”.  When
an exception is raised non-continuably, another exception, with the
condition type ‘&non-continuable’, will be raised when the exception
handler returns locally.  Raising an exception continuably captures the
current continuation and invokes it after a local return from the
exception handler.

   Like SRFI-18 and SRFI-34, R6RS exceptions are implemented on top of
Guile’s native ‘throw’ and ‘catch’ forms, and use custom “throw keys” to
identify their exception types.  As a consequence, Guile’s ‘catch’ form
can handle exceptions thrown by these APIs, but the reverse is not true:
Handlers registered by the ‘with-exception-handler’ procedure described
below will only be called on exceptions thrown by the corresponding
‘raise’ procedure.

 -- Scheme Procedure: with-exception-handler handler thunk
     Installs HANDLER, which must be a procedure taking one argument, as
     the current exception handler during the invocation of THUNK, a
     procedure taking zero arguments.  The handler in place at the time
     ‘with-exception-handler’ is called is made current again once
     either THUNK returns or HANDLER is invoked after an exception is
     thrown from within THUNK.

     This procedure is similar to the ‘with-throw-handler’ procedure
     provided by Guile’s code library; (see Throw Handlers).

 -- Scheme Syntax: guard (variable clause1 clause2 ...) body
     Evaluates the expression given by BODY, first creating an ad hoc
     exception handler that binds a raised exception to VARIABLE and
     then evaluates the specified CLAUSEs as if they were part of a
     ‘cond’ expression, with the value of the first matching clause
     becoming the value of the ‘guard’ expression (see
     Conditionals).  If none of the clause’s test expressions
     evaluates to ‘#t’, the exception is re-raised, with the exception
     handler that was current before the evaluation of the ‘guard’ form.

     For example, the expression

          (guard (ex ((eq? ex 'foo) 'bar) ((eq? ex 'bar) 'baz))
            (raise 'bar))

     evaluates to ‘baz’.

 -- Scheme Procedure: raise obj
     Raises a non-continuable exception by invoking the
     currently-installed exception handler on OBJ.  If the handler
     returns, a ‘&non-continuable’ exception will be raised in the
     dynamic context in which the handler was installed.

 -- Scheme Procedure: raise-continuable obj
     Raises a continuable exception by invoking currently-installed
     exception handler on OBJ.

7.6.2.13 rnrs conditions
........................

The ‘(rnrs condition (6))’ library provides forms and procedures for
constructing new condition types, as well as a library of pre-defined
condition types that represent a variety of common exceptional
situations.  Conditions are records of a subtype of the ‘&condition’
record type, which is neither sealed nor opaque.  See R6RS Records.

   Conditions may be manipulated singly, as “simple conditions”, or when
composed with other conditions to form “compound conditions”.  Compound
conditions do not “nest”—constructing a new compound condition out of
existing compound conditions will “flatten” them into their component
simple conditions.  For example, making a new condition out of a
‘&message’ condition and a compound condition that contains an
‘&assertion’ condition and another ‘&message’ condition will produce a
compound condition that contains two ‘&message’ conditions and one
‘&assertion’ condition.

   The record type predicates and field accessors described below can
operate on either simple or compound conditions.  In the latter case,
the predicate returns ‘#t’ if the compound condition contains a
component simple condition of the appropriate type; the field accessors
return the requisite fields from the first component simple condition
found to be of the appropriate type.

   This library is quite similar to the SRFI-35 conditions module (see
SRFI-35).  Among other minor differences, the ‘(rnrs conditions)’
library features slightly different semantics around condition field
accessors, and comes with a larger number of pre-defined condition
types.  The two APIs are not currently compatible, however; the
‘condition?’ predicate from one API will return ‘#f’ when applied to a
condition object created in the other.

 -- Condition Type: &condition
 -- Scheme Procedure: condition? obj
     The base record type for conditions.

 -- Scheme Procedure: condition condition1 ...
 -- Scheme Procedure: simple-conditions condition
     The ‘condition’ procedure creates a new compound condition out of
     its condition arguments, flattening any specified compound
     conditions into their component simple conditions as described
     above.

     ‘simple-conditions’ returns a list of the component simple
     conditions of the compound condition ‘condition’, in the order in
     which they were specified at construction time.

 -- Scheme Procedure: condition-predicate rtd
 -- Scheme Procedure: condition-accessor rtd proc
     These procedures return condition predicate and accessor procedures
     for the specified condition record type RTD.

 -- Scheme Syntax: define-condition-type condition-type supertype
          constructor predicate field-spec ...
     Evaluates to a new record type definition for a condition type with
     the name CONDITION-TYPE that has the condition type SUPERTYPE as
     its parent.  A default constructor, which binds its arguments to
     the fields of this type and its parent types, will be bound to the
     identifier CONSTRUCTOR; a condition predicate will be bound to
     PREDICATE.  The fields of the new type, which are immutable, are
     specified by the FIELD-SPECs, each of which must be of the form:
          (field accessor)
     where FIELD gives the name of the field and ACCESSOR gives the name
     for a binding to an accessor procedure created for this field.

 -- Condition Type: &message
 -- Scheme Procedure: make-message-condition message
 -- Scheme Procedure: message-condition? obj
 -- Scheme Procedure: condition-message condition
     A type that includes a message describing the condition that
     occurred.

 -- Condition Type: &warning
 -- Scheme Procedure: make-warning
 -- Scheme Procedure: warning? obj
     A base type for representing non-fatal conditions during execution.

 -- Condition Type: &serious
 -- Scheme Procedure: make-serious-condition
 -- Scheme Procedure: serious-condition? obj
     A base type for conditions representing errors serious enough that
     cannot be ignored.

 -- Condition Type: &error
 -- Scheme Procedure: make-error
 -- Scheme Procedure: error? obj
     A base type for conditions representing errors.

 -- Condition Type: &violation
 -- Scheme Procedure: make-violation
 -- Scheme Procedure: violation?
     A subtype of ‘&serious’ that can be used to represent violations of
     a language or library standard.

 -- Condition Type: &assertion
 -- Scheme Procedure: make-assertion-violation
 -- Scheme Procedure: assertion-violation? obj
     A subtype of ‘&violation’ that indicates an invalid call to a
     procedure.

 -- Condition Type: &irritants
 -- Scheme Procedure: make-irritants-condition irritants
 -- Scheme Procedure: irritants-condition? obj
 -- Scheme Procedure: condition-irritants condition
     A base type used for storing information about the causes of
     another condition in a compound condition.

 -- Condition Type: &who
 -- Scheme Procedure: make-who-condition who
 -- Scheme Procedure: who-condition? obj
 -- Scheme Procedure: condition-who condition
     A base type used for storing the identity, a string or symbol, of
     the entity responsible for another condition in a compound
     condition.

 -- Condition Type: &non-continuable
 -- Scheme Procedure: make-non-continuable-violation
 -- Scheme Procedure: non-continuable-violation? obj
     A subtype of ‘&violation’ used to indicate that an exception
     handler invoked by ‘raise’ has returned locally.

 -- Condition Type: &implementation-restriction
 -- Scheme Procedure: make-implementation-restriction-violation
 -- Scheme Procedure: implementation-restriction-violation? obj
     A subtype of ‘&violation’ used to indicate a violation of an
     implementation restriction.

 -- Condition Type: &lexical
 -- Scheme Procedure: make-lexical-violation
 -- Scheme Procedure: lexical-violation? obj
     A subtype of ‘&violation’ used to indicate a syntax violation at
     the level of the datum syntax.

 -- Condition Type: &syntax
 -- Scheme Procedure: make-syntax-violation form subform
 -- Scheme Procedure: syntax-violation? obj
 -- Scheme Procedure: syntax-violation-form condition
 -- Scheme Procedure: syntax-violation-subform condition
     A subtype of ‘&violation’ that indicates a syntax violation.  The
     FORM and SUBFORM fields, which must be datum values, indicate the
     syntactic form responsible for the condition.

 -- Condition Type: &undefined
 -- Scheme Procedure: make-undefined-violation
 -- Scheme Procedure: undefined-violation? obj
     A subtype of ‘&violation’ that indicates a reference to an unbound
     identifier.

7.6.2.14 I/O Conditions
.......................

These condition types are exported by both the ‘(rnrs io ports (6))’ and
‘(rnrs io simple (6))’ libraries.

 -- Condition Type: &i/o
 -- Scheme Procedure: make-i/o-error
 -- Scheme Procedure: i/o-error? obj
     A condition supertype for more specific I/O errors.

 -- Condition Type: &i/o-read
 -- Scheme Procedure: make-i/o-read-error
 -- Scheme Procedure: i/o-read-error? obj
     A subtype of ‘&i/o’; represents read-related I/O errors.

 -- Condition Type: &i/o-write
 -- Scheme Procedure: make-i/o-write-error
 -- Scheme Procedure: i/o-write-error? obj
     A subtype of ‘&i/o’; represents write-related I/O errors.

 -- Condition Type: &i/o-invalid-position
 -- Scheme Procedure: make-i/o-invalid-position-error position
 -- Scheme Procedure: i/o-invalid-position-error? obj
 -- Scheme Procedure: i/o-error-position condition
     A subtype of ‘&i/o’; represents an error related to an attempt to
     set the file position to an invalid position.

 -- Condition Type: &i/o-filename
 -- Scheme Procedure: make-io-filename-error filename
 -- Scheme Procedure: i/o-filename-error? obj
 -- Scheme Procedure: i/o-error-filename condition
     A subtype of ‘&i/o’; represents an error related to an operation on
     a named file.

 -- Condition Type: &i/o-file-protection
 -- Scheme Procedure: make-i/o-file-protection-error filename
 -- Scheme Procedure: i/o-file-protection-error? obj
     A subtype of ‘&i/o-filename’; represents an error resulting from an
     attempt to access a named file for which the caller had
     insufficient permissions.

 -- Condition Type: &i/o-file-is-read-only
 -- Scheme Procedure: make-i/o-file-is-read-only-error filename
 -- Scheme Procedure: i/o-file-is-read-only-error? obj
     A subtype of ‘&i/o-file-protection’; represents an error related to
     an attempt to write to a read-only file.

 -- Condition Type: &i/o-file-already-exists
 -- Scheme Procedure: make-i/o-file-already-exists-error filename
 -- Scheme Procedure: i/o-file-already-exists-error? obj
     A subtype of ‘&i/o-filename’; represents an error related to an
     operation on an existing file that was assumed not to exist.

 -- Condition Type: &i/o-file-does-not-exist
 -- Scheme Procedure: make-i/o-file-does-not-exist-error
 -- Scheme Procedure: i/o-file-does-not-exist-error? obj
     A subtype of ‘&i/o-filename’; represents an error related to an
     operation on a non-existent file that was assumed to exist.

 -- Condition Type: &i/o-port
 -- Scheme Procedure: make-i/o-port-error port
 -- Scheme Procedure: i/o-port-error? obj
 -- Scheme Procedure: i/o-error-port condition
     A subtype of ‘&i/o’; represents an error related to an operation on
     the port PORT.

7.6.2.15 rnrs io ports
......................

The ‘(rnrs io ports (6))’ library provides various procedures and
syntactic forms for use in writing to and reading from ports.  This
functionality is documented in its own section of the manual; (see
R6RS I/O Ports).

7.6.2.16 rnrs io simple
.......................

The ‘(rnrs io simple (6))’ library provides convenience functions for
performing textual I/O on ports.  This library also exports all of the
condition types and associated procedures described in (see I/O Conditions).
In the context of this section, when stating that a
procedure behaves “identically” to the corresponding procedure in
Guile’s core library, this is modulo the behavior wrt.  conditions: such
procedures raise the appropriate R6RS conditions in case of error, but
otherwise behave identically.

     Note: There are still known issues regarding condition-correctness;
     some errors may still be thrown as native Guile exceptions instead
     of the appropriate R6RS conditions.

 -- Scheme Procedure: eof-object
 -- Scheme Procedure: eof-object? obj
     These procedures are identical to the ones provided by the ‘(rnrs
     io ports (6))’ library.  See R6RS I/O Ports, for documentation.

 -- Scheme Procedure: input-port? obj
 -- Scheme Procedure: output-port? obj
     These procedures are identical to the ones provided by Guile’s core
     library.  See Ports, for documentation.

 -- Scheme Procedure: call-with-input-file filename proc
 -- Scheme Procedure: call-with-output-file filename proc
 -- Scheme Procedure: open-input-file filename
 -- Scheme Procedure: open-output-file filename
 -- Scheme Procedure: with-input-from-file filename thunk
 -- Scheme Procedure: with-output-to-file filename thunk
     These procedures are identical to the ones provided by Guile’s core
     library.  See File Ports, for documentation.

 -- Scheme Procedure: close-input-port input-port
 -- Scheme Procedure: close-output-port output-port
     These procedures are identical to the ones provided by Guile’s core
     library.  See Closing, for documentation.

 -- Scheme Procedure: peek-char
 -- Scheme Procedure: peek-char textual-input-port
 -- Scheme Procedure: read-char
 -- Scheme Procedure: read-char textual-input-port
     These procedures are identical to the ones provided by Guile’s core
     library.  See Reading, for documentation.

 -- Scheme Procedure: read
 -- Scheme Procedure: read textual-input-port
     This procedure is identical to the one provided by Guile’s core
     library.  See Scheme Read, for documentation.

 -- Scheme Procedure: display obj
 -- Scheme Procedure: display obj textual-output-port
 -- Scheme Procedure: newline
 -- Scheme Procedure: newline textual-output-port
 -- Scheme Procedure: write obj
 -- Scheme Procedure: write obj textual-output-port
 -- Scheme Procedure: write-char char
 -- Scheme Procedure: write-char char textual-output-port
     These procedures are identical to the ones provided by Guile’s core
     library.  See Writing, for documentation.

7.6.2.17 rnrs files
...................

The ‘(rnrs files (6))’ library provides the ‘file-exists?’ and
‘delete-file’ procedures, which test for the existence of a file and
allow the deletion of files from the file system, respectively.

   These procedures are identical to the ones provided by Guile’s core
library.  See File System, for documentation.

7.6.2.18 rnrs programs
......................

The ‘(rnrs programs (6))’ library provides procedures for process
management and introspection.

 -- Scheme Procedure: command-line
     This procedure is identical to the one provided by Guile’s core
     library.  See Runtime Environment, for documentation.

 -- Scheme Procedure: exit [status]
     This procedure is identical to the one provided by Guile’s core
     library.  See Processes, for documentation.

7.6.2.19 rnrs arithmetic fixnums
................................

The ‘(rnrs arithmetic fixnums (6))’ library provides procedures for
performing arithmetic operations on an implementation-dependent range of
exact integer values, which R6RS refers to as “fixnums”.  In Guile, the
size of a fixnum is determined by the size of the ‘SCM’ type; a single
SCM struct is guaranteed to be able to hold an entire fixnum, making
fixnum computations particularly efficient—(see The SCM Type).  On
32-bit systems, the most negative and most positive fixnum values are,
respectively, -536870912 and 536870911.

   Unless otherwise specified, all of the procedures below take fixnums
as arguments, and will raise an ‘&assertion’ condition if passed a
non-fixnum argument or an ‘&implementation-restriction’ condition if
their result is not itself a fixnum.

 -- Scheme Procedure: fixnum? obj
     Returns ‘#t’ if OBJ is a fixnum, ‘#f’ otherwise.

 -- Scheme Procedure: fixnum-width
 -- Scheme Procedure: least-fixnum
 -- Scheme Procedure: greatest-fixnum
     These procedures return, respectively, the maximum number of bits
     necessary to represent a fixnum value in Guile, the minimum fixnum
     value, and the maximum fixnum value.

 -- Scheme Procedure: fx=? fx1 fx2 fx3 ...
 -- Scheme Procedure: fx>? fx1 fx2 fx3 ...
 -- Scheme Procedure: fx<? fx1 fx2 fx3 ...
 -- Scheme Procedure: fx>=? fx1 fx2 fx3 ...
 -- Scheme Procedure: fx<=? fx1 fx2 fx3 ...
     These procedures return ‘#t’ if their fixnum arguments are
     (respectively): equal, monotonically increasing, monotonically
     decreasing, monotonically nondecreasing, or monotonically
     nonincreasing; ‘#f’ otherwise.

 -- Scheme Procedure: fxzero? fx
 -- Scheme Procedure: fxpositive? fx
 -- Scheme Procedure: fxnegative? fx
 -- Scheme Procedure: fxodd? fx
 -- Scheme Procedure: fxeven? fx
     These numerical predicates return ‘#t’ if FX is, respectively,
     zero, greater than zero, less than zero, odd, or even; ‘#f’
     otherwise.

 -- Scheme Procedure: fxmax fx1 fx2 ...
 -- Scheme Procedure: fxmin fx1 fx2 ...
     These procedures return the maximum or minimum of their arguments.

 -- Scheme Procedure: fx+ fx1 fx2
 -- Scheme Procedure: fx* fx1 fx2
     These procedures return the sum or product of their arguments.

 -- Scheme Procedure: fx- fx1 fx2
 -- Scheme Procedure: fx- fx
     Returns the difference of FX1 and FX2, or the negation of FX, if
     called with a single argument.

     An ‘&assertion’ condition is raised if the result is not itself a
     fixnum.

 -- Scheme Procedure: fxdiv-and-mod fx1 fx2
 -- Scheme Procedure: fxdiv fx1 fx2
 -- Scheme Procedure: fxmod fx1 fx2
 -- Scheme Procedure: fxdiv0-and-mod0 fx1 fx2
 -- Scheme Procedure: fxdiv0 fx1 fx2
 -- Scheme Procedure: fxmod0 fx1 fx2
     These procedures implement number-theoretic division on fixnums;
     see (rnrs base), for a description of their semantics.

 -- Scheme Procedure: fx+/carry fx1 fx2 fx3
     Returns the two fixnum results of the following computation:
          (let* ((s (+ fx1 fx2 fx3))
                 (s0 (mod0 s (expt 2 (fixnum-width))))
                 (s1 (div0 s (expt 2 (fixnum-width)))))
            (values s0 s1))

 -- Scheme Procedure: fx-/carry fx1 fx2 fx3
     Returns the two fixnum results of the following computation:
          (let* ((d (- fx1 fx2 fx3))
                 (d0 (mod0 d (expt 2 (fixnum-width))))
                 (d1 (div0 d (expt 2 (fixnum-width)))))
            (values d0 d1))

 -- Scheme Procedure: fx*/carry fx1 fx2 fx3
          Returns the two fixnum results of the following computation:
          (let* ((s (+ (* fx1 fx2) fx3))
                 (s0 (mod0 s (expt 2 (fixnum-width))))
                 (s1 (div0 s (expt 2 (fixnum-width)))))
            (values s0 s1))

 -- Scheme Procedure: fxnot fx
 -- Scheme Procedure: fxand fx1 ...
 -- Scheme Procedure: fxior fx1 ...
 -- Scheme Procedure: fxxor fx1 ...
     These procedures are identical to the ‘lognot’, ‘logand’, ‘logior’,
     and ‘logxor’ procedures provided by Guile’s core library.  See
     Bitwise Operations, for documentation.

 -- Scheme Procedure: fxif fx1 fx2 fx3
     Returns the bitwise “if” of its fixnum arguments.  The bit at
     position ‘i’ in the return value will be the ‘i’th bit from FX2 if
     the ‘i’th bit of FX1 is 1, the ‘i’th bit from FX3.

 -- Scheme Procedure: fxbit-count fx
     Returns the number of 1 bits in the two’s complement representation
     of FX.

 -- Scheme Procedure: fxlength fx
     Returns the number of bits necessary to represent FX.

 -- Scheme Procedure: fxfirst-bit-set fx
     Returns the index of the least significant 1 bit in the two’s
     complement representation of FX.

 -- Scheme Procedure: fxbit-set? fx1 fx2
     Returns ‘#t’ if the FX2th bit in the two’s complement
     representation of FX1 is 1, ‘#f’ otherwise.

 -- Scheme Procedure: fxcopy-bit fx1 fx2 fx3
     Returns the result of setting the FX2th bit of FX1 to the FX2th bit
     of FX3.

 -- Scheme Procedure: fxbit-field fx1 fx2 fx3
     Returns the integer representation of the contiguous sequence of
     bits in FX1 that starts at position FX2 (inclusive) and ends at
     position FX3 (exclusive).

 -- Scheme Procedure: fxcopy-bit-field fx1 fx2 fx3 fx4
     Returns the result of replacing the bit field in FX1 with start and
     end positions FX2 and FX3 with the corresponding bit field from
     FX4.

 -- Scheme Procedure: fxarithmetic-shift fx1 fx2
 -- Scheme Procedure: fxarithmetic-shift-left fx1 fx2
 -- Scheme Procedure: fxarithmetic-shift-right fx1 fx2
     Returns the result of shifting the bits of FX1 right or left by the
     FX2 positions.  ‘fxarithmetic-shift’ is identical to
     ‘fxarithmetic-shift-left’.

 -- Scheme Procedure: fxrotate-bit-field fx1 fx2 fx3 fx4
     Returns the result of cyclically permuting the bit field in FX1
     with start and end positions FX2 and FX3 by FX4 bits in the
     direction of more significant bits.

 -- Scheme Procedure: fxreverse-bit-field fx1 fx2 fx3
     Returns the result of reversing the order of the bits of FX1
     between position FX2 (inclusive) and position FX3 (exclusive).

7.6.2.20 rnrs arithmetic flonums
................................

The ‘(rnrs arithmetic flonums (6))’ library provides procedures for
performing arithmetic operations on inexact representations of real
numbers, which R6RS refers to as “flonums”.

   Unless otherwise specified, all of the procedures below take flonums
as arguments, and will raise an ‘&assertion’ condition if passed a
non-flonum argument.

 -- Scheme Procedure: flonum? obj
     Returns ‘#t’ if OBJ is a flonum, ‘#f’ otherwise.

 -- Scheme Procedure: real->flonum x
     Returns the flonum that is numerically closest to the real number
     X.

 -- Scheme Procedure: fl=? fl1 fl2 fl3 ...
 -- Scheme Procedure: fl<? fl1 fl2 fl3 ...
 -- Scheme Procedure: fl<=? fl1 fl2 fl3 ...
 -- Scheme Procedure: fl>? fl1 fl2 fl3 ...
 -- Scheme Procedure: fl>=? fl1 fl2 fl3 ...
     These procedures return ‘#t’ if their flonum arguments are
     (respectively): equal, monotonically increasing, monotonically
     decreasing, monotonically nondecreasing, or monotonically
     nonincreasing; ‘#f’ otherwise.

 -- Scheme Procedure: flinteger? fl
 -- Scheme Procedure: flzero? fl
 -- Scheme Procedure: flpositive? fl
 -- Scheme Procedure: flnegative? fl
 -- Scheme Procedure: flodd? fl
 -- Scheme Procedure: fleven? fl
     These numerical predicates return ‘#t’ if FL is, respectively, an
     integer, zero, greater than zero, less than zero, odd, even, ‘#f’
     otherwise.  In the case of ‘flodd?’ and ‘fleven?’, FL must be an
     integer-valued flonum.

 -- Scheme Procedure: flfinite? fl
 -- Scheme Procedure: flinfinite? fl
 -- Scheme Procedure: flnan? fl
     These numerical predicates return ‘#t’ if FL is, respectively, not
     infinite, infinite, or a ‘NaN’ value.

 -- Scheme Procedure: flmax fl1 fl2 ...
 -- Scheme Procedure: flmin fl1 fl2 ...
     These procedures return the maximum or minimum of their arguments.

 -- Scheme Procedure: fl+ fl1 ...
 -- Scheme Procedure: fl* fl ...
     These procedures return the sum or product of their arguments.

 -- Scheme Procedure: fl- fl1 fl2 ...
 -- Scheme Procedure: fl- fl
 -- Scheme Procedure: fl/ fl1 fl2 ...
 -- Scheme Procedure: fl/ fl
     These procedures return, respectively, the difference or quotient
     of their arguments when called with two arguments; when called with
     a single argument, they return the additive or multiplicative
     inverse of FL.

 -- Scheme Procedure: flabs fl
     Returns the absolute value of FL.

 -- Scheme Procedure: fldiv-and-mod fl1 fl2
 -- Scheme Procedure: fldiv fl1 fl2
 -- Scheme Procedure: fldmod fl1 fl2
 -- Scheme Procedure: fldiv0-and-mod0 fl1 fl2
 -- Scheme Procedure: fldiv0 fl1 fl2
 -- Scheme Procedure: flmod0 fl1 fl2
     These procedures implement number-theoretic division on flonums;
     see (rnrs base), for a description for their semantics.

 -- Scheme Procedure: flnumerator fl
 -- Scheme Procedure: fldenominator fl
     These procedures return the numerator or denominator of FL as a
     flonum.

 -- Scheme Procedure: flfloor fl1
 -- Scheme Procedure: flceiling fl
 -- Scheme Procedure: fltruncate fl
 -- Scheme Procedure: flround fl
     These procedures are identical to the ‘floor’, ‘ceiling’,
     ‘truncate’, and ‘round’ procedures provided by Guile’s core
     library.  See Arithmetic, for documentation.

 -- Scheme Procedure: flexp fl
 -- Scheme Procedure: fllog fl
 -- Scheme Procedure: fllog fl1 fl2
 -- Scheme Procedure: flsin fl
 -- Scheme Procedure: flcos fl
 -- Scheme Procedure: fltan fl
 -- Scheme Procedure: flasin fl
 -- Scheme Procedure: flacos fl
 -- Scheme Procedure: flatan fl
 -- Scheme Procedure: flatan fl1 fl2
     These procedures, which compute the usual transcendental functions,
     are the flonum variants of the procedures provided by the R6RS base
     library (see (rnrs base)).

 -- Scheme Procedure: flsqrt fl
     Returns the square root of FL.  If FL is ‘-0.0’, -0.0 is returned;
     for other negative values, a ‘NaN’ value is returned.

 -- Scheme Procedure: flexpt fl1 fl2
     Returns the value of FL1 raised to the power of FL2.

   The following condition types are provided to allow Scheme
implementations that do not support infinities or ‘NaN’ values to
indicate that a computation resulted in such a value.  Guile supports
both of these, so these conditions will never be raised by Guile’s
standard libraries implementation.

 -- Condition Type: &no-infinities
 -- Scheme Procedure: make-no-infinities-violation obj
 -- Scheme Procedure: no-infinities-violation?
     A condition type indicating that a computation resulted in an
     infinite value on a Scheme implementation incapable of representing
     infinities.

 -- Condition Type: &no-nans
 -- Scheme Procedure: make-no-nans-violation obj
 -- Scheme Procedure: no-nans-violation? obj
     A condition type indicating that a computation resulted in a ‘NaN’
     value on a Scheme implementation incapable of representing ‘NaN’s.

 -- Scheme Procedure: fixnum->flonum fx
     Returns the flonum that is numerically closest to the fixnum FX.

7.6.2.21 rnrs arithmetic bitwise
................................

The ‘(rnrs arithmetic bitwise (6))’ library provides procedures for
performing bitwise arithmetic operations on the two’s complement
representations of fixnums.

   This library and the procedures it exports share functionality with
SRFI-60, which provides support for bitwise manipulation of integers
(see SRFI-60).

 -- Scheme Procedure: bitwise-not ei
 -- Scheme Procedure: bitwise-and ei1 ...
 -- Scheme Procedure: bitwise-ior ei1 ...
 -- Scheme Procedure: bitwise-xor ei1 ...
     These procedures are identical to the ‘lognot’, ‘logand’, ‘logior’,
     and ‘logxor’ procedures provided by Guile’s core library.  See
     Bitwise Operations, for documentation.

 -- Scheme Procedure: bitwise-if ei1 ei2 ei3
     Returns the bitwise “if” of its arguments.  The bit at position ‘i’
     in the return value will be the ‘i’th bit from EI2 if the ‘i’th bit
     of EI1 is 1, the ‘i’th bit from EI3.

 -- Scheme Procedure: bitwise-bit-count ei
     Returns the number of 1 bits in the two’s complement representation
     of EI.

 -- Scheme Procedure: bitwise-length ei
     Returns the number of bits necessary to represent EI.

 -- Scheme Procedure: bitwise-first-bit-set ei
     Returns the index of the least significant 1 bit in the two’s
     complement representation of EI.

 -- Scheme Procedure: bitwise-bit-set? ei1 ei2
     Returns ‘#t’ if the EI2th bit in the two’s complement
     representation of EI1 is 1, ‘#f’ otherwise.

 -- Scheme Procedure: bitwise-copy-bit ei1 ei2 ei3
     Returns the result of setting the EI2th bit of EI1 to the EI2th bit
     of EI3.

 -- Scheme Procedure: bitwise-bit-field ei1 ei2 ei3
     Returns the integer representation of the contiguous sequence of
     bits in EI1 that starts at position EI2 (inclusive) and ends at
     position EI3 (exclusive).

 -- Scheme Procedure: bitwise-copy-bit-field ei1 ei2 ei3 ei4
     Returns the result of replacing the bit field in EI1 with start and
     end positions EI2 and EI3 with the corresponding bit field from
     EI4.

 -- Scheme Procedure: bitwise-arithmetic-shift ei1 ei2
 -- Scheme Procedure: bitwise-arithmetic-shift-left ei1 ei2
 -- Scheme Procedure: bitwise-arithmetic-shift-right ei1 ei2
     Returns the result of shifting the bits of EI1 right or left by the
     EI2 positions.  ‘bitwise-arithmetic-shift’ is identical to
     ‘bitwise-arithmetic-shift-left’.

 -- Scheme Procedure: bitwise-rotate-bit-field ei1 ei2 ei3 ei4
     Returns the result of cyclically permuting the bit field in EI1
     with start and end positions EI2 and EI3 by EI4 bits in the
     direction of more significant bits.

 -- Scheme Procedure: bitwise-reverse-bit-field ei1 ei2 ei3
     Returns the result of reversing the order of the bits of EI1
     between position EI2 (inclusive) and position EI3 (exclusive).

7.6.2.22 rnrs syntax-case
.........................

The ‘(rnrs syntax-case (6))’ library provides access to the
‘syntax-case’ system for writing hygienic macros.  With one exception,
all of the forms and procedures exported by this library are
“re-exports” of Guile’s native support for ‘syntax-case’; see Syntax Case,
for documentation, examples, and rationale.

 -- Scheme Procedure: make-variable-transformer proc
     Creates a new variable transformer out of PROC, a procedure that
     takes a syntax object as input and returns a syntax object.  If an
     identifier to which the result of this procedure is bound appears
     on the left-hand side of a ‘set!’ expression, PROC will be called
     with a syntax object representing the entire ‘set!’ expression, and
     its return value will replace that ‘set!’ expression.

 -- Scheme Syntax: syntax-case expression (literal ...) clause ...
     The ‘syntax-case’ pattern matching form.

 -- Scheme Syntax: syntax template
 -- Scheme Syntax: quasisyntax template
 -- Scheme Syntax: unsyntax template
 -- Scheme Syntax: unsyntax-splicing template
     These forms allow references to be made in the body of a
     syntax-case output expression subform to datum and non-datum
     values.  They are identical to the forms provided by Guile’s core
     library; see Syntax Case, for documentation.

 -- Scheme Procedure: identifier? obj
 -- Scheme Procedure: bound-identifier=? id1 id2
 -- Scheme Procedure: free-identifier=? id1 id2
     These predicate procedures operate on syntax objects representing
     Scheme identifiers.  ‘identifier?’ returns ‘#t’ if OBJ represents
     an identifier, ‘#f’ otherwise.  ‘bound-identifier=?’ returns ‘#t’
     if and only if a binding for ID1 would capture a reference to ID2
     in the transformer’s output, or vice-versa.  ‘free-identifier=?’
     returns ‘#t’ if and only ID1 and ID2 would refer to the same
     binding in the output of the transformer, independent of any
     bindings introduced by the transformer.

 -- Scheme Procedure: generate-temporaries l
     Returns a list, of the same length as L, which must be a list or a
     syntax object representing a list, of globally unique symbols.

 -- Scheme Procedure: syntax->datum syntax-object
 -- Scheme Procedure: datum->syntax template-id datum
     These procedures convert wrapped syntax objects to and from Scheme
     datum values.  The syntax object returned by ‘datum->syntax’ shares
     contextual information with the syntax object TEMPLATE-ID.

 -- Scheme Procedure: syntax-violation whom message form
 -- Scheme Procedure: syntax-violation whom message form subform
     Constructs a new compound condition that includes the following
     simple conditions:
        • If WHOM is not ‘#f’, a ‘&who’ condition with the WHOM as its
          field
        • A ‘&message’ condition with the specified MESSAGE
        • A ‘&syntax’ condition with the specified FORM and optional
          SUBFORM fields

7.6.2.23 rnrs hashtables
........................

The ‘(rnrs hashtables (6))’ library provides structures and procedures
for creating and accessing hash tables.  The hash tables API defined by
R6RS is substantially similar to both Guile’s native hash tables
implementation as well as the one provided by SRFI-69; see Hash Tables,
and SRFI-69, respectively.  Note that you can write
portable R6RS library code that manipulates SRFI-69 hash tables (by
importing the ‘(srfi :69)’ library); however, hash tables created by one
API cannot be used by another.

   Like SRFI-69 hash tables—and unlike Guile’s native ones—R6RS hash
tables associate hash and equality functions with a hash table at the
time of its creation.  Additionally, R6RS allows for the creation (via
‘hashtable-copy’; see below) of immutable hash tables.

 -- Scheme Procedure: make-eq-hashtable
 -- Scheme Procedure: make-eq-hashtable k
     Returns a new hash table that uses ‘eq?’ to compare keys and
     Guile’s ‘hashq’ procedure as a hash function.  If K is given, it
     specifies the initial capacity of the hash table.

 -- Scheme Procedure: make-eqv-hashtable
 -- Scheme Procedure: make-eqv-hashtable k
     Returns a new hash table that uses ‘eqv?’ to compare keys and
     Guile’s ‘hashv’ procedure as a hash function.  If K is given, it
     specifies the initial capacity of the hash table.

 -- Scheme Procedure: make-hashtable hash-function equiv
 -- Scheme Procedure: make-hashtable hash-function equiv k
     Returns a new hash table that uses EQUIV to compare keys and
     HASH-FUNCTION as a hash function.  EQUIV must be a procedure that
     accepts two arguments and returns a true value if they are
     equivalent, ‘#f’ otherwise; HASH-FUNCTION must be a procedure that
     accepts one argument and returns a non-negative integer.

     If K is given, it specifies the initial capacity of the hash table.

 -- Scheme Procedure: hashtable? obj
     Returns ‘#t’ if OBJ is an R6RS hash table, ‘#f’ otherwise.

 -- Scheme Procedure: hashtable-size hashtable
     Returns the number of keys currently in the hash table HASHTABLE.

 -- Scheme Procedure: hashtable-ref hashtable key default
     Returns the value associated with KEY in the hash table HASHTABLE,
     or DEFAULT if none is found.

 -- Scheme Procedure: hashtable-set! hashtable key obj
     Associates the key KEY with the value OBJ in the hash table
     HASHTABLE, and returns an unspecified value.  An ‘&assertion’
     condition is raised if HASHTABLE is immutable.

 -- Scheme Procedure: hashtable-delete! hashtable key
     Removes any association found for the key KEY in the hash table
     HASHTABLE, and returns an unspecified value.  An ‘&assertion’
     condition is raised if HASHTABLE is immutable.

 -- Scheme Procedure: hashtable-contains? hashtable key
     Returns ‘#t’ if the hash table HASHTABLE contains an association
     for the key KEY, ‘#f’ otherwise.

 -- Scheme Procedure: hashtable-update! hashtable key proc default
     Associates with KEY in the hash table HASHTABLE the result of
     calling PROC, which must be a procedure that takes one argument, on
     the value currently associated KEY in HASHTABLE—or on DEFAULT if no
     such association exists.  An ‘&assertion’ condition is raised if
     HASHTABLE is immutable.

 -- Scheme Procedure: hashtable-copy hashtable
 -- Scheme Procedure: hashtable-copy hashtable mutable
     Returns a copy of the hash table HASHTABLE.  If the optional
     argument MUTABLE is provided and is a true value, the new hash
     table will be mutable.

 -- Scheme Procedure: hashtable-clear! hashtable
 -- Scheme Procedure: hashtable-clear! hashtable k
     Removes all of the associations from the hash table HASHTABLE.  The
     optional argument K, which specifies a new capacity for the hash
     table, is accepted by Guile’s ‘(rnrs hashtables)’ implementation,
     but is ignored.

 -- Scheme Procedure: hashtable-keys hashtable
     Returns a vector of the keys with associations in the hash table
     HASHTABLE, in an unspecified order.

 -- Scheme Procedure: hashtable-entries hashtable
     Return two values—a vector of the keys with associations in the
     hash table HASHTABLE, and a vector of the values to which these
     keys are mapped, in corresponding but unspecified order.

 -- Scheme Procedure: hashtable-equivalence-function hashtable
     Returns the equivalence predicated use by HASHTABLE.  This
     procedure returns ‘eq?’ and ‘eqv?’, respectively, for hash tables
     created by ‘make-eq-hashtable’ and ‘make-eqv-hashtable’.

 -- Scheme Procedure: hashtable-hash-function hashtable
     Returns the hash function used by HASHTABLE.  For hash tables
     created by ‘make-eq-hashtable’ or ‘make-eqv-hashtable’, ‘#f’ is
     returned.

 -- Scheme Procedure: hashtable-mutable? hashtable
     Returns ‘#t’ if HASHTABLE is mutable, ‘#f’ otherwise.

   A number of hash functions are provided for convenience:

 -- Scheme Procedure: equal-hash obj
     Returns an integer hash value for OBJ, based on its structure and
     current contents.  This hash function is suitable for use with
     ‘equal?’ as an equivalence function.

 -- Scheme Procedure: string-hash string
 -- Scheme Procedure: symbol-hash symbol
     These procedures are identical to the ones provided by Guile’s core
     library.  See Hash Table Reference, for documentation.

 -- Scheme Procedure: string-ci-hash string
     Returns an integer hash value for STRING based on its contents,
     ignoring case.  This hash function is suitable for use with
     ‘string-ci=?’ as an equivalence function.

7.6.2.24 rnrs enums
...................

The ‘(rnrs enums (6))’ library provides structures and procedures for
working with enumerable sets of symbols.  Guile’s implementation defines
an “enum-set” record type that encapsulates a finite set of distinct
symbols, the “universe”, and a subset of these symbols, which define the
enumeration set.

   The SRFI-1 list library provides a number of procedures for
performing set operations on lists; Guile’s ‘(rnrs enums)’
implementation makes use of several of them.  See SRFI-1 Set Operations,
for more information.

 -- Scheme Procedure: make-enumeration symbol-list
     Returns a new enum-set whose universe and enumeration set are both
     equal to SYMBOL-LIST, a list of symbols.

 -- Scheme Procedure: enum-set-universe enum-set
     Returns an enum-set representing the universe of ENUM-SET, an
     enum-set.

 -- Scheme Procedure: enum-set-indexer enum-set
     Returns a procedure that takes a single argument and returns the
     zero-indexed position of that argument in the universe of ENUM-SET,
     or ‘#f’ if its argument is not a member of that universe.

 -- Scheme Procedure: enum-set-constructor enum-set
     Returns a procedure that takes a single argument, a list of symbols
     from the universe of ENUM-SET, an enum-set, and returns a new
     enum-set with the same universe that represents a subset containing
     the specified symbols.

 -- Scheme Procedure: enum-set->list enum-set
     Returns a list containing the symbols of the set represented by
     ENUM-SET, an enum-set, in the order that they appear in the
     universe of ENUM-SET.

 -- Scheme Procedure: enum-set-member? symbol enum-set
 -- Scheme Procedure: enum-set-subset? enum-set1 enum-set2
 -- Scheme Procedure: enum-set=? enum-set1 enum-set2
     These procedures test for membership of symbols and enum-sets in
     other enum-sets.  ‘enum-set-member?’ returns ‘#t’ if and only if
     SYMBOL is a member of the subset specified by ENUM-SET.
     ‘enum-set-subset?’ returns ‘#t’ if and only if the universe of
     ENUM-SET1 is a subset of the universe of ENUM-SET2 and every symbol
     in ENUM-SET1 is present in ENUM-SET2.  ‘enum-set=?’ returns ‘#t’ if
     and only if ENUM-SET1 is a subset, as per ‘enum-set-subset?’ of
     ENUM-SET2 and vice versa.

 -- Scheme Procedure: enum-set-union enum-set1 enum-set2
 -- Scheme Procedure: enum-set-intersection enum-set1 enum-set2
 -- Scheme Procedure: enum-set-difference enum-set1 enum-set2
     These procedures return, respectively, the union, intersection, and
     difference of their enum-set arguments.

 -- Scheme Procedure: enum-set-complement enum-set
     Returns ENUM-SET’s complement (an enum-set), with regard to its
     universe.

 -- Scheme Procedure: enum-set-projection enum-set1 enum-set2
     Returns the projection of the enum-set ENUM-SET1 onto the universe
     of the enum-set ENUM-SET2.

 -- Scheme Syntax: define-enumeration type-name (symbol ...)
          constructor-syntax
     Evaluates to two new definitions: A constructor bound to
     CONSTRUCTOR-SYNTAX that behaves similarly to constructors created
     by ‘enum-set-constructor’, above, and creates new ENUM-SETs in the
     universe specified by ‘(symbol ...)’; and a “predicate macro” bound
     to TYPE-NAME, which has the following form:

          (TYPE-NAME sym)

     If SYM is a member of the universe specified by the SYMBOLs above,
     this form evaluates to SYM.  Otherwise, a ‘&syntax’ condition is
     raised.

7.6.2.25 rnrs
.............

The ‘(rnrs (6))’ library is a composite of all of the other R6RS
standard libraries—it imports and re-exports all of their exported
procedures and syntactic forms—with the exception of the following
libraries:

   • ‘(rnrs eval (6))’
   • ‘(rnrs mutable-pairs (6))’
   • ‘(rnrs mutable-strings (6))’
   • ‘(rnrs r5rs (6))’

7.6.2.26 rnrs eval
..................

The ‘(rnrs eval (6)’ library provides procedures for performing
“on-the-fly” evaluation of expressions.

 -- Scheme Procedure: eval expression environment
     Evaluates EXPRESSION, which must be a datum representation of a
     valid Scheme expression, in the environment specified by
     ENVIRONMENT.  This procedure is identical to the one provided by
     Guile’s code library; see Fly Evaluation, for documentation.

 -- Scheme Procedure: environment import-spec ...
     Constructs and returns a new environment based on the specified
     IMPORT-SPECs, which must be datum representations of the import
     specifications used with the ‘import’ form.  See R6RS Libraries,
     for documentation.

7.6.2.27 rnrs mutable-pairs
...........................

The ‘(rnrs mutable-pairs (6))’ library provides the ‘set-car!’ and
‘set-cdr!’ procedures, which allow the ‘car’ and ‘cdr’ fields of a pair
to be modified.

   These procedures are identical to the ones provide by Guile’s core
library.  See Pairs, for documentation.  All pairs in Guile are
mutable; consequently, these procedures will never throw the
‘&assertion’ condition described in the R6RS libraries specification.

7.6.2.28 rnrs mutable-strings
.............................

The ‘(rnrs mutable-strings (6))’ library provides the ‘string-set!’ and
‘string-fill!’ procedures, which allow the content of strings to be
modified “in-place.”

   These procedures are identical to the ones provided by Guile’s core
library.  See String Modification, for documentation.  All strings
in Guile are mutable; consequently, these procedures will never throw
the ‘&assertion’ condition described in the R6RS libraries
specification.

7.6.2.29 rnrs r5rs
..................

The ‘(rnrs r5rs (6))’ library exports bindings for some procedures
present in R5RS but omitted from the R6RS base library specification.

 -- Scheme Procedure: exact->inexact z
 -- Scheme Procedure: inexact->exact z
     These procedures are identical to the ones provided by Guile’s core
     library.  See Exactness, for documentation.

 -- Scheme Procedure: quotient n1 n2
 -- Scheme Procedure: remainder n1 n2
 -- Scheme Procedure: modulo n1 n2
     These procedures are identical to the ones provided by Guile’s core
     library.  See Integer Operations, for documentation.

 -- Scheme Syntax: delay expr
 -- Scheme Procedure: force promise
     The ‘delay’ form and the ‘force’ procedure are identical to their
     counterparts in Guile’s core library.  See Delayed Evaluation,
     for documentation.

 -- Scheme Procedure: null-environment n
 -- Scheme Procedure: scheme-report-environment n
     These procedures are identical to the ones provided by the ‘(ice-9
     r5rs)’ Guile module.  See Environments, for documentation.

7.7 Pattern Matching
====================

The ‘(ice-9 match)’ module provides a “pattern matcher”, written by Alex
Shinn, and compatible with Andrew K. Wright’s pattern matcher found in
many Scheme implementations.

   A pattern matcher can match an object against several patterns and
extract the elements that make it up.  Patterns can represent any Scheme
object: lists, strings, symbols, records, etc.  They can optionally
contain “pattern variables”.  When a matching pattern is found, an
expression associated with the pattern is evaluated, optionally with all
pattern variables bound to the corresponding elements of the object:

     (let ((l '(hello (world))))
       (match l           ;; <- the input object
         (('hello (who))  ;; <- the pattern
          who)))          ;; <- the expression evaluated upon matching
     ⇒ world

   In this example, list L matches the pattern ‘('hello (who))’, because
it is a two-element list whose first element is the symbol ‘hello’ and
whose second element is a one-element list.  Here WHO is a pattern
variable.  ‘match’, the pattern matcher, locally binds WHO to the value
contained in this one-element list—i.e., the symbol ‘world’.  An error
would be raised if L did not match the pattern.

   The same object can be matched against a simpler pattern:

     (let ((l '(hello (world))))
       (match l
         ((x y)
          (values x y))))
     ⇒ hello
     ⇒ (world)

   Here pattern ‘(x y)’ matches any two-element list, regardless of the
types of these elements.  Pattern variables X and Y are bound to,
respectively, the first and second element of L.

   Patterns can be composed, and nested.  For instance, ‘...’ (ellipsis)
means that the previous pattern may be matched zero or more times in a
list:

     (match lst
       (((heads tails ...) ...)
        heads))

This expression returns the first element of each list within LST.  For
proper lists of proper lists, it is equivalent to ‘(map car lst)’.
However, it performs additional checks to make sure that LST and the
lists therein are proper lists, as prescribed by the pattern, raising an
error if they are not.

   Compared to hand-written code, pattern matching noticeably improves
clarity and conciseness—no need to resort to series of ‘car’ and ‘cdr’
calls when matching lists, for instance.  It also improves robustness,
by making sure the input _completely_ matches the pattern—conversely,
hand-written code often trades robustness for conciseness.  And of
course, ‘match’ is a macro, and the code it expands to is just as
efficient as equivalent hand-written code.

   The pattern matcher is defined as follows:

 -- Scheme Syntax: match exp clause1 clause2 ...
     Match object EXP against the patterns in CLAUSE1 CLAUSE2 ... in the
     order in which they appear.  Return the value produced by the first
     matching clause.  If no clause matches, throw an exception with key
     ‘match-error’.

     Each clause has the form ‘(pattern body1 body2 ...)’.  Each PATTERN
     must follow the syntax described below.  Each body is an arbitrary
     Scheme expression, possibly referring to pattern variables of
     PATTERN.

   The syntax and interpretation of patterns is as follows:

        patterns:                       matches:

pat ::= identifier                      anything, and binds identifier
      | _                               anything
      | ()                              the empty list
      | #t                              #t
      | #f                              #f
      | string                          a string
      | number                          a number
      | character                       a character
      | 'sexp                           an s-expression
      | 'symbol                         a symbol (special case of s-expr)
      | (pat_1 ... pat_n)               list of n elements
      | (pat_1 ... pat_n . pat_{n+1})   list of n or more
      | (pat_1 ... pat_n pat_n+1 ooo)   list of n or more, each element
                                          of remainder must match pat_n+1
      | #(pat_1 ... pat_n)              vector of n elements
      | #(pat_1 ... pat_n pat_n+1 ooo)  vector of n or more, each element
                                          of remainder must match pat_n+1
      | #&pat                           box
      | ($ record-name pat_1 ... pat_n) a record
      | (= field pat)                   a ``field'' of an object
      | (and pat_1 ... pat_n)           if all of pat_1 thru pat_n match
      | (or pat_1 ... pat_n)            if any of pat_1 thru pat_n match
      | (not pat_1 ... pat_n)           if all pat_1 thru pat_n don't match
      | (? predicate pat_1 ... pat_n)   if predicate true and all of
                                          pat_1 thru pat_n match
      | (set! identifier)               anything, and binds setter
      | (get! identifier)               anything, and binds getter
      | `qp                             a quasi-pattern
      | (identifier *** pat)            matches pat in a tree and binds
                                        identifier to the path leading
                                        to the object that matches pat

ooo ::= ...                             zero or more
      | ___                             zero or more
      | ..1                             1 or more

        quasi-patterns:                 matches:

qp  ::= ()                              the empty list
      | #t                              #t
      | #f                              #f
      | string                          a string
      | number                          a number
      | character                       a character
      | identifier                      a symbol
      | (qp_1 ... qp_n)                 list of n elements
      | (qp_1 ... qp_n . qp_{n+1})      list of n or more
      | (qp_1 ... qp_n qp_n+1 ooo)      list of n or more, each element
                                          of remainder must match qp_n+1
      | #(qp_1 ... qp_n)                vector of n elements
      | #(qp_1 ... qp_n qp_n+1 ooo)     vector of n or more, each element
                                          of remainder must match qp_n+1
      | #&qp                            box
      | ,pat                            a pattern
      | ,@pat                           a pattern

   The names ‘quote’, ‘quasiquote’, ‘unquote’, ‘unquote-splicing’, ‘?’,
‘_’, ‘$’, ‘and’, ‘or’, ‘not’, ‘set!’, ‘get!’, ‘...’, and ‘___’ cannot be
used as pattern variables.

   Here is a more complex example:

     (use-modules (srfi srfi-9))

     (let ()
       (define-record-type person
         (make-person name friends)
         person?
         (name    person-name)
         (friends person-friends))

       (letrec ((alice (make-person "Alice" (delay (list bob))))
                (bob   (make-person "Bob" (delay (list alice)))))
         (match alice
           (($ person name (= force (($ person "Bob"))))
            (list 'friend-of-bob name))
           (_ #f))))

     ⇒ (friend-of-bob "Alice")

Here the ‘$’ pattern is used to match a SRFI-9 record of type PERSON
containing two or more slots.  The value of the first slot is bound to
NAME.  The ‘=’ pattern is used to apply ‘force’ on the second slot, and
then checking that the result matches the given pattern.  In other
words, the complete pattern matches any PERSON whose second slot is a
promise that evaluates to a one-element list containing a PERSON whose
first slot is ‘"Bob"’.

   Please refer to the ‘ice-9/match.upstream.scm’ file in your Guile
installation for more details.

   Guile also comes with a pattern matcher specifically tailored to SXML
trees, see sxml-match.