This is guile.info, produced by makeinfo version 6.8 from guile.texi.

This manual documents Guile version 3.0.11.

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

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

   Additionally, the documentation of the SRFI 64 module is adapted from
its specification text, which is made available under the following
Expat license:

     Permission is hereby granted, free of charge, to any person
     obtaining a copy of this software and associated documentation
     files (the "Software"), to deal in the Software without
     restriction, including without limitation the rights to use, copy,
     modify, merge, publish, distribute, sublicense, and/or sell copies
     of the Software, and to permit persons to whom the Software is
     furnished to do so, subject to the following conditions:

     The above copyright notice and this permission notice shall be
     included in all copies or substantial portions of the Software.

     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     SOFTWARE.

   Additionally, the documentation of the SRFI 197 module is adapted
from its specification text, which is made available under the following
MIT license:

     Permission is hereby granted, free of charge, to any person
     obtaining a copy of this software and associated documentation
     files (the "Software"), to deal in the Software without
     restriction, including without limitation the rights to use, copy,
     modify, merge, publish, distribute, sublicense, and/or sell copies
     of the Software, and to permit persons to whom the Software is
     furnished to do so, subject to the following conditions:

     The above copyright notice and this permission notice shall be
     included in all copies or substantial portions of the Software.

     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     SOFTWARE.

INFO-DIR-SECTION The Algorithmic Language Scheme
START-INFO-DIR-ENTRY
* Guile Reference: (guile).     The Guile reference manual.
END-INFO-DIR-ENTRY


File: guile.info,  Node: SRFI-42,  Next: SRFI-43,  Prev: SRFI-41,  Up: SRFI Support

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

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


File: guile.info,  Node: SRFI-43,  Next: SRFI-45,  Prev: SRFI-42,  Up: SRFI Support

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

* Menu:

* SRFI-43 Constructors::
* SRFI-43 Predicates::
* SRFI-43 Selectors::
* SRFI-43 Iteration::
* SRFI-43 Searching::
* SRFI-43 Mutators::
* SRFI-43 Conversion::


File: guile.info,  Node: SRFI-43 Constructors,  Next: SRFI-43 Predicates,  Up: 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)


File: guile.info,  Node: SRFI-43 Predicates,  Next: SRFI-43 Selectors,  Prev: SRFI-43 Constructors,  Up: SRFI-43

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.


File: guile.info,  Node: SRFI-43 Selectors,  Next: SRFI-43 Iteration,  Prev: SRFI-43 Predicates,  Up: SRFI-43

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.


File: guile.info,  Node: SRFI-43 Iteration,  Next: SRFI-43 Searching,  Prev: SRFI-43 Selectors,  Up: SRFI-43

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


File: guile.info,  Node: SRFI-43 Searching,  Next: SRFI-43 Mutators,  Prev: SRFI-43 Iteration,  Up: SRFI-43

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.


File: guile.info,  Node: SRFI-43 Mutators,  Next: SRFI-43 Conversion,  Prev: SRFI-43 Searching,  Up: SRFI-43

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.


File: guile.info,  Node: SRFI-43 Conversion,  Prev: SRFI-43 Mutators,  Up: SRFI-43

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.


File: guile.info,  Node: SRFI-45,  Next: SRFI-46,  Prev: SRFI-43,  Up: SRFI Support

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


File: guile.info,  Node: SRFI-46,  Next: SRFI-55,  Prev: SRFI-45,  Up: SRFI Support

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.  *Note Syntax Rules::.


File: guile.info,  Node: SRFI-55,  Next: SRFI-60,  Prev: SRFI-46,  Up: SRFI Support

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.


