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

This manual documents Guile version 2.2.7.

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

   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.”
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: 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 is
similar to the exception handling systems provided by Guile’s core
library *Note Exceptions::, and by the SRFI-18 and SRFI-34 modules—*Note
SRFI-18 Exceptions::, and *note SRFI-34::, respectively—but there are
some key differences in concepts and behavior.

   A raised exception may be “continuable” or “non-continuable”.  When
an exception is raised non-continuably, another exception, with the
condition type ‘&non-continuable’, will be raised when the exception
handler returns locally.  Raising an exception continuably captures the
current continuation and invokes it after a local return from the
exception handler.

   Like SRFI-18 and SRFI-34, R6RS exceptions are implemented on top of
Guile’s native ‘throw’ and ‘catch’ forms, and use custom “throw keys” to
identify their exception types.  As a consequence, Guile’s ‘catch’ form
can handle exceptions thrown by these APIs, but the reverse is not true:
Handlers registered by the ‘with-exception-handler’ procedure described
below will only be called on exceptions thrown by the corresponding
‘raise’ procedure.

 -- Scheme Procedure: with-exception-handler handler thunk
     Installs HANDLER, which must be a procedure taking one argument, as
     the current exception handler during the invocation of THUNK, a
     procedure taking zero arguments.  The handler in place at the time
     ‘with-exception-handler’ is called is made current again once
     either THUNK returns or HANDLER is invoked after an exception is
     thrown from within THUNK.

     This procedure is similar to the ‘with-throw-handler’ procedure
     provided by Guile’s code library; (*note Throw Handlers::).

 -- Scheme Syntax: guard (variable clause1 clause2 ...) body
     Evaluates the expression given by BODY, first creating an ad hoc
     exception handler that binds a raised exception to VARIABLE and
     then evaluates the specified CLAUSEs as if they were part of a
     ‘cond’ expression, with the value of the first matching clause
     becoming the value of the ‘guard’ expression (*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
     Raises a non-continuable exception by invoking the
     currently-installed exception handler on OBJ.  If the handler
     returns, a ‘&non-continuable’ exception will be raised in the
     dynamic context in which the handler was installed.

 -- Scheme Procedure: raise-continuable obj
     Raises a continuable exception by invoking currently-installed
     exception handler on OBJ.


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.

   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 not currently compatible, however; the
‘condition?’ predicate from one API will return ‘#f’ when applied to a
condition object created in the other.

 -- Condition Type: &condition
 -- Scheme Procedure: condition? obj
     The base record type for conditions.

 -- Scheme Procedure: condition condition1 ...
 -- Scheme Procedure: simple-conditions condition
     The ‘condition’ procedure creates a new compound condition out of
     its condition arguments, flattening any specified compound
     conditions into their component simple conditions as described
     above.

     ‘simple-conditions’ returns a list of the component simple
     conditions of the compound condition ‘condition’, in the order in
     which they were specified at construction time.

 -- Scheme Procedure: condition-predicate rtd
 -- Scheme Procedure: condition-accessor rtd proc
     These procedures return condition predicate and accessor procedures
     for the specified condition record type RTD.

 -- Scheme Syntax: define-condition-type condition-type supertype
          constructor predicate field-spec ...
     Evaluates to a new record type definition for a condition type with
     the name CONDITION-TYPE that has the condition type SUPERTYPE as
     its parent.  A default constructor, which binds its arguments to
     the fields of this type and its parent types, will be bound to the
     identifier CONSTRUCTOR; a condition predicate will be bound to
     PREDICATE.  The fields of the new type, which are immutable, are
     specified by the FIELD-SPECs, each of which must be of the form:
          (field accessor)
     where FIELD gives the name of the field and ACCESSOR gives the name
     for a binding to an accessor procedure created for this field.

 -- Condition Type: &message
 -- Scheme Procedure: make-message-condition message
 -- Scheme Procedure: message-condition? obj
 -- Scheme Procedure: condition-message condition
     A type that includes a message describing the condition that
     occurred.

 -- Condition Type: &warning
 -- Scheme Procedure: make-warning
 -- Scheme Procedure: warning? obj
     A base type for representing non-fatal conditions during execution.

 -- Condition Type: &serious
 -- Scheme Procedure: make-serious-condition
 -- Scheme Procedure: serious-condition? obj
     A base type for conditions representing errors serious enough that
     cannot be ignored.

 -- Condition Type: &error
 -- Scheme Procedure: make-error
 -- Scheme Procedure: error? obj
     A base type for conditions representing errors.

 -- Condition Type: &violation
 -- Scheme Procedure: make-violation
 -- Scheme Procedure: violation?
     A subtype of ‘&serious’ that can be used to represent violations of
     a language or library standard.

 -- Condition Type: &assertion
 -- Scheme Procedure: make-assertion-violation
 -- Scheme Procedure: assertion-violation? obj
     A subtype of ‘&violation’ that indicates an invalid call to a
     procedure.

 -- Condition Type: &irritants
 -- Scheme Procedure: make-irritants-condition irritants
 -- Scheme Procedure: irritants-condition? obj
 -- Scheme Procedure: condition-irritants condition
     A base type used for storing information about the causes of
     another condition in a compound condition.

 -- Condition Type: &who
 -- Scheme Procedure: make-who-condition who
 -- Scheme Procedure: who-condition? obj
 -- Scheme Procedure: condition-who condition
     A base type used for storing the identity, a string or symbol, of
     the entity responsible for another condition in a compound
     condition.

 -- Condition Type: &non-continuable
 -- Scheme Procedure: make-non-continuable-violation
 -- Scheme Procedure: non-continuable-violation? obj
     A subtype of ‘&violation’ used to indicate that an exception
     handler invoked by ‘raise’ has returned locally.

 -- Condition Type: &implementation-restriction
 -- Scheme Procedure: make-implementation-restriction-violation
 -- Scheme Procedure: implementation-restriction-violation? obj
     A subtype of ‘&violation’ used to indicate a violation of an
     implementation restriction.

 -- Condition Type: &lexical
 -- Scheme Procedure: make-lexical-violation
 -- Scheme Procedure: lexical-violation? obj
     A subtype of ‘&violation’ used to indicate a syntax violation at
     the level of the datum syntax.

 -- Condition Type: &syntax
 -- Scheme Procedure: make-syntax-violation form subform
 -- Scheme Procedure: syntax-violation? obj
 -- Scheme Procedure: syntax-violation-form condition
 -- Scheme Procedure: syntax-violation-subform condition
     A subtype of ‘&violation’ that indicates a syntax violation.  The
     FORM and SUBFORM fields, which must be datum values, indicate the
     syntactic form responsible for the condition.

 -- Condition Type: &undefined
 -- Scheme Procedure: make-undefined-violation
 -- Scheme Procedure: undefined-violation? obj
     A subtype of ‘&violation’ that indicates a reference to an unbound
     identifier.


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
     *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 SEEK_CUR 0)’.  *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 SEEK_SET OFFSET)’.  *Note Random
     Access::.

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

 -- Scheme Procedure: call-with-port port proc
     Call PROC, passing it PORT and closing PORT upon exit of PROC.
     Return the return values of PROC.

 -- 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: 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: Pattern Matching,  Next: Readline Support,  Prev: R6RS Support,  Up: Guile Modules

7.7 Pattern Matching
====================

The ‘(ice-9 match)’ module provides a “pattern matcher”, written by Alex
Shinn, and compatible with Andrew K. Wright’s pattern matcher found in
many Scheme implementations.

   A pattern matcher can match an object against several patterns and