File: guile.info,  Node: SRFI-60,  Next: SRFI-61,  Prev: SRFI-55,  Up: SRFI Support

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 (*note 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 (*note 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)’ (*note 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


File: guile.info,  Node: SRFI-61,  Next: SRFI-62,  Prev: SRFI-60,  Up: SRFI Support

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 *note Simple
Conditional Evaluation: Conditionals.


File: guile.info,  Node: SRFI-62,  Next: SRFI-64,  Prev: SRFI-61,  Up: SRFI Support

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.


File: guile.info,  Node: SRFI-64,  Next: SRFI-67,  Prev: SRFI-62,  Up: SRFI Support

7.5.37 SRFI-64: A Scheme API for Test Suites
--------------------------------------------

* Menu:

* SRFI-64 Abstract::
* SRFI-64 Rationale::
* SRFI-64 Writing Basic Test Suites::
* SRFI-64 Conditonal Test Suites and Other Advanced Features::
* SRFI-64 Test Runner::
* SRFI-64 Test Results::
* SRFI-64 Writing a New Test Runner::


File: guile.info,  Node: SRFI-64 Abstract,  Next: SRFI-64 Rationale,  Up: SRFI-64

7.5.37.1 SRFI-64 Abstract
.........................

This defines an API for writing “test suites”, to make it easy to
portably test Scheme APIs, libraries, applications, and implementations.
A test suite is a collection of “test cases” that execute in the context
of a “test-runner”.  This specification also supports writing new
test-runners, to allow customization of reporting and processing the
result of running test suites.


File: guile.info,  Node: SRFI-64 Rationale,  Next: SRFI-64 Writing Basic Test Suites,  Prev: SRFI-64 Abstract,  Up: SRFI-64

7.5.37.2 SRFI-64 Rationale
..........................

The Scheme community needs a standard for writing test suites.  Every
SRFI or other library should come with a test suite.  Such a test suite
must be portable, without requiring any non-standard features, such as
modules.  The test suite implementation or "runner" need not be
portable, but it is desirable that it be possible to write a portable
basic implementation.

   There are other testing frameworks written in Scheme, including
RackUnit (https://docs.racket-lang.org/rackunit/).  However RackUnit is
not portable.  It is also a bit on the verbose side.  It would be useful
to have a bridge between this framework and RackUnit so RackUnit tests
could run under this framework and vice versa.  There exists also at
least one Scheme wrapper providing a Scheme interface to the “standard”
JUnit (https://www.junit.org/) API for Java.  It would be useful to have
a bridge so that tests written using this framework can run under a
JUnit runner.  Neither of these features are part of this specification.

   This API makes use of implicit dynamic state, including an implicit
“test runner”.  This makes the API convenient and terse to use, but it
may be a little less elegant and “compositional” than using explicit
test objects, such as JUnit-style frameworks.  It is not claimed to
follow either object-oriented or functional design principles, but I
hope it is useful and convenient to use and extend.

   This proposal allows converting a Scheme source file to a test suite
by just adding a few macros.  You don’t have to write the entire file in
a new form, thus you don’t have to re-indent it.

   All names defined by the API start with the prefix ‘test-’.  All
function-like forms are defined as syntax.  They may be implemented as
functions or macros or built-ins.  The reason for specifying them as
syntax is to allow specific tests to be skipped without evaluating
sub-expressions, or for implementations to add features such as printing
line numbers or catching exceptions.


File: guile.info,  Node: SRFI-64 Writing Basic Test Suites,  Next: SRFI-64 Conditonal Test Suites and Other Advanced Features,  Prev: SRFI-64 Rationale,  Up: SRFI-64

7.5.37.3 SRFI-64 Writing Basic Test Suites
..........................................

Let’s start with a simple example.  This is a complete self-contained
test-suite.

     ;; Initialize and give a name to a simple testsuite.
     (test-begin "vec-test")
     (define v (make-vector 5 99))
     ;; Require that an expression evaluate to true.
     (test-assert (vector? v))
     ;; Test that an expression is eqv? to some other expression.
     (test-eqv 99 (vector-ref v 2))
     (vector-set! v 2 7)
     (test-eqv 7 (vector-ref v 2))
     ;; Finish the testsuite, and report results.
     (test-end "vec-test")

   This testsuite could be saved in its own source file.  Nothing else
is needed: We do not require any top-level forms, so it is easy to wrap
an existing program or test to this form, without adding indentation.
It is also easy to add new tests, without having to name individual
tests (though that is optional).

   Test cases are executed in the context of a “test runner”, which is
an object that accumulates and reports test results.  This specification
defines how to create and use custom test runners, but implementations
should also provide a default test runner.  It is suggested (but not
required) that loading the above file in a top-level environment will
cause the tests to be executed using an implementation-specified default
test runner, and ‘test-end’ will cause a summary to be displayed in an
implementation-specified manner.  The SRFI 64 implementation used in
Guile provides such a default test runner; running the above snippet at
the REPL prints:

     *** Entering test group: vec-test ***
     $1 = #t
     * PASS:
     $2 = ((pass . 1))
     * PASS:
     $3 = ((pass . 2))
     * PASS:
     $4 = ((pass . 3))
     *** Leaving test group: vec-test ***
     *** Test suite finished. ***
     *** # of expected passes    : 3

   It also returns the ‘<test-runner>’ object.

Simple test-cases
.................

Primitive test cases test that a given condition is true.  They may have
a name.  The core test case form is ‘test-assert’:

 -- Scheme Syntax: test-assert [test-name] expression

     This evaluates the EXPRESSION.  The test passes if the result is
     true; if the result is false, a test failure is reported.  The test
     also fails if an exception is raised, assuming the implementation
     has a way to catch exceptions.  How the failure is reported depends
     on the test runner environment.  The TEST-NAME is a string that
     names the test case.  (Though the TEST-NAME is a string literal in
     the examples, it is an expression.  It is evaluated only once.)  It
     is used when reporting errors, and also when skipping tests, as
     described below.  It is an error to invoke ‘test-assert’if there is
     no current test runner.

   The following forms may be more convenient than using ‘test-assert’
directly:

 -- Scheme Syntax: test-eqv [test-name] expected test-expr

     This is equivalent to:

          (test-assert [TEST-NAME] (eqv? EXPECTED TEST-EXPR))

   Similarly ‘test-equal’ and ‘test-eq’ are shorthand for ‘test-assert’
combined with ‘equal?’ or ‘eq?’, respectively:

 -- Scheme Syntax: test-equal [test-name] expected test-expr
 -- Scheme Syntax: test-eq [test-name] expected test-expr

     Here is a simple example:

          (define (mean x y) (/ (+ x y) 2.0))
          (test-eqv 4 (mean 3 5))

   For testing approximate equality of inexact reals we can use
‘test-approximate’:

 -- Scheme Syntax: test-approximate [test-name] expected test-expr error

     This is equivalent to (except that each argument is only evaluated
     once):

          (test-assert [test-name]
            (and (>= test-expr (- expected error))
                 (<= test-expr (+ expected error))))

     Here’s an example:
          (test-approximate "is 22/7 within 1% of π?"
           3.1415926535
           22/7
           1/100)

Tests for catching errors
.........................

We need a way to specify that evaluation _should_ fail.  This verifies
that errors are detected when required.

 -- Scheme Syntax: test-error [[test-name] error-type] test-expr

     Evaluating TEST-EXPR is expected to signal an error.  The kind of
     error is indicated by ERROR-TYPE.

     If the ERROR-TYPE is left out, or it is ‘#t’, it means "some kind
     of unspecified error should be signaled".  For example:

          (test-error #t (vector-ref '#(1 2) 9))

     This specification leaves it implementation-defined (or for a
     future specification) what form TEST-ERROR may take, though all
     implementations must allow ‘#t’.  Some implementations may support
     SRFI-35’s conditions
     (https://srfi.schemers.org/srfi-35/srfi-35.html), but these are
     only standardized for SRFI-36’s I/O conditions
     (https://srfi.schemers.org/srfi-36/srfi-36.html), which are seldom
     useful in test suites.  An implementation may also allow
     implementation-specific “exception types”.  For example Java-based
     implementations may allow the names of Java exception classes:

          ;; Kawa-specific example
          (test-error <java.lang.IndexOutOfBoundsException> (vector-ref '#(1 2) 9))

     An implementation that cannot catch exceptions should skip
     ‘test-error’ forms.

     The SRFI-64 implementation in Guile supports specifying ERROR-TYPE
     as either:
        • ‘#f’, meaning the test is _not_ expected to produce an error
        • ‘#t’, meaning the test is expected to produce an error, of any
          type
        • A native exception type, as created via ‘make-exception-type’
          or ‘make-condition-type’ from SRFI-35
        • A predicate, which will be applied to the exception caught to
          determine whether is it of the right type
        • A symbol, for the exception kind of legacy
          ‘make-exception-from-throw’ style exceptions.

   Below are some examples valid in Guile:

     (test-error "expect old-style exception kind"
      'numerical-overflow
      (/ 1 0))

     (use-modules (ice-9 exceptions)) ;for standard exception types

     (test-error "expect a native exception type"
      &warning
      (raise-exception (make-warning)))

     (test-error "expect a native exception, using predicate"
      warning?
      (raise-exception (make-warning)))

     (use-modules (srfi srfi-35))

     (test-error "expect a serious SRFI 35 condition type"
      &serious
      (raise-exception (condition (&serious))))

     (test-error "expect a serious SRFI 35 condition type, using predicate"
      serious-condition?
      (raise-exception (condition (&serious))))

Testing syntax
..............

Testing syntax is tricky, especially if we want to check that invalid
syntax is causing an error.  The following utility function can help:

 -- Scheme Procedure: test-read-eval-string string

     This function parses STRING (using ‘read’) and evaluates the
     result.  The result of evaluation is returned from
     ‘test-read-eval-string’.  An error is signalled if there are unread
     characters after the ‘read’ is done.  For example:
     ‘(test-read-eval-string "(+ 3 4)")’ evaluates to ‘7’.
     ‘(test-read-eval-string "(+ 3 4")’ signals an error.
     ‘(test-read-eval-string "(+ 3 4) ")’ signals an error, because
     there is extra “junk” (i.e.  a space) after the list is read.

     The ‘test-read-eval-string’ used in tests:

          (test-equal 7 (test-read-eval-string "(+ 3 4)"))
          (test-error (test-read-eval-string "(+ 3"))
          (test-equal #\newline (test-read-eval-string "#\\newline"))
          (test-error (test-read-eval-string "#\\newlin"))
          ;; Skip the next 2 tests unless srfi-62 is available.
          (test-skip (cond-expand (srfi-62 0) (else 2)))
          (test-equal 5 (test-read-eval-string "(+ 1 #;(* 2 3) 4)"))
          (test-equal '(x z) (test-read-string "(list 'x #;'y 'z)"))

Test groups and paths
.....................

A “test group” is a named sequence of forms containing testcases,
expressions, and definitions.  Entering a group sets the “test group
name”; leaving a group restores the previous group name.  These are
dynamic (run-time) operations, and a group has no other effect or
identity.  Test groups are informal groupings: they are neither Scheme
values, nor are they syntactic forms.  A test group may contain nested
inner test groups.  The “test group path” is a list of the
currently-active (entered) test group names, oldest (outermost) first.

 -- Scheme Syntax: test-begin suite-name [count]

     A ‘test-begin’ enters a new test group.  The SUITE-NAME becomes the
     current test group name, and is added to the end of the test group
     path.  Portable test suites should use a string literal for
     SUITE-NAME; the effect of expressions or other kinds of literals is
     unspecified.

     _Rationale:_ In some ways using symbols would be preferable.
     However, we want human-readable names, and standard Scheme does not
     provide a way to include spaces or mixed-case text in literal
     symbols.

     The optional COUNT must match the number of test-cases executed by
     this group.  (Nested test groups count as a single test case for
     this count.)  This extra test may be useful to catch cases where a
     test doesn’t get executed because of some unexpected error.

     Additionally, if there is no currently executing test runner, one
     is installed in an implementation-defined manner.

 -- Scheme Syntax: test-end [suite-name]

     A ‘test-end’ leaves the current test group.  An error is reported
     if the SUITE-NAME does not match the current test group name.

     Additionally, if the matching ‘test-begin’installed a new
     test-runner, then the ‘test-end’ will uninstall it, after reporting
     the accumulated test results in an implementation-defined manner.

 -- Scheme Syntax: test-group suite-name decl-or-expr ...

     Equivalent to:

          (if (not (test-to-skip% (var suite-name)))
            (dynamic-wind
              (lambda () (test-begin (var suite-name)))
              (lambda () (var decl-or-expr) ...)
              (lambda () (test-end (var suite-name)))))

     This is usually equivalent to executing the DECL-OR-EXPRs within
     the named test group.  However, the entire group is skipped if it
     matched an active ‘test-skip’ (see later).  Also, the ‘test-end’ is
     executed in case of an exception.

Handling set-up and cleanup
...........................

 -- Scheme Syntax: test-group-with-cleanup suite-name decl-or-expr ...
          cleanup-form

     Execute each of the DECL-OR-EXPR forms in order (as in a <BODY>),
     and then execute the CLEANUP-FORM.  The latter should be executed
     even if one of a DECL-OR-EXPR forms raises an exception (assuming
     the implementation has a way to catch exceptions).

     For example:

          (let ((f (open-output-file "log")))
            (test-group-with-cleanup "test-file"
              (do-a-bunch-of-tests f)
              (close-output-port f)))


File: guile.info,  Node: SRFI-64 Conditonal Test Suites and Other Advanced Features,  Next: SRFI-64 Test Runner,  Prev: SRFI-64 Writing Basic Test Suites,  Up: SRFI-64

7.5.37.4 SRFI-64 Conditonal Test Suites and Other Advanced Features
...................................................................

The following describes features for controlling which tests to execute,
or specifying that some tests are _expected_ to fail.

Test specifiers
...............

Sometimes we want to only run certain tests, or we know that certain
tests are expected to fail.  A “test specifier” is a one-argument
function that takes a test-runner and returns a boolean.  The specifier
may be run before a test is performed, and the result may control
whether the test is executed.  For convenience, a specifier may also be
a non-procedure value, which is coerced to a specifier procedure, as
described below for COUNT and NAME.

   A simple example is:

     (if (var some-condition)  (test-skip 2)) ;; skip next 2 tests

 -- Scheme Procedure: test-match-name name

     The resulting specifier matches if the current test name (as
     returned by ‘test-runner-test-name’) is ‘equal?’ to NAME.

 -- Scheme Syntax: test-match-nth n [count]

     This evaluates to a _stateful_ predicate: A counter keeps track of
     how many times it has been called.  The predicate matches the N’th
     time it is called (where ‘1’ is the first time), and the next ‘(-
     COUNT 1)’ times, where COUNT defaults to ‘1’.

 -- Scheme Syntax: test-match-any specifier ...

     The resulting specifier matches if any SPECIFIER matches.  Each
     SPECIFIER is applied, in order, so side-effects from a later
     SPECIFIER happen even if an earlier SPECIFIER is true.

 -- Scheme Syntax: test-match-all specifier ...

     The resulting specifier matches if each SPECIFIER matches.  Each
     SPECIFIER is applied, in order, so side-effects from a later
     SPECIFIER happen even if an earlier SPECIFIER is false.

   COUNT (i.e.  an integer) Convenience short-hand for: ‘(test-match-nth
1 COUNT)’.

   NAME (i.e.  a string) Convenience short-hand for ‘(test-match-name
NAME)’.

Skipping selected tests
.......................

In some cases you may want to skip a test.

 -- Scheme Syntax: test-skip specifier

     Evaluating ‘test-skip’ adds the resulting SPECIFIER to the set of
     currently active skip-specifiers.  Before each test (or
     ‘test-group’) the set of active skip-specifiers are applied to the
     active test-runner.  If any specifier matches, then the test is
     skipped.

     For convenience, if the SPECIFIER is a string that is syntactic
     sugar for ‘(test-match-name SPECIFIER)’.  For example:

          (test-skip "test-b")
          (test-assert "test-a")   ;; executed
          (test-assert "test-b")   ;; skipped

     Any skip specifiers introduced by a ‘test-skip’ are removed by a
     following non-nested ‘test-end’.

          (test-begin "group1")
          (test-skip "test-a")
          (test-assert "test-a")   ;; skipped
          (test-end "group1")      ;; Undoes the prior test-skip
          (test-assert "test-a")   ;; executed

Expected failures
.................

Sometimes you know a test case will fail, but you don’t have time to or
can’t fix it.  Maybe a certain feature only works on certain platforms.
However, you want the test-case to be there to remind you to fix it.
You want to note that such tests are expected to fail.

 -- Scheme Syntax: test-expect-fail specifier

     Matching tests (where matching is defined as in ‘test-skip’) are
     expected to fail.  This only affects test reporting, not test
     execution.  For example:

          (test-expect-fail 2)
          (test-eqv ...) ;; expected to fail
          (test-eqv ...) ;; expected to fail
          (test-eqv ...) ;; expected to pass


File: guile.info,  Node: SRFI-64 Test Runner,  Next: SRFI-64 Test Results,  Prev: SRFI-64 Conditonal Test Suites and Other Advanced Features,  Up: SRFI-64

7.5.37.5 SRFI-64 Test Runner
............................

A “test-runner” is an object that runs a test-suite, and manages the
state.  The test group path, and the sets skip and expected-fail
specifiers are part of the test-runner.  A test-runner will also
typically accumulate statistics about executed tests,

 -- Scheme Procedure: test-runner? value

     True if and only if VALUE is a test-runner object.

 -- Scheme Parameter: test-runner-current
 -- Scheme Parameter: test-runner-current runner

     Get or set the current test-runner.

 -- Scheme Procedure: test-runner-get

     Same as ‘(test-runner-current)’, but throws an exception if there
     is no current test-runner.

 -- Scheme Procedure: test-runner-simple

     Creates a new simple test-runner, that prints errors and a summary
     on the standard output port.

 -- Scheme Procedure: test-runner-null

     Creates a new test-runner, that does nothing with the test results.
     This is mainly meant for extending when writing a custom runner.

 -- Scheme Procedure: test-runner-create

     Create a new test-runner.  Equivalent to ‘((test-runner-factory))’.

 -- Scheme Parameter: test-runner-factory
 -- Scheme Parameter: test-runner-factory factory

     Get or set the current test-runner factory.  A factory is a
     zero-argument function that creates a new test-runner.  The default
     value is ‘test-runner-simple’.

Running specific tests with a specified runner
..............................................

 -- Scheme Procedure: test-apply [runner] specifier ... procedure

     Calls PROCEDURE with no arguments using the specified RUNNER as the
     current test-runner.  If RUNNER is omitted, then
     ‘(test-runner-current)’ is used.  (If there is no current runner,
     one is created as in ‘test-begin’.)  If one or more SPECIFIERs are
     listed then only tests matching the SPECIFIERs are executed.  A
     SPECIFIER has the same form as one used for ‘test-skip’.  A test is
     executed if it matches any of the SPECIFIERs in the ‘test-apply’
     _and_ does not match any active ‘test-skip’ specifiers.

 -- Scheme Syntax: test-with-runner runner decl-or-expr ...

     Executes each DECL-OR-EXPR in order in a context where the current
     test-runner is RUNNER.


File: guile.info,  Node: SRFI-64 Test Results,  Next: SRFI-64 Writing a New Test Runner,  Prev: SRFI-64 Test Runner,  Up: SRFI-64

7.5.37.6 SRFI-64 Test Results
.............................

Running a test sets various status properties in the current
test-runner.  This can be examined by a custom test-runner, or (more
rarely) in a test-suite.

Result Kind
...........

Running a test may yield one of the following status symbols:

‘'pass’
     The test passed, as expected.

‘'fail’
     The test failed (and was not expected to).

‘'xfail’
     The test failed and was expected to.

‘'xpass’
     The test passed, but was expected to fail.

‘'skip’
     The test was skipped.

 -- Scheme Procedure: test-result-kind [runner]

     Returns one of the above result codes from the most recent tests.
     Returns ‘#f’ if no tests have been run yet.  If we’ve started on a
     new test, but don’t have a result yet, then the result kind is
     ‘'xfail’ if the test is expected to fail, ‘'skip’ if the test is
     supposed to be skipped, or ‘#f’ otherwise.

 -- Scheme Procedure: test-passed? [runner]

     True if the value of ‘(test-result-kind [RUNNER])’ is one of
     ‘'pass’ or ‘'xpass’.  This is a convenient shorthand that might be
     useful in a test suite to only run certain tests if the previous
     test passed.

Test result properties
......................

A test runner also maintains a set of more detailed “result properties”
associated with the current or most recent test.  (I.e.  the properties
of the most recent test are available as long as a new test hasn’t
started.)  Each property has a name (a symbol) and a value (any value).
Some properties are standard or set by the implementation;
implementations can add more.

 -- Scheme Procedure: test-result-ref runner pname [default]

     Returns the property value associated with the PNAME property name
     (a symbol).  If there is no value associated with PNAME return
     DEFAULT, or ‘#f’ if DEFAULT isn’t specified.

 -- Scheme Syntax: test-result-set! runner pname value

     Sets the property value associated with the PNAME property name to
     VALUE.  Usually implementation code should call this function, but
     it may be useful for a custom test-runner to add extra properties.

 -- Scheme Procedure: test-result-remove runner pname

     Remove the property with the name PNAME.

 -- Scheme Procedure: test-result-clear runner

     Remove all result properties.  The implementation automatically
     calls ‘test-result-clear’ at the start of a ‘test-assert’ and
     similar procedures.

 -- Scheme Procedure: test-result-alist runner

     Returns an association list of the current result properties.  It
     is unspecified if the result shares state with the test-runner.
     The result should not be modified; on the other hand, the result
     may be implicitly modified by future ‘test-result-set!’ or
     ‘test-result-remove’ calls.  However, a ‘test-result-clear’ does
     not modify the returned alist.  Thus you can “archive” result
     objects from previous runs.

Standard result properties
..........................

The set of available result properties is implementation-specific.
However, it is suggested that the following might be provided:

‘'result-kind’
     The result kind, as defined previously.  This is the only mandatory
     result property.  ‘(test-result-kind RUNNER)’ is equivalent to:
     ‘(test-result-ref RUNNER 'result-kind)’

‘'source-file’
‘'source-line’
     If known, the location of test statements (such as ‘test-assert’)
     in test suite source code.

‘'source-form’
     The source form, if meaningful and known.

‘'expected-value’
     The expected non-error result, if meaningful and known.

‘'expected-error’
     The ERROR-TYPEspecified in a ‘test-error’, if it meaningful and
     known.

‘'actual-value’
     The actual non-error result value, if meaningful and known.

‘'actual-error’
     The error value, if an error was signalled and it is known.  The
     actual error value is implementation-defined.


File: guile.info,  Node: SRFI-64 Writing a New Test Runner,  Prev: SRFI-64 Test Results,  Up: SRFI-64

7.5.37.7 SRFI-64 Writing a New Test Runner
..........................................

This section specifies how to write a test-runner.  It can be ignored if
you just want to write test-cases.

Call-back Functions
...................

These call-back functions are “methods” (in the object-oriented sense)
of a test-runner.  A method ‘test-runner-on-EVENT’ is called by the
implementation when EVENT happens.

   To define (set) the callback function for EVENT use the following
expression.  (This is normally done when initializing a test-runner.)

   ‘(test-runner-on-EVENT! RUNNER EVENT-FUNCTION)’

   An EVENT-FUNCTION takes a test-runner argument, and possibly other
arguments, depending on the EVENT.

   To extract (get) the callback function for EVENT do this:
‘(test-runner-on-EVENT RUNNER)’

   To extract call the callback function for EVENT use the following
expression.  (This is normally done by the implementation core.)
‘((test-runner-on-EVENT RUNNER) RUNNER OTHER-ARGS ...)’.

   The following call-back hooks are available.

 -- Scheme Procedure: test-runner-on-test-begin runner
 -- Scheme Procedure: test-runner-on-test-begin! runner
          on-test-begin-function
 -- Scheme Procedure: on-test-begin-function runner

     The ON-TEST-BEGIN-FUNCTION is called at the start of an individual
     testcase, before the test expression (and expected value) are
     evaluated.

 -- Scheme Procedure: test-runner-on-test-end runner
 -- Scheme Procedure: test-runner-on-test-end! runner
          on-test-end-function
 -- Scheme Procedure: on-test-end-function runner

     The ON-TEST-END-FUNCTION is called at the end of an individual
     testcase, when the result of the test is available.

 -- Scheme Procedure: test-runner-on-group-begin runner
 -- Scheme Procedure: test-runner-on-group-begin! runner
          on-group-begin-function
 -- Scheme Procedure: on-group-begin-function runner suite-name count

     The ON-GROUP-BEGIN-FUNCTION is called by a ‘test-begin’, including
     at the start of a ‘test-group’.  The SUITE-NAME is a Scheme string,
     and COUNT is an integer or ‘#f’.

 -- Scheme Procedure: test-runner-on-group-end runner
 -- Scheme Procedure: test-runner-on-group-end! runner
          on-group-end-function
 -- Scheme Procedure: on-group-end-function runner

     The ON-GROUP-END-FUNCTION is called by a ‘test-end’, including at
     the end of a ‘test-group’.

 -- Scheme Procedure: test-runner-on-bad-count runner
 -- Scheme Procedure: test-runner-on-bad-count! runner
          on-bad-count-function
 -- Scheme Procedure: on-bad-count-function runner actual-count
          expected-count

     Called from ‘test-end’ (before the ON-GROUP-END-FUNCTION is called)
     if an EXPECTED-COUNT was specified by the matching ‘test-begin’ and
     the EXPECTED-COUNT does not match the ACTUAL-COUNT of tests
     actually executed or skipped.

 -- Scheme Procedure: test-runner-on-bad-end-name runner
 -- Scheme Procedure: test-runner-on-bad-end-name! runner
          on-bad-end-name-function
 -- Scheme Procedure: on-bad-end-name-function runner begin-name
          end-name

     Called from ‘test-end’ (before the ON-GROUP-END-FUNCTION is called)
     if a SUITE-NAME was specified, and it did not that the name in the
     matching ‘test-begin’.

 -- Scheme Procedure: test-runner-on-final runner
 -- Scheme Procedure: test-runner-on-final! runner on-final-function
 -- Scheme Procedure: on-final-function runner

     The ON-FINAL-FUNCTION takes one parameter (a test-runner) and
     typically displays a summary (count) of the tests.  The
     ON-FINAL-FUNCTION is called after called the ON-GROUP-END-FUNCTION
     correspondiong to the outermost ‘test-end’.  The default value is
     ‘test-on-final-simple’ which writes to the standard output port the
     number of tests of the various kinds.

   The default test-runner returned by ‘test-runner-simple’ uses the
following call-back functions:

 -- Scheme Procedure: test-on-test-begin-simple runner
 -- Scheme Procedure: test-on-test-end-simple runner
 -- Scheme Procedure: test-on-group-begin-simple runner suite-name count
 -- Scheme Procedure: test-on-group-end-simple runner
 -- Scheme Procedure: test-on-bad-count-simple runner actual-count
          expected-count
 -- Scheme Procedure: test-on-bad-end-name-simple runner begin-name
          end-name

     You can call those if you want to write your own test-runner.

Test-runner components
......................

The following functions are for accessing the other components of a
test-runner.  They would normally only be used to write a new
test-runner or a match-predicate.

 -- Scheme Procedure: test-runner-pass-count runner

     Returns the number of tests that passed, and were expected to pass.

 -- Scheme Procedure: test-runner-fail-count runner

     Returns the number of tests that failed, but were expected to pass.

 -- Scheme Procedure: test-runner-xpass-count runner

     Returns the number of tests that passed, but were expected to fail.

 -- Scheme Procedure: test-runner-xfail-count runner

     Returns the number of tests that failed, and were expected to pass.

 -- Scheme Procedure: test-runner-skip-count runner

     Returns the number of tests or test groups that were skipped.

 -- Scheme Procedure: test-runner-test-name runner

     Returns the name of the current test or test group, as a string.
     During execution of ‘test-begin’ this is the name of the test
     group; during the execution of an actual test, this is the name of
     the test-case.  If no name was specified, the name is the empty
     string.

 -- Scheme Procedure: test-runner-group-path runner

     A list of names of groups we’re nested in, with the outermost group
     first.

 -- Scheme Procedure: test-runner-group-stack runner

     A list of names of groups we’re nested in, with the outermost group
     last.  (This is more efficient than ‘test-runner-group-path’, since
     it doesn’t require any copying.)

 -- Scheme Procedure: test-runner-aux-value runner
 -- Scheme Procedure: test-runner-aux-value! runner on-test

     Get or set the ‘aux-value’ field of a test-runner.  This field is
     not used by this API or the ‘test-runner-simple’ test-runner, but
     may be used by custom test-runners to store extra state.

 -- Scheme Procedure: test-runner-reset runner

     Resets the state of the RUNNER to its initial state.

Example
.......

This is an example of a simple custom test-runner.  Loading this program
before running a test-suite will install it as the default test runner.

     (define (my-simple-runner filename)
       (let ((runner (test-runner-null))
     	(port (open-output-file filename))
             (num-passed 0)
             (num-failed 0))
         (test-runner-on-test-end! runner
           (lambda (runner)
             (case (test-result-kind runner)
               ((pass xpass) (set! num-passed (+ num-passed 1)))
               ((fail xfail) (set! num-failed (+ num-failed 1)))
               (else #t))))
         (test-runner-on-final! runner
            (lambda (runner)
               (format port "Passing tests: ~d.~%Failing tests: ~d.~%"
                       num-passed num-failed)
     	  (close-output-port port)))
         runner))
     (test-runner-factory
      (lambda () (my-simple-runner "/tmp/my-test.log")))


File: guile.info,  Node: SRFI-67,  Next: SRFI-69,  Prev: SRFI-64,  Up: SRFI Support

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

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


File: guile.info,  Node: SRFI-69,  Next: SRFI-71,  Prev: SRFI-67,  Up: SRFI Support

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

This is a portable wrapper around Guile’s built-in hash table and weak
table support.  *Note 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))

* Menu:

* SRFI-69 Creating hash tables::
* SRFI-69 Accessing table items::
* SRFI-69 Table properties::
* SRFI-69 Hash table algorithms::


File: guile.info,  Node: SRFI-69 Creating hash tables,  Next: SRFI-69 Accessing table items,  Up: 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.

     By 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.  *Note 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.


File: guile.info,  Node: SRFI-69 Accessing table items,  Next: SRFI-69 Table properties,  Prev: SRFI-69 Creating hash tables,  Up: SRFI-69

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


File: guile.info,  Node: SRFI-69 Table properties,  Next: SRFI-69 Hash table algorithms,  Prev: SRFI-69 Accessing table items,  Up: SRFI-69

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.


File: guile.info,  Node: SRFI-69 Hash table algorithms,  Prev: SRFI-69 Table properties,  Up: SRFI-69

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


File: guile.info,  Node: SRFI-71,  Next: SRFI-87,  Prev: SRFI-69,  Up: SRFI Support

7.5.40 SRFI-71 - Extended let-syntax for multiple values
--------------------------------------------------------

This SRFI shadows the forms for ‘let’, ‘let*’, and ‘letrec’ so that they
may accept multiple values.  For example:

     (use-modules (srfi srfi-71))

     (let* ((x y (values 1 2))
            (z (+ x y)))
       (* z 2))
     ⇒ 6

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


File: guile.info,  Node: SRFI-87,  Next: SRFI-88,  Prev: SRFI-71,  Up: SRFI Support

7.5.41 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. *Note Conditionals::.


File: guile.info,  Node: SRFI-88,  Next: SRFI-98,  Prev: SRFI-87,  Up: SRFI Support

7.5.42 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 (*note
Keywords::).  SRFI-88 keywords can be entered using the “postfix keyword
syntax”, which consists of an identifier followed by ‘:’ (*note
‘postfix’ keyword syntax: Scheme Read.).  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 (*note ‘keyword?’: Keyword
     Procedures.).

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


File: guile.info,  Node: SRFI-98,  Next: SRFI-105,  Prev: SRFI-88,  Up: SRFI Support

7.5.43 SRFI-98 Accessing environment variables.
-----------------------------------------------

This is a portable wrapper around Guile’s built-in support for
interacting with the current environment, *Note 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.


File: guile.info,  Node: SRFI-105,  Next: SRFI-111,  Prev: SRFI-98,  Up: SRFI Support

7.5.44 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, *Note Scheme Read::.


File: guile.info,  Node: SRFI-111,  Next: SRFI-119,  Prev: SRFI-105,  Up: SRFI Support

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


File: guile.info,  Node: SRFI-119,  Next: SRFI-171,  Prev: SRFI-111,  Up: SRFI Support

7.5.46 SRFI-119 Wisp: simpler indentation-sensitive Scheme.
-----------------------------------------------------------

The languages shipped in Guile include SRFI-119, also referred to as
“Wisp” (for “Whitespace to Lisp”), an encoding of Scheme that allows
replacing parentheses with equivalent indentation and inline colons.
See the specification of SRFI-119
(http://srfi.schemers.org/srfi-119/srfi-119.html).  Some examples:

     display "Hello World!"         ⇒  (display "Hello World!")

     define : factorial n           ⇒  (define (factorial n)
         if : zero? n               ⇒      (if (zero? n)
            . 1                     ⇒          1
            * n : factorial {n - 1} ⇒    (* n (factorial {n - 1}))))

   To execute a file with Wisp code, select the language and filename
extension ‘.w’ vie ‘guile --language=wisp -x .w’.

   In files using Wisp, *Note SRFI-105:: (Curly Infix) is always
activated.


File: guile.info,  Node: SRFI-171,  Next: SRFI-197,  Prev: SRFI-119,  Up: SRFI Support

7.5.47 Transducers
------------------

Some of the most common operations used in the Scheme language are those
transforming lists: map, filter, take and so on.  They work well, are
well understood, and are used daily by most Scheme programmers.  They
are however not general because they only work on lists, and they do not
compose very well since combining N of them builds ‘(- N 1)’
intermediate lists.

   Transducers are oblivious to what kind of process they are used in,
and are composable without building intermediate collections.  This
means we can create a transducer that squares all odd numbers:

     (compose (tfilter odd?) (tmap (lambda (x) (* x x))))

   and reuse it with lists, vectors, or in just about any context where
data flows in one direction.  We could use it as a processing step for
asynchronous channels, with an event framework as a pre-processing step,
or even in lazy contexts where you pass a lazy collection and a
transducer to a function and get a new lazy collection back.

   The traditional Scheme approach of having collection-specific
procedures is not changed.  We instead specify a general form of
transformations that complement these procedures.  The benefits are
obvious: a clear, well-understood way of describing common
transformations in a way that is faster than just chaining the
collection-specific counterparts.  For guile in particular this means a
lot better GC performance.

   Notice however that ‘(compose ...)’ composes transducers
left-to-right, due to how transducers are initiated.

* Menu:

* SRFI-171 General Discussion::       General information about transducers
* SRFI-171 Applying Transducers::     Documentation of collection-specific forms
* SRFI-171 Reducers::                 Reducers specified by the SRFI
* SRFI-171 Transducers::              Transducers specified by the SRFI
* SRFI-171 Helpers::                  Utilities for writing your own transducers


File: guile.info,  Node: SRFI-171 General Discussion,  Next: SRFI-171 Applying Transducers,  Up: SRFI-171

7.5.47.1 SRFI-171 General Discussion
....................................

The concept of reducers
-----------------------

The central part of transducers are 3-arity reducing procedures.

   • no arguments: Produces the identity of the reducer.

   • (result-so-far): completion.  Returns ‘result-so-far’ either with
     or without transforming it first.

   • (result-so-far input) combines ‘result-so-far’ and ‘input’ to
     produce a new ‘result-so-far’.

   In the case of a summing ‘+’ reducer, the reducer would produce, in
arity order: ‘0’, ‘result-so-far’, ‘(+ result-so-far input)’.  This
happens to be exactly what the regular ‘+’ does.

The concept of transducers
--------------------------

A transducer is a one-arity procedure that takes a reducer and produces
a reducing function that behaves as follows:

   • no arguments: calls reducer with no arguments (producing its
     identity)

   • (result-so-far): Maybe transform the result-so-far and call reducer
     with it.

   • (result-so-far input) Maybe do something to input and maybe call
     the reducer with result-so-far and the maybe-transformed input.

   A simple example is as following:

     (list-transduce (tfilter odd?) + '(1 2 3 4 5))

   This first returns a transducer filtering all odd elements, then it
runs ‘+’ without arguments to retrieve its identity.  It then starts the
transduction by passing ‘+’ to the transducer returned by ‘(tfilter
odd?)’ which returns a reducing function.  It works not unlike reduce
from SRFI 1, but also checks whether one of the intermediate transducers
returns a "reduced" value (implemented as a SRFI 9 record), which means
the reduction finished early.

   Because transducers compose and the final reduction is only executed
in the last step, composed transducers will not build any intermediate
result or collections.  Although the normal way of thinking about
application of composed functions is right to left, due to how the
transduction is built it is applied left to right.  ‘(compose (tfilter
odd?) (tmap sqrt))’ will create a transducer that first filters out any
odd values and then computes the square root of the rest.

State
-----

Even though transducers appear to be somewhat of a generalisation of
‘map’ and friends, this is not really true.  Since transducers don’t
know in which context they are being used, some transducers must keep
state where their collection-specific counterparts do not.  The
transducers that keep state do so using hidden mutable state, and as
such all the caveats of mutation, parallelism, and multi-shot
continuations apply.  Each transducer keeping state is clearly described
as doing so in the documentation.

Naming
------

Reducers exported from the transducers module are named as in their
SRFI-1 counterpart, but prepended with an r.  Transducers also follow
that naming, but are prepended with a t.


File: guile.info,  Node: SRFI-171 Applying Transducers,  Next: SRFI-171 Reducers,  Prev: SRFI-171 General Discussion,  Up: SRFI-171

7.5.47.2 Applying Transducers
.............................

 -- Scheme Procedure: list-transduce xform f lst
 -- Scheme Procedure: list-transduce xform f identity lst
     Initialize the transducer XFORM by passing the reducer F to it.  If
     no identity is provided, F runs without arguments to return the
     reducer identity.  It then reduces over LST using the identity as
     the seed.

     If one of the transducers finishes early (such as ‘ttake’ or
     ‘tdrop’), it communicates this by returning a reduced value, which
     in the guile implementation is just a value wrapped in a SRFI 9
     record type named “reduced”.  If such a value is returned by the
     transducer, ‘list-transduce’ must stop execution and return an
     unreduced value immediately.

 -- Scheme Procedure: vector-transduce xform f vec
 -- Scheme Procedure: vector-transduce xform f identity vec
 -- Scheme Procedure: string-transduce xform f str
 -- Scheme Procedure: string-transduce xform f identity str
 -- Scheme Procedure: bytevector-u8-transduce xform f bv
 -- Scheme Procedure: bytevector-u8-transduce xform f identity bv
 -- Scheme Procedure: generator-transduce xform f gen
 -- Scheme Procedure: generator-transduce xform f identity gen

     Same as ‘list-transduce’, but for vectors, strings, u8-bytevectors
     and SRFI-158-styled generators respectively.

 -- Scheme Procedure: port-transduce xform f reader
 -- Scheme Procedure: port-transduce xform f reader port
 -- Scheme Procedure: port-transduce xform f identity reader port

     Same as ‘list-transduce’ but for ports.  Called without a port, it
     reduces over the results of applying READER until the EOF-object is
     returned, presumably to read from ‘current-input-port’.  With a
     port READER is applied to PORT instead of without any arguments.
     If IDENTITY is provided, that is used as the initial identity in
     the reduction.


File: guile.info,  Node: SRFI-171 Reducers,  Next: SRFI-171 Transducers,  Prev: SRFI-171 Applying Transducers,  Up: SRFI-171

7.5.47.3 Reducers
.................

 -- Scheme Procedure: rcons
     a simple consing reducer.  When called without values, it returns
     its identity, ‘'()’.  With one value, which will be a list, it
     reverses the list (using ‘reverse!’).  When called with two values,
     it conses the second value to the first.

          (list-transduce (tmap (lambda (x) (+ x 1)) rcons (list 0 1 2 3))
          ⇒ (1 2 3 4)

 -- Scheme Procedure: reverse-rcons
     same as rcons, but leaves the values in their reversed order.
          (list-transduce (tmap (lambda (x) (+ x 1))) reverse-rcons (list 0 1 2 3))
          ⇒ (4 3 2 1)

 -- Scheme Procedure: rany pred?
     The reducer version of any.  Returns ‘(reduced (pred? value))’ if
     any ‘(pred? value)’ returns non-#f.  The identity is #f.

          (list-transduce (tmap (lambda (x) (+ x 1))) (rany odd?) (list 1 3 5))
          ⇒ #f

          (list-transduce (tmap (lambda (x) (+ x 1))) (rany odd?) (list 1 3 4 5))
          ⇒ #t

 -- Scheme Procedure: revery pred?
     The reducer version of every.  Stops the transduction and returns
     ‘(reduced #f)’ if any ‘(pred? value)’ returns #f.  If every ‘(pred?
     value)’ returns true, it returns the result of the last invocation
     of ‘(pred? value)’.  The identity is #t.

          (list-transduce
            (tmap (lambda (x) (+ x 1)))
            (revery (lambda (v) (if (odd? v) v #f)))
            (list 2 4 6))
            ⇒ 7

          (list-transduce (tmap (lambda (x) (+ x 1)) (revery odd?) (list 2 4 5 6))
          ⇒ #f

 -- Scheme Procedure: rcount
     A simple counting reducer.  Counts the values that pass through the
     transduction.
          (list-transduce (tfilter odd?) rcount (list 1 2 3 4)) ⇒ 2.


File: guile.info,  Node: SRFI-171 Transducers,  Next: SRFI-171 Helpers,  Prev: SRFI-171 Reducers,  Up: SRFI-171

7.5.47.4 Transducers
....................

 -- Scheme Procedure: tmap proc
     Returns a transducer that applies PROC to all values.  Stateless.

 -- Scheme Procedure: tfilter pred?
     Returns a transducer that removes values for which PRED? returns
     #f.

     Stateless.

 -- Scheme Procedure: tremove pred?
     Returns a transducer that removes values for which PRED? returns
     non-#f.

     Stateless

 -- Scheme Procedure: tfilter-map proc
     The same as ‘(compose (tmap proc) (tfilter values))’.  Stateless.

 -- Scheme Procedure: treplace mapping
     The argument MAPPING is an association list (using ‘equal?’ to
     compare keys), a hash-table, a one-argument procedure taking one
     argument and either producing that same argument or a replacement
     value.

     Returns a transducer which checks for the presence of any value
     passed through it in mapping.  If a mapping is found, the value of
     that mapping is returned, otherwise it just returns the original
     value.

     Does not keep internal state, but modifying the mapping while it’s
     in use by treplace is an error.

 -- Scheme Procedure: tdrop n
     Returns a transducer that discards the first N values.

     Stateful.

 -- Scheme Procedure: ttake n
     Returns a transducer that discards all values and stops the
     transduction after the first N values have been let through.  Any
     subsequent values are ignored.

     Stateful.

 -- Scheme Procedure: tdrop-while pred?
     Returns a transducer that discards the first values for which PRED?
     returns true.

     Stateful.

 -- Scheme Procedure: ttake-while pred?
 -- Scheme Procedure: ttake-while pred? retf
     Returns a transducer that stops the transduction after PRED? has
     returned #f.  Any subsequent values are ignored and the last
     successful value is returned.  RETF is a function that gets called
     whenever PRED? returns false.  The arguments passed are the result
     so far and the input for which pred?  returns ‘#f’.  The default
     function is ‘(lambda (result input) result)’.

     Stateful.

 -- Scheme Procedure: tconcatenate
     tconcatenate _is_ a transducer that concatenates the content of
     each value (that must be a list) into the reduction.
          (list-transduce tconcatenate rcons '((1 2) (3 4 5) (6 (7 8) 9)))
          ⇒ (1 2 3 4 5 6 (7 8) 9)

 -- Scheme Procedure: tappend-map proc
     The same as ‘(compose (tmap proc) tconcatenate)’.

 -- Scheme Procedure: tflatten
     tflatten _is_ a transducer that flattens an input consisting of
     lists.

          (list-transduce tflatten rcons '((1 2) 3 (4 (5 6) 7 8) 9)
          ⇒ (1 2 3 4 5 6 7 8 9)

 -- Scheme Procedure: tdelete-neighbor-duplicates
 -- Scheme Procedure: tdelete-neighbor-duplicates equality-predicate
     Returns a transducer that removes any directly following duplicate
     elements.  The default EQUALITY-PREDICATE is ‘equal?’.

     Stateful.

 -- Scheme Procedure: tdelete-duplicates
 -- Scheme Procedure: tdelete-duplicates equality-predicate
     Returns a transducer that removes any subsequent duplicate elements
     compared using EQUALITY-PREDICATE.  The default EQUALITY-PREDICATE
     is ‘equal?’.

     Stateful.

 -- Scheme Procedure: tsegment n
     Returns a transducer that groups inputs into lists of N elements.
     When the transduction stops, it flushes any remaining collection,
     even if it contains fewer than N elements.

     Stateful.

 -- Scheme Procedure: tpartition pred?
     Returns a transducer that groups inputs in lists by whenever
     ‘(pred? input)’ changes value.

     Stateful.

 -- Scheme Procedure: tadd-between value
     Returns a transducer which interposes VALUE between each value and
     the next.  This does not compose gracefully with transducers like
     ‘ttake’, as you might end up ending the transduction on ‘value’.

     Stateful.

 -- Scheme Procedure: tenumerate
 -- Scheme Procedure: tenumerate start
     Returns a transducer that indexes values passed through it,
     starting at START, which defaults to 0.  The indexing is done
     through cons pairs like ‘(index . input)’.

          (list-transduce (tenumerate 1) rcons (list 'first 'second 'third))
          ⇒ ((1 . first) (2 . second) (3 . third))

     Stateful.

 -- Scheme Procedure: tlog
 -- Scheme Procedure: tlog logger
     Returns a transducer that can be used to log or print values and
     results.  The result of the LOGGER procedure is discarded.  The
     default LOGGER is ‘(lambda (result input) (write input)
     (newline))’.

     Stateless.

Guile-specific transducers
--------------------------

These transducers are available in the ‘(srfi srfi-171 gnu)’ library,
and are provided outside the standard described by the SRFI-171
document.

 -- Scheme Procedure: tbatch reducer
 -- Scheme Procedure: tbatch transducer reducer
     A batching transducer that accumulates results using REDUCER or
     ‘((transducer) reducer)’ until it returns a reduced value.  This
     can be used to generalize something like ‘tsegment’:

          ;; This behaves exactly like (tsegment 4).
          (list-transduce (tbatch (ttake 4) rcons) rcons (iota 10))
          ⇒ ((0 1 2 3) (4 5 6 7) (8 9))

 -- Scheme Procedure: tfold reducer
 -- Scheme Procedure: tfold reducer seed

     A folding transducer that yields the result of ‘(reducer seed
     value)’, saving its result between iterations.

          (list-transduce (tfold +) rcons (iota 10))
          ⇒ (0 1 3 6 10 15 21 28 36 45)


File: guile.info,  Node: SRFI-171 Helpers,  Prev: SRFI-171 Transducers,  Up: SRFI-171

7.5.47.5 Helper functions for writing transducers
.................................................

These functions are in the ‘(srfi srfi-171 meta)’ module and are only
usable when you want to write your own transducers.

 -- Scheme Procedure: reduced value
     Wraps a value in a ‘<reduced>’ container, signaling that the
     reduction should stop.

 -- Scheme Procedure: reduced? value
     Returns #t if value is a ‘<reduced>’ record.

 -- Scheme Procedure: unreduce reduced-container
     Returns the value in reduced-container.

 -- Scheme Procedure: ensure-reduced value
     Wraps value in a ‘<reduced>’ container if it is not already
     reduced.

 -- Scheme Procedure: preserving-reduced reducer
     Wraps ‘reducer’ in another reducer that encapsulates any returned
     reduced value in another reduced container.  This is useful in
     places where you re-use a reducer with [collection]-reduce.  If the
     reducer returns a reduced value, [collection]-reduce unwraps it.
     Unless handled, this leads to the reduction continuing.

 -- Scheme Procedure: list-reduce f identity lst
     The reducing function used internally by ‘list-transduce’.  F is a
     reducer as returned by a transducer.  IDENTITY is the identity
     (sometimes called "seed") of the reduction.  LST is a list.  If F
     returns a reduced value, the reduction stops immediately and the
     unreduced value is returned.

 -- Scheme Procedure: vector-reduce f identity vec
     The vector version of list-reduce.

 -- Scheme Procedure: string-reduce f identity str
     The string version of list-reduce.

 -- Scheme Procedure: bytevector-u8-reduce f identity bv
     The bytevector-u8 version of list-reduce.

 -- Scheme Procedure: port-reduce f identity reader port
     The port version of list-reduce.  It reduces over port using reader
     until reader returns the EOF object.

 -- Scheme Procedure: generator-reduce f identity gen
     The generator version of list-reduce.  It reduces over ‘gen’ until
     it returns the EOF object


File: guile.info,  Node: SRFI-197,  Next: SRFI-207,  Prev: SRFI-171,  Up: SRFI Support

7.5.48 SRFI-197: Pipeline Operators
-----------------------------------

SRFI-197 (http://srfi.schemers.org/srfi-197/srfi-197.html) provides
functional pipeline (threading) operators like Clojure’s ‘->’ or OCaml’s
‘|>’.  Pipelines are a simple, terse, and readable way to write
deeply-nested expressions.  This SRFI defines a family of chain and nest
pipeline operators, which can rewrite nested expressions like ‘(a b (c d
(e f g)))’ as a sequence of operations: ‘(chain g (e f _) (c d _) (a b
_))’.

   Note that Like ‘let*’, ‘chain’ guarantees evaluation order.  In fact,
‘(chain a (b _) (c _))’ expands to something like ‘(let* ((x (b a)) (x
(c x))) x)’, not ‘(c (b a))’, and so ‘chain’ is not suitable for
pipelines containing syntax like ‘if’ or ‘let’.

   For pipelines containing complex syntax, the ‘nest’ and
‘nest-reverse’ operators look like ‘chain’ but are guaranteed to expand
to nested forms, not ‘let*’ forms.  ‘nest’ nests in the opposite
direction of ‘chain’, so ‘(nest (a _) (b _) c)’ expands to ‘(a (b c))’.

 -- Scheme Syntax: chain initial-value [placeholder [ellipsis]] step ...
     Converts earch PART into a sequence of small integers and returns a
     bytevector of the corresponding bytes as follows:

     INITIAL-VALUE is an expression.

     PLACEHOLDER and ELLIPSIS are literal symbols; these are the
     placeholder symbol and ellipsis symbol.  If PLACEHOLDER or ELLIPSIS
     are not present, they default to ‘_’ and ‘...’, respectively.

     The syntax of STEP is (DATUM ...), where each DATUM is either the
     placeholder symbol, the ellipsis symbol, or an expression.  A STEP
     must contain at least one DATUM.  The ellipsis symbol is only
     allowed at the end of a STEP, and it must immediately follow a
     placeholder symbol.

     Semantics: ‘chain’ evaluates each STEP in order from left to right,
     passing the result of each step to the next.

     Each STEP is evaluated as an application, and the return value(s)
     of that application are passed to the next step as its pipeline
     values.  INITIAL-VALUE is the pipeline value of the first step.
     The return value(s) of ‘chain’ are the return value(s) of the last
     step.

     The placeholder symbols in each STEP are replaced with that step’s
     pipeline values, in the order they appear.  It is an error if the
     number of placeholders for a step does not equal the number of
     pipeline values for that step, unless the step contains no
     placeholders, in which case it will ignore its pipeline values.

          (chain x (a b _))
            ⇒ (a b x)
          (chain (a b) (c _ d) (e f _))
            ⇒ (let* ((x (a b)) (x (c x d))) (e f x))
          (chain (a) (b _ _) (c _))
            ⇒ (let*-values (((x1 x2) (a)) ((x) (b x1 x2))) (c x))

     If a STEP ends with a placeholder symbol followed by an ellipsis
     symbol, that placeholder sequence is replaced with all remaining
     pipeline values that do not have a matching placeholder.

          (chain (a) (b _ c _ ...) (d _))
            ⇒ (let*-values (((x1 . x2) (a)) ((x) (apply b x1 c x2))) (d x))

     ‘chain’ and all other SRFI 197 macros support custom placeholder
     symbols, which can help to preserve hygiene when used in the body
     of a syntax definition that may insert a ‘_’ or ‘....’

          (chain (a b) <> (c <> d) (e f <>))
            ⇒ (let* ((x (a b)) (x (c x d))) (e f x))
          (chain (a) - --- (b - c - ---) (d -))
            ⇒ (let*-values (((x1 . x2) (a)) ((x) (apply b x1 c x2))) (d x))

 -- Scheme Syntax: chain-and initial-value [placeholder] step ...

     INITIAL-VALUE is an expression.  PLACEHOLDER is a literal symbol;
     this is the placeholder symbol.  If PLACEHOLDER is not given, the
     placeholder symbol is ‘_’.  The syntax of STEP is (DATUM ...
     [PLACEHOLDER DATUM ...]).

     Semantics: A variant of ‘chain’ that short-circuits and returns
     ‘#f’ if any step returns ‘#f’.  ‘chain-and’ is to ‘chain’ as SRFI 2
     ‘and-let*’ is to ‘let*’.

     Each STEP is evaluated as an application.  If the step evaluates to
     ‘#f’, the remaining steps are not evaluated, and ‘chain-and’
     returns #f.  Otherwise, the return value of the step is passed to
     the next step as its pipeline value.  INITIAL-VALUE is the pipeline
     value of the first step.  If no step evaluates to ‘#f’, the return
     value of ‘chain-and’ is the return value of the last step.

     The PLACEHOLDER placeholder in each STEP is replaced with that
     step’s pipeline value.  If a STEP does not contain PLACEHOLDER, it
     will ignore its pipeline value, but ‘chain-and’ will still check
     whether that pipeline value is ‘#f’.

     Because ‘chain-and’ checks the return value of each step, it does
     not support steps with multiple return values.  It is an error if a
     step returns more than one value.

 -- Scheme Syntax: chain-when initial-value [placeholder] ([guard] step)
          ...

     INITIAL-VALUE and GUARD are expressions.  PLACEHOLDER is a literal
     symbol; this is the placeholder symbol.  If PLACEHOLDER is not
     present, the placeholder symbol is ‘_’.  The syntax of STEP is
     (DATUM ... [PLACEHOLDER DATUM ...]).

     Semantics: A variant of ‘chain’ in which each step has a guard
     expression and will be skipped if the guard expression evaluates to
     #f.

          (define (describe-number n)
            (chain-when '()
              ((odd? n) (cons "odd" _))
              ((even? n) (cons "even" _))
              ((zero? n) (cons "zero" _))
              ((positive? n) (cons "positive" _))))

          (describe-number 3) ; => '("positive" "odd")
          (describe-number 4) ; => '("positive" "even")

     Each STEP is evaluated as an application.  The return value of the
     step is passed to the next step as its pipeline value.
     INITIAL-VALUE is the pipeline value of the first step.

     The PLACEHOLDER placeholder in each STEP is replaced with that
     step’s pipeline value.  If a STEP does not contain PLACEHOLDER, it
     will ignore its pipeline value.

     If a step’s GUARD is present and evaluates to ‘#f’, that step will
     be skipped, and its pipeline value will be reused as the pipeline
     value of the next step.  The return value of ‘chain-when’ is the
     return value of the last non-skipped step, or INITIAL-VALUE if all
     steps are skipped.

     Because ‘chain-when’ may skip steps, it does not support steps with
     multiple return values.  It is an error if a step returns more than
     one value.

 -- Scheme Syntax: chain-lambda [placeholder [ellipsis]] step ...

     PLACEHOLDER and ELLIPSIS are literal symbols; these are the
     placeholder symbol and ellipsis symbol.  If PLACEHOLDER or ELLIPSIS
     are not present, they default to ‘_’ and ‘...’, respectively.

     The syntax of STEP is (DATUM ...), where each DATUM is either the
     placeholder symbol, the ellipsis symbol, or an expression.  A STEP
     must contain at least one DATUM.  The ellipsis symbol is only
     allowed at the end of a STEP, and it must immediately follow a
     placeholder symbol.

     Semantics: Creates a procedure from a sequence of ‘chain’ steps.
     When called, a ‘chain-lambda’ procedure evaluates each STEP in
     order from left to right, passing the result of each step to the
     next.

          (chain-lambda (a _) (b _))
            ⇒ (lambda (x) (let* ((x (a x))) (b x)))
          (chain-lambda (a _ _) (b c _))
            ⇒ (lambda (x1 x2) (let* ((x (a x1 x2))) (b c x)))

     Each STEP is evaluated as an application, and the return value(s)
     of that application are passed to the next step as its pipeline
     values.  The procedure’s arguments are the pipeline values of the
     first step.  The return value(s) of the procedure are the return
     value(s) of the last step.

     The placeholder symbols in each STEP are replaced with that step’s
     pipeline values, in the order they appear.  It is an error if the
     number of placeholders for a step does not equal the number of
     pipeline values for that step, unless the step contains no
     placeholders, in which case it will ignore its pipeline values.

     If a STEP ends with a placeholder symbol followed by an ellipsis
     symbol, that placeholder sequence is replaced with all remaining
     pipeline values that do not have a matching placeholder.

     The number of placeholders in the first STEP determines the arity
     of the procedure.  If the first step ends with an ellipsis symbol,
     the procedure is variadic.

 -- Scheme Syntax: nest [placeholder] <step> ... initial-value

     PLACEHOLDER is a literal symbol; this is the placeholder symbol.
     If PLACEHOLDER is not present, the placeholder symbol is ‘_’.  The
     syntax of STEP is (DATUM ... PLACEHOLDER DATUM ...).  INITIAL-VALUE
     is an expression.

     Semantics: ‘nest’ is similar to ‘chain’, but sequences its steps in
     the opposite order.  Unlike ‘chain’, ‘nest’ literally nests
     expressions; as a result, it does not provide the same strict
     evaluation order guarantees as ‘chain’.

          (nest (a b _) (c d _) e) ; => (a b (c d e))

     A ‘nest’ expression is evaluated by lexically replacing the
     PLACEHOLDER in the last STEP with INITIAL-VALUE, then replacing the
     PLACEHOLDER in the next-to-last STEP with that replacement, and so
     on until the PLACEHOLDER in the first STEP has been replaced.  It
     is an error if the resulting final replacement is not an
     expression, which is then evaluated and its values are returned.

     Because it produces an actual nested form, ‘nest’ can build
     expressions that ‘chain’ cannot.  For example, ‘nest’ can build a
     quoted data structure:

          (nest '_ (1 2 _) (3 _ 5) (_) 4) ; => '(1 2 (3 (4) 5))

     ‘nest’ can also safely include special forms like if, let, lambda,
     or parameterize in a pipeline.

     A custom placeholder can be used to safely nest ‘nest’ expressions.

          (nest (nest _2 '_2 (1 2 3 _2) _ 6)
                (_ 5 _2)
                4)
            ⇒ '(1 2 3 (4 5 6))

 -- Scheme Syntax: nest-reverse initial-value [placeholder] step ...

     Syntax: INITIAL-VALUE is an expression.  PLACEHOLDER is a literal
     symbol; this is the placeholder symbol.  If PLACEHOLDER is not
     present, the placeholder symbol is ‘_’.  The syntax of STEP is
     (DATUM ... PLACEHOLDER DATUM ...).

     Semantics: ‘nest-reverse’ is variant of ‘nest’ that nests in
     reverse order, which is the same order as ‘chain’.

          (nest-reverse e (c d _) (a b _)) ; => (a b (c d e))

     A ‘nest-reverse’ expression is evaluated by lexically replacing the
     PLACEHOLDER in the first STEP with INITIAL-VALUE, then replacing
     the PLACEHOLDER in the second STEP with that replacement, and so on
     until the PLACEHOLDER in the last STEP has been replaced.  It is an
     error if the resulting final replacement is not an expression,
     which is then evaluated and its values are returned.

7.5.48.1 Acknowledgements
.........................

Thanks to the participants in the SRFI 197 mailing list who helped Adam
Nelson refine this SRFI, including Marc Nieper-Wißkirchen, Linus
Björnstam, Shiro Kawai, Lassi Kortela, and John Cowan.

   Marc provided a paragraph that has been included (with only minor
changes) in the Semantics section of the nest and nest-reverse macros.

   Thanks to Rich Hickey for Clojure (https://clojure.org) and the
original implementation of Clojure threading macros, and to Paulus
Esterhazy for the (EPL licensed) threading macros documentation page,
which was a source of inspiration and some of the examples in this
document.


File: guile.info,  Node: SRFI-207,  Next: SRFI-244,  Prev: SRFI-197,  Up: SRFI Support

7.5.49 SRFI-207 String-notated bytevectors
------------------------------------------

SRFI-207 (http://srfi.schemers.org/srfi-207/srfi-207.html) provides a
more human-friendly representation for binary-data via an ASCII text
notation for *note Bytevectors::.  It also provides bytestring-oriented
procedures for constructing bytevectors from sequences of integers,
characters, strings, and other bytevectors, and procedures for
manipulating bytevectors as if they were strings.

   Binary file formats are usually not self-describing, and if they are,
the descriptive portion is itself binary, which makes it hard for human
beings to interpret.  To assist with this problem, it is common to have
a human-readable section at the beginning of the file, or in some cases
at the beginning of each distinct section of the file.  For historical
reasons and to avoid text encoding complications, it is usual for this
human-readable section to be expressed as ASCII text.

   For example, ZIP files begin with the hex bytes ‘50 4B’ which are the
ASCII encoding for the characters "PK", the initials of Phil Katz, the
inventor of ZIP format.  As another example, the GIF image format begins
with ‘47 49 46 38 39 61’, the ASCII encoding for "GIF89a", where "89a"
is the format version.  A third example is the PNG image format, where
the file header begins ‘89 50 4E 47’.  The first byte is intentionally
non-ASCII, but the next three are "PNG". Furthermore, a PNG file is
divided into chunks, each of which contains a 4-byte "chunk type" code.
The letters in the chunk type are mnemonics for its purpose, such as
"PLTE" for a palette, "bKGD" for a default background color, and "iTXt"
for descriptive text in UTF-8.

   When bytevectors contain string data of this kind, it is much more
tractable for human programmers to deal with ‘#u8"\x89;PNG\r\n\x1A;\n"’
rather than ‘#u8(0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A)’.

   In addition, this SRFI provides bytevectors with additional
procedures that closely resemble those provided for strings.  For
example, bytevectors can be padded or trimmed, compared case-sensitively
or case-insensitively, searched, joined, and split.

   Most of the procedures of this SRFI begin with ‘bytestring-’ in order
to distinguish them from other bytevector procedures.  This does not
mean that they accept or return a separate bytestring type: bytestrings
and bytevectors are exactly the same type.

* Menu:

* SRFI-207 External Notation::
* SRFI-207 Contructors::
* SRFI-207 Conversion::
* SRFI-207 Selection::
* SRFI-207 Replacement::
* SRFI-207 Comparison::
* SRFI-207 Searching::
* SRFI-207 Joining And Splitting::
* SRFI-207 I/O::
* SRFI-207 Exceptions::
* SRFI-207 Acknowledgements::


File: guile.info,  Node: SRFI-207 External Notation,  Next: SRFI-207 Contructors,  Up: SRFI-207

7.5.49.1 External Notation
..........................

The basic form of a string-notated bytevector is ‘#u8"CONTENT"’.  The
Scheme reader will read them if bytestrings are enabled via
‘(read-enable 'bytestrings)’, and the Scheme writer will write them if
they are enabled via ‘(print-enable 'bytestrings)’.

   To avoid character encoding issues within string-notated bytevectors,
only printable ASCII characters (that is, Unicode codepoints in the
range from U+0020 to U+007E inclusive) are allowed to be used within the
CONTENT of a string-notated bytevector.  All other characters must be
expressed through mnemonic or inline hex escapes, and ‘"’ and ‘\’ must
also be escaped as in normal Scheme strings.

   Within the CONTENT of a string-notated bytevector:

   • ‘\a’ ⇒ 7
   • ‘\b’ ⇒ 8
   • ‘\t’ ⇒ 9
   • ‘\n’ ⇒ 10
   • ‘\r’ ⇒ 13
   • ‘\"’ ⇒ 34
   • ‘\\’ ⇒ 92
   • ‘\|’ ⇒ 124
   • the sequence ‘\x’ followed by zero or more ‘0’ characters, followed
     by one or two hexadecimal digits, followed by ‘;’ represents the
     integer specified by the hexadecimal digits;
   • the sequence ‘\’ followed by zero or more intraline whitespace
     characters, followed by a newline, followed by zero or more further
     intraline whitespace characters, is ignored and corresponds to no
     entry in the resulting bytevector;
   • any other printable ASCII character represents the character number
     of that character in the ASCII/Unicode code chart; and
   • it is an error to use any other character or sequence beginning
     with ‘\’ within a string-notated bytevector.

   Note: The ‘\|’ sequence is provided so that string parsing, symbol
parsing, and string-notated bytevector parsing can all use the same
sequences.  However, we give a complete definition of the valid lexical
syntax in this SRFI rather than inheriting the native syntax of strings,
so that it is clear that ‘#u8"&iota;"’ and ‘#u8"\xE000;"’ are invalid.

   When the Scheme reader encounters a string-notated bytevector, it
produces a datum as if that bytevector had been written out in full.
That is, ‘#u8"A"’ is exactly equivalent to ‘#u8(65)’.


File: guile.info,  Node: SRFI-207 Contructors,  Next: SRFI-207 Conversion,  Prev: SRFI-207 External Notation,  Up: SRFI-207

7.5.49.2 Constructors
.....................

 -- Scheme Procedure: bytestring part ...
     Converts earch PART into a sequence of small integers and returns a
     bytevector of the corresponding bytes as follows:
        • If PART is an exact integer in the range 0-255 inclusive, it
          is added to the result.
        • If PART is an ASCII character (that is, its codepoint is in
          the range 0-127 inclusive), it is converted to its codepoint
          and added to the result.
        • If PART is a bytevector, its elements are added to the result.
        • If PART is a string of ASCII characters, it is converted to a
          sequence of codepoints which are added to the result.

     Otherwise, an error satisfying ‘bytestring-error?’ is signaled, for
     example:

          (bytestring "lo" #\r #x65 #u8(#x6d)) ⇒ #u8"lorem"

          (bytestring "η" #\space #u8(#x65 #x71 #x75 #x69 #x76))
          ⇒ raised &bytestring-error

 -- Scheme Procedure: make-bytestring parts
     If the PARTS are suitable arguments for ‘bytestring’, returns the
     bytevector that would result from applying ‘bytestring’ to them.
     Otherwise, an error satisfying ‘bytestring-error?’ is raised.

 -- Scheme Procedure: make-bytestring! bytevector at parts
     If the PARTS are suitable arguments for ‘bytestring’, writes the
     bytes of the bytevector that would be the result of calling
     ‘make-bytestring’ into BYTEVECTOR starting at index AT.  For
     example:

          (define bv (make-bytevector 10 #x20))
          (make-bytestring! bv 2 '(#\s #\c "he" #u8(#x6d #x65))) bv)
          ⇒ #u8" scheme "


File: guile.info,  Node: SRFI-207 Conversion,  Next: SRFI-207 Selection,  Prev: SRFI-207 Contructors,  Up: SRFI-207

7.5.49.3 Conversion
...................

 -- Scheme Procedure: bytevector->hex-string bytevector
 -- Scheme Procedure: hex-string->bytevecto string
     Converts between a bytevector and a string containing pairs of
     hexadecimal digits.  If STRING is not pairs of hexadecimal digits,
     an error satisfying ‘bytestring-error?’ is raised

          (bytevector->hex-string #u8"Ford") ⇒ "467f7264"
          (hex-string->bytevector "5a6170686f64") ⇒ #u8"Zaphod")

 -- Scheme Procedure: bytevector->base64 bytevector [digits]
 -- Scheme Procedure: base64->bytevecto string [digits]
     Converts between a bytevector and its base-64 encoding as a string.
     The 64 digits are represented by the characters 0-9, A-Z, a-z, and
     the symbols + and /.  However, there are different variants of
     base-64 encoding which use different representations of the 62nd
     and 63rd digit.  If the optional argument DIGITS (a two-character
     string) is provided, those two characters will be used as the 62nd
     and 63rd digit instead.  Details can be found in RFC 4648
     (https://tools.ietf.org/html/rfc4648).

     If STRING is not in base-64 format, an error satisfying
     ‘bytestring-error?’ is raised.  However, characters that satisfy
     ‘char-whitespace?’ are silently ignored.

          (bytevector->base64 #u8(1 2 3 4 5 6)) ⇒ ⇒ "AQIDBAUG"
          (bytevector->base64 #u8"Arthur Dent") ⇒ "QXJ0aHVyIERlbnQ="
          (base64->bytevector "+/     /+") ⇒ #u8(#xfb #xff #xfe)

 -- Scheme Procedure: bytestring->list bytevector [start [end]]
     Converts all or part of a bytevector into a list of the same length
     containing characters for elements in the range 32 to 127 and exact
     integers for all other elements.</p>

          (bytestring->list #u8(#x41 #x42 1 2) 1 3) ⇒ (#\B 1)

 -- Scheme Procedure: make-bytestring-generator arg ...
     Returns a generator that when invoked will return consecutive bytes
     of the bytevector that ‘bytestring’ would create when applied to
     ARGS, but without creating any bytevectors.  The ARGS are validated
     before any bytes are generated; if they are ill-formed, an error
     satisfying ‘bytestring-error?’ is raised.

          (generator->list (make-bytestring-generator "lorem"))
          ⇒ (#x6c #x6f #x72 #x65 #x6d)


File: guile.info,  Node: SRFI-207 Selection,  Next: SRFI-207 Replacement,  Prev: SRFI-207 Conversion,  Up: SRFI-207

7.5.49.4 Selection
..................

 -- Scheme Procedure: bytestring-pad bytevector len char-or-u8
 -- Scheme Procedure: bytestring-pad-right bytevector len char-or-u8
     Returns a newly allocated bytevector with the contents of
     BYTEVECTOR plus sufficient additional bytes at the beginning/end
     containing CHAR-OR-U8 (which can be either an ASCII character or an
     exact integer in the range 0-255) such that the length of the
     result is at least LEN.

          (bytestring-pad #u8"Zaphod" 10 #\_) ⇒ #u8"____Zaphod"
          (bytestring-pad-right #u8(#x80 #x7f) 8 0) ⇒ #u8(#x80 #x7f 0 0 0 0 0 0)

 -- Scheme Procedure: bytestring-trim bytevector pred
 -- Scheme Procedure: bytestring-trim-right bytevector pred
 -- Scheme Procedure: bytestring-trim-both bytevector pred
     Returns a newly allocated bytevector with the contents of
     BYTEVECTOR, except that consecutive bytes at the beginning / the
     end / both the beginning and the end that satisfy PRED are not
     included.

          (bytestring-trim #u8"   Trillian" (lambda (b) (= b #x20)))
          ⇒ #u8"Trillian"
          (bytestring-trim-both #u8(0 0 #x80 #x7f 0 0 0) zero?) ⇒ #u8(#x80 #x7f)


File: guile.info,  Node: SRFI-207 Replacement,  Next: SRFI-207 Comparison,  Prev: SRFI-207 Selection,  Up: SRFI-207

7.5.49.5 Replacement
....................

 -- Scheme Procedure: bytestring-replace bytevector1 bytevector2 start1
          end1 [start2 end2]
     Returns a newly allocated bytevector with the contents of
     BYTEVECTOR1, except that the bytes indexed by START1 and END1 are
     not included but are replaced by the bytes of BYTEVECTOR2 indexed
     by START2 and END2.

          (bytestring-replace #u8"Vogon torture" #u8"poetry" 6 13)
          ⇒ #u8"Vogon poetry"


File: guile.info,  Node: SRFI-207 Comparison,  Next: SRFI-207 Searching,  Prev: SRFI-207 Replacement,  Up: SRFI-207

7.5.49.6 Comparison
...................

To compare bytevectors for equality, use the ‘bytevector=?’ procedure
from ‘(rnrs bytevectors)’ (*note Bytevectors::) or ‘equal?’.

 -- Scheme Procedure: bytestring<? bytevector1 bytevector2
 -- Scheme Procedure: bytestring>? bytevector1 bytevector2
 -- Scheme Procedure: bytestring<=? bytevector1 bytevector2
 -- Scheme Procedure: bytestring>=? bytevector1 bytevector2
     Returns ‘#t’ if BYTEVECTOR1 is less than / greater than / less than
     or equal to / greater than or equal to BYTEVECTOR2.  Comparisons
     are lexicographical: shorter bytevectors compare before longer
     ones, all elements being equal.

          (bytestring<? #u8"Heart Of Gold" #u8"Heart of Gold") ⇒ #t
          (bytestring<=? #u8(#x81 #x95) #u8(#x80 #xa0)) ⇒ #f
          (bytestring>? #u8(1 2 3) #u8(1 2)) ⇒ #t


File: guile.info,  Node: SRFI-207 Searching,  Next: SRFI-207 Joining And Splitting,  Prev: SRFI-207 Comparison,  Up: SRFI-207

7.5.49.7 Searching
..................

 -- Scheme Procedure: bytestring-index bytevector pred [start [end]]
 -- Scheme Procedure: bytestring-index-right bytevector pred [start
          [end]]
     Searches BYTEVECTOR from START to END / from END to START for the
     first byte that satisfies PRED, and returns the index into
     BYTEVECTOR containing that byte.  In either direction, START is
     inclusive and END is exclusive.  If there are no such bytes,
     returns ‘#f’.

          (bytestring-index #u8(#x65 #x72 #x83 #x6f) (λ (b) (> b #x7f))) ⇒ 2
          (bytestring-index #u8"Beeblebrox" (λ (b) (> b #x7f))) ⇒ #f
          (bytestring-index-right #u8"Zaphod" odd?) ⇒ 4

 -- Scheme Procedure: bytestring-break bytevector pred
 -- Scheme Procedure: bytestring-span bytevector pred
     Returns two values, a bytevector containing the maximal sequence of
     characters (searching from the beginning of BYTEVECTOR to the end)
     that do not satisfy / do satisfy PRED, and another bytevector
     containing the remaining characters.

          (bytestring-break #u8(#x50 #x4b 0 0 #x1 #x5) zero?)
            ⇒ #u8(#x50 #x4b) #u8(0 0 #x1 #x5)
          (bytestring-span #u8"ABCDefg" (lambda (b) (and (> b 40) (< b 91))))
            ⇒ #u8"ABCD" #u8"efg"


File: guile.info,  Node: SRFI-207 Joining And Splitting,  Next: SRFI-207 I/O,  Prev: SRFI-207 Searching,  Up: SRFI-207

7.5.49.8 Joining And Splitting
..............................

 -- Scheme Procedure: bytestring-join bytevector-list delimiter
     Joins the bytevectors in BYTEVECTOR-LIST together using the
     DELIMITER, which can be anything suitable as an argument to
     ‘bytestring’.  The GRAMMAR argument is a symbol that determines how
     the delimiter is used, and defaults to ‘infix’.  It is an error for
     grammar to be any symbol other than these four:

     ‘infix’
          means an infix or separator grammar: inserts the delimiter
          between list elements.  An empty list will produce an empty
          bytevector
     ‘strict-infix’
          means the same as ‘infix’ if the list is non-empty, but will
          signal an error satisfying ‘bytestring-error?’ if given an
          empty list.
     ‘suffix’
          means a suffix or terminator grammar: inserts the delimiter
          after every list element.
     ‘prefix’
          means a prefix grammar: inserts the delimiter before every
          list element.

     For example:
          (bytestring-join '(#u8"Heart" #u8"of" #u8"Gold") #x20)
            ⇒ #u8"Heart of Gold"
          (bytestring-join '(#u8(#xef #xbb) #u8(#xbf)) 0 'prefix)
            ⇒ #u8(0 #xef #xbb 0 #xbf)
          (bytestring-join '() 0 'strict-infix)
            ⇒ ⇒ raised &bytestring-error

 -- Scheme Procedure: bytestring-split bytevector delimiter [grammar]
     Divides the elements of BYTEVECTOR and returns a list of newly
     allocated bytevectors using the DELIMITER (an ASCII character or
     exact integer in the range 0-255 inclusive).  Delimiter bytes are
     not included in the result bytevectors.

     The GRAMMAR argument is used to control how BYTEVECTOR is divided.
     It has the same default and meaning as in ‘bytestring-join’, except
     that ‘infix’ and ‘strict-infix’ mean the same thing.  That is, if
     GRAMMAR is ‘prefix’ or ‘suffix’, then ignore any delimiter in the
     first or last position of BYTEVECTOR respectively.

          (bytestring-split #u8"Beeblebrox" #x62)
            ⇒ (#u8"Bee" #u8"le" #u8"rox")
          (bytestring-split #u8(1 0 2 0) 0 'suffix)
            ⇒ (#u8(1) #u8(2))


File: guile.info,  Node: SRFI-207 I/O,  Next: SRFI-207 Exceptions,  Prev: SRFI-207 Joining And Splitting,  Up: SRFI-207

7.5.49.9 I/O
............

 -- Scheme Procedure: read-textual-bytestring prefix [port]
     Reads a string in the external format described in this SRFI from
     PORT and return it as a bytevector.  If the PREFIX argument is
     false, this procedure assumes that "‘#u8’" has already been read
     from PORT.  If PORT is omitted, it defaults to the value of
     ‘(current-input-port)’.  If the characters read are not in the
     external format, an error satisfying ‘bytestring-error?’ is raised.

          (call-with-port
              (open-input-string "#u8\"AB\\xad;\\xf0;\\x0d;CD\"")
            (lambda (port) (read-textual-bytestring #t port)))
          ⇒ #u8(#x41 #x42 #xad #xf0 #x0d #x43 #x44)

 -- Scheme Procedure: write-textual-bytestring bytevector [port]
     Writes BYTEVECTOR in the external format described in this SRFI to
     PORT.  Bytes representing non-graphical ASCII characters are
     unencoded: all other bytes are encoded with a single letter if
     possible, otherwise with a ‘\x’ escape.  If PORT is omitted, it
     defaults to the value of ‘(current-output-port)’.

          (call-with-port
              (open-output-string)
            (lambda (port)
              (write-textual-bytestring
               #u8(#x9 #x41 #x72 #x74 #x68 #x75 #x72 #xa)
               port)
              (get-output-string port)))
          ⇒ "#u8\"\\tArthur\\n\""

 -- Scheme Procedure: write-binary-bytestring port arg ...
     Outputs each ARG to the binary output port PORT using the same
     interpretations as ‘bytestring’, but without creating any
     bytevectors.  The ARGS are validated before any bytes are written
     to PORT; if they are ill-formed, an error satisfying
     ‘bytestring-error?’ is raised.

          (call-with-port
              (open-output-bytevector)
            (lambda (port)
              (write-binary-bytestring port #\Z #x61 #x70 "hod")
              (get-output-bytevector port)))
          ⇒ #u8"Zaphod"


File: guile.info,  Node: SRFI-207 Exceptions,  Next: SRFI-207 Acknowledgements,  Prev: SRFI-207 I/O,  Up: SRFI-207

7.5.49.10 Exceptions
....................

 -- Scheme Procedure: bytestring-error? obj
     Returns ‘#t’ if OBJ is a ‘&bytestring-error’ signaled by any of the
     following procedures, in the circumstances they describe:

          ‘bytestring’
          ‘hex-string->bytestring’
          ‘base64->bytestring’
          ‘make-bytestring’
          ‘make-bytestring!’
          ‘bytestring-join’
          ‘read-textual-bytestring’
          ‘write-binary-bytestring’
          ‘make-bytestring-generator’


File: guile.info,  Node: SRFI-207 Acknowledgements,  Prev: SRFI-207 Exceptions,  Up: SRFI-207

7.5.49.11 Acknowledgements
..........................

Daphne Preston-Kendal devised the string notation for bytevectors; John
Cowan, the procedure library; Wolfgang Corcoran-Mathe, the original,
sample implementation of the procedures.

   The notation is inspired by the notation used in Python since version
2.6 for ‘bytes’ objects, which are fundamentally similar in purpose to
Scheme bytevectors, especially in R7RS. In addition, many of the
procedures are closely analogous to those of SRFI 152
(https://srfi.schemers.org/srfi-152/srfi-152.html).

   Thanks is also due to the participants in the SRFI mailing list.  In
particular: Lassi Kortela corrected an embarrassing technical error;
Marc Nieper-Wißkirchen explained why the ‘write’ procedure ought not to
be allowed to use this notation by default.


File: guile.info,  Node: SRFI-244,  Prev: SRFI-207,  Up: SRFI Support

7.5.50 SRFI-244 - Multiple-value Definitions
--------------------------------------------

The implementation of this SRFI re-exports the ‘define-values’ form
described in *note Binding Multiple Values::.


File: guile.info,  Node: R6RS Support,  Next: R7RS Support,  Prev: SRFI Support,  Up: Guile Modules

7.6 R6RS Support
================

*Note R6RS Libraries::, for more information on how to define R6RS
libraries, and their integration with Guile modules.

* Menu:

* R6RS Incompatibilities::              Guile mostly implements R6RS.
* R6RS Standard Libraries::             Modules defined by the R6RS.


File: guile.info,  Node: R6RS Incompatibilities,  Next: R6RS Standard Libraries,  Up: R6RS Support

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.  *Note String
     Syntax::, for more information.

   • Guile does not yet support Unicode escapes in symbols, such as
     ‘H\x65;llo’ (the same as ‘Hello’), or ‘\x3BB;’ (the same as ‘λ’).

   • 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, or vice versa.  All ports in Guile support both binary and
     textual I/O. *Note Encoding::, for full details.

   • Guile’s implementation of ‘equal?’ may fail to terminate when
     applied to arguments containing cycles.

   Guile exposes a procedure in the root module to choose R6RS defaults
over Guile’s historical defaults.

 -- Scheme Procedure: install-r6rs!
     Alter Guile’s default settings to better conform to the R6RS.

     While Guile’s defaults may evolve over time, the current changes
     that this procedure imposes are to add ‘.sls’ and ‘.guile.sls’ to
     the set of supported ‘%load-extensions’, to better support R6RS
     conventions.  *Note Load Paths::.  Also, enable R6RS unicode
     escapes in strings; see the discussion above.

   Finally, note that the ‘--r6rs’ command-line argument will call
‘install-r6rs!’ before calling user code.  R6RS users probably want to
pass this argument to their Guile.


File: guile.info,  Node: R6RS Standard Libraries,  Prev: R6RS Incompatibilities,  Up: R6RS Support

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 (*note R6RS Standard Libraries: (r6rs)Standard
Libraries.).

* Menu:

* Library Usage::               What to know about Guile’s library support.
* rnrs base::                   The base library.
* rnrs unicode::                Access to Unicode operations.
* rnrs bytevectors::            Functions for working with binary data.
* rnrs lists::                  List utilities.
* rnrs sorting::                Sorting for lists and vectors.
* rnrs control::                Additional control structures.

* R6RS Records::                A note about R6RS records.
* rnrs records syntactic::      Syntactic API for R6RS records.
* rnrs records procedural::     Procedural API for R6RS records.
* rnrs records inspection::     Reflection on R6RS records.

* rnrs exceptions::             Handling exceptional situations.
* rnrs conditions::             Data structures for exceptions.

* R6RS I/O Conditions::         Predefined I/O error types.
* R6RS Transcoders::            Characters and bytes.
* rnrs io ports::               Support for port-based I/O.
* R6RS File Ports::             Working with files.
* rnrs io simple::              High-level I/O API.

* rnrs files::                  Functions for working with files.
* rnrs programs::               Functions for working with processes.
* rnrs arithmetic fixnums::     Fixed-precision arithmetic operations.
* rnrs arithmetic flonums::     Floating-point arithmetic operations.
* rnrs arithmetic bitwise::     Exact bitwise arithmetic operations.
* rnrs syntax-case::            Support for ‘syntax-case’ macros.
* rnrs hashtables::             Hashtables.
* rnrs enums::                  Enumerations.
* rnrs::                        The composite library.
* rnrs eval::                   Support for on-the-fly evaluation.
* rnrs mutable-pairs::          Support for mutable pairs.
* rnrs mutable-strings::        Support for mutable strings.
* rnrs r5rs::                   Compatibility layer for R5RS Scheme.


File: guile.info,  Node: Library Usage,  Next: rnrs base,  Up: R6RS Standard Libraries

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 (*note
R6RS Libraries::).


File: guile.info,  Node: rnrs base,  Next: rnrs unicode,  Prev: Library Usage,  Up: R6RS Standard 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 (*note R6RS Base library:
(r6rs)Base library.).  They are grouped below by the existing manual
sections to which they correspond.

 -- Scheme Procedure: boolean? obj
 -- Scheme Procedure: not x
     *Note Booleans::, for documentation.

 -- Scheme Procedure: symbol? obj
 -- Scheme Procedure: symbol->string sym
 -- Scheme Procedure: string->symbol str
     *Note 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
     *Note Characters::, for documentation.

 -- Scheme Procedure: list? x
 -- Scheme Procedure: null? x
     *Note 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
     *Note Pairs::, for documentation.

 -- Scheme Procedure: number? obj
     *Note Numerical Tower::, for documentation.

 -- Scheme Procedure: string? obj
     *Note String Predicates::, for documentation.

 -- Scheme Procedure: procedure? obj
     *Note Procedure Properties::, for documentation.

 -- Scheme Syntax: define name value
 -- Scheme Syntax: set! variable-name value
     *Note 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
          ...
     *Note Defining Macros::, for documentation.

 -- Scheme Syntax: identifier-syntax exp
     *Note Identifier Macros::, for documentation.

 -- Scheme Syntax: syntax-rules literals (pattern template) ...
     *Note Syntax Rules::, for documentation.

 -- Scheme Syntax: lambda formals body
     *Note Lambda::, for documentation.

 -- Scheme Syntax: let bindings body
 -- Scheme Syntax: let* bindings body
 -- Scheme Syntax: letrec bindings body
 -- Scheme Syntax: letrec* bindings body
     *Note Local Bindings::, for documentation.

 -- Scheme Syntax: let-values bindings body
 -- Scheme Syntax: let*-values bindings body
     *Note SRFI-11::, for documentation.

 -- Scheme Syntax: begin expr1 expr2 ...
     *Note begin::, for documentation.

 -- Scheme Syntax: quote expr
 -- Scheme Syntax: quasiquote expr
 -- Scheme Syntax: unquote expr
 -- Scheme Syntax: unquote-splicing expr
     *Note Expression Syntax::, for documentation.

 -- Scheme Syntax: if test consequence [alternate]
 -- Scheme Syntax: cond clause1 clause2 ...
 -- Scheme Syntax: case key clause1 clause2 ...
     *Note Conditionals::, for documentation.

 -- Scheme Syntax: and expr ...
 -- Scheme Syntax: or expr ...
     *Note and or::, for documentation.

 -- Scheme Procedure: eq? x y
 -- Scheme Procedure: eqv? x y
 -- Scheme Procedure: equal? x y
 -- Scheme Procedure: symbol=? symbol1 symbol2 ...
     *Note Equality::, for documentation.

     ‘symbol=?’ is identical to ‘eq?’.

 -- Scheme Procedure: complex? z
     *Note 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
     *Note 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
     *Note Scientific::, for documentation.

 -- Scheme Procedure: real? x
 -- Scheme Procedure: rational? x
 -- Scheme Procedure: numerator x
 -- Scheme Procedure: denominator x
 -- Scheme Procedure: rationalize x eps
     *Note Reals and Rationals::, for documentation.

 -- Scheme Procedure: exact? x
 -- Scheme Procedure: inexact? x
 -- Scheme Procedure: exact z
 -- Scheme Procedure: inexact z
     *Note 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
     *Note 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
     *Note 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
     *Note Comparison::, for documentation.

 -- Scheme Procedure: for-each f lst1 lst2 ...
     *Note SRFI-1 Fold and Map::, for documentation.

 -- Scheme Procedure: list elem ...
     *Note List Constructors::, for documentation.

 -- Scheme Procedure: length lst
 -- Scheme Procedure: list-ref lst k
 -- Scheme Procedure: list-tail lst k
     *Note List Selection::, for documentation.

 -- Scheme Procedure: append lst ... obj
 -- Scheme Procedure: append
 -- Scheme Procedure: reverse lst
     *Note Append/Reverse::, for documentation.

 -- Scheme Procedure: number->string n [radix]
 -- Scheme Procedure: string->number str [radix]
     *Note Conversion::, for documentation.

 -- Scheme Procedure: string char ...
 -- Scheme Procedure: make-string k [chr]
 -- Scheme Procedure: list->string lst
     *Note String Constructors::, for documentation.

 -- Scheme Procedure: string->list str [start [end]]
     *Note 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]
     *Note 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 ...
     *Note String Comparison::, for documentation.

 -- Scheme Procedure: string-append arg ...
     *Note Reversing and Appending Strings::, for documentation.

 -- Scheme Procedure: string-for-each proc s [start [end]]
     *Note 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
     *Note 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
     *Note 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
     *Note Vector Accessors::, for documentation.

 -- Scheme Procedure: call-with-current-continuation proc
 -- Scheme Procedure: call/cc proc
     *Note Continuations::, for documentation.

 -- Scheme Procedure: values arg ...
 -- Scheme Procedure: call-with-values producer consumer
     *Note Multiple Values::, for documentation.

 -- Scheme Procedure: dynamic-wind in_guard thunk out_guard
     *Note Dynamic Wind::, for documentation.

 -- Scheme Procedure: apply proc arg ... arglst
     *Note Fly Evaluation::, for documentation.


File: guile.info,  Node: rnrs unicode,  Next: rnrs bytevectors,  Prev: rnrs base,  Up: R6RS Standard Libraries

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; *Note 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.  *Note 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.  *Note Characters::, for documentation.

 -- Scheme Procedure: char-general-category char
     *Note 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.  *Note 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.  *Note 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.  *Note String Comparison::, for documentation.


File: guile.info,  Node: rnrs bytevectors,  Next: rnrs lists,  Prev: rnrs unicode,  Up: R6RS Standard Libraries

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; *Note Bytevectors::.


File: guile.info,  Node: rnrs lists,  Next: rnrs sorting,  Prev: rnrs bytevectors,  Up: R6RS Standard Libraries

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.  *Note 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’.  *Note 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.
     *Note List Modification::, for a description of ‘filter’; *Note
     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.  *Note 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.  *Note 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, (*note List
     Modification::).  ‘remp’ is identical to the alternate ‘remove’
     procedure provided by SRFI-1; *Note 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; *Note 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; *Note 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.  *Note List Constructors::, for documentation.


File: guile.info,  Node: rnrs sorting,  Next: rnrs control,  Prev: rnrs lists,  Up: R6RS Standard Libraries

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.  *Note
     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.  *Note Sorting::, for more information.


File: guile.info,  Node: rnrs control,  Next: R6RS Records,  Prev: rnrs sorting,  Up: R6RS Standard Libraries

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.
     *Note while do::, for documentation.

 -- Scheme Syntax: case-lambda clause ...
     This form is identical to the one provided by Guile’s core library.
     *Note Case-lambda::, for documentation.


File: guile.info,  Node: R6RS Records,  Next: rnrs records syntactic,  Prev: rnrs control,  Up: R6RS Standard Libraries

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; *Note
Records::, and *note 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.


File: guile.info,  Node: rnrs records syntactic,  Next: rnrs records procedural,  Prev: R6RS Records,  Up: R6RS Standard Libraries

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.


File: guile.info,  Node: rnrs records procedural,  Next: rnrs records inspection,  Prev: rnrs records syntactic,  Up: R6RS Standard Libraries

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.


File: guile.info,  Node: rnrs records inspection,  Next: rnrs exceptions,  Prev: rnrs records procedural,  Up: R6RS Standard Libraries

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.


File: guile.info,  Node: rnrs exceptions,  Next: rnrs conditions,  Prev: rnrs records inspection,  Up: R6RS Standard Libraries

7.6.2.12 rnrs exceptions
........................

The ‘(rnrs exceptions (6))’ library provides functionality related to
signaling and handling exceptional situations.  This functionality
re-exports Guile’s core exception-handling primitives.  *Note
Exceptions::, for a full discussion.  *Note SRFI-34::, for a similar
pre-R6RS facility.  In Guile, SRFI-34, SRFI-35, and R6RS exception
handling are all built on the same core facilities, and so are
interoperable.

 -- Scheme Procedure: with-exception-handler handler thunk
     *Note Raising and Handling Exceptions::, for more information on
     ‘with-exception-handler’.

 -- 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 (*note
     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
     Equivalent to core Guile ‘(raise-exception OBJ)’.  *Note Raising
     and Handling Exceptions::.  (Unfortunately, ‘raise’ is already
     bound to a different function in core Guile.  *Note Signals::.)

 -- Scheme Procedure: raise-continuable obj
     Equivalent to core Guile ‘(raise-exception OBJ #:continuable? #t)’.
     *Note Raising and Handling Exceptions::.


File: guile.info,  Node: rnrs conditions,  Next: R6RS I/O Conditions,  Prev: rnrs exceptions,  Up: R6RS Standard Libraries

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

   Guile’s R6RS layer uses core exception types from the ‘(ice-9
exceptions)’ module as the basis for its R6RS condition system.  Guile
prefers to use the term “exception object” and “exception type” rather
than “condition” or “condition type”, but that’s just a naming
difference.  Guile also has different names for the types in the
condition hierarchy.  *Note Exception Objects::, for full details.

   This library is quite similar to the SRFI-35 conditions module (*note
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 compatible; the ‘condition?’ predicate from one
API will return ‘#t’ when applied to a condition object created in the
other.  of the condition types are the same, also.

 -- Condition Type: &condition
 -- Scheme Procedure: condition? obj
     The base record type for conditions.  Known as ‘&exception’ in core
     Guile.

 -- 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.  Known as ‘&error’ in core Guile.

 -- Condition Type: &error
 -- Scheme Procedure: make-error
 -- Scheme Procedure: error? obj
     A base type for conditions representing errors.  Known as
     ‘&external-error’ in core Guile.

 -- 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.  Known as ‘&programming-error’ in
     core Guile.

 -- 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.  Known as ‘&assertion-failure’ in core Guile.

 -- 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.  Known as ‘&undefined-variable’ in core Guile.


File: guile.info,  Node: R6RS I/O Conditions,  Next: R6RS Transcoders,  Prev: rnrs conditions,  Up: R6RS Standard Libraries

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.


File: guile.info,  Node: R6RS Transcoders,  Next: rnrs io ports,  Prev: R6RS I/O Conditions,  Up: R6RS Standard Libraries

7.6.2.15 Transcoders
....................

The transcoder facilities are exported by ‘(rnrs io ports)’.

   Several different Unicode encoding schemes describe standard ways to
encode characters and strings as byte sequences and to decode those
sequences.  Within this document, a “codec” is an immutable Scheme
object that represents a Unicode or similar encoding scheme.

   An “end-of-line style” is a symbol that, if it is not ‘none’,
describes how a textual port transcodes representations of line endings.

   A “transcoder” is an immutable Scheme object that combines a codec
with an end-of-line style and a method for handling decoding errors.
Each transcoder represents some specific bidirectional (but not
necessarily lossless), possibly stateful translation between byte
sequences and Unicode characters and strings.  Every transcoder can
operate in the input direction (bytes to characters) or in the output
direction (characters to bytes).  A TRANSCODER parameter name means that
the corresponding argument must be a transcoder.

   A “binary port” is a port that supports binary I/O, does not have an
associated transcoder and does not support textual I/O. A “textual port”
is a port that supports textual I/O, and does not support binary I/O. A
textual port may or may not have an associated transcoder.

 -- Scheme Procedure: latin-1-codec
 -- Scheme Procedure: utf-8-codec
 -- Scheme Procedure: utf-16-codec

     These are predefined codecs for the ISO 8859-1, UTF-8, and UTF-16
     encoding schemes.

     A call to any of these procedures returns a value that is equal in
     the sense of ‘eqv?’ to the result of any other call to the same
     procedure.

 -- Scheme Syntax: eol-style EOL-STYLE-SYMBOL

     EOL-STYLE-SYMBOL should be a symbol whose name is one of ‘lf’,
     ‘cr’, ‘crlf’, ‘nel’, ‘crnel’, ‘ls’, and ‘none’.

     The form evaluates to the corresponding symbol.  If the name of
     EOL-STYLE-SYMBOL is not one of these symbols, the effect and result
     are implementation-dependent; in particular, the result may be an
     eol-style symbol acceptable as an EOL-STYLE argument to
     ‘make-transcoder’.  Otherwise, an exception is raised.

     All eol-style symbols except ‘none’ describe a specific line-ending
     encoding:

     ‘lf’
          linefeed
     ‘cr’
          carriage return
     ‘crlf’
          carriage return, linefeed
     ‘nel’
          next line
     ‘crnel’
          carriage return, next line
     ‘ls’
          line separator

     For a textual port with a transcoder, and whose transcoder has an
     eol-style symbol ‘none’, no conversion occurs.  For a textual input
     port, any eol-style symbol other than ‘none’ means that all of the
     above line-ending encodings are recognized and are translated into
     a single linefeed.  For a textual output port, ‘none’ and ‘lf’ are
     equivalent.  Linefeed characters are encoded according to the
     specified eol-style symbol, and all other characters that
     participate in possible line endings are encoded as is.

          Note: Only the name of EOL-STYLE-SYMBOL is significant.

 -- Scheme Procedure: native-eol-style
     Returns the default end-of-line style of the underlying platform,
     e.g., ‘lf’ on Unix and ‘crlf’ on Windows.

 -- Condition Type: &i/o-decoding
 -- Scheme Procedure: make-i/o-decoding-error port
 -- Scheme Procedure: i/o-decoding-error? obj
     This condition type could be defined by

          (define-condition-type &i/o-decoding &i/o-port
            make-i/o-decoding-error i/o-decoding-error?)

     An exception with this type is raised when one of the operations
     for textual input from a port encounters a sequence of bytes that
     cannot be translated into a character or string by the input
     direction of the port’s transcoder.

     When such an exception is raised, the port’s position is past the
     invalid encoding.

 -- Condition Type: &i/o-encoding
 -- Scheme Procedure: make-i/o-encoding-error port char
 -- Scheme Procedure: i/o-encoding-error? obj
 -- Scheme Procedure: i/o-encoding-error-char condition
     This condition type could be defined by

          (define-condition-type &i/o-encoding &i/o-port
            make-i/o-encoding-error i/o-encoding-error?
            (char i/o-encoding-error-char))

     An exception with this type is raised when one of the operations
     for textual output to a port encounters a character that cannot be
     translated into bytes by the output direction of the port’s
     transcoder.  CHAR is the character that could not be encoded.

 -- Scheme Syntax: error-handling-mode ERROR-HANDLING-MODE-SYMBOL
     ERROR-HANDLING-MODE-SYMBOL should be a symbol whose name is one of
     ‘ignore’, ‘raise’, and ‘replace’.  The form evaluates to the
     corresponding symbol.  If ERROR-HANDLING-MODE-SYMBOL is not one of
     these identifiers, effect and result are implementation-dependent:
     The result may be an error-handling-mode symbol acceptable as a
     HANDLING-MODE argument to ‘make-transcoder’.  If it is not
     acceptable as a HANDLING-MODE argument to ‘make-transcoder’, an
     exception is raised.

          Note: Only the name of ERROR-HANDLING-MODE-SYMBOL is
          significant.

     The error-handling mode of a transcoder specifies the behavior of
     textual I/O operations in the presence of encoding or decoding
     errors.

     If a textual input operation encounters an invalid or incomplete
     character encoding, and the error-handling mode is ‘ignore’, an
     appropriate number of bytes of the invalid encoding are ignored and
     decoding continues with the following bytes.

     If the error-handling mode is ‘replace’, the replacement character
     U+FFFD is injected into the data stream, an appropriate number of
     bytes are ignored, and decoding continues with the following bytes.

     If the error-handling mode is ‘raise’, an exception with condition
     type ‘&i/o-decoding’ is raised.

     If a textual output operation encounters a character it cannot
     encode, and the error-handling mode is ‘ignore’, the character is
     ignored and encoding continues with the next character.  If the
     error-handling mode is ‘replace’, a codec-specific replacement
     character is emitted by the transcoder, and encoding continues with
     the next character.  The replacement character is U+FFFD for
     transcoders whose codec is one of the Unicode encodings, but is the
     ‘?’ character for the Latin-1 encoding.  If the error-handling mode
     is ‘raise’, an exception with condition type ‘&i/o-encoding’ is
     raised.

 -- Scheme Procedure: make-transcoder codec
 -- Scheme Procedure: make-transcoder codec eol-style
 -- Scheme Procedure: make-transcoder codec eol-style handling-mode
     CODEC must be a codec; EOL-STYLE, if present, an eol-style symbol;
     and HANDLING-MODE, if present, an error-handling-mode symbol.

     EOL-STYLE may be omitted, in which case it defaults to the native
     end-of-line style of the underlying platform.  HANDLING-MODE may be
     omitted, in which case it defaults to ‘replace’.  The result is a
     transcoder with the behavior specified by its arguments.

 -- Scheme procedure: native-transcoder
     Returns an implementation-dependent transcoder that represents a
     possibly locale-dependent “native” transcoding.

 -- Scheme Procedure: transcoder-codec transcoder
 -- Scheme Procedure: transcoder-eol-style transcoder
 -- Scheme Procedure: transcoder-error-handling-mode transcoder
     These are accessors for transcoder objects; when applied to a
     transcoder returned by ‘make-transcoder’, they return the CODEC,
     EOL-STYLE, and HANDLING-MODE arguments, respectively.

 -- Scheme Procedure: bytevector->string bytevector transcoder
     Returns the string that results from transcoding the BYTEVECTOR
     according to the input direction of the transcoder.

 -- Scheme Procedure: string->bytevector string transcoder
     Returns the bytevector that results from transcoding the STRING
     according to the output direction of the transcoder.


File: guile.info,  Node: rnrs io ports,  Next: R6RS File Ports,  Prev: R6RS Transcoders,  Up: R6RS Standard Libraries

7.6.2.16 rnrs io ports
......................

Guile’s binary and textual port interface was heavily inspired by R6RS,
so many R6RS port interfaces are documented elsewhere.  Note that R6RS
ports are not disjoint from Guile’s native ports, so Guile-specific
procedures will work on ports created using the R6RS API, and vice
versa.  Also note that in Guile, all ports are both textual and binary.
*Note Input and Output::, for more on Guile’s core port API. The R6RS
ports module wraps Guile’s I/O routines in a helper that will translate
native Guile exceptions to R6RS conditions; *Note R6RS I/O Conditions::,
for more.  *Note R6RS File Ports::, for documentation on the R6RS file
port interface.

   _Note_: The implementation of this R6RS API is not complete yet.

 -- Scheme Procedure: eof-object? obj
     *Note Binary I/O::, for documentation.

 -- Scheme Procedure: eof-object
     Return the end-of-file (EOF) object.

          (eof-object? (eof-object))
          ⇒ #t

 -- Scheme Procedure: port? obj
 -- Scheme Procedure: input-port? obj
 -- Scheme Procedure: output-port? obj
 -- Scheme Procedure: call-with-port port proc
     *Note Ports::, for documentation.

 -- Scheme Procedure: port-transcoder port
     Return a transcoder associated with the encoding of PORT.  *Note
     Encoding::, and *Note R6RS Transcoders::.

 -- Scheme Procedure: binary-port? port
     Return ‘#t’ if PORT appears to be a binary port, else return ‘#f’.
     Note that Guile does not currently distinguish between binary and
     textual ports, so this predicate is not a reliable indicator of
     whether the port was created as a binary port.  Currently, it
     returns ‘#t’ if and only if the port encoding is “ISO-8859-1”,
     because Guile uses this encoding when creating a binary port.
     *Note Encoding::, for more details.

 -- Scheme Procedure: textual-port? port
     Return ‘#t’ if PORT appears to be a textual port, else return ‘#f’.
     Note that Guile does not currently distinguish between binary and
     textual ports, so this predicate is not a reliable indicator of
     whether the port was created as a textual port.  Currently, it
     always returns ‘#t’, because all ports can be used for textual I/O
     in Guile.  *Note Encoding::, for more details.

 -- Scheme Procedure: transcoded-port binary-port transcoder
     The ‘transcoded-port’ procedure returns a new textual port with the
     specified TRANSCODER.  Otherwise the new textual port’s state is
     largely the same as that of BINARY-PORT.  If BINARY-PORT is an
     input port, the new textual port will be an input port and will
     transcode the bytes that have not yet been read from BINARY-PORT.
     If BINARY-PORT is an output port, the new textual port will be an
     output port and will transcode output characters into bytes that
     are written to the byte sink represented by BINARY-PORT.

     As a side effect, however, ‘transcoded-port’ closes BINARY-PORT in
     a special way that allows the new textual port to continue to use
     the byte source or sink represented by BINARY-PORT, even though
     BINARY-PORT itself is closed and cannot be used by the input and
     output operations described in this chapter.

 -- Scheme Procedure: port-position port
     Equivalent to ‘(seek PORT 0 SEEK_CUR)’.  *Note Random Access::.

 -- Scheme Procedure: port-has-port-position? port
     Return ‘#t’ is PORT supports ‘port-position’.

 -- Scheme Procedure: set-port-position! port offset
     Equivalent to ‘(seek PORT OFFSET SEEK_SET)’.  *Note Random
     Access::.

 -- Scheme Procedure: port-has-set-port-position!? port
     Return ‘#t’ is PORT supports ‘set-port-position!’.

 -- Scheme Procedure: port-eof? input-port
     Equivalent to ‘(eof-object? (lookahead-u8 INPUT-PORT))’.

 -- Scheme Procedure: standard-input-port
 -- Scheme Procedure: standard-output-port
 -- Scheme Procedure: standard-error-port
     Returns a fresh binary input port connected to standard input, or a
     binary output port connected to the standard output or standard
     error, respectively.  Whether the port supports the ‘port-position’
     and ‘set-port-position!’ operations is implementation-dependent.

 -- Scheme Procedure: current-input-port
 -- Scheme Procedure: current-output-port
 -- Scheme Procedure: current-error-port
     *Note Default Ports::.

 -- Scheme Procedure: open-bytevector-input-port bv [transcoder]
 -- Scheme Procedure: open-bytevector-output-port [transcoder]
     *Note Bytevector Ports::.

 -- Scheme Procedure: make-custom-binary-input-port id read!
          get-position set-position! close
 -- Scheme Procedure: make-custom-binary-output-port id write!
          get-position set-position! close
 -- Scheme Procedure: make-custom-binary-input/output-port id read!
          write! get-position set-position! close
     *Note Custom Ports::.

 -- Scheme Procedure: make-custom-textual-input-port id read!
          get-position set-position! close
 -- Scheme Procedure: make-custom-textual-output-port id write!
          get-position set-position! close
 -- Scheme Procedure: make-custom-textual-input/output-port id read!
          write! get-position set-position! close
     *Note Custom Ports::.

 -- Scheme Procedure: get-u8 port
 -- Scheme Procedure: lookahead-u8 port
 -- Scheme Procedure: get-bytevector-n port count
 -- Scheme Procedure: get-bytevector-n! port bv start count
 -- Scheme Procedure: get-bytevector-some port
 -- Scheme Procedure: get-bytevector-all port
 -- Scheme Procedure: put-u8 port octet
 -- Scheme Procedure: put-bytevector port bv [start [count]]
     *Note Binary I/O::.

 -- Scheme Procedure: get-char textual-input-port
 -- Scheme Procedure: lookahead-char textual-input-port
 -- Scheme Procedure: get-string-n textual-input-port count
 -- Scheme Procedure: get-string-n! textual-input-port string start
          count
 -- Scheme Procedure: get-string-all textual-input-port
 -- Scheme Procedure: get-line textual-input-port
 -- Scheme Procedure: put-char port char
 -- Scheme Procedure: put-string port string [start [count]]
     *Note Textual I/O::.

 -- Scheme Procedure: get-datum textual-input-port count
     Reads an external representation from TEXTUAL-INPUT-PORT and
     returns the datum it represents.  The ‘get-datum’ procedure returns
     the next datum that can be parsed from the given
     TEXTUAL-INPUT-PORT, updating TEXTUAL-INPUT-PORT to point exactly
     past the end of the external representation of the object.

     Any _interlexeme space_ (comment or whitespace, *note Scheme
     Syntax::) in the input is first skipped.  If an end of file occurs
     after the interlexeme space, the end-of-file object is returned.

     If a character inconsistent with an external representation is
     encountered in the input, an exception with condition types
     ‘&lexical’ and ‘&i/o-read’ is raised.  Also, if the end of file is
     encountered after the beginning of an external representation, but
     the external representation is incomplete and therefore cannot be
     parsed, an exception with condition types ‘&lexical’ and
     ‘&i/o-read’ is raised.

 -- Scheme Procedure: put-datum textual-output-port datum
     DATUM should be a datum value.  The ‘put-datum’ procedure writes an
     external representation of DATUM to TEXTUAL-OUTPUT-PORT.  The
     specific external representation is implementation-dependent.
     However, whenever possible, an implementation should produce a
     representation for which ‘get-datum’, when reading the
     representation, will return an object equal (in the sense of
     ‘equal?’) to DATUM.

          Note: Not all datums may allow producing an external
          representation for which ‘get-datum’ will produce an object
          that is equal to the original.  Specifically, NaNs contained
          in DATUM may make this impossible.

          Note: The ‘put-datum’ procedure merely writes the external
          representation, but no trailing delimiter.  If ‘put-datum’ is
          used to write several subsequent external representations to
          an output port, care should be taken to delimit them properly
          so they can be read back in by subsequent calls to
          ‘get-datum’.

 -- Scheme Procedure: flush-output-port port
     *Note Buffering::, for documentation on ‘force-output’.


File: guile.info,  Node: R6RS File Ports,  Next: rnrs io simple,  Prev: rnrs io ports,  Up: R6RS Standard Libraries

7.6.2.17 R6RS File Ports
........................

The facilities described in this section are exported by the ‘(rnrs io
ports)’ module.

 -- Scheme Syntax: buffer-mode BUFFER-MODE-SYMBOL
     BUFFER-MODE-SYMBOL must be a symbol whose name is one of ‘none’,
     ‘line’, and ‘block’.  The result is the corresponding symbol, and
     specifies the associated buffer mode.  *Note Buffering::, for a
     discussion of these different buffer modes.  To control the amount
     of buffering, use ‘setvbuf’ instead.  Note that only the name of
     BUFFER-MODE-SYMBOL is significant.

     *Note Buffering::, for a discussion of port buffering.

 -- Scheme Procedure: buffer-mode? obj
     Returns ‘#t’ if the argument is a valid buffer-mode symbol, and
     returns ‘#f’ otherwise.

   When opening a file, the various procedures accept a ‘file-options’
object that encapsulates flags to specify how the file is to be opened.
A ‘file-options’ object is an enum-set (*note rnrs enums::) over the
symbols constituting valid file options.

   A FILE-OPTIONS parameter name means that the corresponding argument
must be a file-options object.

 -- Scheme Syntax: file-options FILE-OPTIONS-SYMBOL ...

     Each FILE-OPTIONS-SYMBOL must be a symbol.

     The ‘file-options’ syntax returns a file-options object that
     encapsulates the specified options.

     When supplied to an operation that opens a file for output, the
     file-options object returned by ‘(file-options)’ specifies that the
     file is created if it does not exist and an exception with
     condition type ‘&i/o-file-already-exists’ is raised if it does
     exist.  The following standard options can be included to modify
     the default behavior.

     ‘no-create’
          If the file does not already exist, it is not created;
          instead, an exception with condition type
          ‘&i/o-file-does-not-exist’ is raised.  If the file already
          exists, the exception with condition type
          ‘&i/o-file-already-exists’ is not raised and the file is
          truncated to zero length.
     ‘no-fail’
          If the file already exists, the exception with condition type
          ‘&i/o-file-already-exists’ is not raised, even if ‘no-create’
          is not included, and the file is truncated to zero length.
     ‘no-truncate’
          If the file already exists and the exception with condition
          type ‘&i/o-file-already-exists’ has been inhibited by
          inclusion of ‘no-create’ or ‘no-fail’, the file is not
          truncated, but the port’s current position is still set to the
          beginning of the file.

     These options have no effect when a file is opened only for input.
     Symbols other than those listed above may be used as
     FILE-OPTIONS-SYMBOLs; they have implementation-specific meaning, if
     any.

          Note: Only the name of FILE-OPTIONS-SYMBOL is significant.

 -- Scheme Procedure: open-file-input-port filename
 -- Scheme Procedure: open-file-input-port filename file-options
 -- Scheme Procedure: open-file-input-port filename file-options
          buffer-mode
 -- Scheme Procedure: open-file-input-port filename file-options
          buffer-mode maybe-transcoder
     MAYBE-TRANSCODER must be either a transcoder or ‘#f’.

     The ‘open-file-input-port’ procedure returns an input port for the
     named file.  The FILE-OPTIONS and MAYBE-TRANSCODER arguments are
     optional.

     The FILE-OPTIONS argument, which may determine various aspects of
     the returned port, defaults to the value of ‘(file-options)’.

     The BUFFER-MODE argument, if supplied, must be one of the symbols
     that name a buffer mode.  The BUFFER-MODE argument defaults to
     ‘block’.

     If MAYBE-TRANSCODER is a transcoder, it becomes the transcoder
     associated with the returned port.

     If MAYBE-TRANSCODER is ‘#f’ or absent, the port will be a binary
     port and will support the ‘port-position’ and ‘set-port-position!’
     operations.  Otherwise the port will be a textual port, and whether
     it supports the ‘port-position’ and ‘set-port-position!’ operations
     is implementation-dependent (and possibly transcoder-dependent).

 -- Scheme Procedure: open-file-output-port filename
 -- Scheme Procedure: open-file-output-port filename file-options
 -- Scheme Procedure: open-file-output-port filename file-options
          buffer-mode
 -- Scheme Procedure: open-file-output-port filename file-options
          buffer-mode maybe-transcoder
     MAYBE-TRANSCODER must be either a transcoder or ‘#f’.

     The ‘open-file-output-port’ procedure returns an output port for
     the named file.

     The FILE-OPTIONS argument, which may determine various aspects of
     the returned port, defaults to the value of ‘(file-options)’.

     The BUFFER-MODE argument, if supplied, must be one of the symbols
     that name a buffer mode.  The BUFFER-MODE argument defaults to
     ‘block’.

     If MAYBE-TRANSCODER is a transcoder, it becomes the transcoder
     associated with the port.

     If MAYBE-TRANSCODER is ‘#f’ or absent, the port will be a binary
     port and will support the ‘port-position’ and ‘set-port-position!’
     operations.  Otherwise the port will be a textual port, and whether
     it supports the ‘port-position’ and ‘set-port-position!’ operations
     is implementation-dependent (and possibly transcoder-dependent).


File: guile.info,  Node: rnrs io simple,  Next: rnrs files,  Prev: R6RS File Ports,  Up: R6RS Standard Libraries

7.6.2.18 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 (*note R6RS 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.  *Note rnrs io 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.  *Note 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.  *Note File Ports::, for documentation.

 -- Scheme Procedure: close-input-port input-port
 -- Scheme Procedure: close-output-port output-port
     Closes the given INPUT-PORT or OUTPUT-PORT.  These are legacy
     interfaces; just use ‘close-port’.

 -- 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.  *Note Venerable Port Interfaces::, for documentation.

 -- Scheme Procedure: read
 -- Scheme Procedure: read textual-input-port
     This procedure is identical to the one provided by Guile’s core
     library.  *Note 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.  *Note Venerable Port Interfaces::, and *Note Scheme
     Write::, for documentation.


File: guile.info,  Node: rnrs files,  Next: rnrs programs,  Prev: rnrs io simple,  Up: R6RS Standard Libraries

7.6.2.19 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.  *Note File System::, for documentation.


File: guile.info,  Node: rnrs programs,  Next: rnrs arithmetic fixnums,  Prev: rnrs files,  Up: R6RS Standard Libraries

7.6.2.20 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.  *Note Runtime Environment::, for documentation.

 -- Scheme Procedure: exit [status]
     This procedure is identical to the one provided by Guile’s core
     library.  *Note Processes::, for documentation.


File: guile.info,  Node: rnrs arithmetic fixnums,  Next: rnrs arithmetic flonums,  Prev: rnrs programs,  Up: R6RS Standard Libraries

7.6.2.21 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—(*note 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;
     *Note (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.  *Note
     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).


File: guile.info,  Node: rnrs arithmetic flonums,  Next: rnrs arithmetic bitwise,  Prev: rnrs arithmetic fixnums,  Up: R6RS Standard Libraries

7.6.2.22 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;
     *Note (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.  *Note 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 (*note (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.


File: guile.info,  Node: rnrs arithmetic bitwise,  Next: rnrs syntax-case,  Prev: rnrs arithmetic flonums,  Up: R6RS Standard Libraries

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


File: guile.info,  Node: rnrs syntax-case,  Next: rnrs hashtables,  Prev: rnrs arithmetic bitwise,  Up: R6RS Standard Libraries

7.6.2.24 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’; *Note 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; *Note 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


File: guile.info,  Node: rnrs hashtables,  Next: rnrs enums,  Prev: rnrs syntax-case,  Up: R6RS Standard Libraries

7.6.2.25 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; *Note Hash
Tables::, and *note 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.  *Note 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.


File: guile.info,  Node: rnrs enums,  Next: rnrs,  Prev: rnrs hashtables,  Up: R6RS Standard Libraries

7.6.2.26 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.  *Note 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.


File: guile.info,  Node: rnrs,  Next: rnrs eval,  Prev: rnrs enums,  Up: R6RS Standard Libraries

7.6.2.27 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))’


File: guile.info,  Node: rnrs eval,  Next: rnrs mutable-pairs,  Prev: rnrs,  Up: R6RS Standard Libraries

7.6.2.28 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; *Note 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.  *Note R6RS
     Libraries::, for documentation.


File: guile.info,  Node: rnrs mutable-pairs,  Next: rnrs mutable-strings,  Prev: rnrs eval,  Up: R6RS Standard Libraries

7.6.2.29 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.  *Note Pairs::, for documentation.  All pairs in Guile are
mutable; consequently, these procedures will never throw the
‘&assertion’ condition described in the R6RS libraries specification.


File: guile.info,  Node: rnrs mutable-strings,  Next: rnrs r5rs,  Prev: rnrs mutable-pairs,  Up: R6RS Standard Libraries

7.6.2.30 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.  *Note 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.


File: guile.info,  Node: rnrs r5rs,  Prev: rnrs mutable-strings,  Up: R6RS Standard Libraries

7.6.2.31 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.  *Note 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.  *Note 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.  *Note 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.  *Note Environments::, for documentation.


File: guile.info,  Node: R7RS Support,  Next: Pattern Matching,  Prev: R6RS Support,  Up: Guile Modules

7.7 R7RS Support
================

The R7RS (https://small.r7rs.org/) standard is essentially R5RS
(directly supported by Guile), plus a module facility, plus an
organization of bindings into a standard set of modules.

   Happily, the syntax for R7RS modules was chosen to be compatible with
R6RS, and so Guile’s documentation there applies.  *Note R6RS
Libraries::, for more information on how to define R6RS libraries, and
their integration with Guile modules.  *Note Library Usage::, also.

* Menu:

* R7RS Incompatibilities::              Guile mostly implements R7RS.
* R7RS Standard Libraries::             Modules defined by the R7RS.


File: guile.info,  Node: R7RS Incompatibilities,  Next: R7RS Standard Libraries,  Up: R7RS Support

7.7.1 Incompatibilities with the R7RS
-------------------------------------

As the R7RS is a much less ambitious standard than the R6RS (*note Guile
and Scheme::), it is very easy for Guile to support.  As such, Guile is
a fully conforming implementation of R7RS, with the exception of the
occasional bug and a couple of unimplemented features:

   • The R7RS specifies a syntax for reading circular data structures
     using “datum labels”, such as ‘#0=(1 2 3 . #0#)’.  Guile’s reader
     does not support this syntax currently;
     <https://bugs.gnu.org/38236>.

   • As with R6RS, a number of lexical features of R7RS conflict with
     Guile’s historical syntax.  In addition to ‘r6rs-hex-escapes’ and
     ‘hungry-eol-escapes’ (*note R6RS Incompatibilities::), the
     ‘r7rs-symbols’ reader feature needs to be explicitly enabled.

   Guile exposes a procedure in the root module to choose R7RS defaults
over Guile’s historical defaults.

 -- Scheme Procedure: install-r7rs!
     Alter Guile’s default settings to better conform to the R7RS.

     While Guile’s defaults may evolve over time, the current changes
     that this procedure imposes are to add ‘.sls’ and ‘.guile.sls’ to
     the set of supported ‘%load-extensions’, to better support R7RS
     conventions.  *Note Load Paths::.  ‘install-r7rs!’ will also enable
     the reader options mentioned above.

   Finally, note that the ‘--r7rs’ command-line argument will call
‘install-r7rs!’ before calling user code.  R7RS users probably want to
pass this argument to their Guile.


File: guile.info,  Node: R7RS Standard Libraries,  Prev: R7RS Incompatibilities,  Up: R7RS Support

7.7.2 R7RS Standard Libraries
-----------------------------

The R7RS organizes the definitions from R5RS into modules, and also adds
a few new definitions.

   We do not attempt to document these libraries fully here, as unlike
R6RS, there are few new definitions in R7RS relative to R5RS. Most of
their functionality is already in Guile’s standard environment.  Again,
the expectation is that most Guile users will use the well-known and
well-documented Guile modules; these R7RS libraries are mostly useful to
users who want to port their code to other R7RS systems.

   As a brief overview, we note that the libraries defined by the R7RS
are as follows:

‘(scheme base)’
     The core functions, mostly corresponding to R5RS minus the elements
     listed separately below, but plus SRFI-34 error handling (*note
     SRFI-34::), bytevectors and bytevector ports (*note Bytevectors::),
     and some miscellaneous other new procedures.
‘(scheme case-lambda)’
     ‘case-lambda’.
‘(scheme char)’
     Converting strings and characters to upper or lower case,
     predicates for if a characer is numeric, and so on.
‘(scheme complex)’
     Constructors and accessors for complex numbers.
‘(scheme cxr)’
     ‘cddr’, ‘cadadr’, and all that.
‘(scheme eval)’
     ‘eval’, but also an ‘environment’ routine allowing a user to
     specify an environment using a module import set.
‘(scheme file)’
     ‘call-with-input-file’ and so on.
‘(scheme inexact)’
     Routines that operate on inexact numbers: ‘sin’, ‘finite?’, and so
     on.
‘(scheme lazy)’
     Promises.
‘(scheme load)’
     The ‘load’ procedure.
‘(scheme process-context)’
     Environment variables.  *Note SRFI-98::.  Also, ‘commmand-line’,
     ‘emergency-exit’ (like Guile’s ‘primitive-_exit’), and ‘exit’.
‘(scheme r5rs)’
     The precise set of bindings exported by ‘r5rs’, but without
     ‘transcript-off’ / ‘transcript-on’, and also with the auxiliary
     syntax definitions like ‘_’ or ‘else’.  *Note Syntax Rules::, for
     more on auxiliary syntax.
‘(scheme read)’
     The ‘read’ procedure.
‘(scheme repl)’
     The ‘interaction-environment’ procedure.
‘(scheme time)’
     ‘current-second’, as well as ‘current-jiffy’ and
     ‘jiffies-per-second’.  Guile uses the term “internal time unit” for
     what R7RS calls “jiffies”.
‘(scheme write)’
     ‘display’, ‘write’, as well as ‘write-shared’ and ‘write-simple’.

   For complete documentation, we advise the interested user to consult
the R7RS directly (*note (r7rs)R7RS::).


File: guile.info,  Node: Pattern Matching,  Next: Readline Support,  Prev: R7RS Support,  Up: Guile Modules

7.8 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"’.

   The ‘(ice-9 match)’ module also provides the following convenient
syntactic sugar macros wrapping around ‘match’.

 -- Scheme Syntax: match-lambda clause1 clause2 ...
     Create a procedure of one argument that matches its argument
     against each clause, and returns the result of evaluating the
     corresponding expressions.

          (match-lambda clause1 clause2 ...)
          ≡
          (lambda (arg) (match arg clause1 clause2 ...))

     ((match-lambda
        (('hello (who))
         who))
      '(hello (world)))
     ⇒ world

 -- Scheme Syntax: match-lambda* clause1 clause2 ...
     Create a procedure of any number of arguments that matches its
     argument list against each clause, and returns the result of
     evaluating the corresponding expressions.

          (match-lambda* clause1 clause2 ...)
          ≡
          (lambda args (match args clause1 clause2 ...))

     ((match-lambda*
        (('hello (who))
         who))
      'hello '(world))
     ⇒ world

 -- Scheme Syntax: match-let ((pattern expression) ...) body
     Match each pattern to the corresponding expression, and evaluate
     the body with all matched variables in scope.  Raise an error if
     any of the expressions fail to match.  ‘match-let’ is analogous to
     named let and can also be used for recursive functions which match
     on their arguments as in ‘match-lambda*’.

          (match-let (((x y) (list 1 2))
                      ((a b) (list 3 4)))
            (list a b x y))
          ⇒
          (3 4 1 2)

 -- Scheme Syntax: match-let variable ((pattern init) ...) body
     Similar to ‘match-let’, but analogously to “named let”, locally
     bind VARIABLE to a new procedure which accepts as many arguments as
     there are INIT expressions.  The procedure is initially applied to
     the results of evaluating the INIT expressions.  When called, the
     procedure matches each argument against the corresponding PATTERN,
     and returns the result(s) of evaluating the BODY expressions.
     *Note Iteration: while do, for more on “named let”.

 -- Scheme Syntax: match-let* ((variable expression) ...) body
     Similar to ‘match-let’, but analogously to ‘let*’, match and bind
     the variables in sequence, with preceding match variables in scope.

          (match-let* (((x y) (list 1 2))
                       ((a b) (list x 4)))
            (list a b x y))
          ≡
          (match-let (((x y) (list 1 2)))
            (match-let (((a b) (list x 4)))
              (list a b x y)))
          ⇒
          (1 4 1 2)

 -- Scheme Syntax: match-letrec ((variable expression) ...) body
     Similar to ‘match-let’, but analogously to ‘letrec’, match and bind
     the variables with all match variables in scope.

   Guile also comes with a pattern matcher specifically tailored to SXML
trees, *Note sxml-match::.


File: guile.info,  Node: Readline Support,  Next: Pretty Printing,  Prev: Pattern Matching,  Up: Guile Modules

7.9 Readline Support
====================

Guile comes with an interface module to the readline library (*note
(readline)Top::).  This makes interactive use much more convenient,
because of the command-line editing features of readline.  Using ‘(ice-9
readline)’, you can navigate through the current input line with the
cursor keys, retrieve older command lines from the input history and
even search through the history entries.

* Menu:

* Loading Readline Support::    How to load readline support into Guile.
* Readline Options::            How to modify readline’s behavior.
* Readline Functions::          Programming with readline.


File: guile.info,  Node: Loading Readline Support,  Next: Readline Options,  Up: Readline Support

7.9.1 Loading Readline Support
------------------------------

The module is not loaded by default and so has to be loaded and
activated explicitly.  This is done with two simple lines of code:

     (use-modules (ice-9 readline))
     (activate-readline)

   The first line will load the necessary code, and the second will
activate readline’s features for the REPL. If you plan to use this
module often, you should save these to lines to your ‘.guile’ personal
startup file.

   You will notice that the REPL’s behavior changes a bit when you have
loaded the readline module.  For example, when you press Enter before
typing in the closing parentheses of a list, you will see the
“continuation” prompt, three dots: ‘...’ This gives you a nice visual
feedback when trying to match parentheses.  To make this even easier,
“bouncing parentheses” are implemented.  That means that when you type
in a closing parentheses, the cursor will jump to the corresponding
opening parenthesis for a short time, making it trivial to make them
match.

   Once the readline module is activated, all lines entered
interactively will be stored in a history and can be recalled later
using the cursor-up and -down keys.  Readline also understands the Emacs
keys for navigating through the command line and history.

   When you quit your Guile session by evaluating ‘(quit)’ or pressing
Ctrl-D, the history will be saved to the file ‘.guile_history’ and read
in when you start Guile for the next time.  Thus you can start a new
Guile session and still have the (probably long-winded) definition
expressions available.

   You can specify a different history file by setting the environment
variable ‘GUILE_HISTORY’.  And you can make Guile specific
customizations to your ‘.inputrc’ by testing for application ‘Guile’
(*note (readline)Conditional Init Constructs::).  For instance to define
a key inserting a matched pair of parentheses,

     $if Guile
       "\C-o": "()\C-b"
     $endif


File: guile.info,  Node: Readline Options,  Next: Readline Functions,  Prev: Loading Readline Support,  Up: Readline Support

7.9.2 Readline Options
----------------------

The readline interface module can be tweaked in a few ways to better
suit the user’s needs.  Configuration is done via the readline module’s
options interface, in a similar way to the evaluator and debugging
options (*note Runtime Options::).

 -- Scheme Procedure: readline-options
 -- Scheme Procedure: readline-enable option-name
 -- Scheme Procedure: readline-disable option-name
 -- Scheme Syntax: readline-set! option-name value
     Accessors for the readline options.  Note that unlike the
     enable/disable procedures, ‘readline-set!’ is syntax, which expects
     an unquoted option name.

   Here is the list of readline options generated by typing
‘(readline-options 'help)’ in Guile.  You can also see the default
values.

     history-file    yes     Use history file.
     history-length  200     History length.
     bounce-parens   500     Time (ms) to show matching opening parenthesis
                             (0 = off).
     bracketed-paste yes     Disable interpretation of control characters
                             in pastes.

   The readline options interface can only be used _after_ loading the
readline module, because it is defined in that module.


File: guile.info,  Node: Readline Functions,  Prev: Readline Options,  Up: Readline Support

7.9.3 Readline Functions
------------------------

The following functions are provided by

     (use-modules (ice-9 readline))

   There are two ways to use readline from Scheme code, either make
calls to ‘readline’ directly to get line by line input, or use the
readline port below with all the usual reading functions.

 -- Function: readline [prompt]
     Read a line of input from the user and return it as a string
     (without a newline at the end).  PROMPT is the prompt to show, or
     the default is the string set in ‘set-readline-prompt!’ below.

          (readline "Type something: ") ⇒ "hello"

 -- Function: set-readline-input-port! port
 -- Function: set-readline-output-port! port
     Set the input and output port the readline function should read
     from and write to.  PORT must be a file port (*note File Ports::),
     and should usually be a terminal.

     The default is the ‘current-input-port’ and ‘current-output-port’
     (*note Default Ports::) when ‘(ice-9 readline)’ loads, which in an
     interactive user session means the Unix “standard input” and
     “standard output”.

7.9.3.1 Readline Port
.....................

 -- Function: readline-port
     Return a buffered input port (*note Buffered Input::) which calls
     the ‘readline’ function above to get input.  This port can be used
     with all the usual reading functions (‘read’, ‘read-char’, etc),
     and the user gets the interactive editing features of readline.

     There’s only a single readline port created.  ‘readline-port’
     creates it when first called, and on subsequent calls just returns
     what it previously made.

 -- Function: activate-readline
     If the ‘current-input-port’ is a terminal (*note ‘isatty?’:
     Terminals and Ptys.) then enable readline for all reading from
     ‘current-input-port’ (*note Default Ports::) and enable readline
     features in the interactive REPL (*note The REPL::).

          (activate-readline)
          (read-char)

     ‘activate-readline’ enables readline on ‘current-input-port’ simply
     by a ‘set-current-input-port’ to the ‘readline-port’ above.  An
     application can do that directly if the extra REPL features that
     ‘activate-readline’ adds are not wanted.

 -- Function: set-readline-prompt! prompt1 [prompt2]
     Set the prompt string to print when reading input.  This is used
     when reading through ‘readline-port’, and is also the default
     prompt for the ‘readline’ function above.

     PROMPT1 is the initial prompt shown.  If a user might enter an
     expression across multiple lines, then PROMPT2 is a different
     prompt to show further input required.  In the Guile REPL for
     instance this is an ellipsis (‘...’).

     See ‘set-buffered-input-continuation?!’ (*note Buffered Input::)
     for an application to indicate the boundaries of logical
     expressions (assuming of course an application has such a notion).

7.9.3.2 Completion
..................

 -- Function: with-readline-completion-function completer thunk
     Call ‘(THUNK)’ with COMPLETER as the readline tab completion
     function to be used in any readline calls within that THUNK.
     COMPLETER can be ‘#f’ for no completion.

     COMPLETER will be called as ‘(COMPLETER text state)’, as described
     in (*note (readline)How Completing Works::).  TEXT is a partial
     word to be completed, and each COMPLETER call should return a
     possible completion string or ‘#f’ when no more.  STATE is ‘#f’ for
     the first call asking about a new TEXT then ‘#t’ while getting
     further completions of that TEXT.

     Here’s an example COMPLETER for user login names from the password
     file (*note User Information::), much like readline’s own
     ‘rl_username_completion_function’,

          (define (username-completer-function text state)
            (if (not state)
                (setpwent))  ;; new, go to start of database
            (let more ((pw (getpwent)))
              (if pw
                  (if (string-prefix? text (passwd:name pw))
                      (passwd:name pw)     ;; this name matches, return it
                      (more (getpwent)))   ;; doesn't match, look at next
                  (begin
                    ;; end of database, close it and return #f
                    (endpwent)
                    #f))))

 -- Function: apropos-completion-function text state
     A completion function offering completions for Guile functions and
     variables (all ‘define’s).  This is the default completion
     function.

 -- Function: filename-completion-function text state
     A completion function offering filename completions.  This is
     readline’s ‘rl_filename_completion_function’ (*note
     (readline)Completion Functions::).

 -- Function: make-completion-function string-list
     Return a completion function which offers completions from the
     possibilities in STRING-LIST.  Matching is case-sensitive.


File: guile.info,  Node: Pretty Printing,  Next: Formatted Output,  Prev: Readline Support,  Up: Guile Modules

7.10 Pretty Printing
====================

The module ‘(ice-9 pretty-print)’ provides the procedure ‘pretty-print’,
which provides nicely formatted output of Scheme objects.  This is
especially useful for deeply nested or complex data structures, such as
lists and vectors.

   The module is loaded by entering the following:

     (use-modules (ice-9 pretty-print))

   This makes the procedure ‘pretty-print’ available.  As an example how
‘pretty-print’ will format the output, see the following:

     (pretty-print '(define (foo) (lambda (x)
     (cond ((zero? x) #t) ((negative? x) -x) (else
     (if (= x 1) 2 (* x x x)))))))
     ⊣
     (define (foo)
       (lambda (x)
         (cond ((zero? x) #t)
               ((negative? x) -x)
               (else (if (= x 1) 2 (* x x x))))))

 -- Scheme Procedure: pretty-print obj [port] [keyword-options]
     Print the textual representation of the Scheme object OBJ to PORT.
     PORT defaults to the current output port, if not given.

     The further KEYWORD-OPTIONS are keywords and parameters as follows,

     #:display? FLAG
          If FLAG is true then print using ‘display’.  The default is
          ‘#f’ which means use ‘write’ style.  *Note Scheme Write::.

     #:per-line-prefix STRING
          Print the given STRING as a prefix on each line.  The default
          is no prefix.

     #:width COLUMNS
          Print within the given COLUMNS.  The default is 79.

     #:max-expr-width COLUMNS
          The maximum width of an expression.  The default is 50.

   Also exported by the ‘(ice-9 pretty-print)’ module is
‘truncated-print’, a procedure to print Scheme datums, truncating the
output to a certain number of characters.  This is useful when you need
to present an arbitrary datum to the user, but you only have one line in
which to do so.

     (define exp '(a b #(c d e) f . g))
     (truncated-print exp #:width 10) (newline)
     ⊣ (a b . #)
     (truncated-print exp #:width 15) (newline)
     ⊣ (a b # f . g)
     (truncated-print exp #:width 18) (newline)
     ⊣ (a b #(c ...) . #)
     (truncated-print exp #:width 20) (newline)
     ⊣ (a b #(c d e) f . g)
     (truncated-print "The quick brown fox" #:width 20) (newline)
     ⊣ "The quick brown..."
     (truncated-print (current-module) #:width 20) (newline)
     ⊣ #<directory (gui...>

   ‘truncated-print’ will not output a trailing newline.  If an
expression does not fit in the given width, it will be truncated –
possibly ellipsized(1), or in the worst case, displayed as #.

 -- Scheme Procedure: truncated-print obj [port] [keyword-options]
     Print OBJ, truncating the output, if necessary, to make it fit into
     WIDTH characters.  By default, OBJ will be printed using ‘write’,
     though that behavior can be overridden via the DISPLAY? keyword
     argument.

     The default behavior is to print depth-first, meaning that the
     entire remaining width will be available to each sub-expression of
     OBJ – e.g., if OBJ is a vector, each member of OBJ.  One can
     attempt to “ration” the available width, trying to allocate it
     equally to each sub-expression, via the BREADTH-FIRST? keyword
     argument.

     The further KEYWORD-OPTIONS are keywords and parameters as follows,

     #:display? FLAG
          If FLAG is true then print using ‘display’.  The default is
          ‘#f’ which means use ‘write’ style.  *note Scheme Write::.

     #:width COLUMNS
          Print within the given COLUMNS.  The default is 79.

     #:breadth-first? FLAG
          If FLAG is true, then allocate the available width
          breadth-first among elements of a compound data structure
          (list, vector, pair, etc.).  The default is ‘#f’ which means
          that any element is allowed to consume all of the available
          width.

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

   (1) On Unicode-capable ports, the ellipsis is represented by
character ‘HORIZONTAL ELLIPSIS’ (U+2026), otherwise it is represented by
three dots.


File: guile.info,  Node: Formatted Output,  Next: File Tree Walk,  Prev: Pretty Printing,  Up: Guile Modules

7.11 Formatted Output
=====================

The ‘format’ function is a powerful way to print numbers, strings and
other objects together with literal text under the control of a format
string.  This function is available from

     (use-modules (ice-9 format))

   A format string is generally more compact and easier than using just
the standard procedures like ‘display’, ‘write’ and ‘newline’.
Parameters in the output string allow various output styles, and
parameters can be taken from the arguments for runtime flexibility.

   ‘format’ is similar to the Common Lisp procedure of the same name,
but it’s not identical and doesn’t have quite all the features found in
Common Lisp.

   C programmers will note the similarity between ‘format’ and ‘printf’,
though escape sequences are marked with ~ instead of %, and are more
powerful.


 -- Scheme Procedure: format dest fmt arg ...
     Write output specified by the FMT string to DEST.  DEST can be an
     output port, ‘#t’ for ‘current-output-port’ (*note Default
     Ports::), or ‘#f’ to return the output as a string.

     FMT can contain literal text to be output, and ~ escapes.  Each
     escape has the form

          ~ [param [, param...] [:] [@] code

     code is a character determining the escape sequence.  The : and @
     characters are optional modifiers, one or both of which change the
     way various codes operate.  Optional parameters are accepted by
     some codes too.  Parameters have the following forms,

     [+/-]number
          An integer, with optional + or -.
     ’ (apostrophe)
          The following character in the format string, for instance ’z
          for z.
     v
          The next function argument as the parameter.  v stands for
          “variable”, a parameter can be calculated at runtime and
          included in the arguments.  Upper case V can be used too.
     #
          The number of arguments remaining.  (See ~* below for some
          usages.)

     Parameters are separated by commas (,).  A parameter can be left
     empty to keep its default value when supplying later parameters.


     The following escapes are available.  The code letters are not
     case-sensitive, upper and lower case are the same.

     ~a
     ~s
          Object output.  Parameters: MINWIDTH, PADINC, MINPAD, PADCHAR.

          ~a outputs an argument like ‘display’, ~s outputs an argument
          like ‘write’ (*note Scheme Write::).

               (format #t "~a" "foo") ⊣ foo
               (format #t "~s" "foo") ⊣ "foo"

          ~:a and ~:s put objects that don’t have an external
          representation in quotes like a string.

               (format #t "~:a" car) ⊣ "#<primitive-procedure car>"

          If the output is less than MINWIDTH characters (default 0),
          it’s padded on the right with PADCHAR (default space).  ~@a
          and ~@s put the padding on the left instead.

               (format #f "~5a" 'abc)       ⇒ "abc  "
               (format #f "~5,,,'-@a" 'abc) ⇒ "--abc"

          MINPAD is a minimum for the padding then plus a multiple of
          PADINC.  Ie. the padding is MINPAD + N * PADINC, where N is
          the smallest integer making the total object plus padding
          greater than or equal to MINWIDTH.  The default MINPAD is 0
          and the default PADINC is 1 (imposing no minimum or multiple).

               (format #f "~5,1,4a" 'abc) ⇒ "abc    "

     ~c
          Character.  Parameter: CHARNUM.

          Output a character.  The default is to simply output, as per
          ‘write-char’ (*note Venerable Port Interfaces::).  ~@c prints
          in ‘write’ style.  ~:c prints control characters (ASCII 0 to
          31) in ^X form.

               (format #t "~c" #\z)        ⊣ z
               (format #t "~@c" #\z)       ⊣ #\z
               (format #t "~:c" #\newline) ⊣ ^J

          If the CHARNUM parameter is given then an argument is not
          taken but instead the character is ‘(integer->char CHARNUM)’
          (*note Characters::).  This can be used for instance to output
          characters given by their ASCII code.

               (format #t "~65c")  ⊣ A

     ~d
     ~x
     ~o
     ~b
          Integer.  Parameters: MINWIDTH, PADCHAR, COMMACHAR,
          COMMAWIDTH.

          Output an integer argument as a decimal, hexadecimal, octal or
          binary integer (respectively), in a locale-independent way.

               (format #t "~d" 123) ⊣ 123

          ~@d etc shows a + sign is shown on positive numbers.

               (format #t "~@b" 12) ⊣ +1100

          If the output is less than the MINWIDTH parameter (default no
          minimum), it’s padded on the left with the PADCHAR parameter
          (default space).

               (format #t "~5,'*d" 12)   ⊣ ***12
               (format #t "~5,'0d" 12)   ⊣ 00012
               (format #t "~3d"    1234) ⊣ 1234

          ~:d adds commas (or the COMMACHAR parameter) every three
          digits (or the COMMAWIDTH parameter many).  However, when your
          intent is to write numbers in a way that follows typographical
          conventions, using ~h is recommended.

               (format #t "~:d" 1234567)         ⊣ 1,234,567
               (format #t "~10,'*,'/,2:d" 12345) ⊣ ***1/23/45

          Hexadecimal ~x output is in lower case, but the ~( and ~) case
          conversion directives described below can be used to get upper
          case.

               (format #t "~x"       65261) ⊣ feed
               (format #t "~:@(~x~)" 65261) ⊣ FEED

     ~r
          Integer in words, roman numerals, or a specified radix.
          Parameters: RADIX, MINWIDTH, PADCHAR, COMMACHAR, COMMAWIDTH.

          With no parameters output is in words as a cardinal like
          “ten”, or ~:r prints an ordinal like “tenth”.

               (format #t "~r" 9)  ⊣ nine        ;; cardinal
               (format #t "~r" -9) ⊣ minus nine  ;; cardinal
               (format #t "~:r" 9) ⊣ ninth       ;; ordinal

          And also with no parameters, ~@r gives roman numerals and ~:@r
          gives old roman numerals.  In old roman numerals there’s no
          “subtraction”, so 9 is VIIII instead of IX. In both cases only
          positive numbers can be output.

               (format #t "~@r" 89)  ⊣ LXXXIX     ;; roman
               (format #t "~:@r" 89) ⊣ LXXXVIIII  ;; old roman

          When a parameter is given it means numeric output in the
          specified RADIX.  The modifiers and parameters following the
          radix are the same as described for ~d etc above.

               (format #f "~3r" 27)   ⇒ "1000"    ;; base 3
               (format #f "~3,5r" 26) ⇒ "  222"   ;; base 3 width 5

     ~f
          Fixed-point float.  Parameters: WIDTH, DECIMALS, SCALE,
          OVERFLOWCHAR, PADCHAR.

          Output a number or number string in fixed-point format, ie.
          with a decimal point.

               (format #t "~f" 5)      ⊣ 5.0
               (format #t "~f" "123")  ⊣ 123.0
               (format #t "~f" "1e-1") ⊣ 0.1

          ~@f prints a + sign on positive numbers (including zero).

               (format #t "~@f" 0) ⊣ +0.0

          If the output is less than WIDTH characters it’s padded on the
          left with PADCHAR (space by default).  If the output equals or
          exceeds WIDTH then there’s no padding.  The default for WIDTH
          is no padding.

               (format #f "~6f" -1.5)      ⇒ "  -1.5"
               (format #f "~6,,,,'*f" 23)  ⇒ "**23.0"
               (format #f "~6f" 1234567.0) ⇒ "1234567.0"

          DECIMALS is how many digits to print after the decimal point,
          with the value rounded or padded with zeros as necessary.
          (The default is to output as many decimals as required.)

               (format #t "~1,2f" 3.125) ⊣ 3.13
               (format #t "~1,2f" 1.5)   ⊣ 1.50

          SCALE is a power of 10 applied to the value, moving the
          decimal point that many places.  A positive SCALE increases
          the value shown, a negative decreases it.

               (format #t "~,,2f" 1234)  ⊣ 123400.0
               (format #t "~,,-2f" 1234) ⊣ 12.34

          If OVERFLOWCHAR and WIDTH are both given and if the output
          would exceed WIDTH, then that many OVERFLOWCHARs are printed
          instead of the value.

               (format #t "~6,,,'xf" 12345) ⊣ 12345.
               (format #t "~5,,,'xf" 12345) ⊣ xxxxx

     ~h
          Localized number(1).  Parameters: WIDTH, DECIMALS, PADCHAR.

          Like ~f, output an exact or floating point number, but do so
          according to the current locale, or according to the given
          locale object when the ‘:’ modifier is used (*note
          ‘number->locale-string’: Number Input and Output.).

               (format #t "~h" 12345.5678)  ; with "C" as the current locale
               ⊣ 12345.5678

               (format #t "~14,,'*:h" 12345.5678
                       (make-locale LC_ALL "en_US"))
               ⊣ ***12,345.5678

               (format #t "~,2:h" 12345.5678
                       (make-locale LC_NUMERIC "fr_FR"))
               ⊣ 12 345,56

     ~e
          Exponential float.  Parameters: WIDTH, MANTDIGITS, EXPDIGITS,
          INTDIGITS, OVERFLOWCHAR, PADCHAR, EXPCHAR.

          Output a number or number string in exponential notation.

               (format #t "~e" 5000.25) ⊣ 5.00025E+3
               (format #t "~e" "123.4") ⊣ 1.234E+2
               (format #t "~e" "1e4")   ⊣ 1.0E+4

          ~@e prints a + sign on positive numbers (including zero).
          (This is for the mantissa, a + or - sign is always shown on
          the exponent.)

               (format #t "~@e" 5000.0) ⊣ +5.0E+3

          If the output is less than WIDTH characters it’s padded on the
          left with PADCHAR (space by default).  The default for WIDTH
          is to output with no padding.

               (format #f "~10e" 1234.0)     ⇒ "  1.234E+3"
               (format #f "~10,,,,,'*e" 0.5) ⇒ "****5.0E-1"

          MANTDIGITS is the number of digits shown in the mantissa after
          the decimal point.  The value is rounded or trailing zeros are
          added as necessary.  The default MANTDIGITS is to show as much
          as needed by the value.

               (format #f "~,3e" 11111.0) ⇒ "1.111E+4"
               (format #f "~,8e" 123.0)   ⇒ "1.23000000E+2"

          EXPDIGITS is the minimum number of digits shown for the
          exponent, with leading zeros added if necessary.  The default
          for EXPDIGITS is to show only as many digits as required.  At
          least 1 digit is always shown.

               (format #f "~,,1e" 1.0e99) ⇒ "1.0E+99"
               (format #f "~,,6e" 1.0e99) ⇒ "1.0E+000099"

          INTDIGITS (default 1) is the number of digits to show before
          the decimal point in the mantissa.  INTDIGITS can be zero, in
          which case the integer part is a single 0, or it can be
          negative, in which case leading zeros are shown after the
          decimal point.

               (format #t "~,,,3e" 12345.0)  ⊣ 123.45E+2
               (format #t "~,,,0e" 12345.0)  ⊣ 0.12345E+5
               (format #t "~,,,-3e" 12345.0) ⊣ 0.00012345E+8

          If OVERFLOWCHAR is given then WIDTH is a hard limit.  If the
          output would exceed WIDTH then instead that many OVERFLOWCHARs
          are printed.

               (format #f "~6,,,,'xe" 100.0) ⇒ "1.0E+2"
               (format #f "~3,,,,'xe" 100.0) ⇒ "xxx"

          EXPCHAR is the exponent marker character (default E).

               (format #t "~,,,,,,'ee" 100.0) ⊣ 1.0e+2

     ~g
          General float.  Parameters: WIDTH, MANTDIGITS, EXPDIGITS,
          INTDIGITS, OVERFLOWCHAR, PADCHAR, EXPCHAR.

          Output a number or number string in either exponential format
          the same as ~e, or fixed-point format like ~f but aligned
          where the mantissa would have been and followed by padding
          where the exponent would have been.

          Fixed-point is used when the absolute value is 0.1 or more and
          it takes no more space than the mantissa in exponential
          format, ie. basically up to MANTDIGITS digits.

               (format #f "~12,4,2g" 999.0)    ⇒ "   999.0    "
               (format #f "~12,4,2g" "100000") ⇒ "  1.0000E+05"

          The parameters are interpreted as per ~e above.  When
          fixed-point is used, the DECIMALS parameter to ~f is
          established from MANTDIGITS, so as to give a total
          MANTDIGITS+1 figures.

     ~$
          Monetary style fixed-point float.  Parameters: DECIMALS,
          INTDIGITS, WIDTH, PADCHAR.

          Output a number or number string in fixed-point format, ie.
          with a decimal point.  DECIMALS is the number of decimal
          places to show, default 2.

               (format #t "~$" 5)       ⊣ 5.00
               (format #t "~4$" "2.25") ⊣ 2.2500
               (format #t "~4$" "1e-2") ⊣ 0.0100

          ~@$ prints a + sign on positive numbers (including zero).

               (format #t "~@$" 0) ⊣ +0.00

          INTDIGITS is a minimum number of digits to show in the integer
          part of the value (default 1).

               (format #t "~,3$" 9.5)   ⊣ 009.50
               (format #t "~,0$" 0.125) ⊣ .13

          If the output is less than WIDTH characters (default 0), it’s
          padded on the left with PADCHAR (default space).  ~:$ puts the
          padding after the sign.

               (format #f "~,,8$" -1.5)   ⇒ "   -1.50"
               (format #f "~,,8:$" -1.5)  ⇒ "-   1.50"
               (format #f "~,,8,'.:@$" 3) ⇒ "+...3.00"

          Note that floating point for dollar amounts is generally not a
          good idea, because a cent 0.01 cannot be represented exactly
          in the binary floating point Guile uses, which leads to slowly
          accumulating rounding errors.  Keeping values as cents (or
          fractions of a cent) in integers then printing with the scale
          option in ~f may be a better approach.

     ~i
          Complex fixed-point float.  Parameters: WIDTH, DECIMALS,
          SCALE, OVERFLOWCHAR, PADCHAR.

          Output the argument as a complex number, with both real and
          imaginary part shown (even if one or both are zero).

          The parameters and modifiers are the same as for fixed-point
          ~f described above.  The real and imaginary parts are both
          output with the same given parameters and modifiers, except
          that for the imaginary part the @ modifier is always enabled,
          so as to print a + sign between the real and imaginary parts.

               (format #t "~i" 1)  ⊣ 1.0+0.0i

     ~p
          Plural.  No parameters.

          Output nothing if the argument is 1, or ‘s’ for any other
          value.

               (format #t "enter name~p" 1) ⊣ enter name
               (format #t "enter name~p" 2) ⊣ enter names

          ~@p prints ‘y’ for 1 or ‘ies’ otherwise.

               (format #t "pupp~@p" 1) ⊣ puppy
               (format #t "pupp~@p" 2) ⊣ puppies

          ~:p re-uses the preceding argument instead of taking a new
          one, which can be convenient when printing some sort of count.

               (format #t "~d cat~:p" 9)   ⊣ 9 cats
               (format #t "~d pupp~:@p" 5) ⊣ 5 puppies

          ~p is designed for English plurals and there’s no attempt to
          support other languages.  ~[ conditionals (below) may be able
          to help.  When using ‘gettext’ to translate messages
          ‘ngettext’ is probably best though (*note
          Internationalization::).

     ~y
          Structured printing.  Parameters: WIDTH.

          ~y outputs an argument using ‘pretty-print’ (*note Pretty
          Printing::).  The result will be formatted to fit within WIDTH
          columns (79 by default), consuming multiple lines if
          necessary.

          ~@y outputs an argument using ‘truncated-print’ (*note Pretty
          Printing::).  The resulting code will be formatted to fit
          within WIDTH columns (79 by default), on a single line.  The
          output will be truncated if necessary.

          ~:@y is like ~@y, except the WIDTH parameter is interpreted to
          be the maximum column to which to output.  That is to say, if
          you are at column 10, and ~60:@y is seen, the datum will be
          truncated to 50 columns.

     ~?
     ~k
          Sub-format.  No parameters.

          Take a format string argument and a second argument which is a
          list of arguments for that string, and output the result.

               (format #t "~?" "~d ~d" '(1 2))    ⊣ 1 2

          ~@?  takes arguments for the sub-format directly rather than
          in a list.

               (format #t "~@? ~s" "~d ~d" 1 2 "foo") ⊣ 1 2 "foo"

          ~?  and ~k are the same, ~k is provided for T-Scheme
          compatibility.

     ~*
          Argument jumping.  Parameter: N.

          Move forward N arguments (default 1) in the argument list.
          ~:* moves backwards.  (N cannot be negative.)

               (format #f "~d ~2*~d" 1 2 3 4) ⇒ "1 4"
               (format #f "~d ~:*~d" 6)       ⇒ "6 6"

          ~@* moves to argument number N.  The first argument is number
          0 (and that’s the default for N).

               (format #f "~d~d again ~@*~d~d" 1 2) ⇒ "12 again 12"
               (format #f "~d~d~d ~1@*~d~d" 1 2 3)  ⇒ "123 23"

          A # move to the end followed by a : modifier move back can be
          used for an absolute position relative to the end of the
          argument list, a reverse of what the @ modifier does.

               (format #t "~#*~2:*~a" 'a 'b 'c 'd)   ⊣ c

          At the end of the format string the current argument position
          doesn’t matter, any further arguments are ignored.

     ~t
          Advance to a column position.  Parameters: COLNUM, COLINC,
          PADCHAR.

          Output PADCHAR (space by default) to move to the given COLNUM
          column.  The start of the line is column 0, the default for
          COLNUM is 1.

               (format #f "~tX")  ⇒ " X"
               (format #f "~3tX") ⇒ "   X"

          If the current column is already past COLNUM, then the move is
          to there plus a multiple of COLINC, ie. column COLNUM + N *
          COLINC for the smallest N which makes that value greater than
          or equal to the current column.  The default COLINC is 1
          (which means no further move).

               (format #f "abcd~2,5,'.tx") ⇒ "abcd...x"

          ~@t takes COLNUM as an offset from the current column.  COLNUM
          many pad characters are output, then further padding to make
          the current column a multiple of COLINC, if it isn’t already
          so.

               (format #f "a~3,5'*@tx") ⇒ "a****x"

          ~t is implemented using ‘port-column’ (*note Textual I/O::),
          so it works even there has been other output before ‘format’.

     ~~
          Tilde character.  Parameter: N.

          Output a tilde character ~, or N many if a parameter is given.
          Normally ~ introduces an escape sequence, ~~ is the way to
          output a literal tilde.

     ~%
          Newline.  Parameter: N.

          Output a newline character, or N many if a parameter is given.
          A newline (or a few newlines) can of course be output just by
          including them in the format string.

     ~&
          Start a new line.  Parameter: N.

          Output a newline if not already at the start of a line.  With
          a parameter, output that many newlines, but with the first
          only if not already at the start of a line.  So for instance 3
          would be a newline if not already at the start of a line, and
          2 further newlines.

     ~_
          Space character.  Parameter: N.

          Output a space character, or N many if a parameter is given.

          With a variable parameter this is one way to insert runtime
          calculated padding (~t or the various field widths can do
          similar things).

               (format #f "~v_foo" 4) ⇒ "    foo"

     ~/
          Tab character.  Parameter: N.

          Output a tab character, or N many if a parameter is given.

     ~|
          Formfeed character.  Parameter: N.

          Output a formfeed character, or N many if a parameter is
          given.

     ~!
          Force output.  No parameters.

          At the end of output, call ‘force-output’ to flush any buffers
          on the destination (*note Buffering::).  ~!  can occur
          anywhere in the format string, but the force is done at the
          end of output.

          When output is to a string (destination ‘#f’), ~!  does
          nothing.

     ~newline (ie. newline character)
          Continuation line.  No parameters.

          Skip this newline and any following whitespace in the format
          string, ie. don’t send it to the output.  This can be used to
          break up a long format string for readability, but not print
          the extra whitespace.

               (format #f "abc~
                           ~d def~
                           ~d" 1 2) ⇒ "abc1 def2"

          ~:newline skips the newline but leaves any further whitespace
          to be printed normally.

          ~@newline prints the newline then skips following whitespace.

     ~( ~)
          Case conversion.  No parameters.

          Between ~( and ~) the case of all output is changed.  The
          modifiers on ~( control the conversion.

               ~( — lower case.
               ~:@( — upper case.

          For example,

               (format #t "~(Hello~)")   ⊣ hello
               (format #t "~:@(Hello~)") ⊣ HELLO

          In the future it’s intended the modifiers : and @ alone will
          capitalize the first letters of words, as per Common Lisp
          ‘format’, but the current implementation of this is flawed and
          not recommended for use.

          Case conversions do not nest, currently.  This might change in
          the future, but if it does then it will be to Common Lisp
          style where the outermost conversion has priority, overriding
          inner ones (making those fairly pointless).

     ~{ ~}
          Iteration.  Parameter: MAXREPS (for ~{).

          The format between ~{ and ~} is iterated.  The modifiers to ~{
          determine how arguments are taken.  The default is a list
          argument with each iteration successively consuming elements
          from it.  This is a convenient way to output a whole list.

               (format #t "~{~d~}"     '(1 2 3))       ⊣ 123
               (format #t "~{~s=~d ~}" '("x" 1 "y" 2)) ⊣ "x"=1 "y"=2

          ~:{ takes a single argument which is a list of lists, each of
          those contained lists gives the arguments for the iterated
          format.

               (format #t "~:{~dx~d ~}" '((1 2) (3 4) (5 6)))
               ⊣ 1x2 3x4 5x6

          ~@{ takes arguments directly, with each iteration successively
          consuming arguments.

               (format #t "~@{~d~}"     1 2 3)       ⊣ 123
               (format #t "~@{~s=~d ~}" "x" 1 "y" 2) ⊣ "x"=1 "y"=2

          ~:@{ takes list arguments, one argument for each iteration,
          using that list for the format.

               (format #t "~:@{~dx~d ~}" '(1 2) '(3 4) '(5 6))
               ⊣ 1x2 3x4 5x6

          Iterating stops when there are no more arguments or when the
          MAXREPS parameter to ~{ is reached (default no maximum).

               (format #t "~2{~d~}" '(1 2 3 4)) ⊣ 12

          If the format between ~{ and ~} is empty, then a format string
          argument is taken (before iteration argument(s)) and used
          instead.  This allows a sub-format (like ~?  above) to be
          iterated.

               (format #t "~{~}" "~d" '(1 2 3)) ⊣ 123

          Iterations can be nested, an inner iteration operates in the
          same way as described, but of course on the arguments the
          outer iteration provides it.  This can be used to work into
          nested list structures.  For example in the following the
          inner ~{~d~}x is applied to ‘(1 2)’ then ‘(3 4 5)’ etc.

               (format #t "~{~{~d~}x~}" '((1 2) (3 4 5))) ⊣ 12x345x

          See also ~^ below for escaping from iteration.

     ~[ ~; ~]
          Conditional.  Parameter: SELECTOR.

          A conditional block is delimited by ~[ and ~], and ~;
          separates clauses within the block.  ~[ takes an integer
          argument and that number clause is used.  The first clause is
          number 0.

               (format #f "~[peach~;banana~;mango~]" 1)  ⇒ "banana"

          The SELECTOR parameter can be used for the clause number,
          instead of taking an argument.

               (format #f "~2[peach~;banana~;mango~]") ⇒ "mango"

          If the clause number is out of range then nothing is output.
          Or the last clause can be ~:; to use that for a number out of
          range.

               (format #f "~[banana~;mango~]"         99) ⇒ ""
               (format #f "~[banana~;mango~:;fruit~]" 99) ⇒ "fruit"

          ~:[ treats the argument as a flag, and expects two clauses.
          The first is used if the argument is ‘#f’ or the second
          otherwise.

               (format #f "~:[false~;not false~]" #f)   ⇒ "false"
               (format #f "~:[false~;not false~]" 'abc) ⇒ "not false"

               (let ((n 3))
                 (format #t "~d gnu~:[s are~; is~] here" n (= 1 n)))
               ⊣ 3 gnus are here

          ~@[ also treats the argument as a flag, and expects one
          clause.  If the argument is ‘#f’ then no output is produced
          and the argument is consumed, otherwise the clause is used and
          the argument is not consumed, it’s left for the clause.  This
          can be used for instance to suppress output if ‘#f’ means
          something not available.

               (format #f "~@[temperature=~d~]" 27) ⇒ "temperature=27"
               (format #f "~@[temperature=~d~]" #f) ⇒ ""

     ~^
          Escape.  Parameters: VAL1, VAL2, VAL3.

          Stop formatting if there are no more arguments.  This can be
          used for instance to have a format string adapt to a variable
          number of arguments.

               (format #t "~d~^ ~d" 1)   ⊣ 1
               (format #t "~d~^ ~d" 1 2) ⊣ 1 2

          Within a ~{ ~} iteration, ~^ stops the current iteration step
          if there are no more arguments to that step, but continuing
          with possible further steps and the rest of the format.  This
          can be used for instance to avoid a separator on the last
          iteration, or to adapt to variable length argument lists.

               (format #f "~{~d~^/~} go"    '(1 2 3))     ⇒ "1/2/3 go"
               (format #f "~:{ ~d~^~d~} go" '((1) (2 3))) ⇒ " 1 23 go"

          Within a ~?  sub-format, ~^ operates just on that sub-format.
          If it terminates the sub-format then the originating format
          will still continue.

               (format #t "~? items" "~d~^ ~d" '(1))   ⊣ 1 items
               (format #t "~? items" "~d~^ ~d" '(1 2)) ⊣ 1 2 items

          The parameters to ~^ (which are numbers) change the condition
          used to terminate.  For a single parameter, termination is
          when that value is zero (notice this makes plain ~^ equivalent
          to ~#^).  For two parameters, termination is when those two
          are equal.  For three parameters, termination is when VAL1 <=
          VAL2 and VAL2 <= VAL3.

     ~q
          Inquiry message.  Insert a copyright message into the output.

          ~:q inserts the format implementation version.


     It’s an error if there are not enough arguments for the escapes in
     the format string, but any excess arguments are ignored.

     Iterations ~{ ~} and conditionals ~[ ~; ~] can be nested, but must
     be properly nested, meaning the inner form must be entirely within
     the outer form.  So it’s not possible, for instance, to try to
     conditionalize the endpoint of an iteration.

          (format #t "~{ ~[ ... ~] ~}" ...)       ;; good
          (format #t "~{ ~[ ... ~} ... ~]" ...)   ;; bad

     The same applies to case conversions ~( ~), they must properly nest
     with respect to iterations and conditionals (though currently a
     case conversion cannot nest within another case conversion).

     When a sub-format (~?)  is used, that sub-format string must be
     self-contained.  It cannot for instance give a ~{ to begin an
     iteration form and have the ~} up in the originating format, or
     similar.


   Guile contains a ‘format’ procedure even when the module ‘(ice-9
format)’ is not loaded.  The default ‘format’ is ‘simple-format’ (*note
Simple Output::), it doesn’t support all escape sequences documented in
this section, and will signal an error if you try to use one of them.
The reason for two versions is that the full ‘format’ is fairly large
and requires some time to load.  ‘simple-format’ is often adequate too.

     Note: Beware that when ‘(ice-9 format)’ is loaded, it replaces the
     binding for ‘format’ on the toplevel.  If your module loads another
     module that loads ‘(ice-9 format)’, then your module will see the
     ‘format’ function from ‘(ice-9 format)’, even if it does not itself
     import ‘(ice-9 format)’.

     _This is legacy behavior and may be removed in a future Guile
     version._

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

   (1) The ~h format specifier first appeared in Guile version 2.0.6.