extract the elements that make it up.  Patterns can represent any Scheme
object: lists, strings, symbols, records, etc.  They can optionally
contain “pattern variables”.  When a matching pattern is found, an
expression associated with the pattern is evaluated, optionally with all
pattern variables bound to the corresponding elements of the object:

     (let ((l '(hello (world))))
       (match l           ;; <- the input object
         (('hello (who))  ;; <- the pattern
          who)))          ;; <- the expression evaluated upon matching
     ⇒ world

   In this example, list L matches the pattern ‘('hello (who))’, because
it is a two-element list whose first element is the symbol ‘hello’ and
whose second element is a one-element list.  Here WHO is a pattern
variable.  ‘match’, the pattern matcher, locally binds WHO to the value
contained in this one-element list—i.e., the symbol ‘world’.  An error
would be raised if L did not match the pattern.

   The same object can be matched against a simpler pattern:

     (let ((l '(hello (world))))
       (match l
         ((x y)
          (values x y))))
     ⇒ hello
     ⇒ (world)

   Here pattern ‘(x y)’ matches any two-element list, regardless of the
types of these elements.  Pattern variables X and Y are bound to,
respectively, the first and second element of L.

   Patterns can be composed, and nested.  For instance, ‘...’ (ellipsis)
means that the previous pattern may be matched zero or more times in a
list:

     (match lst
       (((heads tails ...) ...)
        heads))

This expression returns the first element of each list within LST.  For
proper lists of proper lists, it is equivalent to ‘(map car lst)’.
However, it performs additional checks to make sure that LST and the
lists therein are proper lists, as prescribed by the pattern, raising an
error if they are not.

   Compared to hand-written code, pattern matching noticeably improves
clarity and conciseness—no need to resort to series of ‘car’ and ‘cdr’
calls when matching lists, for instance.  It also improves robustness,
by making sure the input _completely_ matches the pattern—conversely,
hand-written code often trades robustness for conciseness.  And of
course, ‘match’ is a macro, and the code it expands to is just as
efficient as equivalent hand-written code.

   The pattern matcher is defined as follows:

 -- Scheme Syntax: match exp clause1 clause2 ...
     Match object EXP against the patterns in CLAUSE1 CLAUSE2 ... in the
     order in which they appear.  Return the value produced by the first
     matching clause.  If no clause matches, throw an exception with key
     ‘match-error’.

     Each clause has the form ‘(pattern body1 body2 ...)’.  Each PATTERN
     must follow the syntax described below.  Each body is an arbitrary
     Scheme expression, possibly referring to pattern variables of
     PATTERN.

   The syntax and interpretation of patterns is as follows:

        patterns:                       matches:

pat ::= identifier                      anything, and binds identifier
      | _                               anything
      | ()                              the empty list
      | #t                              #t
      | #f                              #f
      | string                          a string
      | number                          a number
      | character                       a character
      | 'sexp                           an s-expression
      | 'symbol                         a symbol (special case of s-expr)
      | (pat_1 ... pat_n)               list of n elements
      | (pat_1 ... pat_n . pat_{n+1})   list of n or more
      | (pat_1 ... pat_n pat_n+1 ooo)   list of n or more, each element
                                          of remainder must match pat_n+1
      | #(pat_1 ... pat_n)              vector of n elements
      | #(pat_1 ... pat_n pat_n+1 ooo)  vector of n or more, each element
                                          of remainder must match pat_n+1
      | #&pat                           box
      | ($ record-name pat_1 ... pat_n) a record
      | (= field pat)                   a ``field'' of an object
      | (and pat_1 ... pat_n)           if all of pat_1 thru pat_n match
      | (or pat_1 ... pat_n)            if any of pat_1 thru pat_n match
      | (not pat_1 ... pat_n)           if all pat_1 thru pat_n don't match
      | (? predicate pat_1 ... pat_n)   if predicate true and all of
                                          pat_1 thru pat_n match
      | (set! identifier)               anything, and binds setter
      | (get! identifier)               anything, and binds getter
      | `qp                             a quasi-pattern
      | (identifier *** pat)            matches pat in a tree and binds
                                        identifier to the path leading
                                        to the object that matches pat

ooo ::= ...                             zero or more
      | ___                             zero or more
      | ..1                             1 or more

        quasi-patterns:                 matches:

qp  ::= ()                              the empty list
      | #t                              #t
      | #f                              #f
      | string                          a string
      | number                          a number
      | character                       a character
      | identifier                      a symbol
      | (qp_1 ... qp_n)                 list of n elements
      | (qp_1 ... qp_n . qp_{n+1})      list of n or more
      | (qp_1 ... qp_n qp_n+1 ooo)      list of n or more, each element
                                          of remainder must match qp_n+1
      | #(qp_1 ... qp_n)                vector of n elements
      | #(qp_1 ... qp_n qp_n+1 ooo)     vector of n or more, each element
                                          of remainder must match qp_n+1
      | #&qp                            box
      | ,pat                            a pattern
      | ,@pat                           a pattern

   The names ‘quote’, ‘quasiquote’, ‘unquote’, ‘unquote-splicing’, ‘?’,
‘_’, ‘$’, ‘and’, ‘or’, ‘not’, ‘set!’, ‘get!’, ‘...’, and ‘___’ cannot be
used as pattern variables.

   Here is a more complex example:

     (use-modules (srfi srfi-9))

     (let ()
       (define-record-type person
         (make-person name friends)
         person?
         (name    person-name)
         (friends person-friends))

       (letrec ((alice (make-person "Alice" (delay (list bob))))
                (bob   (make-person "Bob" (delay (list alice)))))
         (match alice
           (($ person name (= force (($ person "Bob"))))
            (list 'friend-of-bob name))
           (_ #f))))

     ⇒ (friend-of-bob "Alice")

Here the ‘$’ pattern is used to match a SRFI-9 record of type PERSON
containing two or more slots.  The value of the first slot is bound to
NAME.  The ‘=’ pattern is used to apply ‘force’ on the second slot, and
then checking that the result matches the given pattern.  In other
words, the complete pattern matches any PERSON whose second slot is a
promise that evaluates to a one-element list containing a PERSON whose
first slot is ‘"Bob"’.

   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.8 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 behaviour.
* Readline Functions::          Programming with readline.


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

7.8.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 behaviour 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.8.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.8.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.8.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.8.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.9 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 behaviour 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.10 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.

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

   (1) The ~h format specifier first appeared in Guile version 2.0.6.


File: guile.info,  Node: File Tree Walk,  Next: Queues,  Prev: Formatted Output,  Up: Guile Modules

7.11 File Tree Walk
===================

The functions in this section traverse a tree of files and directories.
They come in two flavors: the first one is a high-level functional
interface, and the second one is similar to the C ‘ftw’ and ‘nftw’
routines (*note (libc)Working with Directory Trees::).

     (use-modules (ice-9 ftw))

 -- Scheme Procedure: file-system-tree file-name [enter? [stat]]
     Return a tree of the form ‘(FILE-NAME STAT CHILDREN ...)’ where
     STAT is the result of ‘(STAT FILE-NAME)’ and CHILDREN are similar
     structures for each file contained in FILE-NAME when it designates
     a directory.

     The optional ENTER? predicate is invoked as ‘(ENTER? NAME STAT)’
     and should return true to allow recursion into directory NAME; the
     default value is a procedure that always returns ‘#t’.  When a
     directory does not match ENTER?, it nonetheless appears in the
     resulting tree, only with zero children.

     The STAT argument is optional and defaults to ‘lstat’, as for
     ‘file-system-fold’ (see below.)

     The example below shows how to obtain a hierarchical listing of the
     files under the ‘module/language’ directory in the Guile source
     tree, discarding their ‘stat’ info:

          (use-modules (ice-9 match))

          (define remove-stat
            ;; Remove the `stat' object the `file-system-tree' provides
            ;; for each file in the tree.
            (match-lambda
              ((name stat)              ; flat file
               name)
              ((name stat children ...) ; directory
               (list name (map remove-stat children)))))

          (let ((dir (string-append (assq-ref %guile-build-info 'top_srcdir)
                                    "/module/language")))
            (remove-stat (file-system-tree dir)))

          ⇒
          ("language"
           (("value" ("spec.go" "spec.scm"))
            ("scheme"
             ("spec.go"
              "spec.scm"
              "compile-tree-il.scm"
              "decompile-tree-il.scm"
              "decompile-tree-il.go"
              "compile-tree-il.go"))
            ("tree-il"
             ("spec.go"
              "fix-letrec.go"
              "inline.go"
              "fix-letrec.scm"
              "compile-glil.go"
              "spec.scm"
              "optimize.scm"
              "primitives.scm"
              ...))
            ...))

   It is often desirable to process directories entries directly, rather
than building up a tree of entries in memory, like ‘file-system-tree’
does.  The following procedure, a “combinator”, is designed to allow
directory entries to be processed directly as a directory tree is
traversed; in fact, ‘file-system-tree’ is implemented in terms of it.

 -- Scheme Procedure: file-system-fold enter? leaf down up skip error
          init file-name [stat]
     Traverse the directory at FILE-NAME, recursively, and return the
     result of the successive applications of the LEAF, DOWN, UP, and
     SKIP procedures as described below.

     Enter sub-directories only when ‘(ENTER? PATH STAT RESULT)’ returns
     true.  When a sub-directory is entered, call ‘(DOWN PATH STAT
     RESULT)’, where PATH is the path of the sub-directory and STAT the
     result of ‘(false-if-exception (STAT PATH))’; when it is left, call
     ‘(UP PATH STAT RESULT)’.

     For each file in a directory, call ‘(LEAF PATH STAT RESULT)’.

     When ENTER? returns ‘#f’, or when an unreadable directory is
     encountered, call ‘(SKIP PATH STAT RESULT)’.

     When FILE-NAME names a flat file, ‘(LEAF PATH STAT INIT)’ is
     returned.

     When an ‘opendir’ or STAT call fails, call ‘(ERROR PATH STAT ERRNO
     RESULT)’, with ERRNO being the operating system error number that
     was raised—e.g., ‘EACCES’—and STAT either ‘#f’ or the result of the
     STAT call for that entry, when available.

     The special ‘.’ and ‘..’ entries are not passed to these
     procedures.  The PATH argument to the procedures is a full file
     name—e.g., ‘"../foo/bar/gnu"’; if FILE-NAME is an absolute file
     name, then PATH is also an absolute file name.  Files and
     directories, as identified by their device/inode number pair, are
     traversed only once.

     The optional STAT argument defaults to ‘lstat’, which means that
     symbolic links are not followed; the ‘stat’ procedure can be used
     instead when symbolic links are to be followed (*note stat: File
     System.).

     The example below illustrates the use of ‘file-system-fold’:

          (define (total-file-size file-name)
            "Return the size in bytes of the files under FILE-NAME (similar
          to `du --apparent-size' with GNU Coreutils.)"

            (define (enter? name stat result)
              ;; Skip version control directories.
              (not (member (basename name) '(".git" ".svn" "CVS"))))
            (define (leaf name stat result)
              ;; Return RESULT plus the size of the file at NAME.
              (+ result (stat:size stat)))

            ;; Count zero bytes for directories.
            (define (down name stat result) result)
            (define (up name stat result) result)

            ;; Likewise for skipped directories.
            (define (skip name stat result) result)

            ;; Ignore unreadable files/directories but warn the user.
            (define (error name stat errno result)
              (format (current-error-port) "warning: ~a: ~a~%"
                      name (strerror errno))
              result)

            (file-system-fold enter? leaf down up skip error
                                     0  ; initial counter is zero bytes
                                     file-name))

          (total-file-size ".")
          ⇒ 8217554

          (total-file-size "/dev/null")
          ⇒ 0

   The alternative C-like functions are described below.

 -- Scheme Procedure: scandir name [select? [entry<?]]
     Return the list of the names of files contained in directory NAME
     that match predicate SELECT? (by default, all files).  The returned
     list of file names is sorted according to ENTRY<?, which defaults
     to ‘string-locale<?’ such that file names are sorted in the
     locale’s alphabetical order (*note Text Collation::).  Return ‘#f’
     when NAME is unreadable or is not a directory.

     This procedure is modeled after the C library function of the same
     name (*note (libc)Scanning Directory Content::).

 -- Scheme Procedure: ftw startname proc ['hash-size n]
     Walk the file system tree descending from STARTNAME, calling PROC
     for each file and directory.

     Hard links and symbolic links are followed.  A file or directory is
     reported to PROC only once, and skipped if seen again in another
     place.  One consequence of this is that ‘ftw’ is safe against
     circularly linked directory structures.

     Each PROC call is ‘(PROC filename statinfo flag)’ and it should
     return ‘#t’ to continue, or any other value to stop.

     FILENAME is the item visited, being STARTNAME plus a further path
     and the name of the item.  STATINFO is the return from ‘stat’
     (*note File System::) on FILENAME.  FLAG is one of the following
     symbols,

     ‘regular’
          FILENAME is a file, this includes special files like devices,
          named pipes, etc.

     ‘directory’
          FILENAME is a directory.

     ‘invalid-stat’
          An error occurred when calling ‘stat’, so nothing is known.
          STATINFO is ‘#f’ in this case.

     ‘directory-not-readable’
          FILENAME is a directory, but one which cannot be read and
          hence won’t be recursed into.

     ‘symlink’
          FILENAME is a dangling symbolic link.  Symbolic links are
          normally followed and their target reported, the link itself
          is reported if the target does not exist.

     The return value from ‘ftw’ is ‘#t’ if it ran to completion, or
     otherwise the non-‘#t’ value from PROC which caused the stop.

     Optional argument symbol ‘hash-size’ and an integer can be given to
     set the size of the hash table used to track items already visited.
     (*note Hash Table Reference::)

     In the current implementation, returning non-‘#t’ from PROC is the
     only valid way to terminate ‘ftw’.  PROC must not use ‘throw’ or
     similar to escape.

 -- Scheme Procedure: nftw startname proc ['chdir] ['depth] ['hash-size
          n] ['mount] ['physical]
     Walk the file system tree starting at STARTNAME, calling PROC for
     each file and directory.  ‘nftw’ has extra features over the basic
     ‘ftw’ described above.

     Like ‘ftw’, hard links and symbolic links are followed.  A file or
     directory is reported to PROC only once, and skipped if seen again
     in another place.  One consequence of this is that ‘nftw’ is safe
     against circular linked directory structures.

     Each PROC call is ‘(PROC filename statinfo flag base level)’ and it
     should return ‘#t’ to continue, or any other value to stop.

     FILENAME is the item visited, being STARTNAME plus a further path
     and the name of the item.  STATINFO is the return from ‘stat’ on
     FILENAME (*note File System::).  BASE is an integer offset into
     FILENAME which is where the basename for this item begins.  LEVEL
     is an integer giving the directory nesting level, starting from 0
     for the contents of STARTNAME (or that item itself if it’s a file).
     FLAG is one of the following symbols,

     ‘regular’
          FILENAME is a file, including special files like devices,
          named pipes, etc.

     ‘directory’
          FILENAME is a directory.

     ‘directory-processed’
          FILENAME is a directory, and its contents have all been
          visited.  This flag is given instead of ‘directory’ when the
          ‘depth’ option below is used.

     ‘invalid-stat’
          An error occurred when applying ‘stat’ to FILENAME, so nothing
          is known about it.  STATINFO is ‘#f’ in this case.

     ‘directory-not-readable’
          FILENAME is a directory, but one which cannot be read and
          hence won’t be recursed into.

     ‘stale-symlink’
          FILENAME is a dangling symbolic link.  Links are normally
          followed and their target reported, the link itself is
          reported if its target does not exist.

     ‘symlink’
          When the ‘physical’ option described below is used, this
          indicates FILENAME is a symbolic link whose target exists (and
          is not being followed).

     The following optional arguments can be given to modify the way
     ‘nftw’ works.  Each is passed as a symbol (and ‘hash-size’ takes a
     following integer value).

     ‘chdir’
          Change to the directory containing the item before calling
          PROC.  When ‘nftw’ returns the original current directory is
          restored.

          Under this option, generally the BASE parameter to each PROC
          call should be used to pick out the base part of the FILENAME.
          The FILENAME is still a path but with a changed directory it
          won’t be valid (unless the STARTNAME directory was absolute).

     ‘depth’
          Visit files “depth first”, meaning PROC is called for the
          contents of each directory before it’s called for the
          directory itself.  Normally a directory is reported first,
          then its contents.

          Under this option, the FLAG to PROC for a directory is
          ‘directory-processed’ instead of ‘directory’.

     ‘hash-size N’
          Set the size of the hash table used to track items already
          visited.  (*note Hash Table Reference::)

     ‘mount’
          Don’t cross a mount point, meaning only visit items on the
          same file system as STARTNAME (ie. the same ‘stat:dev’).

     ‘physical’
          Don’t follow symbolic links, instead report them to PROC as
          ‘symlink’.  Dangling links (those whose target doesn’t exist)
          are still reported as ‘stale-symlink’.

     The return value from ‘nftw’ is ‘#t’ if it ran to completion, or
     otherwise the non-‘#t’ value from PROC which caused the stop.

     In the current implementation, returning non-‘#t’ from PROC is the
     only valid way to terminate ‘ftw’.  PROC must not use ‘throw’ or
     similar to escape.


File: guile.info,  Node: Queues,  Next: Streams,  Prev: File Tree Walk,  Up: Guile Modules

7.12 Queues
===========

The functions in this section are provided by

     (use-modules (ice-9 q))

   This module implements queues holding arbitrary scheme objects and
designed for efficient first-in / first-out operations.

   ‘make-q’ creates a queue, and objects are entered and removed with
‘enq!’ and ‘deq!’.  ‘q-push!’ and ‘q-pop!’ can be used too, treating the
front of the queue like a stack.


 -- Scheme Procedure: make-q
     Return a new queue.

 -- Scheme Procedure: q? obj
     Return ‘#t’ if OBJ is a queue, or ‘#f’ if not.

     Note that queues are not a distinct class of objects but are
     implemented with cons cells.  For that reason certain list
     structures can get ‘#t’ from ‘q?’.

 -- Scheme Procedure: enq! q obj
     Add OBJ to the rear of Q, and return Q.

 -- Scheme Procedure: deq! q
 -- Scheme Procedure: q-pop! q
     Remove and return the front element from Q.  If Q is empty, a
     ‘q-empty’ exception is thrown.

     ‘deq!’ and ‘q-pop!’ are the same operation, the two names just let
     an application match ‘enq!’ with ‘deq!’, or ‘q-push!’ with
     ‘q-pop!’.

 -- Scheme Procedure: q-push! q obj
     Add OBJ to the front of Q, and return Q.

 -- Scheme Procedure: q-length q
     Return the number of elements in Q.

 -- Scheme Procedure: q-empty? q
     Return true if Q is empty.

 -- Scheme Procedure: q-empty-check q
     Throw a ‘q-empty’ exception if Q is empty.

 -- Scheme Procedure: q-front q
     Return the first element of Q (without removing it).  If Q is
     empty, a ‘q-empty’ exception is thrown.

 -- Scheme Procedure: q-rear q
     Return the last element of Q (without removing it).  If Q is empty,
     a ‘q-empty’ exception is thrown.

 -- Scheme Procedure: q-remove! q obj
     Remove all occurrences of OBJ from Q, and return Q.  OBJ is
     compared to queue elements using ‘eq?’.


   The ‘q-empty’ exceptions described above are thrown just as ‘(throw
'q-empty)’, there’s no message etc like an error throw.

   A queue is implemented as a cons cell, the ‘car’ containing a list of
queued elements, and the ‘cdr’ being the last cell in that list (for
ease of enqueuing).

     (LIST . LAST-CELL)

If the queue is empty, LIST is the empty list and LAST-CELL is ‘#f’.

   An application can directly access the queue list if desired, for
instance to search the elements or to insert at a specific point.

 -- Scheme Procedure: sync-q! q
     Recompute the LAST-CELL field in Q.

     All the operations above maintain LAST-CELL as described, so
     normally there’s no need for ‘sync-q!’.  But if an application
     modifies the queue LIST then it must either maintain LAST-CELL
     similarly, or call ‘sync-q!’ to recompute it.


File: guile.info,  Node: Streams,  Next: Buffered Input,  Prev: Queues,  Up: Guile Modules

7.13 Streams
============

This section documents Guile’s legacy stream module.  For a more
complete and portable stream library, *note SRFI-41::.

   A stream represents a sequence of values, each of which is calculated
only when required.  This allows large or even infinite sequences to be
represented and manipulated with familiar operations like “car”, “cdr”,
“map” or “fold”.  In such manipulations only as much as needed is
actually held in memory at any one time.  The functions in this section
are available from

     (use-modules (ice-9 streams))

   Streams are implemented using promises (*note Delayed Evaluation::),
which is how the underlying calculation of values is made only when
needed, and the values then retained so the calculation is not repeated.

Here is a simple example producing a stream of all odd numbers,

     (define odds (make-stream (lambda (state)
                                 (cons state (+ state 2)))
                               1))
     (stream-car odds)              ⇒ 1
     (stream-car (stream-cdr odds)) ⇒ 3

‘stream-map’ could be used to derive a stream of odd squares,

     (define (square n) (* n n))
     (define oddsquares (stream-map square odds))

   These are infinite sequences, so it’s not possible to convert them to
a list, but they could be printed (infinitely) with for example

     (stream-for-each (lambda (n sq)
                        (format #t "~a squared is ~a\n" n sq))
                      odds oddsquares)
     ⊣
     1 squared is 1
     3 squared is 9
     5 squared is 25
     7 squared is 49
     ...


 -- Scheme Procedure: make-stream proc initial-state
     Return a new stream, formed by calling PROC successively.

     Each call is ‘(PROC STATE)’, it should return a pair, the ‘car’
     being the value for the stream, and the ‘cdr’ being the new STATE
     for the next call.  For the first call STATE is the given
     INITIAL-STATE.  At the end of the stream, PROC should return some
     non-pair object.

 -- Scheme Procedure: stream-car stream
     Return the first element from STREAM.  STREAM must not be empty.

 -- Scheme Procedure: stream-cdr stream
     Return a stream which is the second and subsequent elements of
     STREAM.  STREAM must not be empty.

 -- Scheme Procedure: stream-null? stream
     Return true if STREAM is empty.

 -- Scheme Procedure: list->stream list
 -- Scheme Procedure: vector->stream vector
     Return a stream with the contents of LIST or VECTOR.

     LIST or VECTOR should not be modified subsequently, since it’s
     unspecified whether changes there will be reflected in the stream
     returned.

 -- Scheme Procedure: port->stream port readproc
     Return a stream which is the values obtained by reading from PORT
     using READPROC.  Each read call is ‘(READPROC PORT)’, and it should
     return an EOF object (*note Binary I/O::) at the end of input.

     For example a stream of characters from a file,

          (port->stream (open-input-file "/foo/bar.txt") read-char)

 -- Scheme Procedure: stream->list stream
     Return a list which is the entire contents of STREAM.

 -- Scheme Procedure: stream->reversed-list stream
     Return a list which is the entire contents of STREAM, but in
     reverse order.

 -- Scheme Procedure: stream->list&length stream
     Return two values (*note Multiple Values::), being firstly a list
     which is the entire contents of STREAM, and secondly the number of
     elements in that list.

 -- Scheme Procedure: stream->reversed-list&length stream
     Return two values (*note Multiple Values::) being firstly a list
     which is the entire contents of STREAM, but in reverse order, and
     secondly the number of elements in that list.

 -- Scheme Procedure: stream->vector stream
     Return a vector which is the entire contents of STREAM.

 -- Function: stream-fold proc init stream1 stream2 ...
     Apply PROC successively over the elements of the given streams,
     from first to last until the end of the shortest stream is reached.
     Return the result from the last PROC call.

     Each call is ‘(PROC elem1 elem2 ... prev)’, where each ELEM is from
     the corresponding STREAM.  PREV is the return from the previous
     PROC call, or the given INIT for the first call.

 -- Function: stream-for-each proc stream1 stream2 ...
     Call PROC on the elements from the given STREAMs.  The return value
     is unspecified.

     Each call is ‘(PROC elem1 elem2 ...)’, where each ELEM is from the
     corresponding STREAM.  ‘stream-for-each’ stops when it reaches the
     end of the shortest STREAM.

 -- Function: stream-map proc stream1 stream2 ...
     Return a new stream which is the results of applying PROC to the
     elements of the given STREAMs.

     Each call is ‘(PROC elem1 elem2 ...)’, where each ELEM is from the
     corresponding STREAM.  The new stream ends when the end of the
     shortest given STREAM is reached.


File: guile.info,  Node: Buffered Input,  Next: Expect,  Prev: Streams,  Up: Guile Modules

7.14 Buffered Input
===================

The following functions are provided by

     (use-modules (ice-9 buffered-input))

   A buffered input port allows a reader function to return chunks of
characters which are to be handed out on reading the port.  A notion of
further input for an application level logical expression is maintained
too, and passed through to the reader.

 -- Scheme Procedure: make-buffered-input-port reader
     Create an input port which returns characters obtained from the
     given READER function.  READER is called (READER cont), and should
     return a string or an EOF object.

     The new port gives precisely the characters returned by READER,
     nothing is added, so if any newline characters or other separators
     are desired they must come from the reader function.

     The CONT parameter to READER is ‘#f’ for initial input, or ‘#t’
     when continuing an expression.  This is an application level
     notion, set with ‘set-buffered-input-continuation?!’ below.  If the
     user has entered a partial expression then it allows READER for
     instance to give a different prompt to show more is required.

 -- Scheme Procedure: make-line-buffered-input-port reader
     Create an input port which returns characters obtained from the
     specified READER function, similar to ‘make-buffered-input-port’
     above, but where READER is expected to be a line-oriented.

     READER is called (READER cont), and should return a string or an
     EOF object as above.  Each string is a line of input without a
     newline character, the port code inserts a newline after each
     string.

 -- Scheme Procedure: set-buffered-input-continuation?! port cont
     Set the input continuation flag for a given buffered input PORT.

     An application uses this by calling with a CONT flag of ‘#f’ when
     beginning to read a new logical expression.  For example with the
     Scheme ‘read’ function (*note Scheme Read::),

          (define my-port (make-buffered-input-port my-reader))

          (set-buffered-input-continuation?! my-port #f)
          (let ((obj (read my-port)))
            ...


File: guile.info,  Node: Expect,  Next: sxml-match,  Prev: Buffered Input,  Up: Guile Modules

7.15 Expect
===========

The macros in this section are made available with:

     (use-modules (ice-9 expect))

   ‘expect’ is a macro for selecting actions based on the output from a
port.  The name comes from a tool of similar functionality by Don Libes.
Actions can be taken when a particular string is matched, when a timeout
occurs, or when end-of-file is seen on the port.  The ‘expect’ macro is
described below; ‘expect-strings’ is a front-end to ‘expect’ based on
regexec (see the regular expression documentation).

 -- Macro: expect-strings clause ...
     By default, ‘expect-strings’ will read from the current input port.
     The first term in each clause consists of an expression evaluating
     to a string pattern (regular expression).  As characters are read
     one-by-one from the port, they are accumulated in a buffer string
     which is matched against each of the patterns.  When a pattern
     matches, the remaining expression(s) in the clause are evaluated
     and the value of the last is returned.  For example:

          (with-input-from-file "/etc/passwd"
            (lambda ()
              (expect-strings
                ("^nobody" (display "Got a nobody user.\n")
                           (display "That's no problem.\n"))
                ("^daemon" (display "Got a daemon user.\n")))))

     The regular expression is compiled with the ‘REG_NEWLINE’ flag, so
     that the ^ and $ anchors will match at any newline, not just at the
     start and end of the string.

     There are two other ways to write a clause:

     The expression(s) to evaluate can be omitted, in which case the
     result of the regular expression match (converted to strings, as
     obtained from regexec with match-pick set to "") will be returned
     if the pattern matches.

     The symbol ‘=>’ can be used to indicate that the expression is a
     procedure which will accept the result of a successful regular
     expression match.  E.g.,

          ("^daemon" => write)
          ("^d(aemon)" => (lambda args (for-each write args)))
          ("^da(em)on" => (lambda (all sub)
                            (write all) (newline)
                            (write sub) (newline)))

     The order of the substrings corresponds to the order in which the
     opening brackets occur.

     A number of variables can be used to control the behaviour of
     ‘expect’ (and ‘expect-strings’).  Most have default top-level
     bindings to the value ‘#f’, which produces the default behaviour.
     They can be redefined at the top level or locally bound in a form
     enclosing the expect expression.

     ‘expect-port’
          A port to read characters from, instead of the current input
          port.
     ‘expect-timeout’
          ‘expect’ will terminate after this number of seconds,
          returning ‘#f’ or the value returned by expect-timeout-proc.
     ‘expect-timeout-proc’
          A procedure called if timeout occurs.  The procedure takes a
          single argument: the accumulated string.
     ‘expect-eof-proc’
          A procedure called if end-of-file is detected on the input
          port.  The procedure takes a single argument: the accumulated
          string.
     ‘expect-char-proc’
          A procedure to be called every time a character is read from
          the port.  The procedure takes a single argument: the
          character which was read.
     ‘expect-strings-compile-flags’
          Flags to be used when compiling a regular expression, which
          are passed to ‘make-regexp’ *Note Regexp Functions::.  The
          default value is ‘regexp/newline’.
     ‘expect-strings-exec-flags’
          Flags to be used when executing a regular expression, which
          are passed to regexp-exec *Note Regexp Functions::.  The
          default value is ‘regexp/noteol’, which prevents ‘$’ from
          matching the end of the string while it is still accumulating,
          but still allows it to match after a line break or at the end
          of file.

     Here’s an example using all of the variables:

          (let ((expect-port (open-input-file "/etc/passwd"))
                (expect-timeout 1)
                (expect-timeout-proc
                  (lambda (s) (display "Times up!\n")))
                (expect-eof-proc
                  (lambda (s) (display "Reached the end of the file!\n")))
                (expect-char-proc display)
                (expect-strings-compile-flags (logior regexp/newline regexp/icase))
                (expect-strings-exec-flags 0))
             (expect-strings
               ("^nobody"  (display "Got a nobody user\n"))))

 -- Macro: expect clause ...
     ‘expect’ is used in the same way as ‘expect-strings’, but tests are
     specified not as patterns, but as procedures.  The procedures are
     called in turn after each character is read from the port, with two
     arguments: the value of the accumulated string and a flag to
     indicate whether end-of-file has been reached.  The flag will
     usually be ‘#f’, but if end-of-file is reached, the procedures are
     called an additional time with the final accumulated string and
     ‘#t’.

     The test is successful if the procedure returns a non-false value.

     If the ‘=>’ syntax is used, then if the test succeeds it must
     return a list containing the arguments to be provided to the
     corresponding expression.

     In the following example, a string will only be matched at the
     beginning of the file:

          (let ((expect-port (open-input-file "/etc/passwd")))
            (expect
               ((lambda (s eof?) (string=? s "fnord!"))
                  (display "Got a nobody user!\n"))))

     The control variables described for ‘expect-strings’ also influence
     the behaviour of ‘expect’, with the exception of variables whose
     names begin with ‘expect-strings-’.


File: guile.info,  Node: sxml-match,  Next: The Scheme shell (scsh),  Prev: Expect,  Up: Guile Modules

7.16 ‘sxml-match’: Pattern Matching of SXML
===========================================

The ‘(sxml match)’ module provides syntactic forms for pattern matching
of SXML trees, in a “by example” style reminiscent of the pattern
matching of the ‘syntax-rules’ and ‘syntax-case’ macro systems.  *Note
SXML::, for more information on SXML.

   The following example(1) provides a brief illustration, transforming
a music album catalog language into HTML.

     (define (album->html x)
       (sxml-match x
         [(album (@ (title ,t)) (catalog (num ,n) (fmt ,f)) ...)
          `(ul (li ,t)
               (li (b ,n) (i ,f)) ...)]))

   Three macros are provided: ‘sxml-match’, ‘sxml-match-let’, and
‘sxml-match-let*’.

   Compared to a standard s-expression pattern matcher (*note Pattern
Matching::), ‘sxml-match’ provides the following benefits:

   • matching of SXML elements does not depend on any degree of
     normalization of the SXML;
   • matching of SXML attributes (within an element) is under-ordered;
     the order of the attributes specified within the pattern need not
     match the ordering with the element being matched;
   • all attributes specified in the pattern must be present in the
     element being matched; in the spirit that XML is ’extensible’, the
     element being matched may include additional attributes not
     specified in the pattern.

   The present module is a descendant of WebIt!, and was inspired by an
s-expression pattern matcher developed by Erik Hilsdale, Dan Friedman,
and Kent Dybvig at Indiana University.

Syntax
------

‘sxml-match’ provides ‘case’-like form for pattern matching of XML
nodes.

 -- Scheme Syntax: sxml-match input-expression clause1 clause2 ...
     Match INPUT-EXPRESSION, an SXML tree, according to the given
     CLAUSEs (one or more), each consisting of a pattern and one or more
     expressions to be evaluated if the pattern match succeeds.
     Optionally, each CLAUSE within ‘sxml-match’ may include a “guard
     expression”.

   The pattern notation is based on that of Scheme’s ‘syntax-rules’ and
‘syntax-case’ macro systems.  The grammar for the ‘sxml-match’ syntax is
given below:

match-form ::= (sxml-match input-expression
                 clause+)

clause ::= [node-pattern action-expression+]
         | [node-pattern (guard expression*) action-expression+]

node-pattern ::= literal-pattern
               | pat-var-or-cata
               | element-pattern
               | list-pattern

literal-pattern ::= string
                  | character
                  | number
                  | #t
                  | #f

attr-list-pattern ::= (@ attribute-pattern*)
                    | (@ attribute-pattern* . pat-var-or-cata)

attribute-pattern ::= (tag-symbol attr-val-pattern)

attr-val-pattern ::= literal-pattern
                   | pat-var-or-cata
                   | (pat-var-or-cata default-value-expr)

element-pattern ::= (tag-symbol attr-list-pattern?)
                  | (tag-symbol attr-list-pattern? nodeset-pattern)
                  | (tag-symbol attr-list-pattern?
                                nodeset-pattern? . pat-var-or-cata)

list-pattern ::= (list nodeset-pattern)
               | (list nodeset-pattern? . pat-var-or-cata)
               | (list)

nodeset-pattern ::= node-pattern
                  | node-pattern ...
                  | node-pattern nodeset-pattern
                  | node-pattern ... nodeset-pattern

pat-var-or-cata ::= (unquote var-symbol)
                  | (unquote [var-symbol*])
                  | (unquote [cata-expression -> var-symbol*])

   Within a list or element body pattern, ellipses may appear only once,
but may be followed by zero or more node patterns.

   Guard expressions cannot refer to the return values of catamorphisms.

   Ellipses in the output expressions must appear only in an expression
context; ellipses are not allowed in a syntactic form.

   The sections below illustrate specific aspects of the ‘sxml-match’
pattern matcher.

Matching XML Elements
---------------------

The example below illustrates the pattern matching of an XML element:

     (sxml-match '(e (@ (i 1)) 3 4 5)
       [(e (@ (i ,d)) ,a ,b ,c) (list d a b c)]
       [,otherwise #f])

   Each clause in ‘sxml-match’ contains two parts: a pattern and one or
more expressions which are evaluated if the pattern is successfully
match.  The example above matches an element ‘e’ with an attribute ‘i’
and three children.

   Pattern variables must be “unquoted” in the pattern.  The above
expression binds D to ‘1’, A to ‘3’, B to ‘4’, and C to ‘5’.

Ellipses in Patterns
--------------------

As in ‘syntax-rules’, ellipses may be used to specify a repeated
pattern.  Note that the pattern ‘item ...’ specifies zero-or-more
matches of the pattern ‘item’.

   The use of ellipses in a pattern is illustrated in the code fragment
below, where nested ellipses are used to match the children of repeated
instances of an ‘a’ element, within an element ‘d’.

     (define x '(d (a 1 2 3) (a 4 5) (a 6 7 8) (a 9 10)))

     (sxml-match x
       [(d (a ,b ...) ...)
        (list (list b ...) ...)])

   The above expression returns a value of ‘((1 2 3) (4 5) (6 7 8) (9
10))’.

Ellipses in Quasiquote’d Output
-------------------------------

Within the body of an ‘sxml-match’ form, a slightly extended version of
quasiquote is provided, which allows the use of ellipses.  This is
illustrated in the example below.

     (sxml-match '(e 3 4 5 6 7)
       [(e ,i ... 6 7) `("start" ,(list 'wrap i) ... "end")]
       [,otherwise #f])

   The general pattern is that ‘`(something ,i ...)’ is rewritten as
‘`(something ,@i)’.

Matching Nodesets
-----------------

A nodeset pattern is designated by a list in the pattern, beginning the
identifier list.  The example below illustrates matching a nodeset.

     (sxml-match '("i" "j" "k" "l" "m")
       [(list ,a ,b ,c ,d ,e)
        `((p ,a) (p ,b) (p ,c) (p ,d) (p ,e))])

   This example wraps each nodeset item in an HTML paragraph element.
This example can be rewritten and simplified through using ellipsis:

     (sxml-match '("i" "j" "k" "l" "m")
       [(list ,i ...)
        `((p ,i) ...)])

   This version will match nodesets of any length, and wrap each item in
the nodeset in an HTML paragraph element.

Matching the “Rest” of a Nodeset
--------------------------------

Matching the “rest” of a nodeset is achieved by using a ‘. rest)’
pattern at the end of an element or nodeset pattern.

   This is illustrated in the example below:

     (sxml-match '(e 3 (f 4 5 6) 7)
       [(e ,a (f . ,y) ,d)
        (list a y d)])

   The above expression returns ‘(3 (4 5 6) 7)’.

Matching the Unmatched Attributes
---------------------------------

Sometimes it is useful to bind a list of attributes present in the
element being matched, but which do not appear in the pattern.  This is
achieved by using a ‘. rest)’ pattern at the end of the attribute list
pattern.  This is illustrated in the example below:

     (sxml-match '(a (@ (z 1) (y 2) (x 3)) 4 5 6)
       [(a (@ (y ,www) . ,qqq) ,t ,u ,v)
        (list www qqq t u v)])

   The above expression matches the attribute ‘y’ and binds a list of
the remaining attributes to the variable QQQ.  The result of the above
expression is ‘(2 ((z 1) (x 3)) 4 5 6)’.

   This type of pattern also allows the binding of all attributes:

     (sxml-match '(a (@ (z 1) (y 2) (x 3)))
       [(a (@ . ,qqq))
        qqq])

Default Values in Attribute Patterns
------------------------------------

It is possible to specify a default value for an attribute which is used
if the attribute is not present in the element being matched.  This is
illustrated in the following example:

     (sxml-match '(e 3 4 5)
       [(e (@ (z (,d 1))) ,a ,b ,c) (list d a b c)])

   The value ‘1’ is used when the attribute ‘z’ is absent from the
element ‘e’.

Guards in Patterns
------------------

Guards may be added to a pattern clause via the ‘guard’ keyword.  A
guard expression may include zero or more expressions which are
evaluated only if the pattern is matched.  The body of the clause is
only evaluated if the guard expressions evaluate to ‘#t’.

   The use of guard expressions is illustrated below:

     (sxml-match '(a 2 3)
       ((a ,n) (guard (number? n)) n)
       ((a ,m ,n) (guard (number? m) (number? n)) (+ m n)))

Catamorphisms
-------------

The example below illustrates the use of explicit recursion within an
‘sxml-match’ form.  This example implements a simple calculator for the
basic arithmetic operations, which are represented by the XML elements
‘plus’, ‘minus’, ‘times’, and ‘div’.

     (define simple-eval
       (lambda (x)
         (sxml-match x
           [,i (guard (integer? i)) i]
           [(plus ,x ,y) (+ (simple-eval x) (simple-eval y))]
           [(times ,x ,y) (* (simple-eval x) (simple-eval y))]
           [(minus ,x ,y) (- (simple-eval x) (simple-eval y))]
           [(div ,x ,y) (/ (simple-eval x) (simple-eval y))]
           [,otherwise (error "simple-eval: invalid expression" x)])))

   Using the catamorphism feature of ‘sxml-match’, a more concise
version of ‘simple-eval’ can be written.  The pattern ‘,[x]’ recursively
invokes the pattern matcher on the value bound in this position.

     (define simple-eval
       (lambda (x)
         (sxml-match x
           [,i (guard (integer? i)) i]
           [(plus ,[x] ,[y]) (+ x y)]
           [(times ,[x] ,[y]) (* x y)]
           [(minus ,[x] ,[y]) (- x y)]
           [(div ,[x] ,[y]) (/ x y)]
           [,otherwise (error "simple-eval: invalid expression" x)])))

Named-Catamorphisms
-------------------

It is also possible to explicitly name the operator in the “cata”
position.  Where ‘,[id*]’ recurs to the top of the current ‘sxml-match’,
‘,[cata -> id*]’ recurs to ‘cata’.  ‘cata’ must evaluate to a procedure
which takes one argument, and returns as many values as there are
identifiers following ‘->’.

   Named catamorphism patterns allow processing to be split into
multiple, mutually recursive procedures.  This is illustrated in the
example below: a transformation that formats a “TV Guide” into HTML.

     (define (tv-guide->html g)
       (define (cast-list cl)
         (sxml-match cl
           [(CastList (CastMember (Character (Name ,ch)) (Actor (Name ,a))) ...)
            `(div (ul (li ,ch ": " ,a) ...))]))
       (define (prog p)
         (sxml-match p
           [(Program (Start ,start-time) (Duration ,dur) (Series ,series-title)
                     (Description ,desc ...))
            `(div (p ,start-time
                     (br) ,series-title
                     (br) ,desc ...))]
           [(Program (Start ,start-time) (Duration ,dur) (Series ,series-title)
                     (Description ,desc ...)
                     ,[cast-list -> cl])
            `(div (p ,start-time
                     (br) ,series-title
                     (br) ,desc ...)
                  ,cl)]))
       (sxml-match g
         [(TVGuide (@ (start ,start-date)
                      (end ,end-date))
                   (Channel (Name ,nm) ,[prog -> p] ...) ...)
          `(html (head (title "TV Guide"))
                 (body (h1 "TV Guide")
                       (div (h2 ,nm) ,p ...) ...))]))

‘sxml-match-let’ and ‘sxml-match-let*’
--------------------------------------

 -- Scheme Syntax: sxml-match-let ((pat expr) ...) expression0
          expression ...
 -- Scheme Syntax: sxml-match-let* ((pat expr) ...) expression0
          expression ...
     These forms generalize the ‘let’ and ‘let*’ forms of Scheme to
     allow an XML pattern in the binding position, rather than a simple
     variable.

   For example, the expression below:

     (sxml-match-let ([(a ,i ,j) '(a 1 2)])
       (+ i j))

   binds the variables I and J to ‘1’ and ‘2’ in the XML value given.

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

   (1) This example is taken from a paper by Krishnamurthi et al.  Their
paper was the first to show the usefulness of the ‘syntax-rules’ style
of pattern matching for transformation of XML, though the language
described, XT3D, is an XML language.


File: guile.info,  Node: The Scheme shell (scsh),  Next: Curried Definitions,  Prev: sxml-match,  Up: Guile Modules

7.17 The Scheme shell (scsh)
============================

An incomplete port of the Scheme shell (scsh) was once available for
Guile as a separate package.  However this code has bitrotten somewhat.
The pieces are available in Guile’s legacy CVS repository, which may be
browsed at
<http://cvs.savannah.gnu.org/viewvc/guile/guile-scsh/?root=guile>.

   For information about scsh see <http://www.scsh.net/>.

   This bitrotting is a bit of a shame, as there is a good deal of
well-written Scheme code in scsh.  Adopting this code and porting it to
current Guile should be an educational experience, in addition to
providing something of value to Guile folks.


File: guile.info,  Node: Curried Definitions,  Next: Statprof,  Prev: The Scheme shell (scsh),  Up: Guile Modules

7.18 Curried Definitions
========================

The macros in this section are provided by
     (use-modules (ice-9 curried-definitions))
and replace those provided by default.

   Prior to Guile 2.0, Guile provided a type of definition known
colloquially as a “curried definition”.  The idea is to extend the
syntax of ‘define’ so that you can conveniently define procedures that
return procedures, up to any desired depth.

   For example,
     (define ((foo x) y)
       (list x y))
   is a convenience form of
     (define foo
       (lambda (x)
         (lambda (y)
           (list x y))))

 -- Scheme Syntax: define (... (name args ...) ...) body ...
 -- Scheme Syntax: define* (... (name args ...) ...) body ...
 -- Scheme Syntax: define-public (... (name args ...) ...) body ...

     Create a top level variable NAME bound to the procedure with
     parameter list ARGS.  If NAME is itself a formal parameter list,
     then a higher order procedure is created using that
     formal-parameter list, and returning a procedure that has parameter
     list ARGS.  This nesting may occur to arbitrary depth.

     ‘define*’ is similar but the formal parameter lists take additional
     options as described in *note lambda* and define*::.  For example,
          (define* ((foo #:keys (bar 'baz) (quux 'zot)) frotz #:rest rest)
            (list bar quux frotz rest))

          ((foo #:quux 'foo) 1 2 3 4 5)
          ⇒ (baz foo 1 (2 3 4 5))

     ‘define-public’ is similar to ‘define’ but it also adds NAME to the
     list of exported bindings of the current module.


File: guile.info,  Node: Statprof,  Next: SXML,  Prev: Curried Definitions,  Up: Guile Modules

7.19 Statprof
=============

Statprof is a statistical profiler for Guile.

   A simple use of statprof would look like this:

     (use-modules (statprof))
     (statprof (lambda ()
                 (map 1+ (iota 1000000))
                 #f))

   This would run the thunk with statistical profiling, finally
displaying a flat table of statistics which could look something like
this:

     %     cumulative   self
     time   seconds     seconds  procedure
      57.14  39769.73      0.07  ice-9/boot-9.scm:249:5:map1
      28.57      0.04      0.04  ice-9/boot-9.scm:1165:0:iota
      14.29      0.02      0.02  1+
       0.00      0.12      0.00  <current input>:2:10
     ---
     Sample count: 7
     Total time: 0.123490713 seconds (0.201983993 seconds in GC)

   All of the numerical data with the exception of the calls column is
statistically approximate.  In the following column descriptions, and in
all of statprof, “time” refers to execution time (both user and system),
not wall clock time.

   The ‘% time’ column indicates the percentage of the run-time time
spent inside the procedure itself (not counting children).  It is
calculated as ‘self seconds’, measuring the amount of time spent in the
procedure, divided by the total run-time.

   ‘cumulative seconds’ also counts time spent in children of a
function.  For recursive functions, this can exceed the total time, as
in our example above, because each activation on the stack adds to the
cumulative time.

   Finally, the GC time measures the time spent in the garbage
collector.  On systems with multiple cores, this time can be larger than
the run time, because it counts time spent in all threads, and will run
the “marking” phase of GC in parallel.  If GC time is a significant
fraction of the run time, that means that most time in your program is
spent allocating objects and cleaning up after those allocations.  To
speed up your program, one good place to start would be to look at how
to reduce the allocation rate.

   Statprof’s main mode of operation is as a statistical profiler.
However statprof can also run in a “precise” mode as well.  Pass the
‘#:count-calls? #t’ keyword argument to ‘statprof’ to record all calls:

     (use-modules (statprof))
     (statprof (lambda ()
                 (map 1+ (iota 1000000))
                 #f)
               #:count-calls? #t)

   The result has an additional ‘calls’ column:

     %     cumulative   self
     time   seconds    seconds   calls   procedure
      82.26      0.73      0.73 1000000  1+
      11.29 420925.80      0.10 1000001  ice-9/boot-9.scm:249:5:map1
       4.84      0.06      0.04       1  ice-9/boot-9.scm:1165:0:iota
     [...]
     ---
     Sample count: 62
     Total time: 0.893098065 seconds (1.222796536 seconds in GC)

   As you can see, the profile is perturbed: ‘1+’ ends up on top,
whereas it was not marked as hot in the earlier profile.  This is
because the overhead of call-counting unfairly penalizes calls.  Still,
this precise mode can be useful at times to do algorithmic optimizations
based on the precise call counts.

Implementation notes
====================

The profiler works by setting the unix profiling signal ‘ITIMER_PROF’ to
go off after the interval you define in the call to ‘statprof-reset’.
When the signal fires, a sampling routine runs which crawls up the
stack, recording all instruction pointers into a buffer.  After the
sample is complete, the profiler resets profiling timer to fire again
after the appropriate interval.

   Later, when profiling stops, that log buffer is analyzed to produce
the “self seconds” and “cumulative seconds” statistics.  A procedure at
the top of the stack counts toward “self” samples, and everything on the
stack counts towards “cumulative” samples.

   While the profiler is running it measures how much CPU time (system
and user – which is also what ‘ITIMER_PROF’ tracks) has elapsed while
code has been executing within the profiler.  Only run time counts
towards the profile, not wall-clock time.  For example, sleeping and
waiting for input or output do not cause the timer clock to advance.

Usage
=====

 -- Scheme Procedure: statprof thunk [#:loop loop=1] [#:hz hz=100]
          [#:port port=(current-output-port)] [#:count-calls?
          count-calls?=#f] [#:display-style display-style='flat]
     Profile the execution of THUNK, and return its return values.

     The stack will be sampled HZ times per second, and the thunk itself
     will be called LOOP times.

     If COUNT-CALLS? is true, all procedure calls will be recorded.
     This operation is somewhat expensive.

     After the THUNK has been profiled, print out a profile to PORT.  If
     DISPLAY-STYLE is ‘flat’, the results will be printed as a flat
     profile.  Otherwise if DISPLAY-STYLE is ‘tree’, print the results
     as a tree profile.

     Note that ‘statprof’ requires a working profiling timer.  Some
     platforms do not support profiling timers.  ‘(provided?
     'ITIMER_PROF)’ can be used to check for support of profiling
     timers.

   Profiling can also be enabled and disabled manually.

 -- Scheme Procedure: statprof-active?
     Returns ‘#t’ if ‘statprof-start’ has been called more times than
     ‘statprof-stop’, ‘#f’ otherwise.

 -- Scheme Procedure: statprof-start
 -- Scheme Procedure: statprof-stop
     Start or stop the profiler.

 -- Scheme Procedure: statprof-reset sample-seconds sample-microseconds
          count-calls?
     Reset the profiling sample interval to SAMPLE-SECONDS and
     SAMPLE-MICROSECONDS.  If COUNT-CALLS? is true, arrange to
     instrument procedure calls as well as collecting statistical
     profiling data.

   If you use the manual ‘statprof-start’/‘statprof-stop’ interface, an
implicit statprof state will persist starting from the last call to
‘statprof-reset’, or the first call to ‘statprof-start’.  There are a
number of accessors to fetch statistics from this implicit state.

 -- Scheme Procedure: statprof-accumulated-time
     Returns the time accumulated during the last statprof run.

 -- Scheme Procedure: statprof-sample-count
     Returns the number of samples taken during the last statprof run.

 -- Scheme Procedure: statprof-fold-call-data proc init
     Fold PROC over the call-data accumulated by statprof.  This
     procedure cannot be called while statprof is active.

     PROC will be called with arguments, CALL-DATA and PRIOR-RESULT.

 -- Scheme Procedure: statprof-proc-call-data proc
     Returns the call-data associated with PROC, or ‘#f’ if none is
     available.

 -- Scheme Procedure: statprof-call-data-name cd
 -- Scheme Procedure: statprof-call-data-calls cd
 -- Scheme Procedure: statprof-call-data-cum-samples cd
 -- Scheme Procedure: statprof-call-data-self-samples cd
     Accessors for the fields in a statprof call-data object.

 -- Scheme Procedure: statprof-call-data->stats call-data
     Returns an object of type ‘statprof-stats’.

 -- Scheme Procedure: statprof-stats-proc-name stats
 -- Scheme Procedure: statprof-stats-%-time-in-proc stats
 -- Scheme Procedure: statprof-stats-cum-secs-in-proc stats
 -- Scheme Procedure: statprof-stats-self-secs-in-proc stats
 -- Scheme Procedure: statprof-stats-calls stats
 -- Scheme Procedure: statprof-stats-self-secs-per-call stats
 -- Scheme Procedure: statprof-stats-cum-secs-per-call stats
     Accessors for the fields in a ‘statprof-stats’ object.

 -- Scheme Procedure: statprof-display [port=(current-output-port)]
          [#:style style=flat]
     Displays a summary of the statistics collected.  Possible values
     for STYLE include:

     ‘flat’
          Display a traditional gprof-style flat profile.
     ‘anomalies’
          Find statistical anomalies in the data.
     ‘tree’
          Display a tree profile.

 -- Scheme Procedure: statprof-fetch-stacks
     Returns a list of stacks, as they were captured since the last call
     to ‘statprof-reset’.

 -- Scheme Procedure: statprof-fetch-call-tree [#:precise precise?=#f]
     Return a call tree for the previous statprof run.
     
     The return value is a list of nodes.  A node is a list of the form:
     @code
      node ::= (@var{proc} @var{count} . @var{nodes})
     @end code
     
     The @var{proc} is a printable representation of a procedure, as a
     string.  If @var{precise?} is false, which is the default, then a node
     corresponds to a procedure invocation.  If it is true, then a node
     corresponds to a return point in a procedure.  Passing @code{#:precise?
     #t} allows a user to distinguish different source lines in a procedure,
     but usually it is too much detail, so it is off by default.

 -- Scheme Procedure: gcprof thunk [#:loop]
     Like the ‘statprof’ procedure, but instead of profiling CPU time,
     we profile garbage collection.

     The stack will be sampled soon after every garbage collection
     during the evaluation of THUNK, yielding an approximate idea of
     what is causing allocation in your program.

     Since GC does not occur very frequently, you may need to use the
     LOOP parameter, to cause THUNK to be called LOOP times.


File: guile.info,  Node: SXML,  Next: Texinfo Processing,  Prev: Statprof,  Up: Guile Modules

7.20 SXML
=========

SXML is a native representation of XML in terms of standard Scheme data
types: lists, symbols, and strings.  For example, the simple XML
fragment:

     <parrot type="African Grey"><name>Alfie</name></parrot>

   may be represented with the following SXML:

     (parrot (@ (type "African Grey")) (name "Alfie"))

   SXML is very general, and is capable of representing all of XML.
Formally, this means that SXML is a conforming implementation of the
http://www.w3.org/TR/xml-infoset/ (XML Information Set) standard.

   Guile includes several facilities for working with XML and SXML:
parsers, serializers, and transformers.

* Menu:

* SXML Overview::               XML, as it was meant to be
* Reading and Writing XML::     Convenient XML parsing and serializing
* SSAX::                        Custom functional-style XML parsers
* Transforming SXML::           Munging SXML with ‘pre-post-order’
* SXML Tree Fold::              Fold-based SXML transformations
* SXPath::                      XPath for SXML
* sxml ssax input-parse::       The SSAX tokenizer, optimized for Guile
* sxml apply-templates::        A more XSLT-like approach to SXML transformations


File: guile.info,  Node: SXML Overview,  Next: Reading and Writing XML,  Up: SXML

7.20.1 SXML Overview
--------------------

(This section needs to be written; volunteers welcome.)


File: guile.info,  Node: Reading and Writing XML,  Next: SSAX,  Prev: SXML Overview,  Up: SXML

7.20.2 Reading and Writing XML
------------------------------

The ‘(sxml simple)’ module presents a basic interface for parsing XML
from a port into the Scheme SXML format, and for serializing it back to
text.

     (use-modules (sxml simple))

 -- Scheme Procedure: xml->sxml [string-or-port] [#:namespaces='()]
          [#:declare-namespaces?=#t] [#:trim-whitespace?=#f]
          [#:entities='()] [#:default-entity-handler=#f]
          [#:doctype-handler=#f]
     Use SSAX to parse an XML document into SXML. Takes one optional
     argument, STRING-OR-PORT, which defaults to the current input port.
     Returns the resulting SXML document.  If STRING-OR-PORT is a port,
     it will be left pointing at the next available character in the
     port.

   As is normal in SXML, XML elements parse as tagged lists.
Attributes, if any, are placed after the tag, within an ‘@’ element.
The root of the resulting XML will be contained in a special tag,
‘*TOP*’.  This tag will contain the root element of the XML, but also
any prior processing instructions.

     (xml->sxml "<foo/>")
     ⇒ (*TOP* (foo))
     (xml->sxml "<foo>text</foo>")
     ⇒ (*TOP* (foo "text"))
     (xml->sxml "<foo kind=\"bar\">text</foo>")
     ⇒ (*TOP* (foo (@ (kind "bar")) "text"))
     (xml->sxml "<?xml version=\"1.0\"?><foo/>")
     ⇒ (*TOP* (*PI* xml "version=\"1.0\"") (foo))

   All namespaces in the XML document must be declared, via ‘xmlns’
attributes.  SXML elements built from non-default namespaces will have
their tags prefixed with their URI. Users can specify custom prefixes
for certain namespaces with the ‘#:namespaces’ keyword argument to
‘xml->sxml’.

     (xml->sxml "<foo xmlns=\"http://example.org/ns1\">text</foo>")
     ⇒ (*TOP* (http://example.org/ns1:foo "text"))
     (xml->sxml "<foo xmlns=\"http://example.org/ns1\">text</foo>"
                #:namespaces '((ns1 . "http://example.org/ns1")))
     ⇒ (*TOP* (ns1:foo "text"))
     (xml->sxml "<foo xmlns:bar=\"http://example.org/ns2\"><bar:baz/></foo>"
                #:namespaces '((ns2 . "http://example.org/ns2")))
     ⇒ (*TOP* (foo (ns2:baz)))

   By default, namespaces passed to ‘xml->sxml’ are treated as if they
were declared on the root element.  Passing a false
‘#:declare-namespaces?’ argument will disable this behavior, requiring
in-document declarations of namespaces before use..

     (xml->sxml "<foo><ns2:baz/></foo>"
                #:namespaces '((ns2 . "http://example.org/ns2")))
     ⇒ (*TOP* (foo (ns2:baz)))
     (xml->sxml "<foo><ns2:baz/></foo>"
                #:namespaces '((ns2 . "http://example.org/ns2"))
                #:declare-namespaces? #f)
     ⇒ error: undeclared namespace: `bar'

   By default, all whitespace in XML is significant.  Passing the
‘#:trim-whitespace?’ keyword argument to ‘xml->sxml’ will trim
whitespace in front, behind and between elements, treating it as
“unsignificant”.  Whitespace in text fragments is left alone.

     (xml->sxml "<foo>\n<bar> Alfie the parrot! </bar>\n</foo>")
     ⇒ (*TOP* (foo "\n" (bar " Alfie the parrot! ") "\n"))
     (xml->sxml "<foo>\n<bar> Alfie the parrot! </bar>\n</foo>"
                #:trim-whitespace? #t)
     ⇒ (*TOP* (foo (bar " Alfie the parrot! ")))

   Parsed entities may be declared with the ‘#:entities’ keyword
argument, or handled with the ‘#:default-entity-handler’.  By default,
only the standard ‘&lt;’, ‘&gt;’, ‘&amp;’, ‘&apos;’ and ‘&quot;’
entities are defined, as well as the ‘&#N;’ and ‘&#xN;’ (decimal and
hexadecimal) numeric character entities.

     (xml->sxml "<foo>&amp;</foo>")
     ⇒ (*TOP* (foo "&"))
     (xml->sxml "<foo>&nbsp;</foo>")
     ⇒ error: undefined entity: nbsp
     (xml->sxml "<foo>&#xA0;</foo>")
     ⇒ (*TOP* (foo "\xa0"))
     (xml->sxml "<foo>&nbsp;</foo>"
                #:entities '((nbsp . "\xa0")))
     ⇒ (*TOP* (foo "\xa0"))
     (xml->sxml "<foo>&nbsp; &foo;</foo>"
                #:default-entity-handler
                (lambda (port name)
                  (case name
                    ((nbsp) "\xa0")
                    (else
                     (format (current-warning-port)
                             "~a:~a:~a: undefined entitity: ~a\n"
                             (or (port-filename port) "<unknown file>")
                             (port-line port) (port-column port)
                             name)
                     (symbol->string name)))))
     ⊣ <unknown file>:0:17: undefined entitity: foo
     ⇒ (*TOP* (foo "\xa0 foo"))

   By default, ‘xml->sxml’ skips over the ‘<!DOCTYPE>’ declaration, if
any.  This behavior can be overridden with the ‘#:doctype-handler’
argument, which should be a procedure of three arguments: the “docname”
(a symbol), “systemid” (a string), and the internal doctype subset (as a
string or ‘#f’ if not present).

   The handler should return keyword arguments as multiple values, as if
it were calling its continuation with keyword arguments.  The
continuation accepts the ‘#:entities’ and ‘#:namespaces’ keyword
arguments, in the same format that ‘xml->sxml’ itself takes.  These
entities and namespaces will be prepended to those given to the
‘xml->sxml’ invocation.

     (define (handle-foo docname systemid internal-subset)
       (case docname
         ((foo)
          (values #:entities '((greets . "<i>Hello, world!</i>"))))
         (else
          (values))))

     (xml->sxml "<!DOCTYPE foo><p>&greets;</p>"
                #:doctype-handler handle-foo)
     ⇒ (*TOP* (p (i "Hello, world!")))

   If the document has no doctype declaration, the DOCTYPE-HANDLER is
invoked with ‘#f’ for the three arguments.

   In the future, the continuation may accept other keyword arguments,
for example to validate the parsed SXML against the doctype.

 -- Scheme Procedure: sxml->xml tree [port]
     Serialize the SXML tree TREE as XML. The output will be written to
     the current output port, unless the optional argument PORT is
     present.

 -- Scheme Procedure: sxml->string sxml
     Detag an sxml tree SXML into a string.  Does not perform any
     formatting.


File: guile.info,  Node: SSAX,  Next: Transforming SXML,  Prev: Reading and Writing XML,  Up: SXML

7.20.3 SSAX: A Functional XML Parsing Toolkit
---------------------------------------------

Guile’s XML parser is based on Oleg Kiselyov’s powerful XML parsing
toolkit, SSAX.

7.20.3.1 History
................

Back in the 1990s, when the world was young again and XML was the
solution to all of its problems, there were basically two kinds of XML
parsers out there: DOM parsers and SAX parsers.

   A DOM parser reads through an entire XML document, building up a tree
of “DOM objects” representing the document structure.  They are very
easy to use, but sometimes you don’t actually want all of the
information in a document; building an object tree is not necessary if
all you want to do is to count word frequencies in a document, for
example.

   SAX parsers were created to give the programmer more control on the
parsing process.  A programmer gives the SAX parser a number of
“callbacks”: functions that will be called on various features of the
XML stream as they are encountered.  SAX parsers are more efficient, but
much harder to user, as users typically have to manually maintain a
stack of open elements.

   Kiselyov realized that the SAX programming model could be made much
simpler if the callbacks were formulated not as a linear fold across the
features of the XML stream, but as a _tree fold_ over the structure
implicit in the XML. In this way, the user has a very convenient,
functional-style interface that can still generate optimal parsers.

   The ‘xml->sxml’ interface from the ‘(sxml simple)’ module is a
DOM-style parser built using SSAX, though it returns SXML instead of DOM
objects.

7.20.3.2 Implementation
.......................

‘(sxml ssax)’ is a package of low-to-high level lexing and parsing
procedures that can be combined to yield a SAX, a DOM, a validating
parser, or a parser intended for a particular document type.  The
procedures in the package can be used separately to tokenize or parse
various pieces of XML documents.  The package supports XML Namespaces,
internal and external parsed entities, user-controlled handling of
whitespace, and validation.  This module therefore is intended to be a
framework, a set of “Lego blocks” you can use to build a parser
following any discipline and performing validation to any degree.  As an
example of the parser construction, the source file includes a
semi-validating SXML parser.

   SSAX has a “sequential” feel of SAX yet a “functional style” of DOM.
Like a SAX parser, the framework scans the document only once and
permits incremental processing.  An application that handles document
elements in order can run as efficiently as possible.  _Unlike_ a SAX
parser, the framework does not require an application register stateful
callbacks and surrender control to the parser.  Rather, it is the
application that can drive the framework – calling its functions to get
the current lexical or syntax element.  These functions do not maintain
or mutate any state save the input port.  Therefore, the framework
permits parsing of XML in a pure functional style, with the input port
being a monad (or a linear, read-once parameter).

   Besides the PORT, there is another monad – SEED.  Most of the middle-
and high-level parsers are single-threaded through the SEED.  The
functions of this framework do not process or affect the SEED in any
way: they simply pass it around as an instance of an opaque datatype.
User functions, on the other hand, can use the seed to maintain user’s
state, to accumulate parsing results, etc.  A user can freely mix their
own functions with those of the framework.  On the other hand, the user
may wish to instantiate a high-level parser: ‘SSAX:make-elem-parser’ or
‘SSAX:make-parser’.  In the latter case, the user must provide functions
of specific signatures, which are called at predictable moments during
the parsing: to handle character data, element data, or processing
instructions (PI). The functions are always given the SEED, among other
parameters, and must return the new SEED.

   From a functional point of view, XML parsing is a combined
pre-post-order traversal of a “tree” that is the XML document itself.
This down-and-up traversal tells the user about an element when its
start tag is encountered.  The user is notified about the element once
more, after all element’s children have been handled.  The process of
XML parsing therefore is a fold over the raw XML document.  Unlike a
fold over trees defined in [1], the parser is necessarily
single-threaded – obviously as elements in a text XML document are laid
down sequentially.  The parser therefore is a tree fold that has been
transformed to accept an accumulating parameter [1,2].

   Formally, the denotational semantics of the parser can be expressed
as

      parser:: (Start-tag -> Seed -> Seed) ->
     	   (Start-tag -> Seed -> Seed -> Seed) ->
     	   (Char-Data -> Seed -> Seed) ->
     	   XML-text-fragment -> Seed -> Seed
      parser fdown fup fchar "<elem attrs> content </elem>" seed
       = fup "<elem attrs>" seed
     	(parser fdown fup fchar "content" (fdown "<elem attrs>" seed))

      parser fdown fup fchar "char-data content" seed
       = parser fdown fup fchar "content" (fchar "char-data" seed)

      parser fdown fup fchar "elem-content content" seed
       = parser fdown fup fchar "content" (
     	parser fdown fup fchar "elem-content" seed)

   Compare the last two equations with the left fold

      fold-left kons elem:list seed = fold-left kons list (kons elem seed)

   The real parser created by ‘SSAX:make-parser’ is slightly more
complicated, to account for processing instructions, entity references,
namespaces, processing of document type declaration, etc.

   The XML standard document referred to in this module is
<http://www.w3.org/TR/1998/REC-xml-19980210.html>

   The present file also defines a procedure that parses the text of an
XML document or of a separate element into SXML, an S-expression-based
model of an XML Information Set.  SXML is also an Abstract Syntax Tree
of an XML document.  SXML is similar but not identical to DOM; SXML is
particularly suitable for Scheme-based XML/HTML authoring, SXPath
queries, and tree transformations.  See SXML.html for more details.
SXML is a term implementation of evaluation of the XML document [3].
The other implementation is context-passing.

   The present frameworks fully supports the XML Namespaces
Recommendation: <http://www.w3.org/TR/REC-xml-names/>.

   Other links:

[1]
     Jeremy Gibbons, Geraint Jones, "The Under-appreciated Unfold,"
     Proc.  ICFP’98, 1998, pp.  273-279.

[2]
     Richard S. Bird, The promotion and accumulation strategies in
     transformational programming, ACM Trans.  Progr.  Lang.  Systems,
     6(4):487-504, October 1984.

[3]
     Ralf Hinze, "Deriving Backtracking Monad Transformers," Functional
     Pearl.  Proc ICFP’00, pp.  186-197.

7.20.3.3 Usage
..............

 -- Scheme Procedure: current-ssax-error-port

 -- Scheme Procedure: with-ssax-error-to-port port thunk

 -- Scheme Procedure: xml-token? _
      -- Scheme Procedure: pair? x
          Return `#t' if X is a pair; otherwise return `#f'.
     
      

 -- Scheme Syntax: xml-token-kind token

 -- Scheme Syntax: xml-token-head token

 -- Scheme Procedure: make-empty-attlist

 -- Scheme Procedure: attlist-add attlist name-value

 -- Scheme Procedure: attlist-null? x
     Return ‘#t’ if X is the empty list, else ‘#f’.

 -- Scheme Procedure: attlist-remove-top attlist

 -- Scheme Procedure: attlist->alist attlist

 -- Scheme Procedure: attlist-fold kons knil lis1

 -- Scheme Procedure: define-parsed-entity! entity str
     Define a new parsed entity.  ENTITY should be a symbol.

     Instances of &ENTITY; in XML text will be replaced with the string
     STR, which will then be parsed.

 -- Scheme Procedure: reset-parsed-entity-definitions!
     Restore the set of parsed entity definitions to its initial state.

 -- Scheme Procedure: ssax:uri-string->symbol uri-str

 -- Scheme Procedure: ssax:skip-internal-dtd port

 -- Scheme Procedure: ssax:read-pi-body-as-string port

 -- Scheme Procedure: ssax:reverse-collect-str-drop-ws fragments

 -- Scheme Procedure: ssax:read-markup-token port

 -- Scheme Procedure: ssax:read-cdata-body port str-handler seed

 -- Scheme Procedure: ssax:read-char-ref port

 -- Scheme Procedure: ssax:read-attributes port entities

 -- Scheme Procedure: ssax:complete-start-tag tag-head port elems
          entities namespaces

 -- Scheme Procedure: ssax:read-external-id port

 -- Scheme Procedure: ssax:read-char-data port expect-eof? str-handler
          seed

 -- Scheme Procedure: ssax:xml->sxml port namespace-prefix-assig

 -- Scheme Syntax: ssax:make-parser . kw-val-pairs

 -- Scheme Syntax: ssax:make-pi-parser orig-handlers

 -- Scheme Syntax: ssax:make-elem-parser my-new-level-seed
          my-finish-element my-char-data-handler my-pi-handlers


File: guile.info,  Node: Transforming SXML,  Next: SXML Tree Fold,  Prev: SSAX,  Up: SXML

7.20.4 Transforming SXML
------------------------

7.20.4.1 Overview
.................

SXML expression tree transformers
=================================

Pre-Post-order traversal of a tree and creation of a new tree
-------------------------------------------------------------

     pre-post-order:: <tree> x <bindings> -> <new-tree>

   where

      <bindings> ::= (<binding> ...)
      <binding> ::= (<trigger-symbol> *preorder* . <handler>) |
                    (<trigger-symbol> *macro* . <handler>) |
     		(<trigger-symbol> <new-bindings> . <handler>) |
     		(<trigger-symbol> . <handler>)
      <trigger-symbol> ::= XMLname | *text* | *default*
      <handler> :: <trigger-symbol> x [<tree>] -> <new-tree>

   The pre-post-order function visits the nodes and nodelists
pre-post-order (depth-first).  For each ‘<Node>’ of the form ‘(NAME
<Node> ...)’, it looks up an association with the given NAME among its
<BINDINGS>.  If failed, ‘pre-post-order’ tries to locate a ‘*default*’
binding.  It’s an error if the latter attempt fails as well.  Having
found a binding, the ‘pre-post-order’ function first checks to see if
the binding is of the form

     	(<trigger-symbol> *preorder* . <handler>)

   If it is, the handler is ’applied’ to the current node.  Otherwise,
the pre-post-order function first calls itself recursively for each
child of the current node, with <NEW-BINDINGS> prepended to the
<BINDINGS> in effect.  The result of these calls is passed to the
<HANDLER> (along with the head of the current <NODE>).  To be more
precise, the handler is _applied_ to the head of the current node and
its processed children.  The result of the handler, which should also be
a ‘<tree>’, replaces the current <NODE>.  If the current <NODE> is a
text string or other atom, a special binding with a symbol ‘*text*’ is
looked up.

   A binding can also be of a form

     	(<trigger-symbol> *macro* . <handler>)

   This is equivalent to ‘*preorder*’ described above.  However, the
result is re-processed again, with the current stylesheet.

7.20.4.2 Usage
..............

 -- Scheme Procedure: SRV:send-reply . fragments
     Output the FRAGMENTS to the current output port.

     The fragments are a list of strings, characters, numbers, thunks,
     ‘#f’, ‘#t’ – and other fragments.  The function traverses the tree
     depth-first, writes out strings and characters, executes thunks,
     and ignores ‘#f’ and ‘'()’.  The function returns ‘#t’ if anything
     was written at all; otherwise the result is ‘#f’ If ‘#t’ occurs
     among the fragments, it is not written out but causes the result of
     ‘SRV:send-reply’ to be ‘#t’.

 -- Scheme Procedure: foldts fdown fup fhere seed tree

 -- Scheme Procedure: post-order tree bindings

 -- Scheme Procedure: pre-post-order tree bindings

 -- Scheme Procedure: replace-range beg-pred end-pred forest


File: guile.info,  Node: SXML Tree Fold,  Next: SXPath,  Prev: Transforming SXML,  Up: SXML

7.20.5 SXML Tree Fold
---------------------

7.20.5.1 Overview
.................

‘(sxml fold)’ defines a number of variants of the “fold” algorithm for
use in transforming SXML trees.  Additionally it defines the layout
operator, ‘fold-layout’, which might be described as a context-passing
variant of SSAX’s ‘pre-post-order’.

7.20.5.2 Usage
..............

 -- Scheme Procedure: foldt fup fhere tree
     The standard multithreaded tree fold.

     FUP is of type [a] -> a.  FHERE is of type object -> a.

 -- Scheme Procedure: foldts fdown fup fhere seed tree
     The single-threaded tree fold originally defined in SSAX. *Note
     SSAX::, for more information.

 -- Scheme Procedure: foldts* fdown fup fhere seed tree
     A variant of ‘foldts’ that allows pre-order tree rewrites.
     Originally defined in Andy Wingo’s 2007 paper, _Applications of
     fold to XML transformation_.

 -- Scheme Procedure: fold-values proc list . seeds
     A variant of ‘fold’ that allows multi-valued seeds.  Note that the
     order of the arguments differs from that of ‘fold’.  *Note SRFI-1
     Fold and Map::.

 -- Scheme Procedure: foldts*-values fdown fup fhere tree . seeds
     A variant of ‘foldts*’ that allows multi-valued seeds.  Originally
     defined in Andy Wingo’s 2007 paper, _Applications of fold to XML
     transformation_.

 -- Scheme Procedure: fold-layout tree bindings params layout stylesheet
     A traversal combinator in the spirit of ‘pre-post-order’.  *Note
     Transforming SXML::.

     ‘fold-layout’ was originally presented in Andy Wingo’s 2007 paper,
     _Applications of fold to XML transformation_.

          bindings := (<binding>...)
          binding  := (<tag> <handler-pair>...)
                    | (*default* . <post-handler>)
                    | (*text* . <text-handler>)
          tag      := <symbol>
          handler-pair := (pre-layout . <pre-layout-handler>)
                    | (post . <post-handler>)
                    | (bindings . <bindings>)
                    | (pre . <pre-handler>)
                    | (macro . <macro-handler>)

     PRE-LAYOUT-HANDLER
          A function of three arguments:

          KIDS
               the kids of the current node, before traversal

          PARAMS
               the params of the current node

          LAYOUT
               the layout coming into this node

          PRE-LAYOUT-HANDLER is expected to use this information to
          return a layout to pass to the kids.  The default
          implementation returns the layout given in the arguments.

     POST-HANDLER
          A function of five arguments:

          TAG
               the current tag being processed

          PARAMS
               the params of the current node

          LAYOUT
               the layout coming into the current node, before any kids
               were processed

          KLAYOUT
               the layout after processing all of the children

          KIDS
               the already-processed child nodes

          POST-HANDLER should return two values, the layout to pass to
          the next node and the final tree.

     TEXT-HANDLER
          TEXT-HANDLER is a function of three arguments:

          TEXT
               the string

          PARAMS
               the current params

          LAYOUT
               the current layout

          TEXT-HANDLER should return two values, the layout to pass to
          the next node and the value to which the string should
          transform.


File: guile.info,  Node: SXPath,  Next: sxml ssax input-parse,  Prev: SXML Tree Fold,  Up: SXML

7.20.6 SXPath
-------------

7.20.6.1 Overview
.................

SXPath: SXML Query Language
===========================

SXPath is a query language for SXML, an instance of XML Information set
(Infoset) in the form of s-expressions.  See ‘(sxml ssax)’ for the
definition of SXML and more details.  SXPath is also a translation into
Scheme of an XML Path Language, XPath (http://www.w3.org/TR/xpath).
XPath and SXPath describe means of selecting a set of Infoset’s items or
their properties.

   To facilitate queries, XPath maps the XML Infoset into an explicit
tree, and introduces important notions of a location path and a current,
context node.  A location path denotes a selection of a set of nodes
relative to a context node.  Any XPath tree has a distinguished, root
node – which serves as the context node for absolute location paths.
Location path is recursively defined as a location step joined with a
location path.  A location step is a simple query of the database
relative to a context node.  A step may include expressions that further
filter the selected set.  Each node in the resulting set is used as a
context node for the adjoining location path.  The result of the step is
a union of the sets returned by the latter location paths.

   The SXML representation of the XML Infoset (see SSAX.scm) is rather
suitable for querying as it is.  Bowing to the XPath specification, we
will refer to SXML information items as ’Nodes’:

      	<Node> ::= <Element> | <attributes-coll> | <attrib>
      		   | "text string" | <PI>

   This production can also be described as

     	<Node> ::= (name . <Nodeset>) | "text string"

   An (ordered) set of nodes is just a list of the constituent nodes:

      	<Nodeset> ::= (<Node> ...)

   Nodesets, and Nodes other than text strings are both lists.  A
<Nodeset> however is either an empty list, or a list whose head is not a
symbol.  A symbol at the head of a node is either an XML name (in which
case it’s a tag of an XML element), or an administrative name such as
’@’.  This uniform list representation makes processing rather simple
and elegant, while avoiding confusion.  The multi-branch tree structure
formed by the mutually-recursive datatypes <Node> and <Nodeset> lends
itself well to processing by functional languages.

   A location path is in fact a composite query over an XPath tree or
its branch.  A singe step is a combination of a projection, selection or
a transitive closure.  Multiple steps are combined via join and union
operations.  This insight allows us to _elegantly_ implement XPath as a
sequence of projection and filtering primitives – converters – joined by
“combinators”.  Each converter takes a node and returns a nodeset which
is the result of the corresponding query relative to that node.  A
converter can also be called on a set of nodes.  In that case it returns
a union of the corresponding queries over each node in the set.  The
union is easily implemented as a list append operation as all nodes in a
SXML tree are considered distinct, by XPath conventions.  We also
preserve the order of the members in the union.  Query combinators are
high-order functions: they take converter(s) (which is a Node|Nodeset ->
Nodeset function) and compose or otherwise combine them.  We will be
concerned with only relative location paths [XPath]: an absolute
location path is a relative path applied to the root node.

   Similarly to XPath, SXPath defines full and abbreviated notations for
location paths.  In both cases, the abbreviated notation can be
mechanically expanded into the full form by simple rewriting rules.  In
the case of SXPath the corresponding rules are given in the
documentation of the ‘sxpath’ procedure.  *Note SXPath procedure
documentation: sxpath-procedure-docs.

   The regression test suite at the end of the file ‘SXPATH-old.scm’
shows a representative sample of SXPaths in both notations, juxtaposed
with the corresponding XPath expressions.  Most of the samples are
borrowed literally from the XPath specification.

   Much of the following material is taken from the SXPath sources by
Oleg Kiselyov et al.

7.20.6.2 Basic Converters and Applicators
.........................................

A converter is a function mapping a nodeset (or a single node) to
another nodeset.  Its type can be represented like this:

     type Converter = Node|Nodeset -> Nodeset

   A converter can also play the role of a predicate: in that case, if a
converter, applied to a node or a nodeset, yields a non-empty nodeset,
the converter-predicate is deemed satisfied.  Likewise, an empty nodeset
is equivalent to ‘#f’ in denoting failure.

 -- Scheme Procedure: nodeset? x
     Return ‘#t’ if X is a nodeset.

 -- Scheme Procedure: node-typeof? crit
     This function implements a ’Node test’ as defined in Sec.  2.3 of
     the XPath document.  A node test is one of the components of a
     location step.  It is also a converter-predicate in SXPath.

     The function ‘node-typeof?’ takes a type criterion and returns a
     function, which, when applied to a node, will tell if the node
     satisfies the test.

     The criterion CRIT is a symbol, one of the following:

     ‘id’
          tests if the node has the right name (id)

     ‘@’
          tests if the node is an <attributes-coll>

     ‘*’
          tests if the node is an <Element>

     ‘*text*’
          tests if the node is a text node

     ‘*PI*’
          tests if the node is a PI (processing instruction) node

     ‘*any*’
          ‘#t’ for any type of node

 -- Scheme Procedure: node-eq? other
     A curried equivalence converter predicate that takes a node OTHER
     and returns a function that takes another node.  The two nodes are
     compared using ‘eq?’.

 -- Scheme Procedure: node-equal? other
     A curried equivalence converter predicate that takes a node OTHER
     and returns a function that takes another node.  The two nodes are
     compared using ‘equal?’.

 -- Scheme Procedure: node-pos n
     Select the N’th element of a nodeset and return as a singular
     nodeset.  If the N’th element does not exist, return an empty
     nodeset.  If N is a negative number the node is picked from the
     tail of the list.

          ((node-pos 1) nodeset)  ; return the the head of the nodeset (if exists)
          ((node-pos 2) nodeset)  ; return the node after that (if exists)
          ((node-pos -1) nodeset) ; selects the last node of a non-empty nodeset
          ((node-pos -2) nodeset) ; selects the last but one node, if exists.

 -- Scheme Procedure: filter pred?
     A filter applicator, which introduces a filtering context.  The
     argument converter PRED? is considered a predicate, with either
     ‘#f’ or ‘nil’ meaning failure.

 -- Scheme Procedure: take-until pred?
          take-until:: Converter -> Converter, or
          take-until:: Pred -> Node|Nodeset -> Nodeset

     Given a converter-predicate PRED? and a nodeset, apply the
     predicate to each element of the nodeset, until the predicate
     yields anything but ‘#f’ or ‘nil’.  Return the elements of the
     input nodeset that have been processed until that moment (that is,
     which fail the predicate).

     ‘take-until’ is a variation of the ‘filter’ above: ‘take-until’
     passes elements of an ordered input set up to (but not including)
     the first element that satisfies the predicate.  The nodeset
     returned by ‘((take-until (not pred)) nset)’ is a subset – to be
     more precise, a prefix – of the nodeset returned by ‘((filter pred)
     nset)’.

 -- Scheme Procedure: take-after pred?
          take-after:: Converter -> Converter, or
          take-after:: Pred -> Node|Nodeset -> Nodeset

     Given a converter-predicate PRED? and a nodeset, apply the
     predicate to each element of the nodeset, until the predicate
     yields anything but ‘#f’ or ‘nil’.  Return the elements of the
     input nodeset that have not been processed: that is, return the
     elements of the input nodeset that follow the first element that
     satisfied the predicate.

     ‘take-after’ along with ‘take-until’ partition an input nodeset
     into three parts: the first element that satisfies a predicate, all
     preceding elements and all following elements.

 -- Scheme Procedure: map-union proc lst
     Apply PROC to each element of LST and return the list of results.
     If PROC returns a nodeset, splice it into the result

     From another point of view, ‘map-union’ is a function
     ‘Converter->Converter’, which places an argument-converter in a
     joining context.

 -- Scheme Procedure: node-reverse node-or-nodeset
          node-reverse :: Converter, or
          node-reverse:: Node|Nodeset -> Nodeset

     Reverses the order of nodes in the nodeset.  This basic converter
     is needed to implement a reverse document order (see the XPath
     Recommendation).

 -- Scheme Procedure: node-trace title
          node-trace:: String -> Converter

     ‘(node-trace title)’ is an identity converter.  In addition it
     prints out the node or nodeset it is applied to, prefixed with the
     TITLE.  This converter is very useful for debugging.

7.20.6.3 Converter Combinators
..............................

Combinators are higher-order functions that transmogrify a converter or
glue a sequence of converters into a single, non-trivial converter.  The
goal is to arrive at converters that correspond to XPath location paths.

   From a different point of view, a combinator is a fixed, named
“pattern” of applying converters.  Given below is a complete set of such
patterns that together implement XPath location path specification.  As
it turns out, all these combinators can be built from a small number of
basic blocks: regular functional composition, ‘map-union’ and ‘filter’
applicators, and the nodeset union.

 -- Scheme Procedure: select-kids test-pred?
     ‘select-kids’ takes a converter (or a predicate) as an argument and
     returns another converter.  The resulting converter applied to a
     nodeset returns an ordered subset of its children that satisfy the
     predicate TEST-PRED?.

 -- Scheme Procedure: node-self pred?
     Similar to ‘select-kids’ except that the predicate PRED? is applied
     to the node itself rather than to its children.  The resulting
     nodeset will contain either one component, or will be empty if the
     node failed the predicate.

 -- Scheme Procedure: node-join . selectors
          node-join:: [LocPath] -> Node|Nodeset -> Nodeset, or
          node-join:: [Converter] -> Converter

     Join the sequence of location steps or paths as described above.

 -- Scheme Procedure: node-reduce . converters
          node-reduce:: [LocPath] -> Node|Nodeset -> Nodeset, or
          node-reduce:: [Converter] -> Converter

     A regular functional composition of converters.  From a different
     point of view, ‘((apply node-reduce converters) nodeset)’ is
     equivalent to ‘(foldl apply nodeset converters)’, i.e., folding, or
     reducing, a list of converters with the nodeset as a seed.

 -- Scheme Procedure: node-or . converters
          node-or:: [Converter] -> Converter

     This combinator applies all converters to a given node and produces
     the union of their results.  This combinator corresponds to a union
     (‘|’ operation) for XPath location paths.

 -- Scheme Procedure: node-closure test-pred?
          node-closure:: Converter -> Converter

     Select all _descendants_ of a node that satisfy a
     converter-predicate TEST-PRED?.  This combinator is similar to
     ‘select-kids’ but applies to grand...  children as well.  This
     combinator implements the ‘descendant::’ XPath axis.  Conceptually,
     this combinator can be expressed as

          (define (node-closure f)
            (node-or
              (select-kids f)
              (node-reduce (select-kids (node-typeof? '*)) (node-closure f))))

     This definition, as written, looks somewhat like a fixpoint, and it
     will run forever.  It is obvious however that sooner or later
     ‘(select-kids (node-typeof? '*))’ will return an empty nodeset.  At
     this point further iterations will no longer affect the result and
     can be stopped.

 -- Scheme Procedure: node-parent rootnode
          node-parent:: RootNode -> Converter

     ‘(node-parent rootnode)’ yields a converter that returns a parent
     of a node it is applied to.  If applied to a nodeset, it returns
     the list of parents of nodes in the nodeset.  The ROOTNODE does not
     have to be the root node of the whole SXML tree – it may be a root
     node of a branch of interest.

     Given the notation of Philip Wadler’s paper on semantics of XSLT,

       parent(x) = { y | y=subnode*(root), x=subnode(y) }

     Therefore, ‘node-parent’ is not the fundamental converter: it can
     be expressed through the existing ones.  Yet ‘node-parent’ is a
     rather convenient converter.  It corresponds to a ‘parent::’ axis
     of SXPath.  Note that the ‘parent::’ axis can be used with an
     attribute node as well.

 -- Scheme Procedure: sxpath path
     Evaluate an abbreviated SXPath.

          sxpath:: AbbrPath -> Converter, or
          sxpath:: AbbrPath -> Node|Nodeset -> Nodeset

     PATH is a list.  It is translated to the full SXPath according to
     the following rewriting rules:

          (sxpath '())
          ⇒ (node-join)

          (sxpath '(path-component ...))
          ⇒ (node-join (sxpath1 path-component) (sxpath '(...)))

          (sxpath1 '//)
          ⇒ (node-or
             (node-self (node-typeof? '*any*))
             (node-closure (node-typeof? '*any*)))

          (sxpath1 '(equal? x))
          ⇒ (select-kids (node-equal? x))

          (sxpath1 '(eq? x))
          ⇒ (select-kids (node-eq? x))

          (sxpath1 ?symbol)
          ⇒ (select-kids (node-typeof? ?symbol)

          (sxpath1 procedure)
          ⇒ procedure

          (sxpath1 '(?symbol ...))
          ⇒ (sxpath1 '((?symbol) ...))

          (sxpath1 '(path reducer ...))
          ⇒ (node-reduce (sxpath path) (sxpathr reducer) ...)

          (sxpathr number)
          ⇒ (node-pos number)

          (sxpathr path-filter)
          ⇒ (filter (sxpath path-filter))


File: guile.info,  Node: sxml ssax input-parse,  Next: sxml apply-templates,  Prev: SXPath,  Up: SXML

7.20.7 (sxml ssax input-parse)
------------------------------

7.20.7.1 Overview
.................

A simple lexer.

   The procedures in this module surprisingly often suffice to parse an
input stream.  They either skip, or build and return tokens, according
to inclusion or delimiting semantics.  The list of characters to expect,
include, or to break at may vary from one invocation of a function to
another.  This allows the functions to easily parse even
context-sensitive languages.

   EOF is generally frowned on, and thrown up upon if encountered.
Exceptions are mentioned specifically.  The list of expected characters
(characters to skip until, or break-characters) may include an EOF
"character", which is to be coded as the symbol, ‘*eof*’.

   The input stream to parse is specified as a “port”, which is usually
the last (and optional) argument.  It defaults to the current input port
if omitted.

   If the parser encounters an error, it will throw an exception to the
key ‘parser-error’.  The arguments will be of the form ‘(PORT MESSAGE
SPECIALISING-MSG*)’.

   The first argument is a port, which typically points to the offending
character or its neighborhood.  You can then use ‘port-column’ and
‘port-line’ to query the current position.  MESSAGE is the description
of the error.  Other arguments supply more details about the problem.

7.20.7.2 Usage
..............

 -- Scheme Procedure: peek-next-char [port]

 -- Scheme Procedure: assert-curr-char expected-chars comment [port]

 -- Scheme Procedure: skip-until arg [port]

 -- Scheme Procedure: skip-while skip-chars [port]

 -- Scheme Procedure: next-token prefix-skipped-chars break-chars
          [comment] [port]

 -- Scheme Procedure: next-token-of incl-list/pred [port]

 -- Scheme Procedure: read-text-line [port]

 -- Scheme Procedure: read-string n [port]

 -- Scheme Procedure: find-string-from-port? _ _ . _
     Looks for STR in <INPUT-PORT>, optionally within the first
     MAX-NO-CHAR characters.


File: guile.info,  Node: sxml apply-templates,  Prev: sxml ssax input-parse,  Up: SXML

7.20.8 (sxml apply-templates)
-----------------------------

7.20.8.1 Overview
.................

Pre-order traversal of a tree and creation of a new tree:

     	apply-templates:: tree x <templates> -> <new-tree>

   where

      <templates> ::= (<template> ...)
      <template>  ::= (<node-test> <node-test> ... <node-test> . <handler>)
      <node-test> ::= an argument to node-typeof? above
      <handler>   ::= <tree> -> <new-tree>

   This procedure does a _normal_, pre-order traversal of an SXML tree.
It walks the tree, checking at each node against the list of matching
templates.

   If the match is found (which must be unique, i.e., unambiguous), the
corresponding handler is invoked and given the current node as an
argument.  The result from the handler, which must be a ‘<tree>’, takes
place of the current node in the resulting tree.  The name of the
function is not accidental: it resembles rather closely an
‘apply-templates’ function of XSLT.

7.20.8.2 Usage
..............

 -- Scheme Procedure: apply-templates tree templates


File: guile.info,  Node: Texinfo Processing,  Prev: SXML,  Up: Guile Modules

7.21 Texinfo Processing
=======================

* Menu:

* texinfo::              Parse texinfo files or fragments into ‘stexi’, a scheme representation
* texinfo docbook::      Transform a subset of docbook into ‘stexi’
* texinfo html::         Transform ‘stexi’ into HTML
* texinfo indexing::     Extract an index from a piece of ‘stexi’
* texinfo string-utils::  String utility functions used by the texinfo processor
* texinfo plain-text::   Render ‘stexi’ as plain text
* texinfo serialize::    Render ‘stexi’ as texinfo
* texinfo reflection::   Enable texinfo across Guile’s help system


File: guile.info,  Node: texinfo,  Next: texinfo docbook,  Up: Texinfo Processing

7.21.1 (texinfo)
----------------

7.21.1.1 Overview
.................

Texinfo processing in scheme
----------------------------

This module parses texinfo into SXML. TeX will always be the processor
of choice for print output, of course.  However, although ‘makeinfo’
works well for info, its output in other formats is not very
customizable, and the program is not extensible as a whole.  This module
aims to provide an extensible framework for texinfo processing that
integrates texinfo into the constellation of SXML processing tools.

Notes on the SXML vocabulary
----------------------------

Consider the following texinfo fragment:

      @deffn Primitive set-car! pair value
      This function...
      @end deffn

   Logically, the category (Primitive), name (set-car!), and arguments
(pair value) are “attributes” of the deffn, with the description as the
content.  However, texinfo allows for @-commands within the arguments to
an environment, like ‘@deffn’, which means that texinfo “attributes” are
PCDATA. XML attributes, on the other hand, are CDATA. For this reason,
“attributes” of texinfo @-commands are called “arguments”, and are
grouped under the special element, ‘%’.

   Because ‘%’ is not a valid NCName, stexinfo is a superset of SXML. In
the interests of interoperability, this module provides a conversion
function to replace the ‘%’ with ‘texinfo-arguments’.

7.21.1.2 Usage
..............

 -- Function: call-with-file-and-dir filename proc
     Call the one-argument procedure PROC with an input port that reads
     from FILENAME.  During the dynamic extent of PROC’s execution, the
     current directory will be ‘(dirname FILENAME)’.  This is useful for
     parsing documents that can include files by relative path name.

 -- Variable: texi-command-specs

 -- Function: texi-command-depth command max-depth
     Given the texinfo command COMMAND, return its nesting level, or
     ‘#f’ if it nests too deep for MAX-DEPTH.

     Examples:

           (texi-command-depth 'chapter 4)        ⇒ 1
           (texi-command-depth 'top 4)            ⇒ 0
           (texi-command-depth 'subsection 4)     ⇒ 3
           (texi-command-depth 'appendixsubsec 4) ⇒ 3
           (texi-command-depth 'subsection 2)     ⇒ #f

 -- Function: texi-fragment->stexi string-or-port
     Parse the texinfo commands in STRING-OR-PORT, and return the
     resultant stexi tree.  The head of the tree will be the special
     command, ‘*fragment*’.

 -- Function: texi->stexi port
     Read a full texinfo document from PORT and return the parsed stexi
     tree.  The parsing will start at the ‘@settitle’ and end at ‘@bye’
     or EOF.

 -- Function: stexi->sxml tree
     Transform the stexi tree TREE into sxml.  This involves replacing
     the ‘%’ element that keeps the texinfo arguments with an element
     for each argument.

     FIXME: right now it just changes % to ‘texinfo-arguments’ – that
     doesn’t hang with the idea of making a dtd at some point


File: guile.info,  Node: texinfo docbook,  Next: texinfo html,  Prev: texinfo,  Up: Texinfo Processing

7.21.2 (texinfo docbook)
------------------------

7.21.2.1 Overview
.................

This module exports procedures for transforming a limited subset of the
SXML representation of docbook into stexi.  It is not complete by any
means.  The intention is to gather a number of routines and stylesheets
so that external modules can parse specific subsets of docbook, for
example that set generated by certain tools.

7.21.2.2 Usage
..............

 -- Variable: *sdocbook->stexi-rules*

 -- Variable: *sdocbook-block-commands*

 -- Function: sdocbook-flatten sdocbook
     "Flatten" a fragment of sdocbook so that block elements do not nest
     inside each other.

     Docbook is a nested format, where e.g.  a ‘refsect2’ normally
     appears inside a ‘refsect1’.  Logical divisions in the document are
     represented via the tree topology; a ‘refsect2’ element _contains_
     all of the elements in its section.

     On the contrary, texinfo is a flat format, in which sections are
     marked off by standalone section headers like ‘@subsection’, and
     block elements do not nest inside each other.

     This function takes a nested sdocbook fragment SDOCBOOK and
     flattens all of the sections, such that e.g.

           (refsect1 (refsect2 (para "Hello")))

     becomes

           ((refsect1) (refsect2) (para "Hello"))

     Oftentimes (always?)  sectioning elements have ‘<title>’ as their
     first element child; users interested in processing the ‘refsect*’
     elements into proper sectioning elements like ‘chapter’ might be
     interested in ‘replace-titles’ and ‘filter-empty-elements’.  *Note
     replace-titles: texinfo docbook replace-titles, and *note
     filter-empty-elements: texinfo docbook filter-empty-elements.

     Returns a nodeset; that is to say, an untagged list of stexi
     elements.  *Note SXPath::, for the definition of a nodeset.

 -- Function: filter-empty-elements sdocbook
     Filters out empty elements in an sdocbook nodeset.  Mostly useful
     after running ‘sdocbook-flatten’.

 -- Function: replace-titles sdocbook-fragment
     Iterate over the sdocbook nodeset SDOCBOOK-FRAGMENT, transforming
     contiguous ‘refsect’ and ‘title’ elements into the appropriate
     texinfo sectioning command.  Most useful after having run
     ‘sdocbook-flatten’.

     For example:

           (replace-titles '((refsect1) (title "Foo") (para "Bar.")))
              ⇒ '((chapter "Foo") (para "Bar."))


File: guile.info,  Node: texinfo html,  Next: texinfo indexing,  Prev: texinfo docbook,  Up: Texinfo Processing

7.21.3 (texinfo html)
---------------------

7.21.3.1 Overview
.................

This module implements transformation from ‘stexi’ to HTML. Note that
the output of ‘stexi->shtml’ is actually SXML with the HTML vocabulary.
This means that the output can be further processed, and that it must
eventually be serialized by ‘sxml->xml’.  *Note Reading and Writing
XML::.

   References (i.e., the ‘@ref’ family of commands) are resolved by a
“ref-resolver”.  *Note add-ref-resolver!: texinfo html
add-ref-resolver!.

7.21.3.2 Usage
..............

 -- Function: add-ref-resolver! proc
     Add PROC to the head of the list of ref-resolvers.  PROC will be
     expected to take the name of a node and the name of a manual and
     return the URL of the referent, or ‘#f’ to pass control to the next
     ref-resolver in the list.

     The default ref-resolver will return the concatenation of the
     manual name, ‘#’, and the node name.

 -- Function: stexi->shtml tree
     Transform the stexi TREE into shtml, resolving references via
     ref-resolvers.  See the module commentary for more details.

 -- Function: urlify str


File: guile.info,  Node: texinfo indexing,  Next: texinfo string-utils,  Prev: texinfo html,  Up: Texinfo Processing

7.21.4 (texinfo indexing)
-------------------------

7.21.4.1 Overview
.................

Given a piece of stexi, return an index of a specified variety.

   Note that currently, ‘stexi-extract-index’ doesn’t differentiate
between different kinds of index entries.  That’s a bug ;)

7.21.4.2 Usage
..............

 -- Function: stexi-extract-index tree manual-name kind
     Given an stexi tree TREE, index all of the entries of type KIND.
     KIND can be one of the predefined texinfo indices (‘concept’,
     ‘variable’, ‘function’, ‘key’, ‘program’, ‘type’) or one of the
     special symbols ‘auto’ or ‘all’.  ‘auto’ will scan the stext for a
     ‘(printindex)’ statement, and ‘all’ will generate an index from all
     entries, regardless of type.

     The returned index is a list of pairs, the CAR of which is the
     entry (a string) and the CDR of which is a node name (a string).


File: guile.info,  Node: texinfo string-utils,  Next: texinfo plain-text,  Prev: texinfo indexing,  Up: Texinfo Processing

7.21.5 (texinfo string-utils)
-----------------------------

7.21.5.1 Overview
.................

Module ‘(texinfo string-utils)’ provides various string-related
functions useful to Guile’s texinfo support.

7.21.5.2 Usage
..............

 -- Function: escape-special-chars str special-chars escape-char
     Returns a copy of STR with all given special characters preceded by
     the given ESCAPE-CHAR.

     SPECIAL-CHARS can either be a single character, or a string
     consisting of all the special characters.

          ;; make a string regexp-safe...
           (escape-special-chars "***(Example String)***"
                                "[]()/*."
                                #\\)
          => "\\*\\*\\*\\(Example String\\)\\*\\*\\*"

          ;; also can escape a singe char...
           (escape-special-chars "richardt@vzavenue.net"
                                #\@
                                #\@)
          => "richardt@@vzavenue.net"

 -- Function: transform-string str match? replace [start] [end]
     Uses MATCH? against each character in STR, and performs a
     replacement on each character for which matches are found.

     MATCH? may either be a function, a character, a string, or ‘#t’.
     If MATCH? is a function, then it takes a single character as input,
     and should return ‘#t’ for matches.  MATCH? is a character, it is
     compared to each string character using ‘char=?’.  If MATCH? is a
     string, then any character in that string will be considered a
     match.  ‘#t’ will cause every character to be a match.

     If REPLACE is a function, it is called with the matched character
     as an argument, and the returned value is sent to the output string
     via ‘display’.  If REPLACE is anything else, it is sent through the
     output string via ‘display’.

     Note that the replacement for the matched characters does not need
     to be a single character.  That is what differentiates this
     function from ‘string-map’, and what makes it useful for
     applications such as converting ‘#\&’ to ‘"&amp;"’ in web page
     text.  Some other functions in this module are just wrappers around
     common uses of ‘transform-string’.  Transformations not possible
     with this function should probably be done with regular
     expressions.

     If START and END are given, they control which portion of the
     string undergoes transformation.  The entire input string is still
     output, though.  So, if START is ‘5’, then the first five
     characters of STR will still appear in the returned string.

          ; these two are equivalent...
           (transform-string str #\space #\-) ; change all spaces to -'s
           (transform-string str (lambda (c) (char=? #\space c)) #\-)

 -- Function: expand-tabs str [tab-size]
     Returns a copy of STR with all tabs expanded to spaces.  TAB-SIZE
     defaults to 8.

     Assuming tab size of 8, this is equivalent to:

           (transform-string str #\tab "        ")

 -- Function: center-string str [width] [chr] [rchr]
     Returns a copy of STR centered in a field of WIDTH characters.  Any
     needed padding is done by character CHR, which defaults to
     ‘#\space’.  If RCHR is provided, then the padding to the right will
     use it instead.  See the examples below.  left and RCHR on the
     right.  The default WIDTH is 80.  The default CHR and RCHR is
     ‘#\space’.  The string is never truncated.

           (center-string "Richard Todd" 24)
          => "      Richard Todd      "

           (center-string " Richard Todd " 24 #\=)
          => "===== Richard Todd ====="

           (center-string " Richard Todd " 24 #\< #\>)
          => "<<<<< Richard Todd >>>>>"

 -- Function: left-justify-string str [width] [chr]
     ‘left-justify-string str [width chr]’.  Returns a copy of STR
     padded with CHR such that it is left justified in a field of WIDTH
     characters.  The default WIDTH is 80.  Unlike ‘string-pad’ from
     srfi-13, the string is never truncated.

 -- Function: right-justify-string str [width] [chr]
     Returns a copy of STR padded with CHR such that it is right
     justified in a field of WIDTH characters.  The default WIDTH is 80.
     The default CHR is ‘#\space’.  Unlike ‘string-pad’ from srfi-13,
     the string is never truncated.

 -- Function: collapse-repeated-chars str [chr] [num]
     Returns a copy of STR with all repeated instances of CHR collapsed
     down to at most NUM instances.  The default value for CHR is
     ‘#\space’, and the default value for NUM is 1.

           (collapse-repeated-chars "H  e  l  l  o")
          => "H e l l o"
           (collapse-repeated-chars "H--e--l--l--o" #\-)
          => "H-e-l-l-o"
           (collapse-repeated-chars "H-e--l---l----o" #\- 2)
          => "H-e--l--l--o"

 -- Function: make-text-wrapper [#:line-width] [#:expand-tabs?]
          [#:tab-width] [#:collapse-whitespace?] [#:subsequent-indent]
          [#:initial-indent] [#:break-long-words?]
     Returns a procedure that will split a string into lines according
     to the given parameters.

     ‘#:line-width’
          This is the target length used when deciding where to wrap
          lines.  Default is 80.

     ‘#:expand-tabs?’
          Boolean describing whether tabs in the input should be
          expanded.  Default is #t.

     ‘#:tab-width’
          If tabs are expanded, this will be the number of spaces to
          which they expand.  Default is 8.

     ‘#:collapse-whitespace?’
          Boolean describing whether the whitespace inside the existing
          text should be removed or not.  Default is #t.

          If text is already well-formatted, and is just being wrapped
          to fit in a different width, then set this to ‘#f’.  This way,
          many common text conventions (such as two spaces between
          sentences) can be preserved if in the original text.  If the
          input text spacing cannot be trusted, then leave this setting
          at the default, and all repeated whitespace will be collapsed
          down to a single space.

     ‘#:initial-indent’
          Defines a string that will be put in front of the first line
          of wrapped text.  Default is the empty string, “”.

     ‘#:subsequent-indent’
          Defines a string that will be put in front of all lines of
          wrapped text, except the first one.  Default is the empty
          string, “”.

     ‘#:break-long-words?’
          If a single word is too big to fit on a line, this setting
          tells the wrapper what to do.  Defaults to #t, which will
          break up long words.  When set to #f, the line will be
          allowed, even though it is longer than the defined
          ‘#:line-width’.

     The return value is a procedure of one argument, the input string,
     which returns a list of strings, where each element of the list is
     one line.

 -- Function: fill-string str . kwargs
     Wraps the text given in string STR according to the parameters
     provided in KWARGS, or the default setting if they are not given.
     Returns a single string with the wrapped text.  Valid keyword
     arguments are discussed in ‘make-text-wrapper’.

 -- Function: string->wrapped-lines str . kwargs
     ‘string->wrapped-lines str keywds ...’.  Wraps the text given in
     string STR according to the parameters provided in KEYWDS, or the
     default setting if they are not given.  Returns a list of strings
     representing the formatted lines.  Valid keyword arguments are
     discussed in ‘make-text-wrapper’.


File: guile.info,  Node: texinfo plain-text,  Next: texinfo serialize,  Prev: texinfo string-utils,  Up: Texinfo Processing

7.21.6 (texinfo plain-text)
---------------------------

7.21.6.1 Overview
.................

Transformation from stexi to plain-text.  Strives to re-create the
output from ‘info’; comes pretty damn close.

7.21.6.2 Usage
..............

 -- Function: stexi->plain-text tree
     Transform TREE into plain text.  Returns a string.

 -- Scheme Variable: *line-width*
     This fluid (*note Fluids and Dynamic States::) specifies the length
     of line for the purposes of line wrapping in the
     ‘stexi->plain-text’ conversion.


File: guile.info,  Node: texinfo serialize,  Next: texinfo reflection,  Prev: texinfo plain-text,  Up: Texinfo Processing

7.21.7 (texinfo serialize)
--------------------------

7.21.7.1 Overview
.................

Serialization of ‘stexi’ to plain texinfo.

7.21.7.2 Usage
..............

 -- Function: stexi->texi tree
     Serialize the stexi TREE into plain texinfo.


File: guile.info,  Node: texinfo reflection,  Prev: texinfo serialize,  Up: Texinfo Processing

7.21.8 (texinfo reflection)
---------------------------

7.21.8.1 Overview
.................

Routines to generare ‘stexi’ documentation for objects and modules.

   Note that in this context, an “object” is just a value associated
with a location.  It has nothing to do with GOOPS.

7.21.8.2 Usage
..............

 -- Function: module-stexi-documentation sym-name [%docs-resolver]
          [#:docs-resolver]
     Return documentation for the module named SYM-NAME.  The
     documentation will be formatted as ‘stexi’ (*note texinfo:
     texinfo.).

 -- Function: script-stexi-documentation scriptpath
     Return documentation for given script.  The documentation will be
     taken from the script’s commentary, and will be returned in the
     ‘stexi’ format (*note texinfo: texinfo.).

 -- Function: object-stexi-documentation _ [_] [#:force]

 -- Function: package-stexi-standard-copying name version updated years
          copyright-holder permissions
     Create a standard texinfo ‘copying’ section.

     YEARS is a list of years (as integers) in which the modules being
     documented were released.  All other arguments are strings.

 -- Function: package-stexi-standard-titlepage name version updated
          authors
     Create a standard GNU title page.

     AUTHORS is a list of ‘(NAME . EMAIL)’ pairs.  All other arguments
     are strings.

     Here is an example of the usage of this procedure:

           (package-stexi-standard-titlepage
            "Foolib"
            "3.2"
            "26 September 2006"
            '(("Alyssa P Hacker" . "alyssa@example.com"))
            '(2004 2005 2006)
            "Free Software Foundation, Inc."
            "Standard GPL permissions blurb goes here")

 -- Function: package-stexi-generic-menu name entries
     Create a menu from a generic alist of entries, the car of which
     should be the node name, and the cdr the description.  As an
     exception, an entry of ‘#f’ will produce a separator.

 -- Function: package-stexi-standard-menu name modules
          module-descriptions extra-entries
     Create a standard top node and menu, suitable for processing by
     makeinfo.

 -- Function: package-stexi-extended-menu name module-pairs script-pairs
          extra-entries
     Create an "extended" menu, like the standard menu but with a
     section for scripts.

 -- Function: package-stexi-standard-prologue name filename category
          description copying titlepage menu
     Create a standard prologue, suitable for later serialization to
     texinfo and .info creation with makeinfo.

     Returns a list of stexinfo forms suitable for passing to
     ‘package-stexi-documentation’ as the prologue.  *Note texinfo
     reflection package-stexi-documentation::, *note
     package-stexi-standard-titlepage: texinfo reflection
     package-stexi-standard-titlepage, *note
     package-stexi-standard-copying: texinfo reflection
     package-stexi-standard-copying, and *note
     package-stexi-standard-menu: texinfo reflection
     package-stexi-standard-menu.

 -- Function: package-stexi-documentation modules name filename prologue
          epilogue [#:module-stexi-documentation-args] [#:scripts]
     Create stexi documentation for a “package”, where a package is a
     set of modules that is released together.

     MODULES is expected to be a list of module names, where a module
     name is a list of symbols.  The stexi that is returned will be
     titled NAME and a texinfo filename of FILENAME.

     PROLOGUE and EPILOGUE are lists of stexi forms that will be spliced
     into the output document before and after the generated modules
     documentation, respectively.  *Note texinfo reflection
     package-stexi-standard-prologue::, to create a conventional GNU
     texinfo prologue.

     MODULE-STEXI-DOCUMENTATION-ARGS is an optional argument that, if
     given, will be added to the argument list when
     ‘module-texi-documentation’ is called.  For example, it might be
     useful to define a ‘#:docs-resolver’ argument.

 -- Function: package-stexi-documentation-for-include modules
          module-descriptions [#:module-stexi-documentation-args]
     Create stexi documentation for a “package”, where a package is a
     set of modules that is released together.

     MODULES is expected to be a list of module names, where a module
     name is a list of symbols.  Returns an stexinfo fragment.

     Unlike ‘package-stexi-documentation’, this function simply produces
     a menu and the module documentations instead of producing a full
     texinfo document.  This can be useful if you write part of your
     manual by hand, and just use ‘@include’ to pull in the
     automatically generated parts.

     MODULE-STEXI-DOCUMENTATION-ARGS is an optional argument that, if
     given, will be added to the argument list when
     ‘module-texi-documentation’ is called.  For example, it might be
     useful to define a ‘#:docs-resolver’ argument.


File: guile.info,  Node: GOOPS,  Next: Guile Implementation,  Prev: Guile Modules,  Up: Top

8 GOOPS
*******

GOOPS is the object oriented extension to Guile.  Its implementation is
derived from STk-3.99.3 by Erick Gallesio and version 1.3 of Gregor
Kiczales’ ‘Tiny-Clos’.  It is very close in spirit to CLOS, the Common
Lisp Object System, but is adapted for the Scheme language.

   GOOPS is a full object oriented system, with classes, objects,
multiple inheritance, and generic functions with multi-method dispatch.
Furthermore its implementation relies on a meta object protocol — which
means that GOOPS’s core operations are themselves defined as methods on
relevant classes, and can be customised by overriding or redefining
those methods.

   To start using GOOPS you first need to import the ‘(oop goops)’
module.  You can do this at the Guile REPL by evaluating:

     (use-modules (oop goops))

* Menu:

* Copyright Notice::
* Class Definition::
* Instance Creation::
* Slot Options::
* Slot Description Example::
* Methods and Generic Functions::
* Inheritance::
* Introspection::
* GOOPS Error Handling::
* GOOPS Object Miscellany::
* The Metaobject Protocol::
* Redefining a Class::
* Changing the Class of an Instance::


File: guile.info,  Node: Copyright Notice,  Next: Class Definition,  Up: GOOPS

8.1 Copyright Notice
====================

The material in this chapter is partly derived from the STk Reference
Manual written by Erick Gallesio, whose copyright notice is as follows.

   Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
Permission to use, copy, modify, distribute,and license this software
and its documentation for any purpose is hereby granted, provided that
existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions.  No written agreement,
license, or royalty fee is required for any of the authorized uses.
This software is provided “AS IS” without express or implied warranty.

   The material has been adapted for use in Guile, with the author’s
permission.


File: guile.info,  Node: Class Definition,  Next: Instance Creation,  Prev: Copyright Notice,  Up: GOOPS

8.2 Class Definition
====================

A new class is defined with the ‘define-class’ syntax:

     (define-class CLASS (SUPERCLASS ...)
        SLOT-DESCRIPTION ...
        CLASS-OPTION ...)

   CLASS is the class being defined.  The list of SUPERCLASSes specifies
which existing classes, if any, to inherit slots and properties from.
“Slots” hold per-instance(1) data, for instances of that class — like
“fields” or “member variables” in other object oriented systems.  Each
SLOT-DESCRIPTION gives the name of a slot and optionally some
“properties” of this slot; for example its initial value, the name of a
function which will access its value, and so on.  Class options, slot
descriptions and inheritance are discussed more below.

 -- syntax: define-class name (super ...) slot-definition ...
          class-option ...
     Define a class called NAME that inherits from SUPERs, with direct
     slots defined by SLOT-DEFINITIONs and CLASS-OPTIONs.  The newly
     created class is bound to the variable name NAME in the current
     environment.

     Each SLOT-DEFINITION is either a symbol that names the slot or a
     list,

          (SLOT-NAME-SYMBOL . SLOT-OPTIONS)

     where SLOT-NAME-SYMBOL is a symbol and SLOT-OPTIONS is a list with
     an even number of elements.  The even-numbered elements of
     SLOT-OPTIONS (counting from zero) are slot option keywords; the
     odd-numbered elements are the corresponding values for those
     keywords.

     Each CLASS-OPTION is an option keyword and corresponding value.

   As an example, let us define a type for representing a complex number
in terms of two real numbers.(2)  This can be done with the following
class definition:

     (define-class <my-complex> (<number>)
        r i)

   This binds the variable ‘<my-complex>’ to a new class whose instances
will contain two slots.  These slots are called ‘r’ and ‘i’ and will
hold the real and imaginary parts of a complex number.  Note that this
class inherits from ‘<number>’, which is a predefined class.(3)

   Slot options are described in the next section.  The possible class
options are as follows.

 -- class option: #:metaclass metaclass
     The ‘#:metaclass’ class option specifies the metaclass of the class
     being defined.  METACLASS must be a class that inherits from
     ‘<class>’.  For the use of metaclasses, see *note Metaobjects and
     the Metaobject Protocol:: and *note Metaclasses::.

     If the ‘#:metaclass’ option is absent, GOOPS reuses or constructs a
     metaclass for the new class by calling ‘ensure-metaclass’ (*note
     ensure-metaclass: Class Definition Protocol.).

 -- class option: #:name name
     The ‘#:name’ class option specifies the new class’s name.  This
     name is used to identify the class whenever related objects - the
     class itself, its instances and its subclasses - are printed.

     If the ‘#:name’ option is absent, GOOPS uses the first argument to
     ‘define-class’ as the class name.

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

   (1) Usually — but see also the ‘#:allocation’ slot option.

   (2) Of course Guile already provides complex numbers, and ‘<complex>’
is in fact a predefined class in GOOPS; but the definition here is still
useful as an example.

   (3) ‘<number>’ is the direct superclass of the predefined class
‘<complex>’; ‘<complex>’ is the superclass of ‘<real>’, and ‘<real>’ is
the superclass of ‘<integer>’.


File: guile.info,  Node: Instance Creation,  Next: Slot Options,  Prev: Class Definition,  Up: GOOPS

8.3 Instance Creation and Slot Access
=====================================

An instance (or object) of a defined class can be created with ‘make’.
‘make’ takes one mandatory parameter, which is the class of the instance
to create, and a list of optional arguments that will be used to
initialize the slots of the new instance.  For instance the following
form

     (define c (make <my-complex>))

creates a new ‘<my-complex>’ object and binds it to the Scheme variable
‘c’.

 -- generic: make
 -- method: make (class <class>) initarg ...
     Create and return a new instance of class CLASS, initialized using
     INITARG ....

     In theory, INITARG ... can have any structure that is understood by
     whatever methods get applied when the ‘initialize’ generic function
     is applied to the newly allocated instance.

     In practice, specialized ‘initialize’ methods would normally call
     ‘(next-method)’, and so eventually the standard GOOPS ‘initialize’
     methods are applied.  These methods expect INITARGS to be a list
     with an even number of elements, where even-numbered elements
     (counting from zero) are keywords and odd-numbered elements are the
     corresponding values.

     GOOPS processes initialization argument keywords automatically for
     slots whose definition includes the ‘#:init-keyword’ option (*note
     init-keyword: Slot Options.).  Other keyword value pairs can only
     be processed by an ‘initialize’ method that is specialized for the
     new instance’s class.  Any unprocessed keyword value pairs are
     ignored.

 -- generic: make-instance
 -- method: make-instance (class <class>) initarg ...
     ‘make-instance’ is an alias for ‘make’.

   The slots of the new complex number can be accessed using ‘slot-ref’
and ‘slot-set!’.  ‘slot-set!’ sets the value of an object slot and
‘slot-ref’ retrieves it.

     (slot-set! c 'r 10)
     (slot-set! c 'i 3)
     (slot-ref c 'r) ⇒ 10
     (slot-ref c 'i) ⇒ 3

   The ‘(oop goops describe)’ module provides a ‘describe’ function that
is useful for seeing all the slots of an object; it prints the slots and
their values to standard output.

     (describe c)
     ⊣
     #<<my-complex> 401d8638> is an instance of class <my-complex>
     Slots are:
          r = 10
          i = 3


File: guile.info,  Node: Slot Options,  Next: Slot Description Example,  Prev: Instance Creation,  Up: GOOPS

8.4 Slot Options
================

When specifying a slot (in a ‘(define-class ...)’ form), various options
can be specified in addition to the slot’s name.  Each option is
specified by a keyword.  The list of possible keywords is as follows.

 -- slot option: #:init-value init-value
 -- slot option: #:init-form init-form
 -- slot option: #:init-thunk init-thunk
 -- slot option: #:init-keyword init-keyword
     These options provide various ways to specify how to initialize the
     slot’s value at instance creation time.

     INIT-VALUE specifies a fixed initial slot value (shared across all
     new instances of the class).

     INIT-THUNK specifies a thunk that will provide a default value for
     the slot.  The thunk is called when a new instance is created and
     should return the desired initial slot value.

     INIT-FORM specifies a form that, when evaluated, will return an
     initial value for the slot.  The form is evaluated each time that
     an instance of the class is created, in the lexical environment of
     the containing ‘define-class’ expression.

     INIT-KEYWORD specifies a keyword that can be used to pass an
     initial slot value to ‘make’ when creating a new instance.

     Note that, since an ‘init-value’ value is shared across all
     instances of a class, you should only use it when the initial value
     is an immutable value, like a constant.  If you want to initialize
     a slot with a fresh, independently mutable value, you should use
     ‘init-thunk’ or ‘init-form’ instead.  Consider the following
     example.

          (define-class <chbouib> ()
            (hashtab #:init-value (make-hash-table)))

     Here only one hash table is created and all instances of
     ‘<chbouib>’ have their ‘hashtab’ slot refer to it.  In order to
     have each instance of ‘<chbouib>’ refer to a new hash table, you
     should instead write:

          (define-class <chbouib> ()
            (hashtab #:init-thunk make-hash-table))

     or:

          (define-class <chbouib> ()
            (hashtab #:init-form (make-hash-table)))

     If more than one of these options is specified for the same slot,
     the order of precedence, highest first is

        • ‘#:init-keyword’, if INIT-KEYWORD is present in the options
          passed to ‘make’

        • ‘#:init-thunk’, ‘#:init-form’ or ‘#:init-value’.

     If the slot definition contains more than one initialization option
     of the same precedence, the later ones are ignored.  If a slot is
     not initialized at all, its value is unbound.

     In general, slots that are shared between more than one instance
     are only initialized at new instance creation time if the slot
     value is unbound at that time.  However, if the new instance
     creation specifies a valid init keyword and value for a shared
     slot, the slot is re-initialized regardless of its previous value.

     Note, however, that the power of GOOPS’ metaobject protocol means
     that everything written here may be customized or overridden for
     particular classes!  The slot initializations described here are
     performed by the least specialized method of the generic function
     ‘initialize’, whose signature is

          (define-method (initialize (object <object>) initargs) ...)

     The initialization of instances of any given class can be
     customized by defining a ‘initialize’ method that is specialized
     for that class, and the author of the specialized method may decide
     to call ‘next-method’ - which will result in a call to the next
     less specialized ‘initialize’ method - at any point within the
     specialized code, or maybe not at all.  In general, therefore, the
     initialization mechanisms described here may be modified or
     overridden by more specialized code, or may not be supported at all
     for particular classes.

 -- slot option: #:getter getter
 -- slot option: #:setter setter
 -- slot option: #:accessor accessor
     Given an object OBJ with slots named ‘foo’ and ‘bar’, it is always
     possible to read and write those slots by calling ‘slot-ref’ and
     ‘slot-set!’ with the relevant slot name; for example:

          (slot-ref OBJ 'foo)
          (slot-set! OBJ 'bar 25)

     The ‘#:getter’, ‘#:setter’ and ‘#:accessor’ options, if present,
     tell GOOPS to create generic function and method definitions that
     can be used to get and set the slot value more conveniently.
     GETTER specifies a generic function to which GOOPS will add a
     method for getting the slot value.  SETTER specifies a generic
     function to which GOOPS will add a method for setting the slot
     value.  ACCESSOR specifies an accessor to which GOOPS will add
     methods for both getting and setting the slot value.

     So if a class includes a slot definition like this:

          (c #:getter get-count #:setter set-count #:accessor count)

     GOOPS defines generic function methods such that the slot value can
     be referenced using either the getter or the accessor -

          (let ((current-count (get-count obj))) ...)
          (let ((current-count (count obj))) ...)

     - and set using either the setter or the accessor -

          (set-count obj (+ 1 current-count))
          (set! (count obj) (+ 1 current-count))

     Note that

        • with an accessor, the slot value is set using the generalized
          ‘set!’ syntax

        • in practice, it is unusual for a slot to use all three of
          these options: read-only, write-only and read-write slots
          would typically use only ‘#:getter’, ‘#:setter’ and
          ‘#:accessor’ options respectively.

     The binding of the specified names is done in the environment of
     the ‘define-class’ expression.  If the names are already bound (in
     that environment) to values that cannot be upgraded to generic
     functions, those values are overwritten when the ‘define-class’
     expression is evaluated.  For more detail, see *note
     ensure-generic: Generic Function Internals.

 -- slot option: #:allocation allocation
     The ‘#:allocation’ option tells GOOPS how to allocate storage for
     the slot.  Possible values for ALLOCATION are

        • ‘#:instance’

          Indicates that GOOPS should create separate storage for this
          slot in each new instance of the containing class (and its
          subclasses).  This is the default.

        • ‘#:class’

          Indicates that GOOPS should create storage for this slot that
          is shared by all instances of the containing class (and its
          subclasses).  In other words, a slot in class C with
          allocation ‘#:class’ is shared by all INSTANCEs for which
          ‘(is-a? INSTANCE C)’.  This permits defining a kind of global
          variable which can be accessed only by (in)direct instances of
          the class which defines the slot.

        • ‘#:each-subclass’

          Indicates that GOOPS should create storage for this slot that
          is shared by all _direct_ instances of the containing class,
          and that whenever a subclass of the containing class is
          defined, GOOPS should create a new storage for the slot that
          is shared by all _direct_ instances of the subclass.  In other
          words, a slot with allocation ‘#:each-subclass’ is shared by
          all instances with the same ‘class-of’.

        • ‘#:virtual’

          Indicates that GOOPS should not allocate storage for this
          slot.  The slot definition must also include the ‘#:slot-ref’
          and ‘#:slot-set!’ options to specify how to reference and set
          the value for this slot.  See the example below.

     Slot allocation options are processed when defining a new class by
     the generic function ‘compute-get-n-set’, which is specialized by
     the class’s metaclass.  Hence new types of slot allocation can be
     implemented by defining a new metaclass and a method for
     ‘compute-get-n-set’ that is specialized for the new metaclass.  For
     an example of how to do this, see *note Customizing Class
     Definition::.

 -- slot option: #:slot-ref getter
 -- slot option: #:slot-set! setter
     The ‘#:slot-ref’ and ‘#:slot-set!’ options must be specified if the
     slot allocation is ‘#:virtual’, and are ignored otherwise.

     GETTER should be a closure taking a single INSTANCE parameter that
     returns the current slot value.  SETTER should be a closure taking
     two parameters - INSTANCE and NEW-VAL - that sets the slot value to
     NEW-VAL.


File: guile.info,  Node: Slot Description Example,  Next: Methods and Generic Functions,  Prev: Slot Options,  Up: GOOPS

8.5 Illustrating Slot Description
=================================

To illustrate slot description, we can redefine the ‘<my-complex>’ class
seen before.  A definition could be:

     (define-class <my-complex> (<number>)
        (r #:init-value 0 #:getter get-r #:setter set-r! #:init-keyword #:r)
        (i #:init-value 0 #:getter get-i #:setter set-i! #:init-keyword #:i))

With this definition, the ‘r’ and ‘i’ slots are set to 0 by default, and
can be initialised to other values by calling ‘make’ with the ‘#:r’ and
‘#:i’ keywords.  Also the generic functions ‘get-r’, ‘set-r!’, ‘get-i’
and ‘set-i!’ are automatically defined to read and write the slots.

     (define c1 (make <my-complex> #:r 1 #:i 2))
     (get-r c1) ⇒ 1
     (set-r! c1 12)
     (get-r c1) ⇒ 12
     (define c2 (make <my-complex> #:r 2))
     (get-r c2) ⇒ 2
     (get-i c2) ⇒ 0

   Accessors can both read and write a slot.  So, another definition of
the ‘<my-complex>’ class, using the ‘#:accessor’ option, could be:

     (define-class <my-complex> (<number>)
        (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
        (i #:init-value 0 #:accessor imag-part #:init-keyword #:i))

With this definition, the ‘r’ slot can be read with:
     (real-part c)
and set with:
     (set! (real-part c) new-value)

   Suppose now that we want to manipulate complex numbers with both
rectangular and polar coordinates.  One solution could be to have a
definition of complex numbers which uses one particular representation
and some conversion functions to pass from one representation to the
other.  A better solution is to use virtual slots, like this:

     (define-class <my-complex> (<number>)
        ;; True slots use rectangular coordinates
        (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
        (i #:init-value 0 #:accessor imag-part #:init-keyword #:i)
        ;; Virtual slots access do the conversion
        (m #:accessor magnitude #:init-keyword #:magn
           #:allocation #:virtual
           #:slot-ref (lambda (o)
                       (let ((r (slot-ref o 'r)) (i (slot-ref o 'i)))
                         (sqrt (+ (* r r) (* i i)))))
           #:slot-set! (lambda (o m)
                         (let ((a (slot-ref o 'a)))
                           (slot-set! o 'r (* m (cos a)))
                           (slot-set! o 'i (* m (sin a))))))
        (a #:accessor angle #:init-keyword #:angle
           #:allocation #:virtual
           #:slot-ref (lambda (o)
                       (atan (slot-ref o 'i) (slot-ref o 'r)))
           #:slot-set! (lambda(o a)
                        (let ((m (slot-ref o 'm)))
                           (slot-set! o 'r (* m (cos a)))
                           (slot-set! o 'i (* m (sin a)))))))


   In this class definition, the magnitude ‘m’ and angle ‘a’ slots are
virtual, and are calculated, when referenced, from the normal (i.e.
‘#:allocation #:instance’) slots ‘r’ and ‘i’, by calling the function
defined in the relevant ‘#:slot-ref’ option.  Correspondingly, writing
‘m’ or ‘a’ leads to calling the function defined in the ‘#:slot-set!’
option.  Thus the following expression

     (slot-set! c 'a 3)

permits to set the angle of the ‘c’ complex number.

     (define c (make <my-complex> #:r 12 #:i 20))
     (real-part c) ⇒ 12
     (angle c) ⇒ 1.03037682652431
     (slot-set! c 'i 10)
     (set! (real-part c) 1)
     (describe c)
     ⊣
     #<<my-complex> 401e9b58> is an instance of class <my-complex>
     Slots are:
          r = 1
          i = 10
          m = 10.0498756211209
          a = 1.47112767430373

   Since initialization keywords have been defined for the four slots,
we can now define the standard Scheme primitives ‘make-rectangular’ and
‘make-polar’.

     (define make-rectangular
        (lambda (x y) (make <my-complex> #:r x #:i y)))

     (define make-polar
        (lambda (x y) (make <my-complex> #:magn x #:angle y)))


File: guile.info,  Node: Methods and Generic Functions,  Next: Inheritance,  Prev: Slot Description Example,  Up: GOOPS

8.6 Methods and Generic Functions
=================================

A GOOPS method is like a Scheme procedure except that it is specialized
for a particular set of argument classes, and will only be used when the
actual arguments in a call match the classes in the method definition.

     (define-method (+ (x <string>) (y <string>))
       (string-append x y))

     (+ "abc" "de") ⇒ "abcde"

   A method is not formally associated with any single class (as it is
in many other object oriented languages), because a method can be
specialized for a combination of several classes.  If you’ve studied
object orientation in non-Lispy languages, you may remember discussions
such as whether a method to stretch a graphical image around a surface
should be a method of the image class, with a surface as a parameter, or
a method of the surface class, with an image as a parameter.  In GOOPS
you’d just write

     (define-method (stretch (im <image>) (sf <surface>))
       ...)

and the question of which class the method is more associated with does
not need answering.

   There can simultaneously be several methods with the same name but
different sets of specializing argument classes; for example:

     (define-method (+ (x <string>) (y <string)) ...)
     (define-method (+ (x <matrix>) (y <matrix>)) ...)
     (define-method (+ (f <fish>) (b <bicycle>)) ...)
     (define-method (+ (a <foo>) (b <bar>) (c <baz>)) ...)

A generic function is a container for the set of such methods that a
program intends to use.

   If you look at a program’s source code, and see ‘(+ x y)’ somewhere
in it, conceptually what is happening is that the program at that point
calls a generic function (in this case, the generic function bound to
the identifier ‘+’).  When that happens, Guile works out which of the
generic function’s methods is the most appropriate for the arguments
that the function is being called with; then it evaluates the method’s
code with the arguments as formal parameters.  This happens every time
that a generic function call is evaluated — it isn’t assumed that a
given source code call will end up invoking the same method every time.

   Defining an identifier as a generic function is done with the
‘define-generic’ macro.  Definition of a new method is done with the
‘define-method’ macro.  Note that ‘define-method’ automatically does a
‘define-generic’ if the identifier concerned is not already a generic
function, so often an explicit ‘define-generic’ call is not needed.

 -- syntax: define-generic symbol
     Create a generic function with name SYMBOL and bind it to the
     variable SYMBOL.  If SYMBOL was previously bound to a Scheme
     procedure (or procedure-with-setter), the old procedure (and
     setter) is incorporated into the new generic function as its
     default procedure (and setter).  Any other previous value,
     including an existing generic function, is discarded and replaced
     by a new, empty generic function.

 -- syntax: define-method (generic parameter ...) body ...
     Define a method for the generic function or accessor GENERIC with
     parameters PARAMETERs and body BODY ....

     GENERIC is a generic function.  If GENERIC is a variable which is
     not yet bound to a generic function object, the expansion of
     ‘define-method’ will include a call to ‘define-generic’.  If
     GENERIC is ‘(setter GENERIC-WITH-SETTER)’, where
     GENERIC-WITH-SETTER is a variable which is not yet bound to a
     generic-with-setter object, the expansion will include a call to
     ‘define-accessor’.

     Each PARAMETER must be either a symbol or a two-element list
     ‘(SYMBOL CLASS)’.  The symbols refer to variables in the body forms
     that will be bound to the parameters supplied by the caller when
     calling this method.  The CLASSes, if present, specify the possible
     combinations of parameters to which this method can be applied.

     BODY ... are the bodies of the method definition.

   ‘define-method’ expressions look a little like Scheme procedure
definitions of the form

     (define (name formals ...) . body)

   The important difference is that each formal parameter, apart from
the possible “rest” argument, can be qualified by a class name: ‘FORMAL’
becomes ‘(FORMAL CLASS)’.  The meaning of this qualification is that the
method being defined will only be applicable in a particular generic
function invocation if the corresponding argument is an instance of
‘CLASS’ (or one of its subclasses).  If more than one of the formal
parameters is qualified in this way, then the method will only be
applicable if each of the corresponding arguments is an instance of its
respective qualifying class.

   Note that unqualified formal parameters act as though they are
qualified by the class ‘<top>’, which GOOPS uses to mean the superclass
of all valid Scheme types, including both primitive types and GOOPS
classes.

   For example, if a generic function method is defined with PARAMETERs
‘(s1 <square>)’ and ‘(n <number>)’, that method is only applicable to
invocations of its generic function that have two parameters where the
first parameter is an instance of the ‘<square>’ class and the second
parameter is a number.

* Menu:

* Accessors::
* Extending Primitives::
* Merging Generics::
* Next-method::
* Generic Function and Method Examples::
* Handling Invocation Errors::


File: guile.info,  Node: Accessors,  Next: Extending Primitives,  Up: Methods and Generic Functions

8.6.1 Accessors
---------------

An accessor is a generic function that can also be used with the
generalized ‘set!’ syntax (*note Procedures with Setters::).  Guile will
handle a call like

     (set! (accessor args...) value)

by calling the most specialized method of ‘accessor’ that matches the
classes of ‘args’ and ‘value’.  ‘define-accessor’ is used to bind an
identifier to an accessor.

 -- syntax: define-accessor symbol
     Create an accessor with name SYMBOL and bind it to the variable
     SYMBOL.  If SYMBOL was previously bound to a Scheme procedure (or
     procedure-with-setter), the old procedure (and setter) is
     incorporated into the new accessor as its default procedure (and
     setter).  Any other previous value, including an existing generic
     function or accessor, is discarded and replaced by a new, empty
     accessor.


File: guile.info,  Node: Extending Primitives,  Next: Merging Generics,  Prev: Accessors,  Up: Methods and Generic Functions

8.6.2 Extending Primitives
--------------------------

Many of Guile’s primitive procedures can be extended by giving them a
generic function definition that operates in conjunction with their
normal C-coded implementation.  When a primitive is extended in this
way, it behaves like a generic function with the C-coded implementation
as its default method.

   This extension happens automatically if a method is defined (by a
‘define-method’ call) for a variable whose current value is a primitive.
But it can also be forced by calling ‘enable-primitive-generic!’.

 -- primitive procedure: enable-primitive-generic! primitive
     Force the creation of a generic function definition for PRIMITIVE.

   Once the generic function definition for a primitive has been
created, it can be retrieved using ‘primitive-generic-generic’.

 -- primitive procedure: primitive-generic-generic primitive
     Return the generic function definition of PRIMITIVE.

     ‘primitive-generic-generic’ raises an error if PRIMITIVE is not a
     primitive with generic capability.


File: guile.info,  Node: Merging Generics,  Next: Next-method,  Prev: Extending Primitives,  Up: Methods and Generic Functions

8.6.3 Merging Generics
----------------------

GOOPS generic functions and accessors often have short, generic names.
For example, if a vector package provides an accessor for the X
coordinate of a vector, that accessor may just be called ‘x’.  It
doesn’t need to be called, for example, ‘vector:x’, because GOOPS will
work out, when it sees code like ‘(x OBJ)’, that the vector-specific
method of ‘x’ should be called if OBJ is a vector.

   That raises the question, though, of what happens when different
packages define a generic function with the same name.  Suppose we work
with a graphical package which needs to use two independent vector
packages for 2D and 3D vectors respectively.  If both packages export
‘x’, what does the code using those packages end up with?

   *note duplicate binding handlers: Creating Guile Modules. explains
how this is resolved for conflicting bindings in general.  For generics,
there is a special duplicates handler, ‘merge-generics’, which tells the
module system to merge generic functions with the same name.  Here is an
example:

     (define-module (math 2D-vectors)
       #:use-module (oop goops)
       #:export (x y ...))

     (define-module (math 3D-vectors)
       #:use-module (oop goops)
       #:export (x y z ...))

     (define-module (my-module)
       #:use-module (oop goops)
       #:use-module (math 2D-vectors)
       #:use-module (math 3D-vectors)
       #:duplicates (merge-generics))

   The generic function ‘x’ in ‘(my-module)’ will now incorporate all of
the methods of ‘x’ from both imported modules.

   To be precise, there will now be three distinct generic functions
named ‘x’: ‘x’ in ‘(math 2D-vectors)’, ‘x’ in ‘(math 3D-vectors)’, and
‘x’ in ‘(my-module)’; and these functions share their methods in an
interesting and dynamic way.

   To explain, let’s call the imported generic functions (in ‘(math
2D-vectors)’ and ‘(math 3D-vectors)’) the “ancestors”, and the merged
generic function (in ‘(my-module)’), the “descendant”.  The general rule
is that for any generic function G, the applicable methods are selected
from the union of the methods of G’s descendant functions, the methods
of G itself and the methods of G’s ancestor functions.

   Thus ancestor functions effectively share methods with their
descendants, and vice versa.  In the example above, ‘x’ in ‘(math
2D-vectors)’ will share the methods of ‘x’ in ‘(my-module)’ and vice
versa.(1)  Sharing is dynamic, so adding another new method to a
descendant implies adding it to that descendant’s ancestors too.

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

   (1) But note that ‘x’ in ‘(math 2D-vectors)’ doesn’t share methods
with ‘x’ in ‘(math 3D-vectors)’, so modularity is still preserved.


File: guile.info,  Node: Next-method,  Next: Generic Function and Method Examples,  Prev: Merging Generics,  Up: Methods and Generic Functions

8.6.4 Next-method
-----------------

When you call a generic function, with a particular set of arguments,
GOOPS builds a list of all the methods that are applicable to those
arguments and orders them by how closely the method definitions match
the actual argument types.  It then calls the method at the top of this
list.  If the selected method’s code wants to call on to the next method
in this list, it can do so by using ‘next-method’.

     (define-method (Test (a <integer>)) (cons 'integer (next-method)))
     (define-method (Test (a <number>))  (cons 'number  (next-method)))
     (define-method (Test a)             (list 'top))

   With these definitions,

     (Test 1)   ⇒ (integer number top)
     (Test 1.0) ⇒ (number top)
     (Test #t)  ⇒ (top)

   ‘next-method’ is always called as just ‘(next-method)’.  The
arguments for the next method call are always implicit, and always the
same as for the original method call.

   If you want to call on to a method with the same name but with a
different set of arguments (as you might with overloaded methods in C++,
for example), you do not use ‘next-method’, but instead simply write the
new call as usual:

     (define-method (Test (a <number>) min max)
       (if (and (>= a min) (<= a max))
           (display "Number is in range\n"))
       (Test a))

     (Test 2 1 10)
     ⊣
     Number is in range
     ⇒
     (integer number top)

   (You should be careful in this case that the ‘Test’ calls do not lead
to an infinite recursion, but this consideration is just the same as in
Scheme code in general.)


File: guile.info,  Node: Generic Function and Method Examples,  Next: Handling Invocation Errors,  Prev: Next-method,  Up: Methods and Generic Functions

8.6.5 Generic Function and Method Examples
------------------------------------------

Consider the following definitions:

     (define-generic G)
     (define-method (G (a <integer>) b) 'integer)
     (define-method (G (a <real>) b) 'real)
     (define-method (G a b) 'top)

   The ‘define-generic’ call defines G as a generic function.  The three
next lines define methods for G.  Each method uses a sequence of
“parameter specializers” that specify when the given method is
applicable.  A specializer permits to indicate the class a parameter
must belong to (directly or indirectly) to be applicable.  If no
specializer is given, the system defaults it to ‘<top>’.  Thus, the
first method definition is equivalent to

     (define-method (G (a <integer>) (b <top>)) 'integer)

   Now, let’s look at some possible calls to the generic function G:

     (G 2 3)    ⇒ integer
     (G 2 #t)   ⇒ integer
     (G 1.2 'a) ⇒ real
     (G #t #f)  ⇒ top
     (G 1 2 3)  ⇒ error (since no method exists for 3 parameters)

   The methods above use only one specializer per parameter list.  But
in general, any or all of a method’s parameters may be specialized.
Suppose we define now:

     (define-method (G (a <integer>) (b <number>))  'integer-number)
     (define-method (G (a <integer>) (b <real>))    'integer-real)
     (define-method (G (a <integer>) (b <integer>)) 'integer-integer)
     (define-method (G a (b <number>))              'top-number)

With these definitions:

     (G 1 2)   ⇒ integer-integer
     (G 1 1.0) ⇒ integer-real
     (G 1 #t)  ⇒ integer
     (G 'a 1)  ⇒ top-number

   As a further example we shall continue to define operations on the
‘<my-complex>’ class.  Suppose that we want to use it to implement
complex numbers completely.  For instance a definition for the addition
of two complex numbers could be

     (define-method (new-+ (a <my-complex>) (b <my-complex>))
       (make-rectangular (+ (real-part a) (real-part b))
                         (+ (imag-part a) (imag-part b))))

   To be sure that the ‘+’ used in the method ‘new-+’ is the standard
addition we can do:

     (define-generic new-+)

     (let ((+ +))
       (define-method (new-+ (a <my-complex>) (b <my-complex>))
         (make-rectangular (+ (real-part a) (real-part b))
                           (+ (imag-part a) (imag-part b)))))

   The ‘define-generic’ ensures here that ‘new-+’ will be defined in the
global environment.  Once this is done, we can add methods to the
generic function ‘new-+’ which make a closure on the ‘+’ symbol.  A
complete writing of the ‘new-+’ methods is shown in *note Figure 8.1:
fig:newplus.

     (define-generic new-+)

     (let ((+ +))

       (define-method (new-+ (a <real>) (b <real>)) (+ a b))

       (define-method (new-+ (a <real>) (b <my-complex>))
         (make-rectangular (+ a (real-part b)) (imag-part b)))

       (define-method (new-+ (a <my-complex>) (b <real>))
         (make-rectangular (+ (real-part a) b) (imag-part a)))

       (define-method (new-+ (a <my-complex>) (b <my-complex>))
         (make-rectangular (+ (real-part a) (real-part b))
                           (+ (imag-part a) (imag-part b))))

       (define-method (new-+ (a <number>))  a)

       (define-method (new-+) 0)

       (define-method (new-+ . args)
         (new-+ (car args)
           (apply new-+ (cdr args)))))

     (set! + new-+)

Figure 8.1: Extending ‘+’ to handle complex numbers

   We take advantage here of the fact that generic function are not
obliged to have a fixed number of parameters.  The four first methods
implement dyadic addition.  The fifth method says that the addition of a
single element is this element itself.  The sixth method says that using
the addition with no parameter always return 0 (as is also true for the
primitive ‘+’).  The last method takes an arbitrary number of
parameters(1).  This method acts as a kind of ‘reduce’: it calls the
dyadic addition on the _car_ of the list and on the result of applying
it on its rest.  To finish, the ‘set!’ permits to redefine the ‘+’
symbol to our extended addition.

   To conclude our implementation (integration?)  of complex numbers, we
could redefine standard Scheme predicates in the following manner:

     (define-method (complex? c <my-complex>) #t)
     (define-method (complex? c)           #f)

     (define-method (number? n <number>) #t)
     (define-method (number? n)          #f)
     ...

   Standard primitives in which complex numbers are involved could also
be redefined in the same manner.

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

   (1) The parameter list for a ‘define-method’ follows the conventions
used for Scheme procedures.  In particular it can use the dot notation
or a symbol to denote an arbitrary number of parameters


File: guile.info,  Node: Handling Invocation Errors,  Prev: Generic Function and Method Examples,  Up: Methods and Generic Functions

8.6.6 Handling Invocation Errors
--------------------------------

If a generic function is invoked with a combination of parameters for
which there is no applicable method, GOOPS raises an error.

 -- generic: no-method
 -- method: no-method (gf <generic>) args
     When an application invokes a generic function, and no methods at
     all have been defined for that generic function, GOOPS calls the
     ‘no-method’ generic function.  The default method calls
     ‘goops-error’ with an appropriate message.

 -- generic: no-applicable-method
 -- method: no-applicable-method (gf <generic>) args
     When an application applies a generic function to a set of
     arguments, and no methods have been defined for those argument
     types, GOOPS calls the ‘no-applicable-method’ generic function.
     The default method calls ‘goops-error’ with an appropriate message.

 -- generic: no-next-method
 -- method: no-next-method (gf <generic>) args
     When a generic function method calls ‘(next-method)’ to invoke the
     next less specialized method for that generic function, and no less
     specialized methods have been defined for the current generic
     function arguments, GOOPS calls the ‘no-next-method’ generic
     function.  The default method calls ‘goops-error’ with an
     appropriate message.


File: guile.info,  Node: Inheritance,  Next: Introspection,  Prev: Methods and Generic Functions,  Up: GOOPS

8.7 Inheritance
===============

Here are some class definitions to help illustrate inheritance:

     (define-class A () a)
     (define-class B () b)
     (define-class C () c)
     (define-class D (A B) d a)
     (define-class E (A C) e c)
     (define-class F (D E) f)

   ‘A’, ‘B’, ‘C’ have a null list of superclasses.  In this case, the
system will replace the null list by a list which only contains
‘<object>’, the root of all the classes defined by ‘define-class’.  ‘D’,
‘E’, ‘F’ use multiple inheritance: each class inherits from two
previously defined classes.  Those class definitions define a hierarchy
which is shown in *note Figure 8.2: fig:hier.  In this figure, the class
‘<top>’ is also shown; this class is the superclass of all Scheme
objects.  In particular, ‘<top>’ is the superclass of all standard
Scheme types.

          <top>
          / \\\_____________________
         /   \\___________          \
        /     \           \          \
    <object>  <pair>  <procedure>  <number>
    /  |  \                           |
   /   |   \                          |
  A    B    C                      <complex>
  |\__/__   |                         |
   \ /   \ /                          |
    D     E                         <real>
     \   /                            |
       F                              |
                                   <integer>

Figure 8.2: A class hierarchy.

   When a class has superclasses, its set of slots is calculated by
taking the union of its own slots and those of all its superclasses.
Thus each instance of D will have three slots, ‘a’, ‘b’ and ‘d’).  The
slots of a class can be discovered using the ‘class-slots’ primitive.
For instance,

     (class-slots A) ⇒ ((a))
     (class-slots E) ⇒ ((a) (e) (c))
     (class-slots F) ⇒ ((e) (c) (b) (d) (a) (f))

The ordering of the returned slots is not significant.

* Menu:

* Class Precedence List::
* Sorting Methods::


File: guile.info,  Node: Class Precedence List,  Next: Sorting Methods,  Up: Inheritance

8.7.1 Class Precedence List
---------------------------

What happens when a class inherits from two or more superclasses that
have a slot with the same name but incompatible definitions — for
example, different init values or slot allocations?  We need a rule for
deciding which slot definition the derived class ends up with, and this
rule is provided by the class’s “Class Precedence List”.(1)

   Another problem arises when invoking a generic function, and there is
more than one method that could apply to the call arguments.  Here we
need a way of ordering the applicable methods, so that Guile knows which
method to use first, which to use next if that method calls
‘next-method’, and so on.  One of the ingredients for this ordering is
determining, for each given call argument, which of the specializing
classes, from each applicable method’s definition, is the most specific
for that argument; and here again the class precedence list helps.

   If inheritance was restricted such that each class could only have
one superclass — which is known as “single” inheritance — class ordering
would be easy.  The rule would be simply that a subclass is considered
more specific than its superclass.

   With multiple inheritance, ordering is less obvious, and we have to
impose an arbitrary rule to determine precedence.  Suppose we have

     (define-class X ()
        (x #:init-value 1))

     (define-class Y ()
        (x #:init-value 2))

     (define-class Z (X Y)
        (...))

Clearly the ‘Z’ class is more specific than ‘X’ or ‘Y’, for instances of
‘Z’.  But which is more specific out of ‘X’ and ‘Y’ — and hence, for the
definitions above, which ‘#:init-value’ will take effect when creating
an instance of ‘Z’?  The rule in GOOPS is that the superclasses listed
earlier are more specific than those listed later.  Hence ‘X’ is more
specific than ‘Y’, and the ‘#:init-value’ for slot ‘x’ in instances of
‘Z’ will be 1.

   Hence there is a linear ordering for a class and all its
superclasses, from most specific to least specific, and this ordering is
called the Class Precedence List of the class.

   In fact the rules above are not quite enough to always determine a
unique order, but they give an idea of how things work.  For example,
for the ‘F’ class shown in *note Figure 8.2: fig:hier, the class
precedence list is

     (f d e a c b <object> <top>)

In cases where there is any ambiguity (like this one), it is a bad idea
for programmers to rely on exactly what the order is.  If the order for
some superclasses is important, it can be expressed directly in the
class definition.

   The precedence list of a class can be obtained by calling
‘class-precedence-list’.  This function returns a ordered list whose
first element is the most specific class.  For instance:

     (class-precedence-list B) ⇒ (#<<class> B 401b97c8>
                                          #<<class> <object> 401e4a10>
                                          #<<class> <top> 4026a9d8>)

Or for a more immediately readable result:

     (map class-name (class-precedence-list B)) ⇒ (B <object> <top>)

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

   (1) This section is an adaptation of material from Jeff Dalton’s
(J.Dalton@ed.ac.uk) ‘Brief introduction to CLOS’

