This manual documents Guile version 2.0.14.

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

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

6.14.10.2 File Options
......................

When opening a file, the various procedures in this library 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 (see 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.

6.14.10.3 Buffer Modes
......................

Each port has an associated buffer mode.  For an output port, the buffer
mode defines when an output operation flushes the buffer associated with
the output port.  For an input port, the buffer mode defines how much
data will be read to satisfy read operations.  The possible buffer modes
are the symbols ‘none’ for no buffering, ‘line’ for flushing upon line
endings and reading up to line endings, or other
implementation-dependent behavior, and ‘block’ for arbitrary buffering.
This section uses the parameter name BUFFER-MODE for arguments that must
be buffer-mode symbols.

   If two ports are connected to the same mutable source, both ports are
unbuffered, and reading a byte or character from that shared source via
one of the two ports would change the bytes or characters seen via the
other port, a lookahead operation on one port will render the peeked
byte or character inaccessible via the other port, while a subsequent
read operation on the peeked port will see the peeked byte or character
even though the port is otherwise unbuffered.

   In other words, the semantics of buffering is defined in terms of
side effects on shared mutable sources, and a lookahead operation has
the same side effect on the shared source as a read operation.

 -- 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: Only the name of BUFFER-MODE-SYMBOL is significant.

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

6.14.10.4 Transcoders
.....................

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.

6.14.10.5 The End-of-File Object
................................

R5RS’ ‘eof-object?’ procedure is provided by the ‘(rnrs io ports)’
module:

 -- Scheme Procedure: eof-object? obj
 -- C Function: scm_eof_object_p (obj)
     Return true if OBJ is the end-of-file (EOF) object.

   In addition, the following procedure is provided:

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

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

6.14.10.6 Port Manipulation
...........................

The procedures listed below operate on any kind of R6RS I/O port.

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

 -- Scheme Procedure: port-transcoder port
     Returns the transcoder associated with PORT if PORT is textual and
     has an associated transcoder, and returns ‘#f’ if PORT is binary or
     does not have an associated transcoder.

 -- Scheme Procedure: binary-port? port
     Return ‘#t’ if PORT is a “binary port”, suitable for binary data
     input/output.

     Note that internally Guile does not differentiate between binary
     and textual ports, unlike the R6RS. Thus, this procedure returns
     true when PORT does not have an associated encoding—i.e., when
     ‘(port-encoding PORT)’ is ‘#f’ (see port-encoding).  This
     is the case for ports returned by R6RS procedures such as
     ‘open-bytevector-input-port’ and ‘make-custom-binary-output-port’.

     However, Guile currently does not prevent use of textual I/O
     procedures such as ‘display’ or ‘read-char’ with binary ports.
     Doing so “upgrades” the port from binary to textual, under the
     ISO-8859-1 encoding.  Likewise, Guile does not prevent use of
     ‘set-port-encoding!’ on a binary port, which also turns it into a
     “textual” port.

 -- Scheme Procedure: textual-port? port
     Always return ‘#t’, as all ports can be used for textual I/O in
     Guile.

 -- 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
     If PORT supports it (see below), return the offset (an integer)
     indicating where the next octet will be read from/written to in
     PORT.  If PORT does not support this operation, an error condition
     is raised.

     This is similar to Guile’s ‘seek’ procedure with the ‘SEEK_CUR’
     argument (see Random Access).

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

 -- Scheme Procedure: set-port-position! port offset
     If PORT supports it (see below), set the position where the next
     octet will be read from/written to PORT to OFFSET (an integer).  If
     PORT does not support this operation, an error condition is raised.

     This is similar to Guile’s ‘seek’ procedure with the ‘SEEK_SET’
     argument (see 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.

6.14.10.7 Input Ports
.....................

 -- Scheme Procedure: input-port? obj
     Returns ‘#t’ if the argument is an input port (or a combined input
     and output port), and returns ‘#f’ otherwise.

 -- Scheme Procedure: port-eof? input-port
     Returns ‘#t’ if the ‘lookahead-u8’ procedure (if INPUT-PORT is a
     binary port) or the ‘lookahead-char’ procedure (if INPUT-PORT is a
     textual port) would return the end-of-file object, and ‘#f’
     otherwise.  The operation may block indefinitely if no data is
     available but the port cannot be determined to be at end of file.

 -- 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 (see R6RS File Options), 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: standard-input-port
     Returns a fresh binary input port connected to standard input.
     Whether the port supports the ‘port-position’ and
     ‘set-port-position!’ operations is implementation-dependent.

 -- Scheme Procedure: current-input-port
     This returns a default textual port for input.  Normally, this
     default port is associated with standard input, but can be
     dynamically re-assigned using the ‘with-input-from-file’ procedure
     from the ‘io simple (6)’ library (see rnrs io simple).  The
     port may or may not have an associated transcoder; if it does, the
     transcoder is implementation-dependent.

6.14.10.8 Binary Input
......................

R6RS binary input ports can be created with the procedures described
below.

 -- Scheme Procedure: open-bytevector-input-port bv [transcoder]
 -- C Function: scm_open_bytevector_input_port (bv, transcoder)
     Return an input port whose contents are drawn from bytevector BV
     (see Bytevectors).

     The TRANSCODER argument is currently not supported.

 -- Scheme Procedure: make-custom-binary-input-port id read!
          get-position set-position! close
 -- C Function: scm_make_custom_binary_input_port (id, read!,
          get-position, set-position!, close)
     Return a new custom binary input port(1) named ID (a string) whose
     input is drained by invoking READ! and passing it a bytevector, an
     index where bytes should be written, and the number of bytes to
     read.  The ‘read!’ procedure must return an integer indicating the
     number of bytes read, or ‘0’ to indicate the end-of-file.

     Optionally, if GET-POSITION is not ‘#f’, it must be a thunk that
     will be called when ‘port-position’ is invoked on the custom binary
     port and should return an integer indicating the position within
     the underlying data stream; if GET-POSITION was not supplied, the
     returned port does not support ‘port-position’.

     Likewise, if SET-POSITION! is not ‘#f’, it should be a one-argument
     procedure.  When ‘set-port-position!’ is invoked on the custom
     binary input port, SET-POSITION! is passed an integer indicating
     the position of the next byte is to read.

     Finally, if CLOSE is not ‘#f’, it must be a thunk.  It is invoked
     when the custom binary input port is closed.

     The returned port is fully buffered by default, but its buffering
     mode can be changed using ‘setvbuf’ (see ‘setvbuf’).

     Using a custom binary input port, the ‘open-bytevector-input-port’
     procedure could be implemented as follows:

          (define (open-bytevector-input-port source)
            (define position 0)
            (define length (bytevector-length source))

            (define (read! bv start count)
              (let ((count (min count (- length position))))
                (bytevector-copy! source position
                                  bv start count)
                (set! position (+ position count))
                count))

            (define (get-position) position)

            (define (set-position! new-position)
              (set! position new-position))

            (make-custom-binary-input-port "the port" read!
                                            get-position
                                            set-position!))

          (read (open-bytevector-input-port (string->utf8 "hello")))
          ⇒ hello

   Binary input is achieved using the procedures below:

 -- Scheme Procedure: get-u8 port
 -- C Function: scm_get_u8 (port)
     Return an octet read from PORT, a binary input port, blocking as
     necessary, or the end-of-file object.

 -- Scheme Procedure: lookahead-u8 port
 -- C Function: scm_lookahead_u8 (port)
     Like ‘get-u8’ but does not update PORT’s position to point past the
     octet.

 -- Scheme Procedure: get-bytevector-n port count
 -- C Function: scm_get_bytevector_n (port, count)
     Read COUNT octets from PORT, blocking as necessary and return a
     bytevector containing the octets read.  If fewer bytes are
     available, a bytevector smaller than COUNT is returned.

 -- Scheme Procedure: get-bytevector-n! port bv start count
 -- C Function: scm_get_bytevector_n_x (port, bv, start, count)
     Read COUNT bytes from PORT and store them in BV starting at index
     START.  Return either the number of bytes actually read or the
     end-of-file object.

 -- Scheme Procedure: get-bytevector-some port
 -- C Function: scm_get_bytevector_some (port)
     Read from PORT, blocking as necessary, until bytes are available or
     an end-of-file is reached.  Return either the end-of-file object or
     a new bytevector containing some of the available bytes (at least
     one), and update the port position to point just past these bytes.

 -- Scheme Procedure: get-bytevector-all port
 -- C Function: scm_get_bytevector_all (port)
     Read from PORT, blocking as necessary, until the end-of-file is
     reached.  Return either a new bytevector containing the data read
     or the end-of-file object (if no data were available).

   The ‘(ice-9 binary-ports)’ module provides the following procedure as
an extension to ‘(rnrs io ports)’:

 -- Scheme Procedure: unget-bytevector port bv [start [count]]
 -- C Function: scm_unget_bytevector (port, bv, start, count)
     Place the contents of BV in PORT, optionally starting at index
     START and limiting to COUNT octets, so that its bytes will be read
     from left-to-right as the next bytes from PORT during subsequent
     read operations.  If called multiple times, the unread bytes will
     be read again in last-in first-out order.

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

   (1) This is similar in spirit to Guile’s “soft ports” (see Soft Ports).

6.14.10.9 Textual Input
.......................

 -- Scheme Procedure: get-char textual-input-port
     Reads from TEXTUAL-INPUT-PORT, blocking as necessary, until a
     complete character is available from TEXTUAL-INPUT-PORT, or until
     an end of file is reached.

     If a complete character is available before the next end of file,
     ‘get-char’ returns that character and updates the input port to
     point past the character.  If an end of file is reached before any
     character is read, ‘get-char’ returns the end-of-file object.

 -- Scheme Procedure: lookahead-char textual-input-port
     The ‘lookahead-char’ procedure is like ‘get-char’, but it does not
     update TEXTUAL-INPUT-PORT to point past the character.

 -- Scheme Procedure: get-string-n textual-input-port count

     COUNT must be an exact, non-negative integer object, representing
     the number of characters to be read.

     The ‘get-string-n’ procedure reads from TEXTUAL-INPUT-PORT,
     blocking as necessary, until COUNT characters are available, or
     until an end of file is reached.

     If COUNT characters are available before end of file,
     ‘get-string-n’ returns a string consisting of those COUNT
     characters.  If fewer characters are available before an end of
     file, but one or more characters can be read, ‘get-string-n’
     returns a string containing those characters.  In either case, the
     input port is updated to point just past the characters read.  If
     no characters can be read before an end of file, the end-of-file
     object is returned.

 -- Scheme Procedure: get-string-n! textual-input-port string start
          count

     START and COUNT must be exact, non-negative integer objects, with
     COUNT representing the number of characters to be read.  STRING
     must be a string with at least $START + COUNT$ characters.

     The ‘get-string-n!’ procedure reads from TEXTUAL-INPUT-PORT in the
     same manner as ‘get-string-n’.  If COUNT characters are available
     before an end of file, they are written into STRING starting at
     index START, and COUNT is returned.  If fewer characters are
     available before an end of file, but one or more can be read, those
     characters are written into STRING starting at index START and the
     number of characters actually read is returned as an exact integer
     object.  If no characters can be read before an end of file, the
     end-of-file object is returned.

 -- Scheme Procedure: get-string-all textual-input-port
     Reads from TEXTUAL-INPUT-PORT until an end of file, decoding
     characters in the same manner as ‘get-string-n’ and
     ‘get-string-n!’.

     If characters are available before the end of file, a string
     containing all the characters decoded from that data are returned.
     If no character precedes the end of file, the end-of-file object is
     returned.

 -- Scheme Procedure: get-line textual-input-port
     Reads from TEXTUAL-INPUT-PORT up to and including the linefeed
     character or end of file, decoding characters in the same manner as
     ‘get-string-n’ and ‘get-string-n!’.

     If a linefeed character is read, a string containing all of the
     text up to (but not including) the linefeed character is returned,
     and the port is updated to point just past the linefeed character.
     If an end of file is encountered before any linefeed character is
     read, but some characters have been read and decoded as characters,
     a string containing those characters is returned.  If an end of
     file is encountered before any characters are read, the end-of-file
     object is returned.

          Note: The end-of-line style, if not ‘none’, will cause all
          line endings to be read as linefeed characters.  See R6RS Transcoders.

 -- 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, see Scheme Syntax)
     in the input is first skipped.  If an end of file occurs
     after the interlexeme space, the end-of-file object (see R6RS End-of-File)
     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.

6.14.10.10 Output Ports
.......................

 -- Scheme Procedure: output-port? obj
     Returns ‘#t’ if the argument is an output port (or a combined input
     and output port), ‘#f’ otherwise.

 -- Scheme Procedure: flush-output-port port
     Flushes any buffered output from the buffer of OUTPUT-PORT to the
     underlying file, device, or object.  The ‘flush-output-port’
     procedure returns an unspecified values.

 -- 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 (see R6RS File Options), 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).

 -- Scheme Procedure: standard-output-port
 -- Scheme Procedure: standard-error-port
     Returns a fresh 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-output-port
 -- Scheme Procedure: current-error-port
     These return default textual ports for regular output and error
     output.  Normally, these default ports are associated with standard
     output, and standard error, respectively.  The return value of
     ‘current-output-port’ can be dynamically re-assigned using the
     ‘with-output-to-file’ procedure from the ‘io simple (6)’ library
     (see rnrs io simple).  A port returned by one of these
     procedures may or may not have an associated transcoder; if it
     does, the transcoder is implementation-dependent.

6.14.10.11 Binary Output
........................

Binary output ports can be created with the procedures below.

 -- Scheme Procedure: open-bytevector-output-port [transcoder]
 -- C Function: scm_open_bytevector_output_port (transcoder)
     Return two values: a binary output port and a procedure.  The
     latter should be called with zero arguments to obtain a bytevector
     containing the data accumulated by the port, as illustrated below.

          (call-with-values
            (lambda ()
              (open-bytevector-output-port))
            (lambda (port get-bytevector)
              (display "hello" port)
              (get-bytevector)))

          ⇒ #vu8(104 101 108 108 111)

     The TRANSCODER argument is currently not supported.

 -- Scheme Procedure: make-custom-binary-output-port id write!
          get-position set-position! close
 -- C Function: scm_make_custom_binary_output_port (id, write!,
          get-position, set-position!, close)
     Return a new custom binary output port named ID (a string) whose
     output is sunk by invoking WRITE! and passing it a bytevector, an
     index where bytes should be read from this bytevector, and the
     number of bytes to be “written”.  The ‘write!’ procedure must
     return an integer indicating the number of bytes actually written;
     when it is passed ‘0’ as the number of bytes to write, it should
     behave as though an end-of-file was sent to the byte sink.

     The other arguments are as for ‘make-custom-binary-input-port’
     (see ‘make-custom-binary-input-port’).

   Writing to a binary output port can be done using the following
procedures:

 -- Scheme Procedure: put-u8 port octet
 -- C Function: scm_put_u8 (port, octet)
     Write OCTET, an integer in the 0–255 range, to PORT, a binary
     output port.

 -- Scheme Procedure: put-bytevector port bv [start [count]]
 -- C Function: scm_put_bytevector (port, bv, start, count)
     Write the contents of BV to PORT, optionally starting at index
     START and limiting to COUNT octets.

6.14.10.12 Textual Output
.........................

 -- Scheme Procedure: put-char port char
     Writes CHAR to the port.  The ‘put-char’ procedure returns an
     unspecified value.

 -- Scheme Procedure: put-string port string
 -- Scheme Procedure: put-string port string start
 -- Scheme Procedure: put-string port string start count

     START and COUNT must be non-negative exact integer objects.  STRING
     must have a length of at least START + COUNT.  START defaults to 0.
     COUNT defaults to ‘(string-length STRING)’ - START$.  The
     ‘put-string’ procedure writes the COUNT characters of STRING
     starting at index START to the port.  The ‘put-string’ procedure
     returns an unspecified value.

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

6.14.11 Using and Extending Ports in C
--------------------------------------

6.14.11.1 C Port Interface
..........................

This section describes how to use Scheme ports from C.

Port basics
...........

There are two main data structures.  A port type object (ptob) is of
type ‘scm_ptob_descriptor’.  A port instance is of type ‘scm_port’.
Given an ‘SCM’ variable which points to a port, the corresponding C port
object can be obtained using the ‘SCM_PTAB_ENTRY’ macro.  The ptob can
be obtained by using ‘SCM_PTOBNUM’ to give an index into the ‘scm_ptobs’
global array.

Port buffers
............

An input port always has a read buffer and an output port always has a
write buffer.  However the size of these buffers is not guaranteed to be
more than one byte (e.g., the ‘shortbuf’ field in ‘scm_port’ which is
used when no other buffer is allocated).  The way in which the buffers
are allocated depends on the implementation of the ptob.  For example in
the case of an fport, buffers may be allocated with malloc when the port
is created, but in the case of an strport the underlying string is used
as the buffer.

The ‘rw_random’ flag
....................

Special treatment is required for ports which can be seeked at random.
Before various operations, such as seeking the port or changing from
input to output on a bidirectional port or vice versa, the port
implementation must be given a chance to update its state.  The write
buffer is updated by calling the ‘flush’ ptob procedure and the input
buffer is updated by calling the ‘end_input’ ptob procedure.  In the
case of an fport, ‘flush’ causes buffered output to be written to the
file descriptor, while ‘end_input’ causes the descriptor position to be
adjusted to account for buffered input which was never read.

   The special treatment must be performed if the ‘rw_random’ flag in
the port is non-zero.

The ‘rw_active’ variable
........................

The ‘rw_active’ variable in the port is only used if ‘rw_random’ is set.
It’s defined as an enum with the following values:

‘SCM_PORT_READ’
     the read buffer may have unread data.

‘SCM_PORT_WRITE’
     the write buffer may have unwritten data.

‘SCM_PORT_NEITHER’
     neither the write nor the read buffer has data.

Reading from a port.
....................

To read from a port, it’s possible to either call existing libguile
procedures such as ‘scm_getc’ and ‘scm_read_line’ or to read data from
the read buffer directly.  Reading from the buffer involves the
following steps:

  1. Flush output on the port, if ‘rw_active’ is ‘SCM_PORT_WRITE’.

  2. Fill the read buffer, if it’s empty, using ‘scm_fill_input’.

  3. Read the data from the buffer and update the read position in the
     buffer.  Steps 2) and 3) may be repeated as many times as required.

  4. Set rw_active to ‘SCM_PORT_READ’ if ‘rw_random’ is set.

  5. update the port’s line and column counts.

Writing to a port.
..................

To write data to a port, calling ‘scm_lfwrite’ should be sufficient for
most purposes.  This takes care of the following steps:

  1. End input on the port, if ‘rw_active’ is ‘SCM_PORT_READ’.

  2. Pass the data to the ptob implementation using the ‘write’ ptob
     procedure.  The advantage of using the ptob ‘write’ instead of
     manipulating the write buffer directly is that it allows the data
     to be written in one operation even if the port is using the
     single-byte ‘shortbuf’.

  3. Set ‘rw_active’ to ‘SCM_PORT_WRITE’ if ‘rw_random’ is set.

6.14.11.2 Port Implementation
.............................

This section describes how to implement a new port type in C.

   As described in the previous section, a port type object (ptob) is a
structure of type ‘scm_ptob_descriptor’.  A ptob is created by calling
‘scm_make_port_type’.

 -- Function: scm_t_bits scm_make_port_type (char *name, int
          (*fill_input) (SCM port), void (*write) (SCM port, const void
          *data, size_t size))
     Return a new port type object.  The NAME, FILL_INPUT and WRITE
     parameters are initial values for those port type fields, as
     described below.  The other fields are initialized with default
     values and can be changed later.

   All of the elements of the ptob, apart from ‘name’, are procedures
which collectively implement the port behaviour.  Creating a new port
type mostly involves writing these procedures.

‘name’
     A pointer to a NUL terminated string: the name of the port type.
     This is the only element of ‘scm_ptob_descriptor’ which is not a
     procedure.  Set via the first argument to ‘scm_make_port_type’.

‘mark’
     Called during garbage collection to mark any SCM objects that a
     port object may contain.  It doesn’t need to be set unless the port
     has ‘SCM’ components.  Set using

      -- Function: void scm_set_port_mark (scm_t_bits tc, SCM (*mark)
               (SCM port))

‘free’
     Called when the port is collected during gc.  It should free any
     resources used by the port.  Set using

      -- Function: void scm_set_port_free (scm_t_bits tc, size_t (*free)
               (SCM port))

‘print’
     Called when ‘write’ is called on the port object, to print a port
     description.  E.g., for an fport it may produce something like:
     ‘#<input: /etc/passwd 3>’.  Set using

      -- Function: void scm_set_port_print (scm_t_bits tc, int (*print)
               (SCM port, SCM dest_port, scm_print_state *pstate))
          The first argument PORT is the object being printed, the
          second argument DEST_PORT is where its description should go.

‘equalp’
     Not used at present.  Set using

      -- Function: void scm_set_port_equalp (scm_t_bits tc, SCM
               (*equalp) (SCM, SCM))

‘close’
     Called when the port is closed, unless it was collected during gc.
     It should free any resources used by the port.  Set using

      -- Function: void scm_set_port_close (scm_t_bits tc, int (*close)
               (SCM port))

‘write’
     Accept data which is to be written using the port.  The port
     implementation may choose to buffer the data instead of processing
     it directly.  Set via the third argument to ‘scm_make_port_type’.

‘flush’
     Complete the processing of buffered output data.  Reset the value
     of ‘rw_active’ to ‘SCM_PORT_NEITHER’.  Set using

      -- Function: void scm_set_port_flush (scm_t_bits tc, void (*flush)
               (SCM port))

‘end_input’
     Perform any synchronization required when switching from input to
     output on the port.  Reset the value of ‘rw_active’ to
     ‘SCM_PORT_NEITHER’.  Set using

      -- Function: void scm_set_port_end_input (scm_t_bits tc, void
               (*end_input) (SCM port, int offset))

‘fill_input’
     Read new data into the read buffer and return the first character.
     It can be assumed that the read buffer is empty when this procedure
     is called.  Set via the second argument to ‘scm_make_port_type’.

‘input_waiting’
     Return a lower bound on the number of bytes that could be read from
     the port without blocking.  It can be assumed that the current
     state of ‘rw_active’ is ‘SCM_PORT_NEITHER’.  Set using

      -- Function: void scm_set_port_input_waiting (scm_t_bits tc, int
               (*input_waiting) (SCM port))

‘seek’
     Set the current position of the port.  The procedure can not make
     any assumptions about the value of ‘rw_active’ when it’s called.
     It can reset the buffers first if desired by using something like:

          if (pt->rw_active == SCM_PORT_READ)
            scm_end_input (port);
          else if (pt->rw_active == SCM_PORT_WRITE)
            ptob->flush (port);

     However note that this will have the side effect of discarding any
     data in the unread-char buffer, in addition to any side effects
     from the ‘end_input’ and ‘flush’ ptob procedures.  This is
     undesirable when seek is called to measure the current position of
     the port, i.e., ‘(seek p 0 SEEK_CUR)’.  The libguile fport and
     string port implementations take care to avoid this problem.

     The procedure is set using

      -- Function: void scm_set_port_seek (scm_t_bits tc, scm_t_off
               (*seek) (SCM port, scm_t_off offset, int whence))

‘truncate’
     Truncate the port data to be specified length.  It can be assumed
     that the current state of ‘rw_active’ is ‘SCM_PORT_NEITHER’.  Set
     using

      -- Function: void scm_set_port_truncate (scm_t_bits tc, void
               (*truncate) (SCM port, scm_t_off length))

6.14.12 Handling of Unicode byte order marks.
---------------------------------------------

This section documents the finer points of Guile’s handling of Unicode
byte order marks (BOMs).  A byte order mark (U+FEFF) is typically found
at the start of a UTF-16 or UTF-32 stream, to allow readers to reliably
determine the byte order.  Occasionally, a BOM is found at the start of
a UTF-8 stream, but this is much less common and not generally
recommended.

   Guile attempts to handle BOMs automatically, and in accordance with
the recommendations of the Unicode Standard, when the port encoding is
set to ‘UTF-8’, ‘UTF-16’, or ‘UTF-32’.  In brief, Guile automatically
writes a BOM at the start of a UTF-16 or UTF-32 stream, and
automatically consumes one from the start of a UTF-8, UTF-16, or UTF-32
stream.

   As specified in the Unicode Standard, a BOM is only handled specially
at the start of a stream, and only if the port encoding is set to
‘UTF-8’, ‘UTF-16’ or ‘UTF-32’.  If the port encoding is set to
‘UTF-16BE’, ‘UTF-16LE’, ‘UTF-32BE’, or ‘UTF-32LE’, then BOMs are _not_
handled specially, and none of the special handling described in this
section applies.

   • To ensure that Guile will properly detect the byte order of a
     UTF-16 or UTF-32 stream, you must perform a textual read before any
     writes, seeks, or binary I/O. Guile will not attempt to read a BOM
     unless a read is explicitly requested at the start of the stream.

   • If a textual write is performed before the first read, then an
     arbitrary byte order will be chosen.  Currently, big endian is the
     default on all platforms, but that may change in the future.  If
     you wish to explicitly control the byte order of an output stream,
     set the port encoding to ‘UTF-16BE’, ‘UTF-16LE’, ‘UTF-32BE’, or
     ‘UTF-32LE’, and explicitly write a BOM (‘#\xFEFF’) if desired.

   • If ‘set-port-encoding!’ is called in the middle of a stream, Guile
     treats this as a new logical “start of stream” for purposes of BOM
     handling, and will forget about any BOMs that had previously been
     seen.  Therefore, it may choose a different byte order than had
     been used previously.  This is intended to support multiple logical
     text streams embedded within a larger binary stream.

   • Binary I/O operations are not guaranteed to update Guile’s notion
     of whether the port is at the “start of the stream”, nor are they
     guaranteed to produce or consume BOMs.

   • For ports that support seeking (e.g.  normal files), the input and
     output streams are considered linked: if the user reads first, then
     a BOM will be consumed (if appropriate), but later writes will
     _not_ produce a BOM. Similarly, if the user writes first, then
     later reads will _not_ consume a BOM.

   • For ports that do not support seeking (e.g.  pipes, sockets, and
     terminals), the input and output streams are considered
     _independent_ for purposes of BOM handling: the first read will
     consume a BOM (if appropriate), and the first write will _also_
     produce a BOM (if appropriate).  However, the input and output
     streams will always use the same byte order.

   • Seeks to the beginning of a file will set the “start of stream”
     flags.  Therefore, a subsequent textual read or write will consume
     or produce a BOM. However, unlike ‘set-port-encoding!’, if a byte
     order had already been chosen for the port, it will remain in
     effect after a seek, and cannot be changed by the presence of a
     BOM. Seeks anywhere other than the beginning of a file clear the
     “start of stream” flags.

6.15 Regular Expressions
========================

A “regular expression” (or “regexp”) is a pattern that describes a whole
class of strings.  A full description of regular expressions and their
syntax is beyond the scope of this manual.

   If your system does not include a POSIX regular expression library,
and you have not linked Guile with a third-party regexp library such as
Rx, these functions will not be available.  You can tell whether your
Guile installation includes regular expression support by checking
whether ‘(provided? 'regex)’ returns true.

   The following regexp and string matching features are provided by the
‘(ice-9 regex)’ module.  Before using the described functions, you
should load this module by executing ‘(use-modules (ice-9 regex))’.

6.15.1 Regexp Functions
-----------------------

By default, Guile supports POSIX extended regular expressions.  That
means that the characters ‘(’, ‘)’, ‘+’ and ‘?’ are special, and must be
escaped if you wish to match the literal characters and there is no
support for “non-greedy” variants of ‘*’, ‘+’ or ‘?’.

   This regular expression interface was modeled after that implemented
by SCSH, the Scheme Shell.  It is intended to be upwardly compatible
with SCSH regular expressions.

   Zero bytes (‘#\nul’) cannot be used in regex patterns or input
strings, since the underlying C functions treat that as the end of
string.  If there’s a zero byte an error is thrown.

   Internally, patterns and input strings are converted to the current
locale’s encoding, and then passed to the C library’s regular expression
routines (see Regular Expressions (libc)).  The returned match
structures always point to characters in the strings, not to individual
bytes, even in the case of multi-byte encodings.

 -- Scheme Procedure: string-match pattern str [start]
     Compile the string PATTERN into a regular expression and compare it
     with STR.  The optional numeric argument START specifies the
     position of STR at which to begin matching.

     ‘string-match’ returns a “match structure” which describes what, if
     anything, was matched by the regular expression.  See Match Structures.
     If STR does not match PATTERN at all, ‘string-match’
     returns ‘#f’.

   Two examples of a match follow.  In the first example, the pattern
matches the four digits in the match string.  In the second, the pattern
matches nothing.

     (string-match "[0-9][0-9][0-9][0-9]" "blah2002")
     ⇒ #("blah2002" (4 . 8))

     (string-match "[A-Za-z]" "123456")
     ⇒ #f

   Each time ‘string-match’ is called, it must compile its PATTERN
argument into a regular expression structure.  This operation is
expensive, which makes ‘string-match’ inefficient if the same regular
expression is used several times (for example, in a loop).  For better
performance, you can compile a regular expression in advance and then
match strings against the compiled regexp.

 -- Scheme Procedure: make-regexp pat flag...
 -- C Function: scm_make_regexp (pat, flaglst)
     Compile the regular expression described by PAT, and return the
     compiled regexp structure.  If PAT does not describe a legal
     regular expression, ‘make-regexp’ throws a
     ‘regular-expression-syntax’ error.

     The FLAG arguments change the behavior of the compiled regular
     expression.  The following values may be supplied:

      -- Variable: regexp/icase
          Consider uppercase and lowercase letters to be the same when
          matching.

      -- Variable: regexp/newline
          If a newline appears in the target string, then permit the ‘^’
          and ‘$’ operators to match immediately after or immediately
          before the newline, respectively.  Also, the ‘.’ and ‘[^...]’
          operators will never match a newline character.  The intent of
          this flag is to treat the target string as a buffer containing
          many lines of text, and the regular expression as a pattern
          that may match a single one of those lines.

      -- Variable: regexp/basic
          Compile a basic (“obsolete”) regexp instead of the extended
          (“modern”) regexps that are the default.  Basic regexps do not
          consider ‘|’, ‘+’ or ‘?’ to be special characters, and require
          the ‘{...}’ and ‘(...)’ metacharacters to be backslash-escaped
          (see Backslash Escapes).  There are several other
          differences between basic and extended regular expressions,
          but these are the most significant.

      -- Variable: regexp/extended
          Compile an extended regular expression rather than a basic
          regexp.  This is the default behavior; this flag will not
          usually be needed.  If a call to ‘make-regexp’ includes both
          ‘regexp/basic’ and ‘regexp/extended’ flags, the one which
          comes last will override the earlier one.

 -- Scheme Procedure: regexp-exec rx str [start [flags]]
 -- C Function: scm_regexp_exec (rx, str, start, flags)
     Match the compiled regular expression RX against ‘str’.  If the
     optional integer START argument is provided, begin matching from
     that position in the string.  Return a match structure describing
     the results of the match, or ‘#f’ if no match could be found.

     The FLAGS argument changes the matching behavior.  The following
     flag values may be supplied, use ‘logior’ (see Bitwise Operations)
     to combine them,

      -- Variable: regexp/notbol
          Consider that the START offset into STR is not the beginning
          of a line and should not match operator ‘^’.

          If RX was created with the ‘regexp/newline’ option above, ‘^’
          will still match after a newline in STR.

      -- Variable: regexp/noteol
          Consider that the end of STR is not the end of a line and
          should not match operator ‘$’.

          If RX was created with the ‘regexp/newline’ option above, ‘$’
          will still match before a newline in STR.

     ;; Regexp to match uppercase letters
     (define r (make-regexp "[A-Z]*"))

     ;; Regexp to match letters, ignoring case
     (define ri (make-regexp "[A-Z]*" regexp/icase))

     ;; Search for bob using regexp r
     (match:substring (regexp-exec r "bob"))
     ⇒ ""                  ; no match

     ;; Search for bob using regexp ri
     (match:substring (regexp-exec ri "Bob"))
     ⇒ "Bob"               ; matched case insensitive

 -- Scheme Procedure: regexp? obj
 -- C Function: scm_regexp_p (obj)
     Return ‘#t’ if OBJ is a compiled regular expression, or ‘#f’
     otherwise.

 -- Scheme Procedure: list-matches regexp str [flags]
     Return a list of match structures which are the non-overlapping
     matches of REGEXP in STR.  REGEXP can be either a pattern string or
     a compiled regexp.  The FLAGS argument is as per ‘regexp-exec’
     above.

          (map match:substring (list-matches "[a-z]+" "abc 42 def 78"))
          ⇒ ("abc" "def")

 -- Scheme Procedure: fold-matches regexp str init proc [flags]
     Apply PROC to the non-overlapping matches of REGEXP in STR, to
     build a result.  REGEXP can be either a pattern string or a
     compiled regexp.  The FLAGS argument is as per ‘regexp-exec’ above.

     PROC is called as ‘(PROC match prev)’ where MATCH is a match
     structure and PREV is the previous return from PROC.  For the first
     call PREV is the given INIT parameter.  ‘fold-matches’ returns the
     final value from PROC.

     For example to count matches,

          (fold-matches "[a-z][0-9]" "abc x1 def y2" 0
                        (lambda (match count)
                          (1+ count)))
          ⇒ 2

   Regular expressions are commonly used to find patterns in one string
and replace them with the contents of another string.  The following
functions are convenient ways to do this.

 -- Scheme Procedure: regexp-substitute port match item ...
     Write to PORT selected parts of the match structure MATCH.  Or if
     PORT is ‘#f’ then form a string from those parts and return that.

     Each ITEM specifies a part to be written, and may be one of the
     following,

        • A string.  String arguments are written out verbatim.

        • An integer.  The submatch with that number is written
          (‘match:substring’).  Zero is the entire match.

        • The symbol ‘pre’.  The portion of the matched string preceding
          the regexp match is written (‘match:prefix’).

        • The symbol ‘post’.  The portion of the matched string
          following the regexp match is written (‘match:suffix’).

     For example, changing a match and retaining the text before and
     after,

          (regexp-substitute #f (string-match "[0-9]+" "number 25 is good")
                             'pre "37" 'post)
          ⇒ "number 37 is good"

     Or matching a YYYYMMDD format date such as ‘20020828’ and
     re-ordering and hyphenating the fields.

          (define date-regex
             "([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])")
          (define s "Date 20020429 12am.")
          (regexp-substitute #f (string-match date-regex s)
                             'pre 2 "-" 3 "-" 1 'post " (" 0 ")")
          ⇒ "Date 04-29-2002 12am. (20020429)"

 -- Scheme Procedure: regexp-substitute/global port regexp target
          item...
     Write to PORT selected parts of matches of REGEXP in TARGET.  If
     PORT is ‘#f’ then form a string from those parts and return that.
     REGEXP can be a string or a compiled regex.

     This is similar to ‘regexp-substitute’, but allows global
     substitutions on TARGET.  Each ITEM behaves as per
     ‘regexp-substitute’, with the following differences,

        • A function.  Called as ‘(ITEM match)’ with the match structure
          for the REGEXP match, it should return a string to be written
          to PORT.

        • The symbol ‘post’.  This doesn’t output anything, but instead
          causes ‘regexp-substitute/global’ to recurse on the unmatched
          portion of TARGET.

          This _must_ be supplied to perform a global search and replace
          on TARGET; without it ‘regexp-substitute/global’ returns after
          a single match and output.

     For example, to collapse runs of tabs and spaces to a single hyphen
     each,

          (regexp-substitute/global #f "[ \t]+"  "this   is   the text"
                                    'pre "-" 'post)
          ⇒ "this-is-the-text"

     Or using a function to reverse the letters in each word,

          (regexp-substitute/global #f "[a-z]+"  "to do and not-do"
            'pre (lambda (m) (string-reverse (match:substring m))) 'post)
          ⇒ "ot od dna ton-od"

     Without the ‘post’ symbol, just one regexp match is made.  For
     example the following is the date example from ‘regexp-substitute’
     above, without the need for the separate ‘string-match’ call.

          (define date-regex
             "([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])")
          (define s "Date 20020429 12am.")
          (regexp-substitute/global #f date-regex s
                                    'pre 2 "-" 3 "-" 1 'post " (" 0 ")")

          ⇒ "Date 04-29-2002 12am. (20020429)"

6.15.2 Match Structures
-----------------------

A “match structure” is the object returned by ‘string-match’ and
‘regexp-exec’.  It describes which portion of a string, if any, matched
the given regular expression.  Match structures include: a reference to
the string that was checked for matches; the starting and ending
positions of the regexp match; and, if the regexp included any
parenthesized subexpressions, the starting and ending positions of each
submatch.

   In each of the regexp match functions described below, the ‘match’
argument must be a match structure returned by a previous call to
‘string-match’ or ‘regexp-exec’.  Most of these functions return some
information about the original target string that was matched against a
regular expression; we will call that string TARGET for easy reference.

 -- Scheme Procedure: regexp-match? obj
     Return ‘#t’ if OBJ is a match structure returned by a previous call
     to ‘regexp-exec’, or ‘#f’ otherwise.

 -- Scheme Procedure: match:substring match [n]
     Return the portion of TARGET matched by subexpression number N.
     Submatch 0 (the default) represents the entire regexp match.  If
     the regular expression as a whole matched, but the subexpression
     number N did not match, return ‘#f’.

     (define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo"))
     (match:substring s)
     ⇒ "2002"

     ;; match starting at offset 6 in the string
     (match:substring
       (string-match "[0-9][0-9][0-9][0-9]" "blah987654" 6))
     ⇒ "7654"

 -- Scheme Procedure: match:start match [n]
     Return the starting position of submatch number N.

   In the following example, the result is 4, since the match starts at
character index 4:

     (define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo"))
     (match:start s)
     ⇒ 4

 -- Scheme Procedure: match:end match [n]
     Return the ending position of submatch number N.

   In the following example, the result is 8, since the match runs
between characters 4 and 8 (i.e. the “2002”).

     (define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo"))
     (match:end s)
     ⇒ 8

 -- Scheme Procedure: match:prefix match
     Return the unmatched portion of TARGET preceding the regexp match.

          (define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo"))
          (match:prefix s)
          ⇒ "blah"

 -- Scheme Procedure: match:suffix match
     Return the unmatched portion of TARGET following the regexp match.

     (define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo"))
     (match:suffix s)
     ⇒ "foo"

 -- Scheme Procedure: match:count match
     Return the number of parenthesized subexpressions from MATCH.  Note
     that the entire regular expression match itself counts as a
     subexpression, and failed submatches are included in the count.

 -- Scheme Procedure: match:string match
     Return the original TARGET string.

     (define s (string-match "[0-9][0-9][0-9][0-9]" "blah2002foo"))
     (match:string s)
     ⇒ "blah2002foo"

6.15.3 Backslash Escapes
------------------------

Sometimes you will want a regexp to match characters like ‘*’ or ‘$’
exactly.  For example, to check whether a particular string represents a
menu entry from an Info node, it would be useful to match it against a
regexp like ‘^* [^:]*::’.  However, this won’t work; because the
asterisk is a metacharacter, it won’t match the ‘*’ at the beginning of
the string.  In this case, we want to make the first asterisk un-magic.

   You can do this by preceding the metacharacter with a backslash
character ‘\’.  (This is also called “quoting” the metacharacter, and is
known as a “backslash escape”.)  When Guile sees a backslash in a
regular expression, it considers the following glyph to be an ordinary
character, no matter what special meaning it would ordinarily have.
Therefore, we can make the above example work by changing the regexp to
‘^\* [^:]*::’.  The ‘\*’ sequence tells the regular expression engine to
match only a single asterisk in the target string.

   Since the backslash is itself a metacharacter, you may force a regexp
to match a backslash in the target string by preceding the backslash
with itself.  For example, to find variable references in a TeX program,
you might want to find occurrences of the string ‘\let\’ followed by any
number of alphabetic characters.  The regular expression
‘\\let\\[A-Za-z]*’ would do this: the double backslashes in the regexp
each match a single backslash in the target string.

 -- Scheme Procedure: regexp-quote str
     Quote each special character found in STR with a backslash, and
     return the resulting string.

   *Very important:* Using backslash escapes in Guile source code (as in
Emacs Lisp or C) can be tricky, because the backslash character has
special meaning for the Guile reader.  For example, if Guile encounters
the character sequence ‘\n’ in the middle of a string while processing
Scheme code, it replaces those characters with a newline character.
Similarly, the character sequence ‘\t’ is replaced by a horizontal tab.
Several of these “escape sequences” are processed by the Guile reader
before your code is executed.  Unrecognized escape sequences are
ignored: if the characters ‘\*’ appear in a string, they will be
translated to the single character ‘*’.

   This translation is obviously undesirable for regular expressions,
since we want to be able to include backslashes in a string in order to
escape regexp metacharacters.  Therefore, to make sure that a backslash
is preserved in a string in your Guile program, you must use _two_
consecutive backslashes:

     (define Info-menu-entry-pattern (make-regexp "^\\* [^:]*"))

   The string in this example is preprocessed by the Guile reader before
any code is executed.  The resulting argument to ‘make-regexp’ is the
string ‘^\* [^:]*’, which is what we really want.

   This also means that in order to write a regular expression that
matches a single backslash character, the regular expression string in
the source code must include _four_ backslashes.  Each consecutive pair
of backslashes gets translated by the Guile reader to a single
backslash, and the resulting double-backslash is interpreted by the
regexp engine as matching a single backslash character.  Hence:

     (define tex-variable-pattern (make-regexp "\\\\let\\\\=[A-Za-z]*"))

   The reason for the unwieldiness of this syntax is historical.  Both
regular expression pattern matchers and Unix string processing systems
have traditionally used backslashes with the special meanings described
above.  The POSIX regular expression specification and ANSI C standard
both require these semantics.  Attempting to abandon either convention
would cause other kinds of compatibility problems, possibly more severe
ones.  Therefore, without extending the Scheme reader to support strings
with different quoting conventions (an ungainly and confusing extension
when implemented in other languages), we must adhere to this cumbersome
escape syntax.

6.16 LALR(1) Parsing
====================

The ‘(system base lalr)’ module provides the ‘lalr-scm’ LALR(1) parser
generator by Dominique Boucher (http://code.google.com/p/lalr-scm/).
‘lalr-scm’ uses the same algorithm as GNU Bison (see Introduction to Bison (bison)).
Parsers are defined using the
‘lalr-parser’ macro.

 -- Scheme Syntax: lalr-parser [OPTIONS] TOKENS RULES...
     Generate an LALR(1) syntax analyzer.  TOKENS is a list of symbols
     representing the terminal symbols of the grammar.  RULES are the
     grammar production rules.

     Each rule has the form ‘(NON-TERMINAL (RHS ...) : ACTION ...)’,
     where NON-TERMINAL is the name of the rule, RHS are the right-hand
     sides, i.e., the production rule, and ACTION is a semantic action
     associated with the rule.

     The generated parser is a two-argument procedure that takes a
     “tokenizer” and a “syntax error procedure”.  The tokenizer should
     be a thunk that returns lexical tokens as produced by
     ‘make-lexical-token’.  The syntax error procedure may be called
     with at least an error message (a string), and optionally the
     lexical token that caused the error.

   Please refer to the ‘lalr-scm’ documentation for details.

6.17 Reading and Evaluating Scheme Code
=======================================

This chapter describes Guile functions that are concerned with reading,
loading, evaluating, and compiling Scheme code at run time.

6.17.1 Scheme Syntax: Standard and Guile Extensions
---------------------------------------------------

6.17.1.1 Expression Syntax
..........................

An expression to be evaluated takes one of the following forms.

SYMBOL
     A symbol is evaluated by dereferencing.  A binding of that symbol
     is sought and the value there used.  For example,

          (define x 123)
          x ⇒ 123

(PROC ARGS...)
     A parenthesised expression is a function call.  PROC and each
     argument are evaluated, then the function (which PROC evaluated to)
     is called with those arguments.

     The order in which PROC and the arguments are evaluated is
     unspecified, so be careful when using expressions with side
     effects.

          (max 1 2 3) ⇒ 3

          (define (get-some-proc)  min)
          ((get-some-proc) 1 2 3) ⇒ 1

     The same sort of parenthesised form is used for a macro invocation,
     but in that case the arguments are not evaluated.  See the
     descriptions of macros for more on this (see Macros, and
     Syntax Rules).

CONSTANT
     Number, string, character and boolean constants evaluate “to
     themselves”, so can appear as literals.

          123     ⇒ 123
          99.9    ⇒ 99.9
          "hello" ⇒ "hello"
          #\z     ⇒ #\z
          #t      ⇒ #t

     Note that an application must not attempt to modify literal
     strings, since they may be in read-only memory.

(quote DATA)
’DATA
     Quoting is used to obtain a literal symbol (instead of a variable
     reference), a literal list (instead of a function call), or a
     literal vector.  ’ is simply a shorthand for a ‘quote’ form.  For
     example,

          'x                   ⇒ x
          '(1 2 3)             ⇒ (1 2 3)
          '#(1 (2 3) 4)        ⇒ #(1 (2 3) 4)
          (quote x)            ⇒ x
          (quote (1 2 3))      ⇒ (1 2 3)
          (quote #(1 (2 3) 4)) ⇒ #(1 (2 3) 4)

     Note that an application must not attempt to modify literal lists
     or vectors obtained from a ‘quote’ form, since they may be in
     read-only memory.

(quasiquote DATA)
‘DATA
     Backquote quasi-quotation is like ‘quote’, but selected
     sub-expressions are evaluated.  This is a convenient way to
     construct a list or vector structure most of which is constant, but
     at certain points should have expressions substituted.

     The same effect can always be had with suitable ‘list’, ‘cons’ or
     ‘vector’ calls, but quasi-quoting is often easier.

     (unquote EXPR)
     ,EXPR
          Within the quasiquote DATA, ‘unquote’ or ‘,’ indicates an
          expression to be evaluated and inserted.  The comma syntax ‘,’
          is simply a shorthand for an ‘unquote’ form.  For example,

               `(1 2 (* 9 9) 3 4)       ⇒ (1 2 (* 9 9) 3 4)
               `(1 2 ,(* 9 9) 3 4)      ⇒ (1 2 81 3 4)
               `(1 (unquote (+ 1 1)) 3) ⇒ (1 2 3)
               `#(1 ,(/ 12 2))          ⇒ #(1 6)

     (unquote-splicing EXPR)
     ,@EXPR
          Within the quasiquote DATA, ‘unquote-splicing’ or ‘,@’
          indicates an expression to be evaluated and the elements of
          the returned list inserted.  EXPR must evaluate to a list.
          The “comma-at” syntax ‘,@’ is simply a shorthand for an
          ‘unquote-splicing’ form.

               (define x '(2 3))
               `(1 ,x 4)                           ⇒ (1 (2 3) 4)
               `(1 ,@x 4)                         ⇒ (1 2 3 4)
               `(1 (unquote-splicing (map 1+ x)))  ⇒ (1 3 4)
               `#(9 ,@x 9)                        ⇒ #(9 2 3 9)

          Notice ‘,@’ differs from plain ‘,’ in the way one level of
          nesting is stripped.  For ‘,@’ the elements of a returned list
          are inserted, whereas with ‘,’ it would be the list itself
          inserted.

6.17.1.2 Comments
.................

Comments in Scheme source files are written by starting them with a
semicolon character (‘;’).  The comment then reaches up to the end of
the line.  Comments can begin at any column, and the may be inserted on
the same line as Scheme code.

     ; Comment
     ;; Comment too
     (define x 1)        ; Comment after expression
     (let ((y 1))
       ;; Display something.
       (display y)
     ;;; Comment at left margin.
       (display (+ y 1)))

   It is common to use a single semicolon for comments following
expressions on a line, to use two semicolons for comments which are
indented like code, and three semicolons for comments which start at
column 0, even if they are inside an indented code block.  This
convention is used when indenting code in Emacs’ Scheme mode.

6.17.1.3 Block Comments
.......................

In addition to the standard line comments defined by R5RS, Guile has
another comment type for multiline comments, called “block comments”.
This type of comment begins with the character sequence ‘#!’ and ends
with the characters ‘!#’.

   These comments are compatible with the block comments in the Scheme
Shell ‘scsh’ (see The Scheme shell (scsh)).  The characters ‘#!’
were chosen because they are the magic characters used in shell scripts
for indicating that the name of the program for executing the script
follows on the same line.

   Thus a Guile script often starts like this.

     #! /usr/local/bin/guile -s
     !#

   More details on Guile scripting can be found in the scripting section
(see Guile Scripting).

   Similarly, Guile (starting from version 2.0) supports nested block
comments as specified by R6RS and SRFI-30
(http://srfi.schemers.org/srfi-30/srfi-30.html):

     (+ 1 #| this is a #| nested |# block comment |# 2)
     ⇒ 3

   For backward compatibility, this syntax can be overridden with
‘read-hash-extend’ (see ‘read-hash-extend’).

   There is one special case where the contents of a comment can
actually affect the interpretation of code.  When a character encoding
declaration, such as ‘coding: utf-8’ appears in one of the first few
lines of a source file, it indicates to Guile’s default reader that this
source code file is not ASCII. For details see Character Encoding of Source Files.

6.17.1.4 Case Sensitivity
.........................

Scheme as defined in R5RS is not case sensitive when reading symbols.
Guile, on the contrary is case sensitive by default, so the identifiers

     guile-whuzzy
     Guile-Whuzzy

   are the same in R5RS Scheme, but are different in Guile.

   It is possible to turn off case sensitivity in Guile by setting the
reader option ‘case-insensitive’.  For more information on reader
options, see Scheme Read.

     (read-enable 'case-insensitive)

   It is also possible to disable (or enable) case sensitivity within a
single file by placing the reader directives ‘#!fold-case’ (or
‘#!no-fold-case’) within the file itself.

6.17.1.5 Keyword Syntax
.......................

6.17.1.6 Reader Extensions
..........................

 -- Scheme Procedure: read-hash-extend chr proc
 -- C Function: scm_read_hash_extend (chr, proc)
     Install the procedure PROC for reading expressions starting with
     the character sequence ‘#’ and CHR.  PROC will be called with two
     arguments: the character CHR and the port to read further data
     from.  The object returned will be the return value of ‘read’.
     Passing ‘#f’ for PROC will remove a previous setting.

6.17.2 Reading Scheme Code
--------------------------

 -- Scheme Procedure: read [port]
 -- C Function: scm_read (port)
     Read an s-expression from the input port PORT, or from the current
     input port if PORT is not specified.  Any whitespace before the
     next token is discarded.

   The behaviour of Guile’s Scheme reader can be modified by
manipulating its read options.

 -- Scheme Procedure: read-options [setting]
     Display the current settings of the global read options.  If
     SETTING is omitted, only a short form of the current read options
     is printed.  Otherwise if SETTING is the symbol ‘help’, a complete
     options description is displayed.

   The set of available options, and their default values, may be had by
invoking ‘read-options’ at the prompt.

     scheme@(guile-user)> (read-options)
     (square-brackets keywords #f positions)
     scheme@(guile-user)> (read-options 'help)
     copy              no    Copy source code expressions.
     positions         yes   Record positions of source code expressions.
     case-insensitive  no    Convert symbols to lower case.
     keywords          #f    Style of keyword recognition: #f, 'prefix or 'postfix.
     r6rs-hex-escapes  no    Use R6RS variable-length character and string hex escapes.
     square-brackets   yes   Treat `[' and `]' as parentheses, for R6RS compatibility.
     hungry-eol-escapes no   In strings, consume leading whitespace after an
                             escaped end-of-line.
     curly-infix       no    Support SRFI-105 curly infix expressions.
     r7rs-symbols      no    Support R7RS |...| symbol notation.

   Note that Guile also includes a preliminary mechanism for setting
read options on a per-port basis.  For instance, the ‘case-insensitive’
read option is set (or unset) on the port when the reader encounters the
‘#!fold-case’ or ‘#!no-fold-case’ reader directives.  Similarly, the
‘#!curly-infix’ reader directive sets the ‘curly-infix’ read option on
the port, and ‘#!curly-infix-and-bracket-lists’ sets ‘curly-infix’ and
unsets ‘square-brackets’ on the port (see SRFI-105).  There is
currently no other way to access or set the per-port read options.

   The boolean options may be toggled with ‘read-enable’ and
‘read-disable’.  The non-boolean ‘keywords’ option must be set using
‘read-set!’.

 -- Scheme Procedure: read-enable option-name
 -- Scheme Procedure: read-disable option-name
 -- Scheme Syntax: read-set! option-name value
     Modify the read options.  ‘read-enable’ should be used with boolean
     options and switches them on, ‘read-disable’ switches them off.

     ‘read-set!’ can be used to set an option to a specific value.  Due
     to historical oddities, it is a macro that expects an unquoted
     option name.

   For example, to make ‘read’ fold all symbols to their lower case
(perhaps for compatibility with older Scheme code), you can enter:

     (read-enable 'case-insensitive)

   For more information on the effect of the ‘r6rs-hex-escapes’ and
‘hungry-eol-escapes’ options, see (see String Syntax).

   For more information on the ‘r7rs-symbols’ option, see (see Symbol Read Syntax).

6.17.3 Writing Scheme Values
----------------------------

Any scheme value may be written to a port.  Not all values may be read
back in (see Scheme Read), however.

 -- Scheme Procedure: write obj [port]
     Send a representation of OBJ to PORT or to the current output port
     if not given.

     The output is designed to be machine readable, and can be read back
     with ‘read’ (see Scheme Read).  Strings are printed in double
     quotes, with escapes if necessary, and characters are printed in
     ‘#\’ notation.

 -- Scheme Procedure: display obj [port]
     Send a representation of OBJ to PORT or to the current output port
     if not given.

     The output is designed for human readability, it differs from
     ‘write’ in that strings are printed without double quotes and
     escapes, and characters are printed as per ‘write-char’, not in
     ‘#\’ form.

   As was the case with the Scheme reader, there are a few options that
affect the behavior of the Scheme printer.

 -- Scheme Procedure: print-options [setting]
     Display the current settings of the read options.  If SETTING is
     omitted, only a short form of the current read options is printed.
     Otherwise if SETTING is the symbol ‘help’, a complete options
     description is displayed.

   The set of available options, and their default values, may be had by
invoking ‘print-options’ at the prompt.

     scheme@(guile-user)> (print-options)
     (quote-keywordish-symbols reader highlight-suffix "}" highlight-prefix "{")
     scheme@(guile-user)> (print-options 'help)
     highlight-prefix          {       The string to print before highlighted values.
     highlight-suffix          }       The string to print after highlighted values.
     quote-keywordish-symbols  reader  How to print symbols that have a colon
                                       as their first or last character. The
                                       value '#f' does not quote the colons;
                                       '#t' quotes them; 'reader' quotes them
                                       when the reader option 'keywords' is
                                       not '#f'.
     escape-newlines           yes     Render newlines as \n when printing
                                       using `write'.
     r7rs-symbols              no      Escape symbols using R7RS |...| symbol
                                       notation.

   These options may be modified with the print-set!  syntax.

 -- Scheme Syntax: print-set! option-name value
     Modify the print options.  Due to historical oddities, ‘print-set!’
     is a macro that expects an unquoted option name.

6.17.4 Procedures for On the Fly Evaluation
-------------------------------------------

Scheme has the lovely property that its expressions may be represented
as data.  The ‘eval’ procedure takes a Scheme datum and evaluates it as
code.

 -- Scheme Procedure: eval exp module_or_state
 -- C Function: scm_eval (exp, module_or_state)
     Evaluate EXP, a list representing a Scheme expression, in the
     top-level environment specified by MODULE_OR_STATE.  While EXP is
     evaluated (using ‘primitive-eval’), MODULE_OR_STATE is made the
     current module.  The current module is reset to its previous value
     when ‘eval’ returns.  XXX - dynamic states.  Example: (eval ’(+ 1
     2) (interaction-environment))

 -- Scheme Procedure: interaction-environment
 -- C Function: scm_interaction_environment ()
     Return a specifier for the environment that contains
     implementation–defined bindings, typically a superset of those
     listed in the report.  The intent is that this procedure will
     return the environment in which the implementation would evaluate
     expressions dynamically typed by the user.

   See Environments, for other environments.

   One does not always receive code as Scheme data, of course, and this
is especially the case for Guile’s other language implementations (see
Other Languages).  For the case in which all you have is a string, we
have ‘eval-string’.  There is a legacy version of this procedure in the
default environment, but you really want the one from ‘(ice-9
eval-string)’, so load it up:

     (use-modules (ice-9 eval-string))

 -- Scheme Procedure: eval-string string [#:module=#f] [#:file=#f]
          [#:line=#f] [#:column=#f] [#:lang=(current-language)]
          [#:compile?=#f]
     Parse STRING according to the current language, normally Scheme.
     Evaluate or compile the expressions it contains, in order,
     returning the last expression.

     If the MODULE keyword argument is set, save a module excursion
     (see Module System Reflection) and set the current module to
     MODULE before evaluation.

     The FILE, LINE, and COLUMN keyword arguments can be used to
     indicate that the source string begins at a particular source
     location.

     Finally, LANG is a language, defaulting to the current language,
     and the expression is compiled if COMPILE? is true or there is no
     evaluator for the given language.

 -- C Function: scm_eval_string (string)
 -- C Function: scm_eval_string_in_module (string, module)
     These C bindings call ‘eval-string’ from ‘(ice-9 eval-string)’,
     evaluating within MODULE or the current module.

 -- C Function: SCM scm_c_eval_string (const char *string)
     ‘scm_eval_string’, but taking a C string in locale encoding instead
     of an ‘SCM’.

 -- Scheme Procedure: apply proc arg ... arglst
 -- C Function: scm_apply_0 (proc, arglst)
 -- C Function: scm_apply_1 (proc, arg1, arglst)
 -- C Function: scm_apply_2 (proc, arg1, arg2, arglst)
 -- C Function: scm_apply_3 (proc, arg1, arg2, arg3, arglst)
 -- C Function: scm_apply (proc, arg, rest)
     Call PROC with arguments ARG ... and the elements of the ARGLST
     list.

     ‘scm_apply’ takes parameters corresponding to a Scheme level
     ‘(lambda (proc arg1 . rest) ...)’.  So ARG1 and all but the last
     element of the REST list make up ARG ..., and the last element of
     REST is the ARGLST list.  Or if REST is the empty list ‘SCM_EOL’
     then there’s no ARG ..., and (ARG1) is the ARGLST.

     ARGLST is not modified, but the REST list passed to ‘scm_apply’ is
     modified.

 -- C Function: scm_call_0 (proc)
 -- C Function: scm_call_1 (proc, arg1)
 -- C Function: scm_call_2 (proc, arg1, arg2)
 -- C Function: scm_call_3 (proc, arg1, arg2, arg3)
 -- C Function: scm_call_4 (proc, arg1, arg2, arg3, arg4)
 -- C Function: scm_call_5 (proc, arg1, arg2, arg3, arg4, arg5)
 -- C Function: scm_call_6 (proc, arg1, arg2, arg3, arg4, arg5, arg6)
 -- C Function: scm_call_7 (proc, arg1, arg2, arg3, arg4, arg5, arg6,
          arg7)
 -- C Function: scm_call_8 (proc, arg1, arg2, arg3, arg4, arg5, arg6,
          arg7, arg8)
 -- C Function: scm_call_9 (proc, arg1, arg2, arg3, arg4, arg5, arg6,
          arg7, arg8, arg9)
     Call PROC with the given arguments.

 -- C Function: scm_call (proc, ...)
     Call PROC with any number of arguments.  The argument list must be
     terminated by ‘SCM_UNDEFINED’.  For example:

          scm_call (scm_c_public_ref ("guile", "+"),
                    scm_from_int (1),
                    scm_from_int (2),
                    SCM_UNDEFINED);

 -- C Function: scm_call_n (proc, argv, nargs)
     Call PROC with the array of arguments ARGV, as a ‘SCM*’.  The
     length of the arguments should be passed in NARGS, as a ‘size_t’.

 -- Scheme Procedure: apply:nconc2last lst
 -- C Function: scm_nconc2last (lst)
     LST should be a list (ARG1 ... ARGN ARGLST), with ARGLST being a
     list.  This function returns a list comprising ARG1 to ARGN plus
     the elements of ARGLST.  LST is modified to form the return.
     ARGLST is not modified, though the return does share structure with
     it.

     This operation collects up the arguments from a list which is
     ‘apply’ style parameters.

 -- Scheme Procedure: primitive-eval exp
 -- C Function: scm_primitive_eval (exp)
     Evaluate EXP in the top-level environment specified by the current
     module.

6.17.5 Compiling Scheme Code
----------------------------

The ‘eval’ procedure directly interprets the S-expression representation
of Scheme.  An alternate strategy for evaluation is to determine ahead
of time what computations will be necessary to evaluate the expression,
and then use that recipe to produce the desired results.  This is known
as “compilation”.

   While it is possible to compile simple Scheme expressions such as ‘(+
2 2)’ or even ‘"Hello world!"’, compilation is most interesting in the
context of procedures.  Compiling a lambda expression produces a
compiled procedure, which is just like a normal procedure except
typically much faster, because it can bypass the generic interpreter.

   Functions from system modules in a Guile installation are normally
compiled already, so they load and run quickly.

   Note that well-written Scheme programs will not typically call the
procedures in this section, for the same reason that it is often bad
taste to use ‘eval’.  By default, Guile automatically compiles any files
it encounters that have not been compiled yet (see ‘--auto-compile’).
The compiler can also be invoked explicitly from the
shell as ‘guild compile foo.scm’.

   (Why are calls to ‘eval’ and ‘compile’ usually in bad taste?  Because
they are limited, in that they can only really make sense for top-level
expressions.  Also, most needs for “compile-time” computation are
fulfilled by macros and closures.  Of course one good counterexample is
the REPL itself, or any code that reads expressions from a port.)

   Automatic compilation generally works transparently, without any need
for user intervention.  However Guile does not yet do proper dependency
tracking, so that if file ‘A.scm’ uses macros from ‘B.scm’, and B.SCM
changes, ‘A.scm’ would not be automatically recompiled.  To forcibly
invalidate the auto-compilation cache, pass the ‘--fresh-auto-compile’
option to Guile, or set the ‘GUILE_AUTO_COMPILE’ environment variable to
‘fresh’ (instead of to ‘0’ or ‘1’).

   For more information on the compiler itself, see Compiling to the Virtual Machine.
For information on the virtual machine, see
A Virtual Machine for Guile.

   The command-line interface to Guile’s compiler is the ‘guild compile’
command:

 -- Command: guild compile [‘option’...] FILE...
     Compile FILE, a source file, and store bytecode in the compilation
     cache or in the file specified by the ‘-o’ option.  The following
     options are available:

     ‘-L DIR’
     ‘--load-path=DIR’
          Add DIR to the front of the module load path.

     ‘-o OFILE’
     ‘--output=OFILE’
          Write output bytecode to OFILE.  By convention, bytecode file
          names end in ‘.go’.  When ‘-o’ is omitted, the output file
          name is as for ‘compile-file’ (see below).

     ‘-W WARNING’
     ‘--warn=WARNING’
          Emit warnings of type WARNING; use ‘--warn=help’ for a list of
          available warnings and their description.  Currently
          recognized warnings include ‘unused-variable’,
          ‘unused-toplevel’, ‘unbound-variable’, ‘arity-mismatch’,
          ‘format’, ‘duplicate-case-datum’, and ‘bad-case-datum’.

     ‘-f LANG’
     ‘--from=LANG’
          Use LANG as the source language of FILE.  If this option is
          omitted, ‘scheme’ is assumed.

     ‘-t LANG’
     ‘--to=LANG’
          Use LANG as the target language of FILE.  If this option is
          omitted, ‘objcode’ is assumed.

     ‘-T TARGET’
     ‘--target=TARGET’
          Produce bytecode for TARGET instead of %HOST-TYPE (see
          %host-type).  Target must be a valid GNU
          triplet, such as ‘armv5tel-unknown-linux-gnueabi’ (see
          Specifying Target Triplets (autoconf)).

     Each FILE is assumed to be UTF-8-encoded, unless it contains a
     coding declaration as recognized by ‘file-encoding’ (see
     Character Encoding of Source Files).

   The compiler can also be invoked directly by Scheme code using the
procedures below:

 -- Scheme Procedure: compile exp [#:env=#f] [#:from=(current-language)]
          [#:to=value] [#:opts=()]
     Compile the expression EXP in the environment ENV.  If EXP is a
     procedure, the result will be a compiled procedure; otherwise
     ‘compile’ is mostly equivalent to ‘eval’.

     For a discussion of languages and compiler options, see Compiling to the Virtual Machine.

 -- Scheme Procedure: compile-file file [#:output-file=#f]
          [#:from=(current-language)] [#:to='objcode]
          [#:env=(default-environment from)] [#:opts='()]
          [#:canonicalization='relative]
     Compile the file named FILE.

     Output will be written to a OUTPUT-FILE.  If you do not supply an
     output file name, output is written to a file in the cache
     directory, as computed by ‘(compiled-file-name FILE)’.

     FROM and TO specify the source and target languages.  See
     Compiling to the Virtual Machine, for more information on these
     options, and on ENV and OPTS.

     As with ‘guild compile’, FILE is assumed to be UTF-8-encoded unless
     it contains a coding declaration.

 -- Scheme Procedure: compiled-file-name file
     Compute a cached location for a compiled version of a Scheme file
     named FILE.

     This file will usually be below the ‘$HOME/.cache/guile/ccache’
     directory, depending on the value of the ‘XDG_CACHE_HOME’
     environment variable.  The intention is that ‘compiled-file-name’
     provides a fallback location for caching auto-compiled files.  If
     you want to place a compile file in the ‘%load-compiled-path’, you
     should pass the OUTPUT-FILE option to ‘compile-file’, explicitly.

 -- Scheme Variable: %auto-compilation-options
     This variable contains the options passed to the ‘compile-file’
     procedure when auto-compiling source files.  By default, it enables
     useful compilation warnings.  It can be customized from ‘~/.guile’.

6.17.6 Loading Scheme Code from File
------------------------------------

 -- Scheme Procedure: load filename [reader]
     Load FILENAME and evaluate its contents in the top-level
     environment.

     READER if provided should be either ‘#f’, or a procedure with the
     signature ‘(lambda (port) ...)’ which reads the next expression
     from PORT.  If READER is ‘#f’ or absent, Guile’s built-in ‘read’
     procedure is used (see Scheme Read).

     The READER argument takes effect by setting the value of the
     ‘current-reader’ fluid (see below) before loading the file, and
     restoring its previous value when loading is complete.  The Scheme
     code inside FILENAME can itself change the current reader procedure
     on the fly by setting ‘current-reader’ fluid.

     If the variable ‘%load-hook’ is defined, it should be bound to a
     procedure that will be called before any code is loaded.  See
     documentation for ‘%load-hook’ later in this section.

 -- Scheme Procedure: load-compiled filename
     Load the compiled file named FILENAME.

     Compiling a source file (see Read/Load/Eval/Compile) and then
     calling ‘load-compiled’ on the resulting file is equivalent to
     calling ‘load’ on the source file.

 -- Scheme Procedure: primitive-load filename
 -- C Function: scm_primitive_load (filename)
     Load the file named FILENAME and evaluate its contents in the
     top-level environment.  FILENAME must either be a full pathname or
     be a pathname relative to the current directory.  If the variable
     ‘%load-hook’ is defined, it should be bound to a procedure that
     will be called before any code is loaded.  See the documentation
     for ‘%load-hook’ later in this section.

 -- C Function: SCM scm_c_primitive_load (const char *filename)
     ‘scm_primitive_load’, but taking a C string instead of an ‘SCM’.

 -- Variable: current-reader
     ‘current-reader’ holds the read procedure that is currently being
     used by the above loading procedures to read expressions (from the
     file that they are loading).  ‘current-reader’ is a fluid, so it
     has an independent value in each dynamic root and should be read
     and set using ‘fluid-ref’ and ‘fluid-set!’ (see Fluids and Dynamic States).

     Changing ‘current-reader’ is typically useful to introduce local
     syntactic changes, such that code following the ‘fluid-set!’ call
     is read using the newly installed reader.  The ‘current-reader’
     change should take place at evaluation time when the code is
     evaluated, or at compilation time when the code is compiled:

          (eval-when (compile eval)
            (fluid-set! current-reader my-own-reader))

     The ‘eval-when’ form above ensures that the ‘current-reader’ change
     occurs at the right time.

 -- Variable: %load-hook
     A procedure to be called ‘(%load-hook FILENAME)’ whenever a file is
     loaded, or ‘#f’ for no such call.  ‘%load-hook’ is used by all of
     the loading functions (‘load’ and ‘primitive-load’, and
     ‘load-from-path’ and ‘primitive-load-path’ documented in the next
     section).

     For example an application can set this to show what’s loaded,

          (set! %load-hook (lambda (filename)
                             (format #t "Loading ~a ...\n" filename)))
          (load-from-path "foo.scm")
          ⊣ Loading /usr/local/share/guile/site/foo.scm ...

 -- Scheme Procedure: current-load-port
 -- C Function: scm_current_load_port ()
     Return the current-load-port.  The load port is used internally by
     ‘primitive-load’.

6.17.7 Load Paths
-----------------

The procedure in the previous section look for Scheme code in the file
system at specific location.  Guile also has some procedures to search
the load path for code.

 -- Variable: %load-path
     List of directories which should be searched for Scheme modules and
     libraries.  When Guile starts up, ‘%load-path’ is initialized to
     the default load path ‘(list (%library-dir) (%site-dir)
     (%global-site-dir) (%package-data-dir))’.  The ‘GUILE_LOAD_PATH’
     environment variable can be used to prepend or append additional
     directories (see Environment Variables).

     See Build Config, for more on ‘%site-dir’ and related
     procedures.

 -- Scheme Procedure: load-from-path filename
     Similar to ‘load’, but searches for FILENAME in the load paths.
     Preferentially loads a compiled version of the file, if it is
     available and up-to-date.

   A user can extend the load path by calling ‘add-to-load-path’.

 -- Scheme Syntax: add-to-load-path dir
     Add DIR to the load path.

   For example, a script might include this form to add the directory
that it is in to the load path:

     (add-to-load-path (dirname (current-filename)))

   It’s better to use ‘add-to-load-path’ than to modify ‘%load-path’
directly, because ‘add-to-load-path’ takes care of modifying the path
both at compile-time and at run-time.

 -- Scheme Procedure: primitive-load-path filename
          [exception-on-not-found]
 -- C Function: scm_primitive_load_path (filename)
     Search ‘%load-path’ for the file named FILENAME and load it into
     the top-level environment.  If FILENAME is a relative pathname and
     is not found in the list of search paths, an error is signalled.
     Preferentially loads a compiled version of the file, if it is
     available and up-to-date.

     If FILENAME is a relative pathname and is not found in the list of
     search paths, one of three things may happen, depending on the
     optional second argument, EXCEPTION-ON-NOT-FOUND.  If it is ‘#f’,
     ‘#f’ will be returned.  If it is a procedure, it will be called
     with no arguments.  (This allows a distinction to be made between
     exceptions raised by loading a file, and exceptions related to the
     loader itself.)  Otherwise an error is signalled.

     For compatibility with Guile 1.8 and earlier, the C function takes
     only one argument, which can be either a string (the file name) or
     an argument list.

 -- Scheme Procedure: %search-load-path filename
 -- C Function: scm_sys_search_load_path (filename)
     Search ‘%load-path’ for the file named FILENAME, which must be
     readable by the current user.  If FILENAME is found in the list of
     paths to search or is an absolute pathname, return its full
     pathname.  Otherwise, return ‘#f’.  Filenames may have any of the
     optional extensions in the ‘%load-extensions’ list;
     ‘%search-load-path’ will try each extension automatically.

 -- Variable: %load-extensions
     A list of default file extensions for files containing Scheme code.
     ‘%search-load-path’ tries each of these extensions when looking for
     a file to load.  By default, ‘%load-extensions’ is bound to the
     list ‘("" ".scm")’.

   As mentioned above, when Guile searches the ‘%load-path’ for a source
file, it will also search the ‘%load-compiled-path’ for a corresponding
compiled file.  If the compiled file is as new or newer than the source
file, it will be loaded instead of the source file, using
‘load-compiled’.

 -- Variable: %load-compiled-path
     Like ‘%load-path’, but for compiled files.  By default, this path
     has two entries: one for compiled files from Guile itself, and one
     for site packages.  The ‘GUILE_LOAD_COMPILED_PATH’ environment
     variable can be used to prepend or append additional directories
     (see Environment Variables).

   When ‘primitive-load-path’ searches the ‘%load-compiled-path’ for a
corresponding compiled file for a relative path it does so by appending
‘.go’ to the relative path.  For example, searching for ‘ice-9/popen’
could find ‘/usr/lib/guile/2.0/ccache/ice-9/popen.go’, and use it
instead of ‘/usr/share/guile/2.0/ice-9/popen.scm’.

   If ‘primitive-load-path’ does not find a corresponding ‘.go’ file in
the ‘%load-compiled-path’, or the ‘.go’ file is out of date, it will
search for a corresponding auto-compiled file in the fallback path,
possibly creating one if one does not exist.

   See Installing Site Packages, for more on how to correctly
install site packages.  See Modules and the File System, for more on
the relationship between load paths and modules.  See Compilation,
for more on the fallback path and auto-compilation.

   Finally, there are a couple of helper procedures for general path
manipulation.

 -- Scheme Procedure: parse-path path [tail]
 -- C Function: scm_parse_path (path, tail)
     Parse PATH, which is expected to be a colon-separated string, into
     a list and return the resulting list with TAIL appended.  If PATH
     is ‘#f’, TAIL is returned.

 -- Scheme Procedure: parse-path-with-ellipsis path base
 -- C Function: scm_parse_path_with_ellipsis (path, base)
     Parse PATH, which is expected to be a colon-separated string, into
     a list and return the resulting list with BASE (a list) spliced in
     place of the ‘...’ path component, if present, or else BASE is
     added to the end.  If PATH is ‘#f’, BASE is returned.

 -- Scheme Procedure: search-path path filename [extensions
          [require-exts?]]
 -- C Function: scm_search_path (path, filename, rest)
     Search PATH for a directory containing a file named FILENAME.  The
     file must be readable, and not a directory.  If we find one, return
     its full filename; otherwise, return ‘#f’.  If FILENAME is
     absolute, return it unchanged.  If given, EXTENSIONS is a list of
     strings; for each directory in PATH, we search for FILENAME
     concatenated with each EXTENSION.  If REQUIRE-EXTS? is true,
     require that the returned file name have one of the given
     extensions; if REQUIRE-EXTS? is not given, it defaults to ‘#f’.

     For compatibility with Guile 1.8 and earlier, the C function takes
     only three arguments.

6.17.8 Character Encoding of Source Files
-----------------------------------------

Scheme source code files are usually encoded in ASCII or UTF-8, but the
built-in reader can interpret other character encodings as well.  When
Guile loads Scheme source code, it uses the ‘file-encoding’ procedure
(described below) to try to guess the encoding of the file.  In the
absence of any hints, UTF-8 is assumed.  One way to provide a hint about
the encoding of a source file is to place a coding declaration in the
top 500 characters of the file.

   A coding declaration has the form ‘coding: XXXXXX’, where ‘XXXXXX’ is
the name of a character encoding in which the source code file has been
encoded.  The coding declaration must appear in a scheme comment.  It
can either be a semicolon-initiated comment, or the first block ‘#!’
comment in the file.

   The name of the character encoding in the coding declaration is
typically lower case and containing only letters, numbers, and hyphens,
as recognized by ‘set-port-encoding!’ (see ‘set-port-encoding!’).
Common examples of character encoding names are ‘utf-8’ and
‘iso-8859-1’, as defined by IANA
(http://www.iana.org/assignments/character-sets).  Thus, the coding
declaration is mostly compatible with Emacs.

   However, there are some differences in encoding names recognized by
Emacs and encoding names defined by IANA, the latter being essentially a
subset of the former.  For instance, ‘latin-1’ is a valid encoding name
for Emacs, but it’s not according to the IANA standard, which Guile
follows; instead, you should use ‘iso-8859-1’, which is both understood
by Emacs and dubbed by IANA (IANA writes it uppercase but Emacs wants it
lowercase and Guile is case insensitive.)

   For source code, only a subset of all possible character encodings
can be interpreted by the built-in source code reader.  Only those
character encodings in which ASCII text appears unmodified can be used.
This includes ‘UTF-8’ and ‘ISO-8859-1’ through ‘ISO-8859-15’.  The
multi-byte character encodings ‘UTF-16’ and ‘UTF-32’ may not be used
because they are not compatible with ASCII.

   There might be a scenario in which one would want to read non-ASCII
code from a port, such as with the function ‘read’, instead of with
‘load’.  If the port’s character encoding is the same as the encoding of
the code to be read by the port, not other special handling is
necessary.  The port will automatically do the character encoding
conversion.  The functions ‘setlocale’ or by ‘set-port-encoding!’ are
used to set port encodings (see Ports).

   If a port is used to read code of unknown character encoding, it can
accomplish this in three steps.  First, the character encoding of the
port should be set to ISO-8859-1 using ‘set-port-encoding!’.  Then, the
procedure ‘file-encoding’, described below, is used to scan for a coding
declaration when reading from the port.  As a side effect, it rewinds
the port after its scan is complete.  After that, the port’s character
encoding should be set to the encoding returned by ‘file-encoding’, if
any, again by using ‘set-port-encoding!’.  Then the code can be read as
normal.

   Alternatively, one can use the ‘#:guess-encoding’ keyword argument of
‘open-file’ and related procedures.  See File Ports.

 -- Scheme Procedure: file-encoding port
 -- C Function: scm_file_encoding (port)
     Attempt to scan the first few hundred bytes from the PORT for hints
     about its character encoding.  Return a string containing the
     encoding name or ‘#f’ if the encoding cannot be determined.  The
     port is rewound.

     Currently, the only supported method is to look for an Emacs-like
     character coding declaration (see how Emacs recognizes file encoding (emacs)).
     The coding declaration is of
     the form ‘coding: XXXXX’ and must appear in a Scheme comment.
     Additional heuristics may be added in the future.

6.17.9 Delayed Evaluation
-------------------------

Promises are a convenient way to defer a calculation until its result is
actually needed, and to run such a calculation only once.  Also
SRFI-45.

 -- syntax: delay expr
     Return a promise object which holds the given EXPR expression,
     ready to be evaluated by a later ‘force’.

 -- Scheme Procedure: promise? obj
 -- C Function: scm_promise_p (obj)
     Return true if OBJ is a promise.

 -- Scheme Procedure: force p
 -- C Function: scm_force (p)
     Return the value obtained from evaluating the EXPR in the given
     promise P.  If P has previously been forced then its EXPR is not
     evaluated again, instead the value obtained at that time is simply
     returned.

     During a ‘force’, an EXPR can call ‘force’ again on its own
     promise, resulting in a recursive evaluation of that EXPR.  The
     first evaluation to return gives the value for the promise.  Higher
     evaluations run to completion in the normal way, but their results
     are ignored, ‘force’ always returns the first value.

6.17.10 Local Evaluation
------------------------

Guile includes a facility to capture a lexical environment, and later
evaluate a new expression within that environment.  This code is
implemented in a module.

     (use-modules (ice-9 local-eval))

 -- syntax: the-environment
     Captures and returns a lexical environment for use with
     ‘local-eval’ or ‘local-compile’.

 -- Scheme Procedure: local-eval exp env
 -- C Function: scm_local_eval (exp, env)
 -- Scheme Procedure: local-compile exp env [opts=()]
     Evaluate or compile the expression EXP in the lexical environment
     ENV.

   Here is a simple example, illustrating that it is the variable that
gets captured, not just its value at one point in time.

     (define e (let ((x 100)) (the-environment)))
     (define fetch-x (local-eval '(lambda () x) e))
     (fetch-x)
     ⇒ 100
     (local-eval '(set! x 42) e)
     (fetch-x)
     ⇒ 42

   While EXP is evaluated within the lexical environment of
‘(the-environment)’, it has the dynamic environment of the call to
‘local-eval’.

   ‘local-eval’ and ‘local-compile’ can only evaluate expressions, not
definitions.

     (local-eval '(define foo 42)
                 (let ((x 100)) (the-environment)))
     ⇒ syntax error: definition in expression context

   Note that the current implementation of ‘(the-environment)’ only
captures “normal” lexical bindings, and pattern variables bound by
‘syntax-case’.  It does not currently capture local syntax transformers
bound by ‘let-syntax’, ‘letrec-syntax’ or non-top-level ‘define-syntax’
forms.  Any attempt to reference such captured syntactic keywords via
‘local-eval’ or ‘local-compile’ produces an error.

6.17.11 Local Inclusion
-----------------------

This section has discussed various means of linking Scheme code
together: fundamentally, loading up files at run-time using ‘load’ and
‘load-compiled’.  Guile provides another option to compose parts of
programs together at expansion-time instead of at run-time.

 -- Scheme Syntax: include file-name
     Open FILE-NAME, at expansion-time, and read the Scheme forms that
     it contains, splicing them into the location of the ‘include’,
     within a ‘begin’.

     If FILE-NAME is a relative path, it is searched for relative to the
     path that contains the file that the ‘include’ for appears in.

   If you are a C programmer, if ‘load’ in Scheme is like ‘dlopen’ in C,
consider ‘include’ to be like the C preprocessor’s ‘#include’.  When you
use ‘include’, it is as if the contents of the included file were typed
in instead of the ‘include’ form.

   Because the code is included at compile-time, it is available to the
macroexpander.  Syntax definitions in the included file are available to
later code in the form in which the ‘include’ appears, without the need
for ‘eval-when’.  (see Eval When.)

   For the same reason, compiling a form that uses ‘include’ results in
one compilation unit, composed of multiple files.  Loading the compiled
file is one ‘stat’ operation for the compilation unit, instead of ‘2*N’
in the case of ‘load’ (once for each loaded source file, and once each
corresponding compiled file, in the best case).

   Unlike ‘load’, ‘include’ also works within nested lexical contexts.
It so happens that the optimizer works best within a lexical context,
because all of the uses of bindings in a lexical context are visible, so
composing files by including them within a ‘(let () ...)’ can sometimes
lead to important speed improvements.

   On the other hand, ‘include’ does have all the disadvantages of early
binding: once the code with the ‘include’ is compiled, no change to the
included file is reflected in the future behavior of the including form.

   Also, the particular form of ‘include’, which requires an absolute
path, or a path relative to the current directory at compile-time, is
not very amenable to compiling the source in one place, but then
installing the source to another place.  For this reason, Guile provides
another form, ‘include-from-path’, which looks for the source file to
include within a load path.

 -- Scheme Syntax: include-from-path file-name
     Like ‘include’, but instead of expecting ‘file-name’ to be an
     absolute file name, it is expected to be a relative path to search
     in the ‘%load-path’.

   ‘include-from-path’ is more useful when you want to install all of
the source files for a package (as you should!).  It makes it possible
to evaluate an installed file from source, instead of relying on the
‘.go’ file being up to date.

6.17.12 REPL Servers
--------------------

The procedures in this section are provided by
     (use-modules (system repl server))

   When an application is written in Guile, it is often convenient to
allow the user to be able to interact with it by evaluating Scheme
expressions in a REPL.

   The procedures of this module allow you to spawn a “REPL server”,
which permits interaction over a local or TCP connection.  Guile itself
uses them internally to implement the ‘--listen’ switch, see
Command-line Options.

 -- Scheme Procedure: make-tcp-server-socket [#:host=#f] [#:addr]
          [#:port=37146]
     Return a stream socket bound to a given address ADDR and port
     number PORT.  If the HOST is given, and ADDR is not, then the HOST
     string is converted to an address.  If neither is given, we use the
     loopback address.

 -- Scheme Procedure: make-unix-domain-server-socket
          [#:path="/tmp/guile-socket"]
     Return a UNIX domain socket, bound to a given PATH.

 -- Scheme Procedure: run-server [server-socket]
 -- Scheme Procedure: spawn-server [server-socket]
     Create and run a REPL, making it available over the given
     SERVER-SOCKET.  If SERVER-SOCKET is not provided, it defaults to
     the socket created by calling ‘make-tcp-server-socket’ with no
     arguments.

     ‘run-server’ runs the server in the current thread, whereas
     ‘spawn-server’ runs the server in a new thread.

 -- Scheme Procedure: stop-server-and-clients!
     Closes the connection on all running server sockets.

     Please note that in the current implementation, the REPL threads
     are cancelled without unwinding their stacks.  If any of them are
     holding mutexes or are within a critical section, the results are
     unspecified.

6.17.13 Cooperative REPL Servers
--------------------------------

The procedures in this section are provided by
     (use-modules (system repl coop-server))

   Whereas ordinary REPL servers run in their own threads (see REPL Servers),
sometimes it is more convenient to provide REPLs that run at
specified times within an existing thread, for example in programs
utilizing an event loop or in single-threaded programs.  This allows for
safe access and mutation of a program’s data structures from the REPL,
without concern for thread synchronization.

   Although the REPLs are run in the thread that calls
‘spawn-coop-repl-server’ and ‘poll-coop-repl-server’, dedicated threads
are spawned so that the calling thread is not blocked.  The spawned
threads read input for the REPLs and to listen for new connections.

   Cooperative REPL servers must be polled periodically to evaluate any
pending expressions by calling ‘poll-coop-repl-server’ with the object
returned from ‘spawn-coop-repl-server’.  The thread that calls
‘poll-coop-repl-server’ will be blocked for as long as the expression
takes to be evaluated or if the debugger is entered.

 -- Scheme Procedure: spawn-coop-repl-server [server-socket]
     Create and return a new cooperative REPL server object, and spawn a
     new thread to listen for connections on SERVER-SOCKET.  Proper
     functioning of the REPL server requires that
     ‘poll-coop-repl-server’ be called periodically on the returned
     server object.

 -- Scheme Procedure: poll-coop-repl-server coop-server
     Poll the cooperative REPL server COOP-SERVER and apply a pending
     operation if there is one, such as evaluating an expression typed
     at the REPL prompt.  This procedure must be called from the same
     thread that called ‘spawn-coop-repl-server’.

6.18 Memory Management and Garbage Collection
=============================================

Guile uses a _garbage collector_ to manage most of its objects.  While
the garbage collector is designed to be mostly invisible, you sometimes
need to interact with it explicitly.

   See Garbage Collection for a general discussion of how
garbage collection relates to using Guile from C.

6.18.1 Function related to Garbage Collection
---------------------------------------------

 -- Scheme Procedure: gc
 -- C Function: scm_gc ()
     Finds all of the “live” ‘SCM’ objects and reclaims for further use
     those that are no longer accessible.  You normally don’t need to
     call this function explicitly.  Its functionality is invoked
     automatically as needed.

 -- C Function: SCM scm_gc_protect_object (SCM OBJ)
     Protects OBJ from being freed by the garbage collector, when it
     otherwise might be.  When you are done with the object, call
     ‘scm_gc_unprotect_object’ on the object.  Calls to
     ‘scm_gc_protect_object’/‘scm_gc_unprotect_object’ can be nested,
     and the object remains protected until it has been unprotected as
     many times as it was protected.  It is an error to unprotect an
     object more times than it has been protected.  Returns the SCM
     object it was passed.

     Note that storing OBJ in a C global variable has the same
     effect(1).

 -- C Function: SCM scm_gc_unprotect_object (SCM OBJ)

     Unprotects an object from the garbage collector which was protected
     by ‘scm_gc_unprotect_object’.  Returns the SCM object it was
     passed.

 -- C Function: SCM scm_permanent_object (SCM OBJ)

     Similar to ‘scm_gc_protect_object’ in that it causes the collector
     to always mark the object, except that it should not be nested
     (only call ‘scm_permanent_object’ on an object once), and it has no
     corresponding unpermanent function.  Once an object is declared
     permanent, it will never be freed.  Returns the SCM object it was
     passed.

 -- C Macro: void scm_remember_upto_here_1 (SCM obj)
 -- C Macro: void scm_remember_upto_here_2 (SCM obj1, SCM obj2)
     Create a reference to the given object or objects, so they’re
     certain to be present on the stack or in a register and hence will
     not be freed by the garbage collector before this point.

     Note that these functions can only be applied to ordinary C local
     variables (ie. “automatics”).  Objects held in global or static
     variables or some malloced block or the like cannot be protected
     with this mechanism.

 -- Scheme Procedure: gc-stats
 -- C Function: scm_gc_stats ()
     Return an association list of statistics about Guile’s current use
     of storage.

 -- Scheme Procedure: gc-live-object-stats
 -- C Function: scm_gc_live_object_stats ()
     Return an alist of statistics of the current live objects.

 -- Function: void scm_gc_mark (SCM X)
     Mark the object X, and recurse on any objects X refers to.  If X’s
     mark bit is already set, return immediately.  This function must
     only be called during the mark-phase of garbage collection,
     typically from a smob _mark_ function.

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

   (1) In Guile up to version 1.8, C global variables were not visited
by the garbage collector in the mark phase; hence,
‘scm_gc_protect_object’ was the only way in C to prevent a Scheme object
from being freed.

6.18.2 Memory Blocks
--------------------

In C programs, dynamic management of memory blocks is normally done with
the functions malloc, realloc, and free.  Guile has additional functions
for dynamic memory allocation that are integrated into the garbage
collector and the error reporting system.

   Memory blocks that are associated with Scheme objects (for example a
foreign object) should be allocated with ‘scm_gc_malloc’ or
‘scm_gc_malloc_pointerless’.  These two functions will either return a
valid pointer or signal an error.  Memory blocks allocated this way may
be released explicitly; however, this is not strictly needed, and we
recommend _not_ calling ‘scm_gc_free’.  All memory allocated with
‘scm_gc_malloc’ or ‘scm_gc_malloc_pointerless’ is automatically
reclaimed when the garbage collector no longer sees any live reference
to it(1).

   When garbage collection occurs, Guile will visit the words in memory
allocated with ‘scm_gc_malloc’, looking for live pointers.  This means
that if ‘scm_gc_malloc’-allocated memory contains a pointer to some
other part of the memory, the garbage collector notices it and prevents
it from being reclaimed(2).  Conversely, memory allocated with
‘scm_gc_malloc_pointerless’ is assumed to be “pointer-less” and is not
scanned for pointers.

   For memory that is not associated with a Scheme object, you can use
‘scm_malloc’ instead of ‘malloc’.  Like ‘scm_gc_malloc’, it will either
return a valid pointer or signal an error.  However, it will not assume
that the new memory block can be freed by a garbage collection.  The
memory must be explicitly freed with ‘free’.

   There is also ‘scm_gc_realloc’ and ‘scm_realloc’, to be used in place
of ‘realloc’ when appropriate, and ‘scm_gc_calloc’ and ‘scm_calloc’, to
be used in place of ‘calloc’ when appropriate.

   The function ‘scm_dynwind_free’ can be useful when memory should be
freed with libc’s ‘free’ when leaving a dynwind context, see Dynamic Wind.

 -- C Function: void * scm_malloc (size_t SIZE)
 -- C Function: void * scm_calloc (size_t SIZE)
     Allocate SIZE bytes of memory and return a pointer to it.  When
     SIZE is 0, return ‘NULL’.  When not enough memory is available,
     signal an error.  This function runs the GC to free up some memory
     when it deems it appropriate.

     The memory is allocated by the libc ‘malloc’ function and can be
     freed with ‘free’.  There is no ‘scm_free’ function to go with
     ‘scm_malloc’ to make it easier to pass memory back and forth
     between different modules.

     The function ‘scm_calloc’ is similar to ‘scm_malloc’, but
     initializes the block of memory to zero as well.

     These functions will (indirectly) call
     ‘scm_gc_register_allocation’.

 -- C Function: void * scm_realloc (void *MEM, size_t NEW_SIZE)
     Change the size of the memory block at MEM to NEW_SIZE and return
     its new location.  When NEW_SIZE is 0, this is the same as calling
     ‘free’ on MEM and ‘NULL’ is returned.  When MEM is ‘NULL’, this
     function behaves like ‘scm_malloc’ and allocates a new block of
     size NEW_SIZE.

     When not enough memory is available, signal an error.  This
     function runs the GC to free up some memory when it deems it
     appropriate.

     This function will call ‘scm_gc_register_allocation’.

 -- C Function: void * scm_gc_malloc (size_t SIZE, const char *WHAT)
 -- C Function: void * scm_gc_malloc_pointerless (size_t SIZE, const
          char *WHAT)
 -- C Function: void * scm_gc_realloc (void *MEM, size_t OLD_SIZE,
          size_t NEW_SIZE, const char *WHAT);
 -- C Function: void * scm_gc_calloc (size_t SIZE, const char *WHAT)
     Allocate SIZE bytes of automatically-managed memory.  The memory is
     automatically freed when no longer referenced from any live memory
     block.

     When garbage collection occurs, Guile will visit the words in
     memory allocated with ‘scm_gc_malloc’ or ‘scm_gc_calloc’, looking
     for pointers to other memory allocations that are managed by the
     GC. In contrast, memory allocated by ‘scm_gc_malloc_pointerless’ is
     not scanned for pointers.

     The ‘scm_gc_realloc’ call preserves the “pointerlessness” of the
     memory area pointed to by MEM.  Note that you need to pass the old
     size of a reallocated memory block as well.  See below for a
     motivation.

 -- C Function: void scm_gc_free (void *MEM, size_t SIZE, const char
          *WHAT)
     Explicitly free the memory block pointed to by MEM, which was
     previously allocated by one of the above ‘scm_gc’ functions.  This
     function is almost always unnecessary, except for codebases that
     still need to compile on Guile 1.8.

     Note that you need to explicitly pass the SIZE parameter.  This is
     done since it should normally be easy to provide this parameter
     (for memory that is associated with GC controlled objects) and help
     keep the memory management overhead very low.  However, in Guile
     2.x, SIZE is always ignored.

 -- C Function: void scm_gc_register_allocation (size_t SIZE)
     Informs the garbage collector that SIZE bytes have been allocated,
     which the collector would otherwise not have known about.

     In general, Scheme will decide to collect garbage only after some
     amount of memory has been allocated.  Calling this function will
     make the Scheme garbage collector know about more allocation, and
     thus run more often (as appropriate).

     It is especially important to call this function when large
     unmanaged allocations, like images, may be freed by small Scheme
     allocations, like foreign objects.

 -- C Function: void scm_dynwind_free (void *mem)
     Equivalent to ‘scm_dynwind_unwind_handler (free, MEM,
     SCM_F_WIND_EXPLICITLY)’.  That is, the memory block at MEM will be
     freed (using ‘free’ from the C library) when the current dynwind is
     left.

 -- Scheme Procedure: malloc-stats
     Return an alist ((WHAT .  N) ...)  describing number of malloced
     objects.  WHAT is the second argument to ‘scm_gc_malloc’, N is the
     number of objects of that type currently allocated.

     This function is only available if the ‘GUILE_DEBUG_MALLOC’
     preprocessor macro was defined when Guile was compiled.

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

   (1) In Guile up to version 1.8, memory allocated with ‘scm_gc_malloc’
_had_ to be freed with ‘scm_gc_free’.

   (2) In Guile up to 1.8, memory allocated with ‘scm_gc_malloc’ was
_not_ visited by the collector in the mark phase.  Consequently, the GC
had to be told explicitly about pointers to live objects contained in
the memory block, e.g., via SMOB mark functions (see
‘scm_set_smob_mark’)

6.18.3 Weak References
----------------------

[FIXME: This chapter is based on Mikael Djurfeldt’s answer to a question
by Michael Livshin.  Any mistakes are not theirs, of course.  ]

   Weak references let you attach bookkeeping information to data so
that the additional information automatically disappears when the
original data is no longer in use and gets garbage collected.  In a weak
key hash, the hash entry for that key disappears as soon as the key is
no longer referenced from anywhere else.  For weak value hashes, the
same happens as soon as the value is no longer in use.  Entries in a
doubly weak hash disappear when either the key or the value are not used
anywhere else anymore.

   Object properties offer the same kind of functionality as weak key
hashes in many situations.  (see Object Properties)

   Here’s an example (a little bit strained perhaps, but one of the
examples is actually used in Guile):

   Assume that you’re implementing a debugging system where you want to
associate information about filename and position of source code
expressions with the expressions themselves.

   Hashtables can be used for that, but if you use ordinary hash tables
it will be impossible for the scheme interpreter to "forget" old source
when, for example, a file is reloaded.

   To implement the mapping from source code expressions to positional
information it is necessary to use weak-key tables since we don’t want
the expressions to be remembered just because they are in our table.

   To implement a mapping from source file line numbers to source code
expressions you would use a weak-value table.

   To implement a mapping from source code expressions to the procedures
they constitute a doubly-weak table has to be used.

6.18.3.1 Weak hash tables
.........................

 -- Scheme Procedure: make-weak-key-hash-table [size]
 -- Scheme Procedure: make-weak-value-hash-table [size]
 -- Scheme Procedure: make-doubly-weak-hash-table [size]
 -- C Function: scm_make_weak_key_hash_table (size)
 -- C Function: scm_make_weak_value_hash_table (size)
 -- C Function: scm_make_doubly_weak_hash_table (size)
     Return a weak hash table with SIZE buckets.  As with any hash
     table, choosing a good size for the table requires some caution.

     You can modify weak hash tables in exactly the same way you would
     modify regular hash tables.  (see Hash Tables)

 -- Scheme Procedure: weak-key-hash-table? obj
 -- Scheme Procedure: weak-value-hash-table? obj
 -- Scheme Procedure: doubly-weak-hash-table? obj
 -- C Function: scm_weak_key_hash_table_p (obj)
 -- C Function: scm_weak_value_hash_table_p (obj)
 -- C Function: scm_doubly_weak_hash_table_p (obj)
     Return ‘#t’ if OBJ is the specified weak hash table.  Note that a
     doubly weak hash table is neither a weak key nor a weak value hash
     table.

6.18.3.2 Weak vectors
.....................

 -- Scheme Procedure: make-weak-vector size [fill]
 -- C Function: scm_make_weak_vector (size, fill)
     Return a weak vector with SIZE elements.  If the optional argument
     FILL is given, all entries in the vector will be set to FILL.  The
     default value for FILL is the empty list.

 -- Scheme Procedure: weak-vector elem ...
 -- Scheme Procedure: list->weak-vector l
 -- C Function: scm_weak_vector (l)
     Construct a weak vector from a list: ‘weak-vector’ uses the list of
     its arguments while ‘list->weak-vector’ uses its only argument L (a
     list) to construct a weak vector the same way ‘list->vector’ would.

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

 -- Scheme Procedure: weak-vector-ref wvect k
 -- C Function: scm_weak_vector_ref (wvect, k)
     Return the Kth element of the weak vector WVECT, or ‘#f’ if that
     element has been collected.

 -- Scheme Procedure: weak-vector-set! wvect k elt
 -- C Function: scm_weak_vector_set_x (wvect, k, elt)
     Set the Kth element of the weak vector WVECT to ELT.

6.18.4 Guardians
----------------

Guardians provide a way to be notified about objects that would
otherwise be collected as garbage.  Guarding them prevents the objects
from being collected and cleanup actions can be performed on them, for
example.

   See R. Kent Dybvig, Carl Bruggeman, and David Eby (1993) "Guardians
in a Generation-Based Garbage Collector".  ACM SIGPLAN Conference on
Programming Language Design and Implementation, June 1993.

 -- Scheme Procedure: make-guardian
 -- C Function: scm_make_guardian ()
     Create a new guardian.  A guardian protects a set of objects from
     garbage collection, allowing a program to apply cleanup or other
     actions.

     ‘make-guardian’ returns a procedure representing the guardian.
     Calling the guardian procedure with an argument adds the argument
     to the guardian’s set of protected objects.  Calling the guardian
     procedure without an argument returns one of the protected objects
     which are ready for garbage collection, or ‘#f’ if no such object
     is available.  Objects which are returned in this way are removed
     from the guardian.

     You can put a single object into a guardian more than once and you
     can put a single object into more than one guardian.  The object
     will then be returned multiple times by the guardian procedures.

     An object is eligible to be returned from a guardian when it is no
     longer referenced from outside any guardian.

     There is no guarantee about the order in which objects are returned
     from a guardian.  If you want to impose an order on finalization
     actions, for example, you can do that by keeping objects alive in
     some global data structure until they are no longer needed for
     finalizing other objects.

     Being an element in a weak vector, a key in a hash table with weak
     keys, or a value in a hash table with weak values does not prevent
     an object from being returned by a guardian.  But as long as an
     object can be returned from a guardian it will not be removed from
     such a weak vector or hash table.  In other words, a weak link does
     not prevent an object from being considered collectable, but being
     inside a guardian prevents a weak link from being broken.

     A key in a weak key hash table can be thought of as having a strong
     reference to its associated value as long as the key is accessible.
     Consequently, when the key is only accessible from within a
     guardian, the reference from the key to the value is also
     considered to be coming from within a guardian.  Thus, if there is
     no other reference to the value, it is eligible to be returned from
     a guardian.

6.19 Modules
============

When programs become large, naming conflicts can occur when a function
or global variable defined in one file has the same name as a function
or global variable in another file.  Even just a _similarity_ between
function names can cause hard-to-find bugs, since a programmer might
type the wrong function name.

   The approach used to tackle this problem is called _information
encapsulation_, which consists of packaging functional units into a
given name space that is clearly separated from other name spaces.

   The language features that allow this are usually called _the module
system_ because programs are broken up into modules that are compiled
separately (or loaded separately in an interpreter).

   Older languages, like C, have limited support for name space
manipulation and protection.  In C a variable or function is public by
default, and can be made local to a module with the ‘static’ keyword.
But you cannot reference public variables and functions from another
module with different names.

   More advanced module systems have become a common feature in recently
designed languages: ML, Python, Perl, and Modula 3 all allow the
_renaming_ of objects from a foreign module, so they will not clutter
the global name space.

   In addition, Guile offers variables as first-class objects.  They can
be used for interacting with the module system.

6.19.1 General Information about Modules
----------------------------------------

A Guile module can be thought of as a collection of named procedures,
variables and macros.  More precisely, it is a set of “bindings” of
symbols (names) to Scheme objects.

   Within a module, all bindings are visible.  Certain bindings can be
declared “public”, in which case they are added to the module’s
so-called “export list”; this set of public bindings is called the
module’s “public interface” (see Creating Guile Modules).

   A client module “uses” a providing module’s bindings by either
accessing the providing module’s public interface, or by building a
custom interface (and then accessing that).  In a custom interface, the
client module can “select” which bindings to access and can also
algorithmically “rename” bindings.  In contrast, when using the
providing module’s public interface, the entire export list is available
without renaming (see Using Guile Modules).

   All Guile modules have a unique “module name”, for example ‘(ice-9
popen)’ or ‘(srfi srfi-11)’.  Module names are lists of one or more
symbols.

   When Guile goes to use an interface from a module, for example
‘(ice-9 popen)’, Guile first looks to see if it has loaded ‘(ice-9
popen)’ for any reason.  If the module has not been loaded yet, Guile
searches a “load path” for a file that might define it, and loads that
file.

   The following subsections go into more detail on using, creating,
installing, and otherwise manipulating modules and the module system.

6.19.2 Using Guile Modules
--------------------------

To use a Guile module is to access either its public interface or a
custom interface (see General Information about Modules).  Both
types of access are handled by the syntactic form ‘use-modules’, which
accepts one or more interface specifications and, upon evaluation,
arranges for those interfaces to be available to the current module.
This process may include locating and loading code for a given module if
that code has not yet been loaded, following ‘%load-path’ (see Modules and the File System).

   An “interface specification” has one of two forms.  The first
variation is simply to name the module, in which case its public
interface is the one accessed.  For example:

     (use-modules (ice-9 popen))

   Here, the interface specification is ‘(ice-9 popen)’, and the result
is that the current module now has access to ‘open-pipe’, ‘close-pipe’,
‘open-input-pipe’, and so on (see Pipes).

   Note in the previous example that if the current module had already
defined ‘open-pipe’, that definition would be overwritten by the
definition in ‘(ice-9 popen)’.  For this reason (and others), there is a
second variation of interface specification that not only names a module
to be accessed, but also selects bindings from it and renames them to
suit the current module’s needs.  For example:

     (use-modules ((ice-9 popen)
                   #:select ((open-pipe . pipe-open) close-pipe)
                   #:renamer (symbol-prefix-proc 'unixy:)))

or more simply:

     (use-modules ((ice-9 popen)
                   #:select ((open-pipe . pipe-open) close-pipe)
                   #:prefix unixy:))

   Here, the interface specification is more complex than before, and
the result is that a custom interface with only two bindings is created
and subsequently accessed by the current module.  The mapping of old to
new names is as follows:

     (ice-9 popen) sees:             current module sees:
     open-pipe                       unixy:pipe-open
     close-pipe                      unixy:close-pipe

   This example also shows how to use the convenience procedure
‘symbol-prefix-proc’.

   You can also directly refer to bindings in a module by using the ‘@’
syntax.  For example, instead of using the ‘use-modules’ statement from
above and writing ‘unixy:pipe-open’ to refer to the ‘pipe-open’ from the
‘(ice-9 popen)’, you could also write ‘(@ (ice-9 popen) open-pipe)’.
Thus an alternative to the complete ‘use-modules’ statement would be

     (define unixy:pipe-open (@ (ice-9 popen) open-pipe))
     (define unixy:close-pipe (@ (ice-9 popen) close-pipe))

   There is also ‘@@’, which can be used like ‘@’, but does not check
whether the variable that is being accessed is actually exported.  Thus,
‘@@’ can be thought of as the impolite version of ‘@’ and should only be
used as a last resort or for debugging, for example.

   Note that just as with a ‘use-modules’ statement, any module that has
not yet been loaded will be loaded when referenced by a ‘@’ or ‘@@’
form.

   You can also use the ‘@’ and ‘@@’ syntaxes as the target of a ‘set!’
when the binding refers to a variable.

 -- Scheme Procedure: symbol-prefix-proc prefix-sym
     Return a procedure that prefixes its arg (a symbol) with
     PREFIX-SYM.

 -- syntax: use-modules spec ...
     Resolve each interface specification SPEC into an interface and
     arrange for these to be accessible by the current module.  The
     return value is unspecified.

     SPEC can be a list of symbols, in which case it names a module
     whose public interface is found and used.

     SPEC can also be of the form:

           (MODULE-NAME [#:select SELECTION]
                        [#:prefix PREFIX]
                        [#:renamer RENAMER])

     in which case a custom interface is newly created and used.
     MODULE-NAME is a list of symbols, as above; SELECTION is a list of
     selection-specs; PREFIX is a symbol that is prepended to imported
     names; and RENAMER is a procedure that takes a symbol and returns
     its new name.  A selection-spec is either a symbol or a pair of
     symbols ‘(ORIG . SEEN)’, where ORIG is the name in the used module
     and SEEN is the name in the using module.  Note that SEEN is also
     modified by PREFIX and RENAMER.

     The ‘#:select’, ‘#:prefix’, and ‘#:renamer’ clauses are optional.
     If all are omitted, the returned interface has no bindings.  If the
     ‘#:select’ clause is omitted, PREFIX and RENAMER operate on the
     used module’s public interface.

     In addition to the above, SPEC can also include a ‘#:version’
     clause, of the form:

           #:version VERSION-SPEC

     where VERSION-SPEC is an R6RS-compatible version reference.  An
     error will be signaled in the case in which a module with the same
     name has already been loaded, if that module specifies a version
     and that version is not compatible with VERSION-SPEC.  See R6RS Version References,
     for more on version references.

     If the module name is not resolvable, ‘use-modules’ will signal an
     error.

 -- syntax: @ module-name binding-name
     Refer to the binding named BINDING-NAME in module MODULE-NAME.  The
     binding must have been exported by the module.

 -- syntax: @@ module-name binding-name
     Refer to the binding named BINDING-NAME in module MODULE-NAME.  The
     binding must not have been exported by the module.  This syntax is
     only intended for debugging purposes or as a last resort.

6.19.3 Creating Guile Modules
-----------------------------

When you want to create your own modules, you have to take the following
steps:

   • Create a Scheme source file and add all variables and procedures
     you wish to export, or which are required by the exported
     procedures.

   • Add a ‘define-module’ form at the beginning.

   • Export all bindings which should be in the public interface, either
     by using ‘define-public’ or ‘export’ (both documented below).

 -- syntax: define-module module-name option ...
     MODULE-NAME is a list of one or more symbols.

          (define-module (ice-9 popen))

     ‘define-module’ makes this module available to Guile programs under
     the given MODULE-NAME.

     OPTION ... are keyword/value pairs which specify more about the
     defined module.  The recognized options and their meaning are shown
     in the following table.

     ‘#:use-module INTERFACE-SPECIFICATION’
          Equivalent to a ‘(use-modules INTERFACE-SPECIFICATION)’ (see
          Using Guile Modules).

     ‘#:autoload MODULE SYMBOL-LIST’
          Load MODULE when any of SYMBOL-LIST are accessed.  For
          example,

               (define-module (my mod)
                 #:autoload (srfi srfi-1) (partition delete-duplicates))
               ...
               (if something
                   (set! foo (delete-duplicates ...)))

          When a module is autoloaded, all its bindings become
          available.  SYMBOL-LIST is just those that will first trigger
          the load.

          An autoload is a good way to put off loading a big module
          until it’s really needed, for instance for faster startup or
          if it will only be needed in certain circumstances.

          ‘@’ can do a similar thing (see Using Guile Modules), but
          in that case an ‘@’ form must be written every time a binding
          from the module is used.

     ‘#:export LIST’
          Export all identifiers in LIST which must be a list of symbols
          or pairs of symbols.  This is equivalent to ‘(export LIST)’ in
          the module body.

     ‘#:re-export LIST’
          Re-export all identifiers in LIST which must be a list of
          symbols or pairs of symbols.  The symbols in LIST must be
          imported by the current module from other modules.  This is
          equivalent to ‘re-export’ below.

     ‘#:replace LIST’
          Export all identifiers in LIST (a list of symbols or pairs of
          symbols) and mark them as “replacing bindings”.  In the module
          user’s name space, this will have the effect of replacing any
          binding with the same name that is not also “replacing”.
          Normally a replacement results in an “override” warning
          message, ‘#:replace’ avoids that.

          In general, a module that exports a binding for which the
          ‘(guile)’ module already has a definition should use
          ‘#:replace’ instead of ‘#:export’.  ‘#:replace’, in a sense,
          lets Guile know that the module _purposefully_ replaces a core
          binding.  It is important to note, however, that this binding
          replacement is confined to the name space of the module user.
          In other words, the value of the core binding in question
          remains unchanged for other modules.

          Note that although it is often a good idea for the replaced
          binding to remain compatible with a binding in ‘(guile)’, to
          avoid surprising the user, sometimes the bindings will be
          incompatible.  For example, SRFI-19 exports its own version of
          ‘current-time’ (see SRFI-19 Time) which is not compatible
          with the core ‘current-time’ function (see Time).  Guile
          assumes that a user importing a module knows what she is
          doing, and uses ‘#:replace’ for this binding rather than
          ‘#:export’.

          A ‘#:replace’ clause is equivalent to ‘(export! LIST)’ in the
          module body.

          The ‘#:duplicates’ (see below) provides fine-grain control
          about duplicate binding handling on the module-user side.

     ‘#:version LIST’
          Specify a version for the module in the form of LIST, a list
          of zero or more exact, nonnegative integers.  The
          corresponding ‘#:version’ option in the ‘use-modules’ form
          allows callers to restrict the value of this option in various
          ways.

     ‘#:duplicates LIST’
          Tell Guile to handle duplicate bindings for the bindings
          imported by the current module according to the policy defined
          by LIST, a list of symbols.  LIST must contain symbols
          representing a duplicate binding handling policy chosen among
          the following:

          ‘check’
               Raises an error when a binding is imported from more than
               one place.
          ‘warn’
               Issue a warning when a binding is imported from more than
               one place and leave the responsibility of actually
               handling the duplication to the next duplicate binding
               handler.
          ‘replace’
               When a new binding is imported that has the same name as
               a previously imported binding, then do the following:

                 1. If the old binding was said to be “replacing” (via
                    the ‘#:replace’ option above) and the new binding is
                    not replacing, the keep the old binding.
                 2. If the old binding was not said to be replacing and
                    the new binding is replacing, then replace the old
                    binding with the new one.
                 3. If neither the old nor the new binding is replacing,
                    then keep the old one.

          ‘warn-override-core’
               Issue a warning when a core binding is being overwritten
               and actually override the core binding with the new one.
          ‘first’
               In case of duplicate bindings, the firstly imported
               binding is always the one which is kept.
          ‘last’
               In case of duplicate bindings, the lastly imported
               binding is always the one which is kept.
          ‘noop’
               In case of duplicate bindings, leave the responsibility
               to the next duplicate handler.

          If LIST contains more than one symbol, then the duplicate
          binding handlers which appear first will be used first when
          resolving a duplicate binding situation.  As mentioned above,
          some resolution policies may explicitly leave the
          responsibility of handling the duplication to the next handler
          in LIST.

          If GOOPS has been loaded before the ‘#:duplicates’ clause is
          processed, there are additional strategies available for
          dealing with generic functions.  See Merging Generics, for
          more information.

          The default duplicate binding resolution policy is given by
          the ‘default-duplicate-binding-handler’ procedure, and is

               (replace warn-override-core warn last)

     ‘#:pure’
          Create a “pure” module, that is a module which does not
          contain any of the standard procedure bindings except for the
          syntax forms.  This is useful if you want to create “safe”
          modules, that is modules which do not know anything about
          dangerous procedures.

 -- syntax: export variable ...
     Add all VARIABLEs (which must be symbols or pairs of symbols) to
     the list of exported bindings of the current module.  If VARIABLE
     is a pair, its ‘car’ gives the name of the variable as seen by the
     current module and its ‘cdr’ specifies a name for the binding in
     the current module’s public interface.

 -- syntax: define-public ...
     Equivalent to ‘(begin (define foo ...) (export foo))’.

 -- syntax: re-export variable ...
     Add all VARIABLEs (which must be symbols or pairs of symbols) to
     the list of re-exported bindings of the current module.  Pairs of
     symbols are handled as in ‘export’.  Re-exported bindings must be
     imported by the current module from some other module.

 -- syntax: export! variable ...
     Like ‘export’, but marking the exported variables as replacing.
     Using a module with replacing bindings will cause any existing
     bindings to be replaced without issuing any warnings.  See the
     discussion of ‘#:replace’ above.

6.19.4 Modules and the File System
----------------------------------

Typical programs only use a small subset of modules installed on a Guile
system.  In order to keep startup time down, Guile only loads modules
when a program uses them, on demand.

   When a program evaluates ‘(use-modules (ice-9 popen))’, and the
module is not loaded, Guile searches for a conventionally-named file
from in the “load path”.

   In this case, loading ‘(ice-9 popen)’ will eventually cause Guile to
run ‘(primitive-load-path "ice-9/popen")’.  ‘primitive-load-path’ will
search for a file ‘ice-9/popen’ in the ‘%load-path’ (see Load Paths).
For each directory in ‘%load-path’, Guile will try to find
the file name, concatenated with the extensions from ‘%load-extensions’.
By default, this will cause Guile to ‘stat’ ‘ice-9/popen.scm’, and then
‘ice-9/popen’.  See Load Paths, for more on ‘primitive-load-path’.

   If a corresponding compiled ‘.go’ file is found in the
‘%load-compiled-path’ or in the fallback path, and is as fresh as the
source file, it will be loaded instead of the source file.  If no
compiled file is found, Guile may try to compile the source file and
cache away the resulting ‘.go’ file.  See Compilation, for more on
compilation.

   Once Guile finds a suitable source or compiled file is found, the
file will be loaded.  If, after loading the file, the module under
consideration is still not defined, Guile will signal an error.

   For more information on where and how to install Scheme modules,
see Installing Site Packages.

6.19.5 R6RS Version References
------------------------------

Guile’s module system includes support for locating modules based on a
declared version specifier of the same form as the one described in R6RS
(see R6RS Library Form (r6rs)).  By using the
‘#:version’ keyword in a ‘define-module’ form, a module may specify a
version as a list of zero or more exact, nonnegative integers.

   This version can then be used to locate the module during the module
search process.  Client modules and callers of the ‘use-modules’
function may specify constraints on the versions of target modules by
providing a “version reference”, which has one of the following forms:

      (SUB-VERSION-REFERENCE ...)
      (and VERSION-REFERENCE ...)
      (or VERSION-REFERENCE ...)
      (not VERSION-REFERENCE)

   in which SUB-VERSION-REFERENCE is in turn one of:

      (SUB-VERSION)
      (>= SUB-VERSION)
      (<= SUB-VERSION)
      (and SUB-VERSION-REFERENCE ...)
      (or SUB-VERSION-REFERENCE ...)
      (not SUB-VERSION-REFERENCE)

   in which SUB-VERSION is an exact, nonnegative integer as above.  A
version reference matches a declared module version if each element of
the version reference matches a corresponding element of the module
version, according to the following rules:

   • The ‘and’ sub-form matches a version or version element if every
     element in the tail of the sub-form matches the specified version
     or version element.

   • The ‘or’ sub-form matches a version or version element if any
     element in the tail of the sub-form matches the specified version
     or version element.

   • The ‘not’ sub-form matches a version or version element if the tail
     of the sub-form does not match the version or version element.

   • The ‘>=’ sub-form matches a version element if the element is
     greater than or equal to the SUB-VERSION in the tail of the
     sub-form.

   • The ‘<=’ sub-form matches a version element if the version is less
     than or equal to the SUB-VERSION in the tail of the sub-form.

   • A SUB-VERSION matches a version element if one is EQV? to the
     other.

   For example, a module declared as:

      (define-module (mylib mymodule) #:version (1 2 0))

   would be successfully loaded by any of the following ‘use-modules’
expressions:

      (use-modules ((mylib mymodule) #:version (1 2 (>= 0))))
      (use-modules ((mylib mymodule) #:version (or (1 2 0) (1 2 1))))
      (use-modules ((mylib mymodule) #:version ((and (>= 1) (not 2)) 2 0)))

6.19.6 R6RS Libraries
---------------------

In addition to the API described in the previous sections, you also have
the option to create modules using the portable ‘library’ form described
in R6RS (see R6RS Library Form (r6rs)), and to import
libraries created in this format by other programmers.  Guile’s R6RS
library implementation takes advantage of the flexibility built into the
module system by expanding the R6RS library form into a corresponding
Guile ‘define-module’ form that specifies equivalent import and export
requirements and includes the same body expressions.  The library
expression:

       (library (mylib (1 2))
         (export mybinding)
         (import (otherlib (3))))

   is equivalent to the module definition:

       (define-module (mylib)
         #:version (1 2)
         #:use-module ((otherlib) #:version (3))
         #:export (mybinding))

   Central to the mechanics of R6RS libraries is the concept of import
and export “levels”, which control the visibility of bindings at various
phases of a library’s lifecycle — macros necessary to expand forms in
the library’s body need to be available at expand time; variables used
in the body of a procedure exported by the library must be available at
runtime.  R6RS specifies the optional ‘for’ sub-form of an _import set_
specification (see below) as a mechanism by which a library author can
indicate that a particular library import should take place at a
particular phase with respect to the lifecycle of the importing library.

   Guile’s library implementation uses a technique called “implicit
phasing” (first described by Abdulaziz Ghuloum and R. Kent Dybvig),
which allows the expander and compiler to automatically determine the
necessary visibility of a binding imported from another library.  As
such, the ‘for’ sub-form described below is ignored by Guile (but may be
required by Schemes in which phasing is explicit).

 -- Scheme Syntax: library name (export export-spec ...) (import
          import-spec ...) body ...
     Defines a new library with the specified name, exports, and
     imports, and evaluates the specified body expressions in this
     library’s environment.

     The library NAME is a non-empty list of identifiers, optionally
     ending with a version specification of the form described above
     (see Creating Guile Modules).

     Each EXPORT-SPEC is the name of a variable defined or imported by
     the library, or must take the form ‘(rename (internal-name
     external-name) ...)’, where the identifier INTERNAL-NAME names a
     variable defined or imported by the library and EXTERNAL-NAME is
     the name by which the variable is seen by importing libraries.

     Each IMPORT-SPEC must be either an “import set” (see below) or must
     be of the form ‘(for import-set import-level ...)’, where each
     IMPORT-LEVEL is one of:

            run
            expand
            (meta LEVEL)

     where LEVEL is an integer.  Note that since Guile does not require
     explicit phase specification, any IMPORT-SETs found inside of ‘for’
     sub-forms will be “unwrapped” during expansion and processed as if
     they had been specified directly.

     Import sets in turn take one of the following forms:

            LIBRARY-REFERENCE
            (library LIBRARY-REFERENCE)
            (only IMPORT-SET IDENTIFIER ...)
            (except IMPORT-SET IDENTIFIER ...)
            (prefix IMPORT-SET IDENTIFIER)
            (rename IMPORT-SET (INTERNAL-IDENTIFIER EXTERNAL-IDENTIFIER) ...)

     where LIBRARY-REFERENCE is a non-empty list of identifiers ending
     with an optional version reference (see R6RS Version References),
     and the other sub-forms have the following
     semantics, defined recursively on nested IMPORT-SETs:

        • The ‘library’ sub-form is used to specify libraries for import
          whose names begin with the identifier “library.”

        • The ‘only’ sub-form imports only the specified IDENTIFIERs
          from the given IMPORT-SET.

        • The ‘except’ sub-form imports all of the bindings exported by
          IMPORT-SET except for those that appear in the specified list
          of IDENTIFIERs.

        • The ‘prefix’ sub-form imports all of the bindings exported by
          IMPORT-SET, first prefixing them with the specified
          IDENTIFIER.

        • The ‘rename’ sub-form imports all of the identifiers exported
          by IMPORT-SET.  The binding for each INTERNAL-IDENTIFIER among
          these identifiers is made visible to the importing library as
          the corresponding EXTERNAL-IDENTIFIER; all other bindings are
          imported using the names provided by IMPORT-SET.

     Note that because Guile translates R6RS libraries into module
     definitions, an import specification may be used to declare a
     dependency on a native Guile module — although doing so may make
     your libraries less portable to other Schemes.

 -- Scheme Syntax: import import-spec ...
     Import into the current environment the libraries specified by the
     given import specifications, where each IMPORT-SPEC takes the same
     form as in the ‘library’ form described above.

6.19.7 Variables
----------------

Each module has its own hash table, sometimes known as an “obarray”,
that maps the names defined in that module to their corresponding
variable objects.

   A variable is a box-like object that can hold any Scheme value.  It
is said to be “undefined” if its box holds a special Scheme value that
denotes undefined-ness (which is different from all other Scheme values,
including for example ‘#f’); otherwise the variable is “defined”.

   On its own, a variable object is anonymous.  A variable is said to be
“bound” when it is associated with a name in some way, usually a symbol
in a module obarray.  When this happens, the name is said to be bound to
the variable, in that module.

   (That’s the theory, anyway.  In practice, defined-ness and bound-ness
sometimes get confused, because Lisp and Scheme implementations have
often conflated — or deliberately drawn no distinction between — a name
that is unbound and a name that is bound to a variable whose value is
undefined.  We will try to be clear about the difference and explain any
confusion where it is unavoidable.)

   Variables do not have a read syntax.  Most commonly they are created
and bound implicitly by ‘define’ expressions: a top-level ‘define’
expression of the form

     (define NAME VALUE)

creates a variable with initial value VALUE and binds it to the name
NAME in the current module.  But they can also be created dynamically by
calling one of the constructor procedures ‘make-variable’ and
‘make-undefined-variable’.

 -- Scheme Procedure: make-undefined-variable
 -- C Function: scm_make_undefined_variable ()
     Return a variable that is initially unbound.

 -- Scheme Procedure: make-variable init
 -- C Function: scm_make_variable (init)
     Return a variable initialized to value INIT.

 -- Scheme Procedure: variable-bound? var
 -- C Function: scm_variable_bound_p (var)
     Return ‘#t’ if VAR is bound to a value, or ‘#f’ otherwise.  Throws
     an error if VAR is not a variable object.

 -- Scheme Procedure: variable-ref var
 -- C Function: scm_variable_ref (var)
     Dereference VAR and return its value.  VAR must be a variable
     object; see ‘make-variable’ and ‘make-undefined-variable’.

 -- Scheme Procedure: variable-set! var val
 -- C Function: scm_variable_set_x (var, val)
     Set the value of the variable VAR to VAL.  VAR must be a variable
     object, VAL can be any value.  Return an unspecified value.

 -- Scheme Procedure: variable-unset! var
 -- C Function: scm_variable_unset_x (var)
     Unset the value of the variable VAR, leaving VAR unbound.

 -- Scheme Procedure: variable? obj
 -- C Function: scm_variable_p (obj)
     Return ‘#t’ if OBJ is a variable object, else return ‘#f’.

6.19.8 Module System Reflection
-------------------------------

The previous sections have described a declarative view of the module
system.  You can also work with it programmatically by accessing and
modifying various parts of the Scheme objects that Guile uses to
implement the module system.

   At any time, there is a “current module”.  This module is the one
where a top-level ‘define’ and similar syntax will add new bindings.
You can find other module objects with ‘resolve-module’, for example.

   These module objects can be used as the second argument to ‘eval’.

 -- Scheme Procedure: current-module
 -- C Function: scm_current_module ()
     Return the current module object.

 -- Scheme Procedure: set-current-module module
 -- C Function: scm_set_current_module (module)
     Set the current module to MODULE and return the previous current
     module.

 -- Scheme Procedure: save-module-excursion thunk
     Call THUNK within a ‘dynamic-wind’ such that the module that is
     current at invocation time is restored when THUNK’s dynamic extent
     is left (see Dynamic Wind).

     More precisely, if THUNK escapes non-locally, the current module
     (at the time of escape) is saved, and the original current module
     (at the time THUNK’s dynamic extent was last entered) is restored.
     If THUNK’s dynamic extent is re-entered, then the current module is
     saved, and the previously saved inner module is set current again.

 -- Scheme Procedure: resolve-module name [autoload=#t] [version=#f]
          [#:ensure=#t]
 -- C Function: scm_resolve_module (name)
     Find the module named NAME and return it.  When it has not already
     been defined and AUTOLOAD is true, try to auto-load it.  When it
     can’t be found that way either, create an empty module if ENSURE is
     true, otherwise return ‘#f’.  If VERSION is true, ensure that the
     resulting module is compatible with the given version reference
     (see R6RS Version References).  The name is a list of symbols.

 -- Scheme Procedure: resolve-interface name [#:select=#f] [#:hide='()]
          [#:prefix=#f] [#:renamer=#f] [#:version=#f]
     Find the module named NAME as with ‘resolve-module’ and return its
     interface.  The interface of a module is also a module object, but
     it contains only the exported bindings.

 -- Scheme Procedure: module-uses module
     Return a list of the interfaces used by MODULE.

 -- Scheme Procedure: module-use! module interface
     Add INTERFACE to the front of the use-list of MODULE.  Both
     arguments should be module objects, and INTERFACE should very
     likely be a module returned by ‘resolve-interface’.

 -- Scheme Procedure: reload-module module
     Revisit the source file that corresponds to MODULE.  Raises an
     error if no source file is associated with the given module.

   As mentioned in the previous section, modules contain a mapping
between identifiers (as symbols) and storage locations (as variables).
Guile defines a number of procedures to allow access to this mapping.
If you are programming in C, see Accessing Modules from C.

 -- Scheme Procedure: module-variable module name
     Return the variable bound to NAME (a symbol) in MODULE, or ‘#f’ if
     NAME is unbound.

 -- Scheme Procedure: module-add! module name var
     Define a new binding between NAME (a symbol) and VAR (a variable)
     in MODULE.

 -- Scheme Procedure: module-ref module name
     Look up the value bound to NAME in MODULE.  Like ‘module-variable’,
     but also does a ‘variable-ref’ on the resulting variable, raising
     an error if NAME is unbound.

 -- Scheme Procedure: module-define! module name value
     Locally bind NAME to VALUE in MODULE.  If NAME was already locally
     bound in MODULE, i.e., defined locally and not by an imported
     module, the value stored in the existing variable will be updated.
     Otherwise, a new variable will be added to the module, via
     ‘module-add!’.

 -- Scheme Procedure: module-set! module name value
     Update the binding of NAME in MODULE to VALUE, raising an error if
     NAME is not already bound in MODULE.

   There are many other reflective procedures available in the default
environment.  If you find yourself using one of them, please contact the
Guile developers so that we can commit to stability for that interface.

6.19.9 Accessing Modules from C
-------------------------------

The last sections have described how modules are used in Scheme code,
which is the recommended way of creating and accessing modules.  You can
also work with modules from C, but it is more cumbersome.

   The following procedures are available.

 -- C Function: SCM scm_c_call_with_current_module (SCM MODULE, SCM
          (*FUNC)(void *), void *DATA)
     Call FUNC and make MODULE the current module during the call.  The
     argument DATA is passed to FUNC.  The return value of
     ‘scm_c_call_with_current_module’ is the return value of FUNC.

 -- C Function: SCM scm_public_variable (SCM MODULE_NAME, SCM NAME)
 -- C Function: SCM scm_c_public_variable (const char *MODULE_NAME,
          const char *NAME)
     Find a the variable bound to the symbol NAME in the public
     interface of the module named MODULE_NAME.

     MODULE_NAME should be a list of symbols, when represented as a
     Scheme object, or a space-separated string, in the ‘const char *’
     case.  See ‘scm_c_define_module’ below, for more examples.

     Signals an error if no module was found with the given name.  If
     NAME is not bound in the module, just returns ‘#f’.

 -- C Function: SCM scm_private_variable (SCM MODULE_NAME, SCM NAME)
 -- C Function: SCM scm_c_private_variable (const char *MODULE_NAME,
          const char *NAME)
     Like ‘scm_public_variable’, but looks in the internals of the
     module named MODULE_NAME instead of the public interface.
     Logically, these procedures should only be called on modules you
     write.

 -- C Function: SCM scm_public_lookup (SCM MODULE_NAME, SCM NAME)
 -- C Function: SCM scm_c_public_lookup (const char *MODULE_NAME, const
          char *NAME)
 -- C Function: SCM scm_private_lookup (SCM MODULE_NAME, SCM NAME)
 -- C Function: SCM scm_c_private_lookup (const char *MODULE_NAME, const
          char *NAME)
     Like ‘scm_public_variable’ or ‘scm_private_variable’, but if the
     NAME is not bound in the module, signals an error.  Returns a
     variable, always.

          static SCM eval_string_var;

          /* NOTE: It is important that the call to 'my_init'
             happens-before all calls to 'my_eval_string'. */
          void my_init (void)
          {
            eval_string_var = scm_c_public_lookup ("ice-9 eval-string",
                                                   "eval-string");
          }

          SCM my_eval_string (SCM str)
          {
            return scm_call_1 (scm_variable_ref (eval_string_var), str);
          }

 -- C Function: SCM scm_public_ref (SCM MODULE_NAME, SCM NAME)
 -- C Function: SCM scm_c_public_ref (const char *MODULE_NAME, const
          char *NAME)
 -- C Function: SCM scm_private_ref (SCM MODULE_NAME, SCM NAME)
 -- C Function: SCM scm_c_private_ref (const char *MODULE_NAME, const
          char *NAME)
     Like ‘scm_public_lookup’ or ‘scm_private_lookup’, but additionally
     dereferences the variable.  If the variable object is unbound,
     signals an error.  Returns the value bound to NAME in MODULE_NAME.

   In addition, there are a number of other lookup-related procedures.
We suggest that you use the ‘scm_public_’ and ‘scm_private_’ family of
procedures instead, if possible.

 -- C Function: SCM scm_c_lookup (const char *NAME)
     Return the variable bound to the symbol indicated by NAME in the
     current module.  If there is no such binding or the symbol is not
     bound to a variable, signal an error.

 -- C Function: SCM scm_lookup (SCM NAME)
     Like ‘scm_c_lookup’, but the symbol is specified directly.

 -- C Function: SCM scm_c_module_lookup (SCM MODULE, const char *NAME)
 -- C Function: SCM scm_module_lookup (SCM MODULE, SCM NAME)
     Like ‘scm_c_lookup’ and ‘scm_lookup’, but the specified module is
     used instead of the current one.

 -- C Function: SCM scm_module_variable (SCM MODULE, SCM NAME)
     Like ‘scm_module_lookup’, but if the binding does not exist, just
     returns ‘#f’ instead of raising an error.

   To define a value, use ‘scm_define’:

 -- C Function: SCM scm_c_define (const char *NAME, SCM VAL)
     Bind the symbol indicated by NAME to a variable in the current
     module and set that variable to VAL.  When NAME is already bound to
     a variable, use that.  Else create a new variable.

 -- C Function: SCM scm_define (SCM NAME, SCM VAL)
     Like ‘scm_c_define’, but the symbol is specified directly.

 -- C Function: SCM scm_c_module_define (SCM MODULE, const char *NAME,
          SCM VAL)
 -- C Function: SCM scm_module_define (SCM MODULE, SCM NAME, SCM VAL)
     Like ‘scm_c_define’ and ‘scm_define’, but the specified module is
     used instead of the current one.

   In some rare cases, you may need to access the variable that
‘scm_module_define’ would have accessed, without changing the binding of
the existing variable, if one is present.  In that case, use
‘scm_module_ensure_local_variable’:

 -- C Function: SCM scm_module_ensure_local_variable (SCM MODULE, SCM
          SYM)
     Like ‘scm_module_define’, but if the SYM is already locally bound
     in that module, the variable’s existing binding is not reset.
     Returns a variable.

 -- C Function: SCM scm_module_reverse_lookup (SCM MODULE, SCM VARIABLE)
     Find the symbol that is bound to VARIABLE in MODULE.  When no such
     binding is found, return ‘#f’.

 -- C Function: SCM scm_c_define_module (const char *NAME, void
          (*INIT)(void *), void *DATA)
     Define a new module named NAME and make it current while INIT is
     called, passing it DATA.  Return the module.

     The parameter NAME is a string with the symbols that make up the
     module name, separated by spaces.  For example, ‘"foo bar"’ names
     the module ‘(foo bar)’.

     When there already exists a module named NAME, it is used
     unchanged, otherwise, an empty module is created.

 -- C Function: SCM scm_c_resolve_module (const char *NAME)
     Find the module name NAME and return it.  When it has not already
     been defined, try to auto-load it.  When it can’t be found that way
     either, create an empty module.  The name is interpreted as for
     ‘scm_c_define_module’.

 -- C Function: SCM scm_c_use_module (const char *NAME)
     Add the module named NAME to the uses list of the current module,
     as with ‘(use-modules NAME)’.  The name is interpreted as for
     ‘scm_c_define_module’.

 -- C Function: void scm_c_export (const char *NAME, ...)
     Add the bindings designated by NAME, ...  to the public interface
     of the current module.  The list of names is terminated by ‘NULL’.

6.19.10 provide and require
---------------------------

Aubrey Jaffer, mostly to support his portable Scheme library SLIB,
implemented a provide/require mechanism for many Scheme implementations.
Library files in SLIB _provide_ a feature, and when user programs
_require_ that feature, the library file is loaded in.

   For example, the file ‘random.scm’ in the SLIB package contains the
line

     (provide 'random)

   so to use its procedures, a user would type

     (require 'random)

   and they would magically become available, _but still have the same
names!_  So this method is nice, but not as good as a full-featured
module system.

   When SLIB is used with Guile, provide and require can be used to
access its facilities.

6.19.11 Environments
--------------------

Scheme, as defined in R5RS, does _not_ have a full module system.
However it does define the concept of a top-level “environment”.  Such
an environment maps identifiers (symbols) to Scheme objects such as
procedures and lists: About Closure.  In other words, it
implements a set of “bindings”.

   Environments in R5RS can be passed as the second argument to ‘eval’
(see Fly Evaluation).  Three procedures are defined to return
environments: ‘scheme-report-environment’, ‘null-environment’ and
‘interaction-environment’ (see Fly Evaluation).

   In addition, in Guile any module can be used as an R5RS environment,
i.e., passed as the second argument to ‘eval’.

   Note: the following two procedures are available only when the
‘(ice-9 r5rs)’ module is loaded:

     (use-modules (ice-9 r5rs))

 -- Scheme Procedure: scheme-report-environment version
 -- Scheme Procedure: null-environment version
     VERSION must be the exact integer ‘5’, corresponding to revision 5
     of the Scheme report (the Revised^5 Report on Scheme).
     ‘scheme-report-environment’ returns a specifier for an environment
     that is empty except for all bindings defined in the report that
     are either required or both optional and supported by the
     implementation.  ‘null-environment’ returns a specifier for an
     environment that is empty except for the (syntactic) bindings for
     all syntactic keywords defined in the report that are either
     required or both optional and supported by the implementation.

     Currently Guile does not support values of VERSION for other
     revisions of the report.

     The effect of assigning (through the use of ‘eval’) a variable
     bound in a ‘scheme-report-environment’ (for example ‘car’) is
     unspecified.  Currently the environments specified by
     ‘scheme-report-environment’ are not immutable in Guile.

6.20 Foreign Function Interface
===============================

The more one hacks in Scheme, the more one realizes that there are
actually two computational worlds: one which is warm and alive, that
land of parentheses, and one cold and dead, the land of C and its ilk.

   But yet we as programmers live in both worlds, and Guile itself is
half implemented in C. So it is that Guile’s living half pays respect to
its dead counterpart, via a spectrum of interfaces to C ranging from
dynamic loading of Scheme primitives to dynamic binding of stock C
library procedures.

6.20.1 Foreign Libraries
------------------------

Most modern Unices have something called “shared libraries”.  This
ordinarily means that they have the capability to share the executable
image of a library between several running programs to save memory and
disk space.  But generally, shared libraries give a lot of additional
flexibility compared to the traditional static libraries.  In fact,
calling them ‘dynamic’ libraries is as correct as calling them ‘shared’.

   Shared libraries really give you a lot of flexibility in addition to
the memory and disk space savings.  When you link a program against a
shared library, that library is not closely incorporated into the final
executable.  Instead, the executable of your program only contains
enough information to find the needed shared libraries when the program
is actually run.  Only then, when the program is starting, is the final
step of the linking process performed.  This means that you need not
recompile all programs when you install a new, only slightly modified
version of a shared library.  The programs will pick up the changes
automatically the next time they are run.

   Now, when all the necessary machinery is there to perform part of the
linking at run-time, why not take the next step and allow the programmer
to explicitly take advantage of it from within their program?  Of
course, many operating systems that support shared libraries do just
that, and chances are that Guile will allow you to access this feature
from within your Scheme programs.  As you might have guessed already,
this feature is called “dynamic linking”.(1)

   We titled this section “foreign libraries” because although the name
“foreign” doesn’t leak into the API, the world of C really is foreign to
Scheme – and that estrangement extends to components of foreign
libraries as well, as we see in future sections.

 -- Scheme Procedure: dynamic-link [library]
 -- C Function: scm_dynamic_link (library)
     Find the shared library denoted by LIBRARY (a string) and link it
     into the running Guile application.  When everything works out,
     return a Scheme object suitable for representing the linked object
     file.  Otherwise an error is thrown.  How object files are searched
     is system dependent.

     Normally, LIBRARY is just the name of some shared library file that
     will be searched for in the places where shared libraries usually
     reside, such as in ‘/usr/lib’ and ‘/usr/local/lib’.

     LIBRARY should not contain an extension such as ‘.so’.  The correct
     file name extension for the host operating system is provided
     automatically, according to libltdl’s rules (see lt_dlopenext (libtool)).

     When LIBRARY is omitted, a “global symbol handle” is returned.
     This handle provides access to the symbols available to the program
     at run-time, including those exported by the program itself and the
     shared libraries already loaded.

 -- Scheme Procedure: dynamic-object? obj
 -- C Function: scm_dynamic_object_p (obj)
     Return ‘#t’ if OBJ is a dynamic library handle, or ‘#f’ otherwise.

 -- Scheme Procedure: dynamic-unlink dobj
 -- C Function: scm_dynamic_unlink (dobj)
     Unlink the indicated object file from the application.  The
     argument DOBJ must have been obtained by a call to ‘dynamic-link’.
     After ‘dynamic-unlink’ has been called on DOBJ, its content is no
     longer accessible.

     (define libgl-obj (dynamic-link "libGL"))
     libgl-obj
     ⇒ #<dynamic-object "libGL">
     (dynamic-unlink libGL-obj)
     libGL-obj
     ⇒ #<dynamic-object "libGL" (unlinked)>

   As you can see, after calling ‘dynamic-unlink’ on a dynamically
linked library, it is marked as ‘(unlinked)’ and you are no longer able
to use it with ‘dynamic-call’, etc.  Whether the library is really
removed from you program is system-dependent and will generally not
happen when some other parts of your program still use it.

   When dynamic linking is disabled or not supported on your system, the
above functions throw errors, but they are still available.

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

   (1) Some people also refer to the final linking stage at program
startup as ‘dynamic linking’, so if you want to make yourself perfectly
clear, it is probably best to use the more technical term “dlopening”,
as suggested by Gordon Matzigkeit in his libtool documentation.

6.20.2 Foreign Functions
------------------------

The most natural thing to do with a dynamic library is to grovel around
in it for a function pointer: a “foreign function”.  ‘dynamic-func’
exists for that purpose.

 -- Scheme Procedure: dynamic-func name dobj
 -- C Function: scm_dynamic_func (name, dobj)
     Return a “handle” for the func NAME in the shared object referred
     to by DOBJ.  The handle can be passed to ‘dynamic-call’ to actually
     call the function.

     Regardless whether your C compiler prepends an underscore ‘_’ to
     the global names in a program, you should *not* include this
     underscore in NAME since it will be added automatically when
     necessary.

   Guile has static support for calling functions with no arguments,
‘dynamic-call’.

 -- Scheme Procedure: dynamic-call func dobj
 -- C Function: scm_dynamic_call (func, dobj)
     Call the C function indicated by FUNC and DOBJ.  The function is
     passed no arguments and its return value is ignored.  When FUNCTION
     is something returned by ‘dynamic-func’, call that function and
     ignore DOBJ.  When FUNC is a string , look it up in DYNOBJ; this is
     equivalent to
          (dynamic-call (dynamic-func FUNC DOBJ) #f)

   ‘dynamic-call’ is not very powerful.  It is mostly intended to be
used for calling specially written initialization functions that will
then add new primitives to Guile.  For example, we do not expect that
you will dynamically link ‘libX11’ with ‘dynamic-link’ and then
construct a beautiful graphical user interface just by using
‘dynamic-call’.  Instead, the usual way would be to write a special
Guile-to-X11 glue library that has intimate knowledge about both Guile
and X11 and does whatever is necessary to make them inter-operate
smoothly.  This glue library could then be dynamically linked into a
vanilla Guile interpreter and activated by calling its initialization
function.  That function would add all the new types and primitives to
the Guile interpreter that it has to offer.

   (There is actually another, better option: simply to create a
‘libX11’ wrapper in Scheme via the dynamic FFI. See Dynamic FFI, for
more information.)

   Given some set of C extensions to Guile, the next logical step is to
integrate these glue libraries into the module system of Guile so that
you can load new primitives into a running system just as you can load
new Scheme code.

 -- Scheme Procedure: load-extension lib init
 -- C Function: scm_load_extension (lib, init)
     Load and initialize the extension designated by LIB and INIT. When
     there is no pre-registered function for LIB/INIT, this is
     equivalent to

          (dynamic-call INIT (dynamic-link LIB))

     When there is a pre-registered function, that function is called
     instead.

     Normally, there is no pre-registered function.  This option exists
     only for situations where dynamic linking is unavailable or
     unwanted.  In that case, you would statically link your program
     with the desired library, and register its init function right
     after Guile has been initialized.

     As for ‘dynamic-link’, LIB should not contain any suffix such as
     ‘.so’ (see dynamic-link).  It should also not
     contain any directory components.  Libraries that implement Guile
     Extensions should be put into the normal locations for shared
     libraries.  We recommend to use the naming convention
     ‘libguile-bla-blum’ for a extension related to a module ‘(bla
     blum)’.

     The normal way for a extension to be used is to write a small
     Scheme file that defines a module, and to load the extension into
     this module.  When the module is auto-loaded, the extension is
     loaded as well.  For example,

          (define-module (bla blum))

          (load-extension "libguile-bla-blum" "bla_init_blum")

6.20.3 C Extensions
-------------------

The most interesting application of dynamically linked libraries is
probably to use them for providing _compiled code modules_ to Scheme
programs.  As much fun as programming in Scheme is, every now and then
comes the need to write some low-level C stuff to make Scheme even more
fun.

   Not only can you put these new primitives into their own module (see
the previous section), you can even put them into a shared library that
is only then linked to your running Guile image when it is actually
needed.

   An example will hopefully make everything clear.  Suppose we want to
make the Bessel functions of the C library available to Scheme in the
module ‘(math bessel)’.  First we need to write the appropriate glue
code to convert the arguments and return values of the functions from
Scheme to C and back.  Additionally, we need a function that will add
them to the set of Guile primitives.  Because this is just an example,
we will only implement this for the ‘j0’ function.

     #include <math.h>
     #include <libguile.h>

     SCM
     j0_wrapper (SCM x)
     {
       return scm_from_double (j0 (scm_to_double (x, "j0")));
     }

     void
     init_math_bessel ()
     {
       scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper);
     }

   We can already try to bring this into action by manually calling the
low level functions for performing dynamic linking.  The C source file
needs to be compiled into a shared library.  Here is how to do it on
GNU/Linux, please refer to the ‘libtool’ documentation for how to create
dynamically linkable libraries portably.

     gcc -shared -o libbessel.so -fPIC bessel.c

   Now fire up Guile:

     (define bessel-lib (dynamic-link "./libbessel.so"))
     (dynamic-call "init_math_bessel" bessel-lib)
     (j0 2)
     ⇒ 0.223890779141236

   The filename ‘./libbessel.so’ should be pointing to the shared
library produced with the ‘gcc’ command above, of course.  The second
line of the Guile interaction will call the ‘init_math_bessel’ function
which in turn will register the C function ‘j0_wrapper’ with the Guile
interpreter under the name ‘j0’.  This function becomes immediately
available and we can call it from Scheme.

   Fun, isn’t it?  But we are only half way there.  This is what
‘apropos’ has to say about ‘j0’:

     (apropos "j0")
     ⊣ (guile-user): j0     #<primitive-procedure j0>

   As you can see, ‘j0’ is contained in the root module, where all the
other Guile primitives like ‘display’, etc live.  In general, a
primitive is put into whatever module is the “current module” at the
time ‘scm_c_define_gsubr’ is called.

   A compiled module should have a specially named “module init
function”.  Guile knows about this special name and will call that
function automatically after having linked in the shared library.  For
our example, we replace ‘init_math_bessel’ with the following code in
‘bessel.c’:

     void
     init_math_bessel (void *unused)
     {
       scm_c_define_gsubr ("j0", 1, 0, 0, j0_wrapper);
       scm_c_export ("j0", NULL);
     }

     void
     scm_init_math_bessel_module ()
     {
       scm_c_define_module ("math bessel", init_math_bessel, NULL);
     }

   The general pattern for the name of a module init function is:
‘scm_init_’, followed by the name of the module where the individual
hierarchical components are concatenated with underscores, followed by
‘_module’.

   After ‘libbessel.so’ has been rebuilt, we need to place the shared
library into the right place.

   Once the module has been correctly installed, it should be possible
to use it like this:

     guile> (load-extension "./libbessel.so" "scm_init_math_bessel_module")
     guile> (use-modules (math bessel))
     guile> (j0 2)
     0.223890779141236
     guile> (apropos "j0")
     ⊣ (math bessel): j0      #<primitive-procedure j0>

   That’s it!

6.20.4 Modules and Extensions
-----------------------------

The new primitives that you add to Guile with ‘scm_c_define_gsubr’
(see Primitive Procedures) or with any of the other mechanisms are
placed into the module that is current when the ‘scm_c_define_gsubr’ is
executed.  Extensions loaded from the REPL, for example, will be placed
into the ‘(guile-user)’ module, if the REPL module was not changed.

   To define C primitives within a specific module, the simplest way is:

     (define-module (foo bar))
     (load-extension "foobar-c-code" "foo_bar_init")

   When loaded with ‘(use-modules (foo bar))’, the ‘load-extension’ call
looks for the ‘foobar-c-code.so’ (etc) object file in Guile’s
‘extensiondir’, which is usually a subdirectory of the ‘libdir’.  For
example, if your libdir is ‘/usr/lib’, the ‘extensiondir’ for the Guile
2.0.X series will be ‘/usr/lib/guile/2.0/’.

   The extension path includes the major and minor version of Guile (the
“effective version”), because Guile guarantees compatibility within a
given effective version.  This allows you to install different versions
of the same extension for different versions of Guile.

   If the extension is not found in the ‘extensiondir’, Guile will also
search the standard system locations, such as ‘/usr/lib’ or
‘/usr/local/lib’.  It is preferable, however, to keep your extension out
of the system library path, to prevent unintended interference with
other dynamically-linked C libraries.

   If someone installs your module to a non-standard location then the
object file won’t be found.  You can address this by inserting the
install location in the ‘foo/bar.scm’ file.  This is convenient for the
user and also guarantees the intended object is read, even if stray
older or newer versions are in the loader’s path.

   The usual way to specify an install location is with a ‘prefix’ at
the configure stage, for instance ‘./configure prefix=/opt’ results in
library files as say ‘/opt/lib/foobar-c-code.so’.  When using Autoconf
(see Introduction (autoconf)), the library location is in a
‘libdir’ variable.  Its value is intended to be expanded by ‘make’, and
can by substituted into a source file like ‘foo.scm.in’

     (define-module (foo bar))
     (load-extension "XXextensiondirXX/foobar-c-code" "foo_bar_init")

with the following in a ‘Makefile’, using ‘sed’ (see Introduction (sed)),

     foo.scm: foo.scm.in
             sed 's|XXextensiondirXX|$(libdir)/guile/2.0|' <foo.scm.in >foo.scm

   The actual pattern ‘XXextensiondirXX’ is arbitrary, it’s only
something which doesn’t otherwise occur.  If several modules need the
value, it can be easier to create one ‘foo/config.scm’ with a define of
the ‘extensiondir’ location, and use that as required.

     (define-module (foo config))
     (define-public foo-config-extensiondir "XXextensiondirXX"")

   Such a file might have other locations too, for instance a data
directory for auxiliary files, or ‘localedir’ if the module has its own
‘gettext’ message catalogue (see Internationalization).

   It will be noted all of the above requires that the Scheme code to be
found in ‘%load-path’ (see Load Paths).  Presently it’s left up to
the system administrator or each user to augment that path when
installing Guile modules in non-default locations.  But having reached
the Scheme code, that code should take care of hitting any of its own
private files etc.

6.20.5 Foreign Pointers
-----------------------

The previous sections have shown how Guile can be extended at runtime by
loading compiled C extensions.  This approach is all well and good, but
wouldn’t it be nice if we didn’t have to write any C at all?  This
section takes up the problem of accessing C values from Scheme, and the
next discusses C functions.

6.20.5.1 Foreign Types
......................

The first impedance mismatch that one sees between C and Scheme is that
in C, the storage locations (variables) are typed, but in Scheme types
are associated with values, not variables.  See Values and Variables.

   So when describing a C function or a C structure so that it can be
accessed from Scheme, the data types of the parameters or fields must be
passed explicitly.

   These “C type values” may be constructed using the constants and
procedures from the ‘(system foreign)’ module, which may be loaded like
this:

     (use-modules (system foreign))

   ‘(system foreign)’ exports a number of values expressing the basic C
types:

 -- Scheme Variable: int8
 -- Scheme Variable: uint8
 -- Scheme Variable: uint16
 -- Scheme Variable: int16
 -- Scheme Variable: uint32
 -- Scheme Variable: int32
 -- Scheme Variable: uint64
 -- Scheme Variable: int64
 -- Scheme Variable: float
 -- Scheme Variable: double
     These values represent the C numeric types of the specified sizes
     and signednesses.

   In addition there are some convenience bindings for indicating types
of platform-dependent size:

 -- Scheme Variable: int
 -- Scheme Variable: unsigned-int
 -- Scheme Variable: long
 -- Scheme Variable: unsigned-long
 -- Scheme Variable: size_t
 -- Scheme Variable: ssize_t
 -- Scheme Variable: ptrdiff_t
     Values exported by the ‘(system foreign)’ module, representing C
     numeric types.  For example, ‘long’ may be ‘equal?’ to ‘int64’ on a
     64-bit platform.

 -- Scheme Variable: void
     The ‘void’ type.  It can be used as the first argument to
     ‘pointer->procedure’ to wrap a C function that returns nothing.

   In addition, the symbol ‘*’ is used by convention to denote pointer
types.  Procedures detailed in the following sections, such as
‘pointer->procedure’, accept it as a type descriptor.

6.20.5.2 Foreign Variables
..........................

Pointers to variables in the current address space may be looked up
dynamically using ‘dynamic-pointer’.

 -- Scheme Procedure: dynamic-pointer name dobj
 -- C Function: scm_dynamic_pointer (name, dobj)
     Return a “wrapped pointer” for the symbol NAME in the shared object
     referred to by DOBJ.  The returned pointer points to a C object.

     Regardless whether your C compiler prepends an underscore ‘_’ to
     the global names in a program, you should *not* include this
     underscore in NAME since it will be added automatically when
     necessary.

   For example, currently Guile has a variable, ‘scm_numptob’, as part
of its API. It is declared as a C ‘long’.  So, to create a handle
pointing to that foreign value, we do:

     (use-modules (system foreign))
     (define numptob (dynamic-pointer "scm_numptob" (dynamic-link)))
     numptob
     ⇒ #<pointer 0x7fb35b1b4688>

   (The next section discusses ways to dereference pointers.)

   A value returned by ‘dynamic-pointer’ is a Scheme wrapper for a C
pointer.

 -- Scheme Procedure: pointer-address pointer
 -- C Function: scm_pointer_address (pointer)
     Return the numerical value of POINTER.

          (pointer-address numptob)
          ⇒ 139984413364296 ; YMMV

 -- Scheme Procedure: make-pointer address [finalizer]
     Return a foreign pointer object pointing to ADDRESS.  If FINALIZER
     is passed, it should be a pointer to a one-argument C function that
     will be called when the pointer object becomes unreachable.

 -- Scheme Procedure: pointer? obj
     Return ‘#t’ if OBJ is a pointer object, ‘#f’ otherwise.

 -- Scheme Variable: %null-pointer
     A foreign pointer whose value is 0.

 -- Scheme Procedure: null-pointer? pointer
     Return ‘#t’ if POINTER is the null pointer, ‘#f’ otherwise.

   For the purpose of passing SCM values directly to foreign functions,
and allowing them to return SCM values, Guile also supports some unsafe
casting operators.

 -- Scheme Procedure: scm->pointer scm
     Return a foreign pointer object with the ‘object-address’ of SCM.

 -- Scheme Procedure: pointer->scm pointer
     Unsafely cast POINTER to a Scheme object.  Cross your fingers!

   Sometimes you want to give C extensions access to the dynamic FFI. At
that point, the names get confusing, because “pointer” can refer to a
‘SCM’ object that wraps a pointer, or to a ‘void*’ value.  We will try
to use “pointer object” to refer to Scheme objects, and “pointer value”
to refer to ‘void *’ values.

 -- C Function: SCM scm_from_pointer (void *ptr, void (*finalizer)
          (void*))
     Create a pointer object from a pointer value.

     If FINALIZER is non-null, Guile arranges to call it on the pointer
     value at some point after the pointer object becomes collectable.

 -- C Function: void* scm_to_pointer (SCM obj)
     Unpack the pointer value from a pointer object.

6.20.5.3 Void Pointers and Byte Access
......................................

Wrapped pointers are untyped, so they are essentially equivalent to C
‘void’ pointers.  As in C, the memory region pointed to by a pointer can
be accessed at the byte level.  This is achieved using _bytevectors_
(see Bytevectors).  The ‘(rnrs bytevectors)’ module contains
procedures that can be used to convert byte sequences to Scheme objects
such as strings, floating point numbers, or integers.

 -- Scheme Procedure: pointer->bytevector pointer len [offset
          [uvec_type]]
 -- C Function: scm_pointer_to_bytevector (pointer, len, offset,
          uvec_type)
     Return a bytevector aliasing the LEN bytes pointed to by POINTER.

     The user may specify an alternate default interpretation for the
     memory by passing the UVEC_TYPE argument, to indicate that the
     memory is an array of elements of that type.  UVEC_TYPE should be
     something that ‘array-type’ would return, like ‘f32’ or ‘s16’.

     When OFFSET is passed, it specifies the offset in bytes relative to
     POINTER of the memory region aliased by the returned bytevector.

     Mutating the returned bytevector mutates the memory pointed to by
     POINTER, so buckle your seatbelts.

 -- Scheme Procedure: bytevector->pointer bv [offset]
 -- C Function: scm_bytevector_to_pointer (bv, offset)
     Return a pointer pointer aliasing the memory pointed to by BV or
     OFFSET bytes after BV when OFFSET is passed.

   In addition to these primitives, convenience procedures are
available:

 -- Scheme Procedure: dereference-pointer pointer
     Assuming POINTER points to a memory region that holds a pointer,
     return this pointer.

 -- Scheme Procedure: string->pointer string [encoding]
     Return a foreign pointer to a nul-terminated copy of STRING in the
     given ENCODING, defaulting to the current locale encoding.  The C
     string is freed when the returned foreign pointer becomes
     unreachable.

     This is the Scheme equivalent of ‘scm_to_stringn’.

 -- Scheme Procedure: pointer->string pointer [length] [encoding]
     Return the string representing the C string pointed to by POINTER.
     If LENGTH is omitted or ‘-1’, the string is assumed to be
     nul-terminated.  Otherwise LENGTH is the number of bytes in memory
     pointed to by POINTER.  The C string is assumed to be in the given
     ENCODING, defaulting to the current locale encoding.

     This is the Scheme equivalent of ‘scm_from_stringn’.

   Most object-oriented C libraries use pointers to specific data
structures to identify objects.  It is useful in such cases to reify the
different pointer types as disjoint Scheme types.  The
‘define-wrapped-pointer-type’ macro simplifies this.

 -- Scheme Syntax: define-wrapped-pointer-type type-name pred wrap
          unwrap print
     Define helper procedures to wrap pointer objects into Scheme
     objects with a disjoint type.  Specifically, this macro defines:

        • PRED, a predicate for the new Scheme type;
        • WRAP, a procedure that takes a pointer object and returns an
          object that satisfies PRED;
        • UNWRAP, which does the reverse.

     WRAP preserves pointer identity, for two pointer objects P1 and P2
     that are ‘equal?’, ‘(eq? (WRAP P1) (WRAP P2)) ⇒ #t’.

     Finally, PRINT should name a user-defined procedure to print such
     objects.  The procedure is passed the wrapped object and a port to
     write to.

     For example, assume we are wrapping a C library that defines a
     type, ‘bottle_t’, and functions that can be passed ‘bottle_t *’
     pointers to manipulate them.  We could write:

          (define-wrapped-pointer-type bottle
            bottle?
            wrap-bottle unwrap-bottle
            (lambda (b p)
              (format p "#<bottle of ~a ~x>"
                      (bottle-contents b)
                      (pointer-address (unwrap-bottle b)))))

          (define grab-bottle
            ;; Wrapper for `bottle_t *grab (void)'.
            (let ((grab (pointer->procedure '*
                                            (dynamic-func "grab_bottle" libbottle)
                                            '())))
              (lambda ()
                "Return a new bottle."
                (wrap-bottle (grab)))))

          (define bottle-contents
            ;; Wrapper for `const char *bottle_contents (bottle_t *)'.
            (let ((contents (pointer->procedure '*
                                                (dynamic-func "bottle_contents"
                                                               libbottle)
                                                '(*))))
              (lambda (b)
                "Return the contents of B."
                (pointer->string (contents (unwrap-bottle b))))))

          (write (grab-bottle))
          ⇒ #<bottle of Château Haut-Brion 803d36>

     In this example, ‘grab-bottle’ is guaranteed to return a genuine
     ‘bottle’ object satisfying ‘bottle?’.  Likewise, ‘bottle-contents’
     errors out when its argument is not a genuine ‘bottle’ object.

   Going back to the ‘scm_numptob’ example above, here is how we can
read its value as a C ‘long’ integer:

     (use-modules (rnrs bytevectors))

     (bytevector-uint-ref (pointer->bytevector numptob (sizeof long))
                          0 (native-endianness)
                          (sizeof long))
     ⇒ 8

   If we wanted to corrupt Guile’s internal state, we could set
‘scm_numptob’ to another value; but we shouldn’t, because that variable
is not meant to be set.  Indeed this point applies more widely: the C
API is a dangerous place to be.  Not only might setting a value crash
your program, simply accessing the data pointed to by a dangling pointer
or similar can prove equally disastrous.

6.20.5.4 Foreign Structs
........................

Finally, one last note on foreign values before moving on to actually
calling foreign functions.  Sometimes you need to deal with C structs,
which requires interpreting each element of the struct according to the
its type, offset, and alignment.  Guile has some primitives to support
this.

 -- Scheme Procedure: sizeof type
 -- C Function: scm_sizeof (type)
     Return the size of TYPE, in bytes.

     TYPE should be a valid C type, like ‘int’.  Alternately TYPE may be
     the symbol ‘*’, in which case the size of a pointer is returned.
     TYPE may also be a list of types, in which case the size of a
     ‘struct’ with ABI-conventional packing is returned.

 -- Scheme Procedure: alignof type
 -- C Function: scm_alignof (type)
     Return the alignment of TYPE, in bytes.

     TYPE should be a valid C type, like ‘int’.  Alternately TYPE may be
     the symbol ‘*’, in which case the alignment of a pointer is
     returned.  TYPE may also be a list of types, in which case the
     alignment of a ‘struct’ with ABI-conventional packing is returned.

   Guile also provides some convenience methods to pack and unpack
foreign pointers wrapping C structs.

 -- Scheme Procedure: make-c-struct types vals
     Create a foreign pointer to a C struct containing VALS with types
     ‘types’.

     VALS and ‘types’ should be lists of the same length.

 -- Scheme Procedure: parse-c-struct foreign types
     Parse a foreign pointer to a C struct, returning a list of values.

     ‘types’ should be a list of C types.

   For example, to create and parse the equivalent of a ‘struct {
int64_t a; uint8_t b; }’:

     (parse-c-struct (make-c-struct (list int64 uint8)
                                    (list 300 43))
                     (list int64 uint8))
     ⇒ (300 43)

   As yet, Guile only has convenience routines to support
conventionally-packed structs.  But given the ‘bytevector->pointer’ and
‘pointer->bytevector’ routines, one can create and parse tightly packed
structs and unions by hand.  See the code for ‘(system foreign)’ for
details.

6.20.6 Dynamic FFI
------------------

Of course, the land of C is not all nouns and no verbs: there are
functions too, and Guile allows you to call them.

 -- Scheme Procedure: pointer->procedure return_type func_ptr arg_types
          [#:return-errno?=#f]
 -- C Function: scm_pointer_to_procedure (return_type, func_ptr,
          arg_types)
 -- C Function: scm_pointer_to_procedure_with_errno (return_type,
          func_ptr, arg_types)

     Make a foreign function.

     Given the foreign void pointer FUNC_PTR, its argument and return
     types ARG_TYPES and RETURN_TYPE, return a procedure that will pass
     arguments to the foreign function and return appropriate values.

     ARG_TYPES should be a list of foreign types.  ‘return_type’ should
     be a foreign type.  See Foreign Types, for more information on
     foreign types.

     If RETURN-ERRNO? is true, or when calling
     ‘scm_pointer_to_procedure_with_errno’, the returned procedure will
     return two values, with ‘errno’ as the second value.

   Here is a better definition of ‘(math bessel)’:

     (define-module (math bessel)
       #:use-module (system foreign)
       #:export (j0))

     (define libm (dynamic-link "libm"))

     (define j0
       (pointer->procedure double
                           (dynamic-func "j0" libm)
                           (list double)))

   That’s it!  No C at all.

   Numeric arguments and return values from foreign functions are
represented as Scheme values.  For example, ‘j0’ in the above example
takes a Scheme number as its argument, and returns a Scheme number.

   Pointers may be passed to and returned from foreign functions as
well.  In that case the type of the argument or return value should be
the symbol ‘*’, indicating a pointer.  For example, the following code
makes ‘memcpy’ available to Scheme:

     (define memcpy
       (let ((this (dynamic-link)))
         (pointer->procedure '*
                             (dynamic-func "memcpy" this)
                             (list '* '* size_t))))

   To invoke ‘memcpy’, one must pass it foreign pointers:

     (use-modules (rnrs bytevectors))

     (define src-bits
       (u8-list->bytevector '(0 1 2 3 4 5 6 7)))
     (define src
       (bytevector->pointer src-bits))
     (define dest
       (bytevector->pointer (make-bytevector 16 0)))

     (memcpy dest src (bytevector-length src-bits))

     (bytevector->u8-list (pointer->bytevector dest 16))
     ⇒ (0 1 2 3 4 5 6 7 0 0 0 0 0 0 0 0)

   One may also pass structs as values, passing structs as foreign
pointers.  See Foreign Structs, for more information on how to
express struct types and struct values.

   “Out” arguments are passed as foreign pointers.  The memory pointed
to by the foreign pointer is mutated in place.

     ;; struct timeval {
     ;;      time_t      tv_sec;     /* seconds */
     ;;      suseconds_t tv_usec;    /* microseconds */
     ;; };
     ;; assuming fields are of type "long"

     (define gettimeofday
       (let ((f (pointer->procedure
                 int
                 (dynamic-func "gettimeofday" (dynamic-link))
                 (list '* '*)))
             (tv-type (list long long)))
         (lambda ()
           (let* ((timeval (make-c-struct tv-type (list 0 0)))
                  (ret (f timeval %null-pointer)))
             (if (zero? ret)
                 (apply values (parse-c-struct timeval tv-type))
                 (error "gettimeofday returned an error" ret))))))

     (gettimeofday)
     ⇒ 1270587589
     ⇒ 499553

   As you can see, this interface to foreign functions is at a very low,
somewhat dangerous level(1).

   The FFI can also work in the opposite direction: making Scheme
procedures callable from C. This makes it possible to use Scheme
procedures as “callbacks” expected by C function.

 -- Scheme Procedure: procedure->pointer return-type proc arg-types
 -- C Function: scm_procedure_to_pointer (return_type, proc, arg_types)
     Return a pointer to a C function of type RETURN-TYPE taking
     arguments of types ARG-TYPES (a list) and behaving as a proxy to
     procedure PROC.  Thus PROC’s arity, supported argument types, and
     return type should match RETURN-TYPE and ARG-TYPES.

   As an example, here’s how the C library’s ‘qsort’ array sorting
function can be made accessible to Scheme (see ‘qsort’ (libc)):

     (define qsort!
       (let ((qsort (pointer->procedure void
                                        (dynamic-func "qsort"
                                                      (dynamic-link))
                                        (list '* size_t size_t '*))))
         (lambda (bv compare)
           ;; Sort bytevector BV in-place according to comparison
           ;; procedure COMPARE.
           (let ((ptr (procedure->pointer int
                                          (lambda (x y)
                                            ;; X and Y are pointers so,
                                            ;; for convenience, dereference
                                            ;; them before calling COMPARE.
                                            (compare (dereference-uint8* x)
                                                     (dereference-uint8* y)))
                                          (list '* '*))))
             (qsort (bytevector->pointer bv)
                    (bytevector-length bv) 1 ;; we're sorting bytes
                    ptr)))))

     (define (dereference-uint8* ptr)
       ;; Helper function: dereference the byte pointed to by PTR.
       (let ((b (pointer->bytevector ptr 1)))
         (bytevector-u8-ref b 0)))

     (define bv
       ;; An unsorted array of bytes.
       (u8-list->bytevector '(7 1 127 3 5 4 77 2 9 0)))

     ;; Sort BV.
     (qsort! bv (lambda (x y) (- x y)))

     ;; Let's see what the sorted array looks like:
     (bytevector->u8-list bv)
     ⇒ (0 1 2 3 4 5 7 9 77 127)

   And voilà!

   Note that ‘procedure->pointer’ is not supported (and not defined) on
a few exotic architectures.  Thus, user code may need to check
‘(defined? 'procedure->pointer)’.  Nevertheless, it is available on many
architectures, including (as of libffi 3.0.9) x86, ia64, SPARC, PowerPC,
ARM, and MIPS, to name a few.

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

   (1) A contribution to Guile in the form of a high-level FFI would be
most welcome.

6.21 Threads, Mutexes, Asyncs and Dynamic Roots
===============================================

6.21.1 Arbiters
---------------

Arbiters are synchronization objects, they can be used by threads to
control access to a shared resource.  An arbiter can be locked to
indicate a resource is in use, and unlocked when done.

   An arbiter is like a light-weight mutex (see Mutexes and Condition Variables).
It uses less memory and may be faster, but there’s no way
for a thread to block waiting on an arbiter, it can only test and get
the status returned.

 -- Scheme Procedure: make-arbiter name
 -- C Function: scm_make_arbiter (name)
     Return an object of type arbiter and name NAME.  Its state is
     initially unlocked.  Arbiters are a way to achieve process
     synchronization.

 -- Scheme Procedure: try-arbiter arb
 -- C Function: scm_try_arbiter (arb)
     If ARB is unlocked, then lock it and return ‘#t’.  If ARB is
     already locked, then do nothing and return ‘#f’.

 -- Scheme Procedure: release-arbiter arb
 -- C Function: scm_release_arbiter (arb)
     If ARB is locked, then unlock it and return ‘#t’.  If ARB is
     already unlocked, then do nothing and return ‘#f’.

     Typical usage is for the thread which locked an arbiter to later
     release it, but that’s not required, any thread can release it.

6.21.2 Asyncs
-------------

Asyncs are a means of deferring the execution of Scheme code until it is
safe to do so.

   Guile provides two kinds of asyncs that share the basic concept but
are otherwise quite different: system asyncs and user asyncs.  System
asyncs are integrated into the core of Guile and are executed
automatically when the system is in a state to allow the execution of
Scheme code.  For example, it is not possible to execute Scheme code in
a POSIX signal handler, but such a signal handler can queue a system
async to be executed in the near future, when it is safe to do so.

   System asyncs can also be queued for threads other than the current
one.  This way, you can cause threads to asynchronously execute
arbitrary code.

   User asyncs offer a convenient means of queuing procedures for future
execution and triggering this execution.  They will not be executed
automatically.

6.21.2.1 System asyncs
......................

To cause the future asynchronous execution of a procedure in a given
thread, use ‘system-async-mark’.

   Automatic invocation of system asyncs can be temporarily disabled by
calling ‘call-with-blocked-asyncs’.  This function works by temporarily
increasing the _async blocking level_ of the current thread while a
given procedure is running.  The blocking level starts out at zero, and
whenever a safe point is reached, a blocking level greater than zero
will prevent the execution of queued asyncs.

   Analogously, the procedure ‘call-with-unblocked-asyncs’ will
temporarily decrease the blocking level of the current thread.  You can
use it when you want to disable asyncs by default and only allow them
temporarily.

   In addition to the C versions of ‘call-with-blocked-asyncs’ and
‘call-with-unblocked-asyncs’, C code can use ‘scm_dynwind_block_asyncs’
and ‘scm_dynwind_unblock_asyncs’ inside a “dynamic context” (see
Dynamic Wind) to block or unblock system asyncs temporarily.

 -- Scheme Procedure: system-async-mark proc [thread]
 -- C Function: scm_system_async_mark (proc)
 -- C Function: scm_system_async_mark_for_thread (proc, thread)
     Mark PROC (a procedure with zero arguments) for future execution in
     THREAD.  When PROC has already been marked for THREAD but has not
     been executed yet, this call has no effect.  When THREAD is
     omitted, the thread that called ‘system-async-mark’ is used.

     This procedure is not safe to be called from signal handlers.  Use
     ‘scm_sigaction’ or ‘scm_sigaction_for_thread’ to install signal
     handlers.

 -- Scheme Procedure: call-with-blocked-asyncs proc
 -- C Function: scm_call_with_blocked_asyncs (proc)
     Call PROC and block the execution of system asyncs by one level for
     the current thread while it is running.  Return the value returned
     by PROC.  For the first two variants, call PROC with no arguments;
     for the third, call it with DATA.

 -- C Function: void * scm_c_call_with_blocked_asyncs (void * (*proc)
          (void *data), void *data)
     The same but with a C function PROC instead of a Scheme thunk.

 -- Scheme Procedure: call-with-unblocked-asyncs proc
 -- C Function: scm_call_with_unblocked_asyncs (proc)
     Call PROC and unblock the execution of system asyncs by one level
     for the current thread while it is running.  Return the value
     returned by PROC.  For the first two variants, call PROC with no
     arguments; for the third, call it with DATA.

 -- C Function: void * scm_c_call_with_unblocked_asyncs (void *(*proc)
          (void *data), void *data)
     The same but with a C function PROC instead of a Scheme thunk.

 -- C Function: void scm_dynwind_block_asyncs ()
     During the current dynwind context, increase the blocking of asyncs
     by one level.  This function must be used inside a pair of calls to
     ‘scm_dynwind_begin’ and ‘scm_dynwind_end’ (see Dynamic Wind).

 -- C Function: void scm_dynwind_unblock_asyncs ()
     During the current dynwind context, decrease the blocking of asyncs
     by one level.  This function must be used inside a pair of calls to
     ‘scm_dynwind_begin’ and ‘scm_dynwind_end’ (see Dynamic Wind).

6.21.2.2 User asyncs
....................

A user async is a pair of a thunk (a parameterless procedure) and a
mark.  Setting the mark on a user async will cause the thunk to be
executed when the user async is passed to ‘run-asyncs’.  Setting the
mark more than once is satisfied by one execution of the thunk.

   User asyncs are created with ‘async’.  They are marked with
‘async-mark’.

 -- Scheme Procedure: async thunk
 -- C Function: scm_async (thunk)
     Create a new user async for the procedure THUNK.

 -- Scheme Procedure: async-mark a
 -- C Function: scm_async_mark (a)
     Mark the user async A for future execution.

 -- Scheme Procedure: run-asyncs list_of_a
 -- C Function: scm_run_asyncs (list_of_a)
     Execute all thunks from the marked asyncs of the list LIST_OF_A.

6.21.3 Threads
--------------

Guile supports POSIX threads, unless it was configured with
‘--without-threads’ or the host lacks POSIX thread support.  When thread
support is available, the ‘threads’ feature is provided (see
‘provided?’).

   The procedures below manipulate Guile threads, which are wrappers
around the system’s POSIX threads.  For application-level parallelism,
using higher-level constructs, such as futures, is recommended (see
Futures).

 -- Scheme Procedure: all-threads
 -- C Function: scm_all_threads ()
     Return a list of all threads.

 -- Scheme Procedure: current-thread
 -- C Function: scm_current_thread ()
     Return the thread that called this function.

 -- Scheme Procedure: call-with-new-thread thunk [handler]
     Call ‘thunk’ in a new thread and with a new dynamic state,
     returning the new thread.  The procedure THUNK is called via
     ‘with-continuation-barrier’.

     When HANDLER is specified, then THUNK is called from within a
     ‘catch’ with tag ‘#t’ that has HANDLER as its handler.  This catch
     is established inside the continuation barrier.

     Once THUNK or HANDLER returns, the return value is made the _exit
     value_ of the thread and the thread is terminated.

 -- C Function: SCM scm_spawn_thread (scm_t_catch_body body, void
          *body_data, scm_t_catch_handler handler, void *handler_data)
     Call BODY in a new thread, passing it BODY_DATA, returning the new
     thread.  The function BODY is called via
     ‘scm_c_with_continuation_barrier’.

     When HANDLER is non-‘NULL’, BODY is called via ‘scm_internal_catch’
     with tag ‘SCM_BOOL_T’ that has HANDLER and HANDLER_DATA as the
     handler and its data.  This catch is established inside the
     continuation barrier.

     Once BODY or HANDLER returns, the return value is made the _exit
     value_ of the thread and the thread is terminated.

 -- Scheme Procedure: thread? obj
 -- C Function: scm_thread_p (obj)
     Return ‘#t’ ff OBJ is a thread; otherwise, return ‘#f’.

 -- Scheme Procedure: join-thread thread [timeout [timeoutval]]
 -- C Function: scm_join_thread (thread)
 -- C Function: scm_join_thread_timed (thread, timeout, timeoutval)
     Wait for THREAD to terminate and return its exit value.  Threads
     that have not been created with ‘call-with-new-thread’ or
     ‘scm_spawn_thread’ have an exit value of ‘#f’.  When TIMEOUT is
     given, it specifies a point in time where the waiting should be
     aborted.  It can be either an integer as returned by ‘current-time’
     or a pair as returned by ‘gettimeofday’.  When the waiting is
     aborted, TIMEOUTVAL is returned (if it is specified; ‘#f’ is
     returned otherwise).

 -- Scheme Procedure: thread-exited? thread
 -- C Function: scm_thread_exited_p (thread)
     Return ‘#t’ if THREAD has exited, or ‘#f’ otherwise.

 -- Scheme Procedure: yield
     If one or more threads are waiting to execute, calling yield forces
     an immediate context switch to one of them.  Otherwise, yield has
     no effect.

 -- Scheme Procedure: cancel-thread thread
 -- C Function: scm_cancel_thread (thread)
     Asynchronously notify THREAD to exit.  Immediately after receiving
     this notification, THREAD will call its cleanup handler (if one has
     been set) and then terminate, aborting any evaluation that is in
     progress.

     Because Guile threads are isomorphic with POSIX threads, THREAD
     will not receive its cancellation signal until it reaches a
     cancellation point.  See your operating system’s POSIX threading
     documentation for more information on cancellation points; note
     that in Guile, unlike native POSIX threads, a thread can receive a
     cancellation notification while attempting to lock a mutex.

 -- Scheme Procedure: set-thread-cleanup! thread proc
 -- C Function: scm_set_thread_cleanup_x (thread, proc)
     Set PROC as the cleanup handler for the thread THREAD.  PROC, which
     must be a thunk, will be called when THREAD exits, either normally
     or by being canceled.  Thread cleanup handlers can be used to
     perform useful tasks like releasing resources, such as locked
     mutexes, when thread exit cannot be predicted.

     The return value of PROC will be set as the _exit value_ of THREAD.

     To remove a cleanup handler, pass ‘#f’ for PROC.

 -- Scheme Procedure: thread-cleanup thread
 -- C Function: scm_thread_cleanup (thread)
     Return the cleanup handler currently installed for the thread
     THREAD.  If no cleanup handler is currently installed,
     thread-cleanup returns ‘#f’.

   Higher level thread procedures are available by loading the ‘(ice-9
threads)’ module.  These provide standardized thread creation.

 -- macro: make-thread proc arg ...
     Apply PROC to ARG ... in a new thread formed by
     ‘call-with-new-thread’ using a default error handler that display
     the error to the current error port.  The ARG ... expressions are
     evaluated in the new thread.

 -- macro: begin-thread expr1 expr2 ...
     Evaluate forms EXPR1 EXPR2 ... in a new thread formed by
     ‘call-with-new-thread’ using a default error handler that display
     the error to the current error port.

6.21.4 Mutexes and Condition Variables
--------------------------------------

A mutex is a thread synchronization object, it can be used by threads to
control access to a shared resource.  A mutex can be locked to indicate
a resource is in use, and other threads can then block on the mutex to
wait for the resource (or can just test and do something else if not
available).  “Mutex” is short for “mutual exclusion”.

   There are two types of mutexes in Guile, “standard” and “recursive”.
They’re created by ‘make-mutex’ and ‘make-recursive-mutex’ respectively,
the operation functions are then common to both.

   Note that for both types of mutex there’s no protection against a
“deadly embrace”.  For instance if one thread has locked mutex A and is
waiting on mutex B, but another thread owns B and is waiting on A, then
an endless wait will occur (in the current implementation).  Acquiring
requisite mutexes in a fixed order (like always A before B) in all
threads is one way to avoid such problems.

 -- Scheme Procedure: make-mutex flag ...
 -- C Function: scm_make_mutex ()
 -- C Function: scm_make_mutex_with_flags (SCM flags)
     Return a new mutex.  It is initially unlocked.  If FLAG ... is
     specified, it must be a list of symbols specifying configuration
     flags for the newly-created mutex.  The supported flags are:
     ‘unchecked-unlock’
          Unless this flag is present, a call to ‘unlock-mutex’ on the
          returned mutex when it is already unlocked will cause an error
          to be signalled.

     ‘allow-external-unlock’
          Allow the returned mutex to be unlocked by the calling thread
          even if it was originally locked by a different thread.

     ‘recursive’
          The returned mutex will be recursive.

 -- Scheme Procedure: mutex? obj
 -- C Function: scm_mutex_p (obj)
     Return ‘#t’ if OBJ is a mutex; otherwise, return ‘#f’.

 -- Scheme Procedure: make-recursive-mutex
 -- C Function: scm_make_recursive_mutex ()
     Create a new recursive mutex.  It is initially unlocked.  Calling
     this function is equivalent to calling ‘make-mutex’ and specifying
     the ‘recursive’ flag.

 -- Scheme Procedure: lock-mutex mutex [timeout [owner]]
 -- C Function: scm_lock_mutex (mutex)
 -- C Function: scm_lock_mutex_timed (mutex, timeout, owner)
     Lock MUTEX.  If the mutex is already locked, then block and return
     only when MUTEX has been acquired.

     When TIMEOUT is given, it specifies a point in time where the
     waiting should be aborted.  It can be either an integer as returned
     by ‘current-time’ or a pair as returned by ‘gettimeofday’.  When
     the waiting is aborted, ‘#f’ is returned.

     When OWNER is given, it specifies an owner for MUTEX other than the
     calling thread.  OWNER may also be ‘#f’, indicating that the mutex
     should be locked but left unowned.

     For standard mutexes (‘make-mutex’), and error is signalled if the
     thread has itself already locked MUTEX.

     For a recursive mutex (‘make-recursive-mutex’), if the thread has
     itself already locked MUTEX, then a further ‘lock-mutex’ call
     increments the lock count.  An additional ‘unlock-mutex’ will be
     required to finally release.

     If MUTEX was locked by a thread that exited before unlocking it,
     the next attempt to lock MUTEX will succeed, but
     ‘abandoned-mutex-error’ will be signalled.

     When a system async (see System asyncs) is activated for a
     thread blocked in ‘lock-mutex’, the wait is interrupted and the
     async is executed.  When the async returns, the wait resumes.

 -- C Function: void scm_dynwind_lock_mutex (SCM mutex)
     Arrange for MUTEX to be locked whenever the current dynwind context
     is entered and to be unlocked when it is exited.

 -- Scheme Procedure: try-mutex mx
 -- C Function: scm_try_mutex (mx)
     Try to lock MUTEX as per ‘lock-mutex’.  If MUTEX can be acquired
     immediately then this is done and the return is ‘#t’.  If MUTEX is
     locked by some other thread then nothing is done and the return is
     ‘#f’.

 -- Scheme Procedure: unlock-mutex mutex [condvar [timeout]]
 -- C Function: scm_unlock_mutex (mutex)
 -- C Function: scm_unlock_mutex_timed (mutex, condvar, timeout)
     Unlock MUTEX.  An error is signalled if MUTEX is not locked and was
     not created with the ‘unchecked-unlock’ flag set, or if MUTEX is
     locked by a thread other than the calling thread and was not
     created with the ‘allow-external-unlock’ flag set.

     If CONDVAR is given, it specifies a condition variable upon which
     the calling thread will wait to be signalled before returning.
     (This behavior is very similar to that of
     ‘wait-condition-variable’, except that the mutex is left in an
     unlocked state when the function returns.)

     When TIMEOUT is also given and not false, it specifies a point in
     time where the waiting should be aborted.  It can be either an
     integer as returned by ‘current-time’ or a pair as returned by
     ‘gettimeofday’.  When the waiting is aborted, ‘#f’ is returned.
     Otherwise the function returns ‘#t’.

 -- Scheme Procedure: mutex-owner mutex
 -- C Function: scm_mutex_owner (mutex)
     Return the current owner of MUTEX, in the form of a thread or ‘#f’
     (indicating no owner).  Note that a mutex may be unowned but still
     locked.

 -- Scheme Procedure: mutex-level mutex
 -- C Function: scm_mutex_level (mutex)
     Return the current lock level of MUTEX.  If MUTEX is currently
     unlocked, this value will be 0; otherwise, it will be the number of
     times MUTEX has been recursively locked by its current owner.

 -- Scheme Procedure: mutex-locked? mutex
 -- C Function: scm_mutex_locked_p (mutex)
     Return ‘#t’ if MUTEX is locked, regardless of ownership; otherwise,
     return ‘#f’.

 -- Scheme Procedure: make-condition-variable
 -- C Function: scm_make_condition_variable ()
     Return a new condition variable.

 -- Scheme Procedure: condition-variable? obj
 -- C Function: scm_condition_variable_p (obj)
     Return ‘#t’ if OBJ is a condition variable; otherwise, return ‘#f’.

 -- Scheme Procedure: wait-condition-variable condvar mutex [time]
 -- C Function: scm_wait_condition_variable (condvar, mutex, time)
     Wait until CONDVAR has been signalled.  While waiting, MUTEX is
     atomically unlocked (as with ‘unlock-mutex’) and is locked again
     when this function returns.  When TIME is given, it specifies a
     point in time where the waiting should be aborted.  It can be
     either a integer as returned by ‘current-time’ or a pair as
     returned by ‘gettimeofday’.  When the waiting is aborted, ‘#f’ is
     returned.  When the condition variable has in fact been signalled,
     ‘#t’ is returned.  The mutex is re-locked in any case before
     ‘wait-condition-variable’ returns.

     When a system async is activated for a thread that is blocked in a
     call to ‘wait-condition-variable’, the waiting is interrupted, the
     mutex is locked, and the async is executed.  When the async
     returns, the mutex is unlocked again and the waiting is resumed.
     When the thread block while re-acquiring the mutex, execution of
     asyncs is blocked.

 -- Scheme Procedure: signal-condition-variable condvar
 -- C Function: scm_signal_condition_variable (condvar)
     Wake up one thread that is waiting for CONDVAR.

 -- Scheme Procedure: broadcast-condition-variable condvar
 -- C Function: scm_broadcast_condition_variable (condvar)
     Wake up all threads that are waiting for CONDVAR.

   The following are higher level operations on mutexes.  These are
available from

     (use-modules (ice-9 threads))

 -- macro: with-mutex mutex body1 body2 ...
     Lock MUTEX, evaluate the body BODY1 BODY2 ..., then unlock MUTEX.
     The return value is that returned by the last body form.

     The lock, body and unlock form the branches of a ‘dynamic-wind’
     (see Dynamic Wind), so MUTEX is automatically unlocked if an
     error or new continuation exits the body, and is re-locked if the
     body is re-entered by a captured continuation.

 -- macro: monitor body1 body2 ...
     Evaluate the body form BODY1 BODY2 ... with a mutex locked so only
     one thread can execute that code at any one time.  The return value
     is the return from the last body form.

     Each ‘monitor’ form has its own private mutex and the locking and
     evaluation is as per ‘with-mutex’ above.  A standard mutex
     (‘make-mutex’) is used, which means the body must not recursively
     re-enter the ‘monitor’ form.

     The term “monitor” comes from operating system theory, where it
     means a particular bit of code managing access to some resource and
     which only ever executes on behalf of one process at any one time.

6.21.5 Blocking in Guile Mode
-----------------------------

Up to Guile version 1.8, a thread blocked in guile mode would prevent
the garbage collector from running.  Thus threads had to explicitly
leave guile mode with ‘scm_without_guile ()’ before making a potentially
blocking call such as a mutex lock, a ‘select ()’ system call, etc.  The
following functions could be used to temporarily leave guile mode or to
perform some common blocking operations in a supported way.

   Starting from Guile 2.0, blocked threads no longer hinder garbage
collection.  Thus, the functions below are not needed anymore.  They can
still be used to inform the GC that a thread is about to block, giving
it a (small) optimization opportunity for “stop the world” garbage
collections, should they occur while the thread is blocked.

 -- C Function: void * scm_without_guile (void *(*func) (void *), void
          *data)
     Leave guile mode, call FUNC on DATA, enter guile mode and return
     the result of calling FUNC.

     While a thread has left guile mode, it must not call any libguile
     functions except ‘scm_with_guile’ or ‘scm_without_guile’ and must
     not use any libguile macros.  Also, local variables of type ‘SCM’
     that are allocated while not in guile mode are not protected from
     the garbage collector.

     When used from non-guile mode, calling ‘scm_without_guile’ is still
     allowed: it simply calls FUNC.  In that way, you can leave guile
     mode without having to know whether the current thread is in guile
     mode or not.

 -- C Function: int scm_pthread_mutex_lock (pthread_mutex_t *mutex)
     Like ‘pthread_mutex_lock’, but leaves guile mode while waiting for
     the mutex.

 -- C Function: int scm_pthread_cond_wait (pthread_cond_t *cond,
          pthread_mutex_t *mutex)
 -- C Function: int scm_pthread_cond_timedwait (pthread_cond_t *cond,
          pthread_mutex_t *mutex, struct timespec *abstime)
     Like ‘pthread_cond_wait’ and ‘pthread_cond_timedwait’, but leaves
     guile mode while waiting for the condition variable.

 -- C Function: int scm_std_select (int nfds, fd_set *readfds, fd_set
          *writefds, fd_set *exceptfds, struct timeval *timeout)
     Like ‘select’ but leaves guile mode while waiting.  Also, the
     delivery of a system async causes this function to be interrupted
     with error code ‘EINTR’.

 -- C Function: unsigned int scm_std_sleep (unsigned int seconds)
     Like ‘sleep’, but leaves guile mode while sleeping.  Also, the
     delivery of a system async causes this function to be interrupted.

 -- C Function: unsigned long scm_std_usleep (unsigned long usecs)
     Like ‘usleep’, but leaves guile mode while sleeping.  Also, the
     delivery of a system async causes this function to be interrupted.

6.21.6 Critical Sections
------------------------

 -- C Macro: SCM_CRITICAL_SECTION_START
 -- C Macro: SCM_CRITICAL_SECTION_END
     These two macros can be used to delimit a critical section.
     Syntactically, they are both statements and need to be followed
     immediately by a semicolon.

     Executing ‘SCM_CRITICAL_SECTION_START’ will lock a recursive mutex
     and block the executing of system asyncs.  Executing
     ‘SCM_CRITICAL_SECTION_END’ will unblock the execution of system
     asyncs and unlock the mutex.  Thus, the code that executes between
     these two macros can only be executed in one thread at any one time
     and no system asyncs will run.  However, because the mutex is a
     recursive one, the code might still be reentered by the same
     thread.  You must either allow for this or avoid it, both by
     careful coding.

     On the other hand, critical sections delimited with these macros
     can be nested since the mutex is recursive.

     You must make sure that for each ‘SCM_CRITICAL_SECTION_START’, the
     corresponding ‘SCM_CRITICAL_SECTION_END’ is always executed.  This
     means that no non-local exit (such as a signalled error) might
     happen, for example.

 -- C Function: void scm_dynwind_critical_section (SCM mutex)
     Call ‘scm_dynwind_lock_mutex’ on MUTEX and call
     ‘scm_dynwind_block_asyncs’.  When MUTEX is false, a recursive mutex
     provided by Guile is used instead.

     The effect of a call to ‘scm_dynwind_critical_section’ is that the
     current dynwind context (see Dynamic Wind) turns into a
     critical section.  Because of the locked mutex, no second thread
     can enter it concurrently and because of the blocked asyncs, no
     system async can reenter it from the current thread.

     When the current thread reenters the critical section anyway, the
     kind of MUTEX determines what happens: When MUTEX is recursive, the
     reentry is allowed.  When it is a normal mutex, an error is
     signalled.

6.21.7 Fluids and Dynamic States
--------------------------------

A _fluid_ is an object that can store one value per _dynamic state_.
Each thread has a current dynamic state, and when accessing a fluid,
this current dynamic state is used to provide the actual value.  In this
way, fluids can be used for thread local storage, but they are in fact
more flexible: dynamic states are objects of their own and can be made
current for more than one thread at the same time, or only be made
current temporarily, for example.

   Fluids can also be used to simulate the desirable effects of
dynamically scoped variables.  Dynamically scoped variables are useful
when you want to set a variable to a value during some dynamic extent in
the execution of your program and have them revert to their original
value when the control flow is outside of this dynamic extent.  See the
description of ‘with-fluids’ below for details.

   New fluids are created with ‘make-fluid’ and ‘fluid?’ is used for
testing whether an object is actually a fluid.  The values stored in a
fluid can be accessed with ‘fluid-ref’ and ‘fluid-set!’.

 -- Scheme Procedure: make-fluid [dflt]
 -- C Function: scm_make_fluid ()
 -- C Function: scm_make_fluid_with_default (dflt)
     Return a newly created fluid, whose initial value is DFLT, or ‘#f’
     if DFLT is not given.  Fluids are objects that can hold one value
     per dynamic state.  That is, modifications to this value are only
     visible to code that executes with the same dynamic state as the
     modifying code.  When a new dynamic state is constructed, it
     inherits the values from its parent.  Because each thread normally
     executes with its own dynamic state, you can use fluids for thread
     local storage.

 -- Scheme Procedure: make-unbound-fluid
 -- C Function: scm_make_unbound_fluid ()
     Return a new fluid that is initially unbound (instead of being
     implicitly bound to some definite value).

 -- Scheme Procedure: fluid? obj
 -- C Function: scm_fluid_p (obj)
     Return ‘#t’ if OBJ is a fluid; otherwise, return ‘#f’.

 -- Scheme Procedure: fluid-ref fluid
 -- C Function: scm_fluid_ref (fluid)
     Return the value associated with FLUID in the current dynamic root.
     If FLUID has not been set, then return its default value.  Calling
     ‘fluid-ref’ on an unbound fluid produces a runtime error.

 -- Scheme Procedure: fluid-set! fluid value
 -- C Function: scm_fluid_set_x (fluid, value)
     Set the value associated with FLUID in the current dynamic root.

 -- Scheme Procedure: fluid-unset! fluid
 -- C Function: scm_fluid_unset_x (fluid)
     Disassociate the given fluid from any value, making it unbound.

 -- Scheme Procedure: fluid-bound? fluid
 -- C Function: scm_fluid_bound_p (fluid)
     Returns ‘#t’ if the given fluid is bound to a value, otherwise
     ‘#f’.

   ‘with-fluids*’ temporarily changes the values of one or more fluids,
so that the given procedure and each procedure called by it access the
given values.  After the procedure returns, the old values are restored.

 -- Scheme Procedure: with-fluid* fluid value thunk
 -- C Function: scm_with_fluid (fluid, value, thunk)
     Set FLUID to VALUE temporarily, and call THUNK.  THUNK must be a
     procedure with no argument.

 -- Scheme Procedure: with-fluids* fluids values thunk
 -- C Function: scm_with_fluids (fluids, values, thunk)
     Set FLUIDS to VALUES temporary, and call THUNK.  FLUIDS must be a
     list of fluids and VALUES must be the same number of their values
     to be applied.  Each substitution is done in the order given.
     THUNK must be a procedure with no argument.  It is called inside a
     ‘dynamic-wind’ and the fluids are set/restored when control enter
     or leaves the established dynamic extent.

 -- Scheme Macro: with-fluids ((fluid value) ...) body1 body2 ...
     Execute body BODY1 BODY2 ... while each FLUID is set to the
     corresponding VALUE.  Both FLUID and VALUE are evaluated and FLUID
     must yield a fluid.  The body is executed inside a ‘dynamic-wind’
     and the fluids are set/restored when control enter or leaves the
     established dynamic extent.

 -- C Function: SCM scm_c_with_fluids (SCM fluids, SCM vals, SCM
          (*cproc)(void *), void *data)
 -- C Function: SCM scm_c_with_fluid (SCM fluid, SCM val, SCM
          (*cproc)(void *), void *data)
     The function ‘scm_c_with_fluids’ is like ‘scm_with_fluids’ except
     that it takes a C function to call instead of a Scheme thunk.

     The function ‘scm_c_with_fluid’ is similar but only allows one
     fluid to be set instead of a list.

 -- C Function: void scm_dynwind_fluid (SCM fluid, SCM val)
     This function must be used inside a pair of calls to
     ‘scm_dynwind_begin’ and ‘scm_dynwind_end’ (see Dynamic Wind).
     During the dynwind context, the fluid FLUID is set to VAL.

     More precisely, the value of the fluid is swapped with a ‘backup’
     value whenever the dynwind context is entered or left.  The backup
     value is initialized with the VAL argument.

 -- Scheme Procedure: make-dynamic-state [parent]
 -- C Function: scm_make_dynamic_state (parent)
     Return a copy of the dynamic state object PARENT or of the current
     dynamic state when PARENT is omitted.

 -- Scheme Procedure: dynamic-state? obj
 -- C Function: scm_dynamic_state_p (obj)
     Return ‘#t’ if OBJ is a dynamic state object; return ‘#f’
     otherwise.

 -- C Procedure: int scm_is_dynamic_state (SCM obj)
     Return non-zero if OBJ is a dynamic state object; return zero
     otherwise.

 -- Scheme Procedure: current-dynamic-state
 -- C Function: scm_current_dynamic_state ()
     Return the current dynamic state object.

 -- Scheme Procedure: set-current-dynamic-state state
 -- C Function: scm_set_current_dynamic_state (state)
     Set the current dynamic state object to STATE and return the
     previous current dynamic state object.

 -- Scheme Procedure: with-dynamic-state state proc
 -- C Function: scm_with_dynamic_state (state, proc)
     Call PROC while STATE is the current dynamic state object.

 -- C Procedure: void scm_dynwind_current_dynamic_state (SCM state)
     Set the current dynamic state to STATE for the current dynwind
     context.

 -- C Procedure: void * scm_c_with_dynamic_state (SCM state, void
          *(*func)(void *), void *data)
     Like ‘scm_with_dynamic_state’, but call FUNC with DATA.

6.21.8 Parameters
-----------------

A parameter object is a procedure.  Calling it with no arguments returns
its value.  Calling it with one argument sets the value.

     (define my-param (make-parameter 123))
     (my-param) ⇒ 123
     (my-param 456)
     (my-param) ⇒ 456

   The ‘parameterize’ special form establishes new locations for
parameters, those new locations having effect within the dynamic scope
of the ‘parameterize’ body.  Leaving restores the previous locations.
Re-entering (through a saved continuation) will again use the new
locations.

     (parameterize ((my-param 789))
       (my-param)) ⇒ 789
     (my-param) ⇒ 456

   Parameters are like dynamically bound variables in other Lisp
dialects.  They allow an application to establish parameter settings (as
the name suggests) just for the execution of a particular bit of code,
restoring when done.  Examples of such parameters might be
case-sensitivity for a search, or a prompt for user input.

   Global variables are not as good as parameter objects for this sort
of thing.  Changes to them are visible to all threads, but in Guile
parameter object locations are per-thread, thereby truly limiting the
effect of ‘parameterize’ to just its dynamic execution.

   Passing arguments to functions is thread-safe, but that soon becomes
tedious when there’s more than a few or when they need to pass down
through several layers of calls before reaching the point they should
affect.  And introducing a new setting to existing code is often easier
with a parameter object than adding arguments.

 -- Scheme Procedure: make-parameter init [converter]
     Return a new parameter object, with initial value INIT.

     If a CONVERTER is given, then a call ‘(CONVERTER val)’ is made for
     each value set, its return is the value stored.  Such a call is
     made for the INIT initial value too.

     A CONVERTER allows values to be validated, or put into a canonical
     form.  For example,

          (define my-param (make-parameter 123
                             (lambda (val)
                               (if (not (number? val))
                                   (error "must be a number"))
                               (inexact->exact val))))
          (my-param 0.75)
          (my-param) ⇒ 3/4

 -- library syntax: parameterize ((param value) ...) body1 body2 ...
     Establish a new dynamic scope with the given PARAMs bound to new
     locations and set to the given VALUEs.  BODY1 BODY2 ... is
     evaluated in that environment.  The value returned is that of last
     body form.

     Each PARAM is an expression which is evaluated to get the parameter
     object.  Often this will just be the name of a variable holding the
     object, but it can be anything that evaluates to a parameter.

     The PARAM expressions and VALUE expressions are all evaluated
     before establishing the new dynamic bindings, and they’re evaluated
     in an unspecified order.

     For example,

          (define prompt (make-parameter "Type something: "))
          (define (get-input)
            (display (prompt))
            ...)

          (parameterize ((prompt "Type a number: "))
            (get-input)
            ...)

   Parameter objects are implemented using fluids (see Fluids and Dynamic States),
so each dynamic state has its own parameter
locations.  That includes the separate locations when outside any
‘parameterize’ form.  When a parameter is created it gets a separate
initial location in each dynamic state, all initialized to the given
INIT value.

   New code should probably just use parameters instead of fluids,
because the interface is better.  But for migrating old code or
otherwise providing interoperability, Guile provides the
‘fluid->parameter’ procedure:

 -- Scheme Procedure: fluid->parameter fluid [conv]
     Make a parameter that wraps a fluid.

     The value of the parameter will be the same as the value of the
     fluid.  If the parameter is rebound in some dynamic extent, perhaps
     via ‘parameterize’, the new value will be run through the optional
     CONV procedure, as with any parameter.  Note that unlike
     ‘make-parameter’, CONV is not applied to the initial value.

   As alluded to above, because each thread usually has a separate
dynamic state, each thread has its own locations behind parameter
objects, and changes in one thread are not visible to any other.  When a
new dynamic state or thread is created, the values of parameters in the
originating context are copied, into new locations.

   Guile’s parameters conform to SRFI-39 (see SRFI-39).

6.21.9 Futures
--------------

The ‘(ice-9 futures)’ module provides “futures”, a construct for
fine-grain parallelism.  A future is a wrapper around an expression
whose computation may occur in parallel with the code of the calling
thread, and possibly in parallel with other futures.  Like promises,
futures are essentially proxies that can be queried to obtain the value
of the enclosed expression:

     (touch (future (+ 2 3)))
     ⇒ 5

   However, unlike promises, the expression associated with a future may
be evaluated on another CPU core, should one be available.  This
supports “fine-grain parallelism”, because even relatively small
computations can be embedded in futures.  Consider this sequential code:

     (define (find-prime lst1 lst2)
       (or (find prime? lst1)
           (find prime? lst2)))

   The two arms of ‘or’ are potentially computation-intensive.  They are
independent of one another, yet, they are evaluated sequentially when
the first one returns ‘#f’.  Using futures, one could rewrite it like
this:

     (define (find-prime lst1 lst2)
       (let ((f (future (find prime? lst2))))
         (or (find prime? lst1)
             (touch f))))

   This preserves the semantics of ‘find-prime’.  On a multi-core
machine, though, the computation of ‘(find prime? lst2)’ may be done in
parallel with that of the other ‘find’ call, which can reduce the
execution time of ‘find-prime’.

   Futures may be nested: a future can itself spawn and then ‘touch’
other futures, leading to a directed acyclic graph of futures.  Using
this facility, a parallel ‘map’ procedure can be defined along these
lines:

     (use-modules (ice-9 futures) (ice-9 match))

     (define (par-map proc lst)
       (match lst
         (()
          '())
         ((head tail ...)
          (let ((tail (future (par-map proc tail)))
                (head (proc head)))
            (cons head (touch tail))))))

   Note that futures are intended for the evaluation of purely
functional expressions.  Expressions that have side-effects or rely on
I/O may require additional care, such as explicit synchronization (see
Mutexes and Condition Variables).

   Guile’s futures are implemented on top of POSIX threads (see
Threads).  Internally, a fixed-size pool of threads is used to
evaluate futures, such that offloading the evaluation of an expression
to another thread doesn’t incur thread creation costs.  By default, the
pool contains one thread per available CPU core, minus one, to account
for the main thread.  The number of available CPU cores is determined
using ‘current-processor-count’ (see Processes).

   When a thread touches a future that has not completed yet, it
processes any pending future while waiting for it to complete, or just
waits if there are no pending futures.  When ‘touch’ is called from
within a future, the execution of the calling future is suspended,
allowing its host thread to process other futures, and resumed when the
touched future has completed.  This suspend/resume is achieved by
capturing the calling future’s continuation, and later reinstating it
(see delimited continuations).

   Note that ‘par-map’ above is not tail-recursive.  This could lead to
stack overflows when LST is large compared to
‘(current-processor-count)’.  To address that, ‘touch’ uses the suspend
mechanism described above to limit the number of nested futures
executing on the same stack.  Thus, the above code should never run into
stack overflows.

 -- Scheme Syntax: future exp
     Return a future for expression EXP.  This is equivalent to:

          (make-future (lambda () exp))

 -- Scheme Procedure: make-future thunk
     Return a future for THUNK, a zero-argument procedure.

     This procedure returns immediately.  Execution of THUNK may begin
     in parallel with the calling thread’s computations, if idle CPU
     cores are available, or it may start when ‘touch’ is invoked on the
     returned future.

     If the execution of THUNK throws an exception, that exception will
     be re-thrown when ‘touch’ is invoked on the returned future.

 -- Scheme Procedure: future? obj
     Return ‘#t’ if OBJ is a future.

 -- Scheme Procedure: touch f
     Return the result of the expression embedded in future F.

     If the result was already computed in parallel, ‘touch’ returns
     instantaneously.  Otherwise, it waits for the computation to
     complete, if it already started, or initiates it.  In the former
     case, the calling thread may process other futures in the meantime.

6.21.10 Parallel forms
----------------------

The functions described in this section are available from

     (use-modules (ice-9 threads))

   They provide high-level parallel constructs.  The following functions
are implemented in terms of futures (see Futures).  Thus they are
relatively cheap as they re-use existing threads, and portable, since
they automatically use one thread per available CPU core.

 -- syntax: parallel expr ...
     Evaluate each EXPR expression in parallel, each in its own thread.
     Return the results of N expressions as a set of N multiple values
     (see Multiple Values).

 -- syntax: letpar ((var expr) ...) body1 body2 ...
     Evaluate each EXPR in parallel, each in its own thread, then bind
     the results to the corresponding VAR variables, and then evaluate
     BODY1 BODY2 ...

     ‘letpar’ is like ‘let’ (see Local Bindings), but all the
     expressions for the bindings are evaluated in parallel.

 -- Scheme Procedure: par-map proc lst1 lst2 ...
 -- Scheme Procedure: par-for-each proc lst1 lst2 ...
     Call PROC on the elements of the given lists.  ‘par-map’ returns a
     list comprising the return values from PROC.  ‘par-for-each’
     returns an unspecified value, but waits for all calls to complete.

     The PROC calls are ‘(PROC ELEM1 ELEM2 ...)’, where each ELEM is
     from the corresponding LST .  Each LST must be the same length.
     The calls are potentially made in parallel, depending on the number
     of CPU cores available.

     These functions are like ‘map’ and ‘for-each’ (see List Mapping),
     but make their PROC calls in parallel.

   Unlike those above, the functions described below take a number of
threads as an argument.  This makes them inherently non-portable since
the specified number of threads may differ from the number of available
CPU cores as returned by ‘current-processor-count’ (see Processes).
In addition, these functions create the specified number of threads when
they are called and terminate them upon completion, which makes them
quite expensive.

   Therefore, they should be avoided.

 -- Scheme Procedure: n-par-map n proc lst1 lst2 ...
 -- Scheme Procedure: n-par-for-each n proc lst1 lst2 ...
     Call PROC on the elements of the given lists, in the same way as
     ‘par-map’ and ‘par-for-each’ above, but use no more than N threads
     at any one time.  The order in which calls are initiated within
     that threads limit is unspecified.

     These functions are good for controlling resource consumption if
     PROC calls might be costly, or if there are many to be made.  On a
     dual-CPU system for instance N=4 might be enough to keep the CPUs
     utilized, and not consume too much memory.

 -- Scheme Procedure: n-for-each-par-map n sproc pproc lst1 lst2 ...
     Apply PPROC to the elements of the given lists, and apply SPROC to
     each result returned by PPROC.  The final return value is
     unspecified, but all calls will have been completed before
     returning.

     The calls made are ‘(SPROC (PPROC ELEM1 ... ELEMN))’, where each
     ELEM is from the corresponding LST.  Each LST must have the same
     number of elements.

     The PPROC calls are made in parallel, in separate threads.  No more
     than N threads are used at any one time.  The order in which PPROC
     calls are initiated within that limit is unspecified.

     The SPROC calls are made serially, in list element order, one at a
     time.  PPROC calls on later elements may execute in parallel with
     the SPROC calls.  Exactly which thread makes each SPROC call is
     unspecified.

     This function is designed for individual calculations that can be
     done in parallel, but with results needing to be handled serially,
     for instance to write them to a file.  The N limit on threads
     controls system resource usage when there are many calculations or
     when they might be costly.

     It will be seen that ‘n-for-each-par-map’ is like a combination of
     ‘n-par-map’ and ‘for-each’,

          (for-each sproc (n-par-map n pproc lst1 ... lstN))

     But the actual implementation is more efficient since each SPROC
     call, in turn, can be initiated once the relevant PPROC call has
     completed, it doesn’t need to wait for all to finish.

6.22 Configuration, Features and Runtime Options
================================================

Why is my Guile different from your Guile?  There are three kinds of
possible variation:

   • build differences — different versions of the Guile source code,
     installation directories, configuration flags that control pieces
     of functionality being included or left out, etc.

   • differences in dynamically loaded code — behaviour and features
     provided by modules that can be dynamically loaded into a running
     Guile

   • different runtime options — some of the options that are provided
     for controlling Guile’s behaviour may be set differently.

   Guile provides “introspective” variables and procedures to query all
of these possible variations at runtime.  For runtime options, it also
provides procedures to change the settings of options and to obtain
documentation on what the options mean.

6.22.1 Configuration, Build and Installation
--------------------------------------------

The following procedures and variables provide information about how
Guile was configured, built and installed on your system.

 -- Scheme Procedure: version
 -- Scheme Procedure: effective-version
 -- Scheme Procedure: major-version
 -- Scheme Procedure: minor-version
 -- Scheme Procedure: micro-version
 -- C Function: scm_version ()
 -- C Function: scm_effective_version ()
 -- C Function: scm_major_version ()
 -- C Function: scm_minor_version ()
 -- C Function: scm_micro_version ()
     Return a string describing Guile’s full version number, effective
     version number, major, minor or micro version number, respectively.
     The ‘effective-version’ function returns the version name that
     should remain unchanged during a stable series.  Currently that
     means that it omits the micro version.  The effective version
     should be used for items like the versioned share directory name
     i.e. ‘/usr/share/guile/2.0/’

          (version) ⇒ "2.0.4"
          (effective-version) ⇒ "2.0"
          (major-version) ⇒ "2"
          (minor-version) ⇒ "0"
          (micro-version) ⇒ "4"

 -- Scheme Procedure: %package-data-dir
 -- C Function: scm_sys_package_data_dir ()
     Return the name of the directory under which Guile Scheme files in
     general are stored.  On Unix-like systems, this is usually
     ‘/usr/local/share/guile’ or ‘/usr/share/guile’.

 -- Scheme Procedure: %library-dir
 -- C Function: scm_sys_library_dir ()
     Return the name of the directory where the Guile Scheme files that
     belong to the core Guile installation (as opposed to files from a
     3rd party package) are installed.  On Unix-like systems this is
     usually ‘/usr/local/share/guile/GUILE_EFFECTIVE_VERSION’ or
     ‘/usr/share/guile/GUILE_EFFECTIVE_VERSION’;

     for example ‘/usr/local/share/guile/2.0’.

 -- Scheme Procedure: %site-dir
 -- C Function: scm_sys_site_dir ()
     Return the name of the directory where Guile Scheme files specific
     to your site should be installed.  On Unix-like systems, this is
     usually ‘/usr/local/share/guile/site’ or ‘/usr/share/guile/site’.

 -- Scheme Procedure: %site-ccache-dir
 -- C Function: scm_sys_site_ccache_dir ()
     Return the directory where users should install compiled ‘.go’
     files for use with this version of Guile.  Might look something
     like ‘/usr/lib/guile/2.0/site-ccache’.

 -- Variable: %guile-build-info
     Alist of information collected during the building of a particular
     Guile.  Entries can be grouped into one of several categories:
     directories, env vars, and versioning info.

     Briefly, here are the keys in ‘%guile-build-info’, by group:

     directories
          srcdir, top_srcdir, prefix, exec_prefix, bindir, sbindir,
          libexecdir, datadir, sysconfdir, sharedstatedir,
          localstatedir, libdir, infodir, mandir, includedir,
          pkgdatadir, pkglibdir, pkgincludedir
     env vars
          LIBS
     versioning info
          guileversion, libguileinterface, buildstamp

     Values are all strings.  The value for ‘LIBS’ is typically found
     also as a part of ‘pkg-config --libs guile-2.0’ output.  The value
     for ‘guileversion’ has form X.Y.Z, and should be the same as
     returned by ‘(version)’.  The value for ‘libguileinterface’ is
     libtool compatible and has form CURRENT:REVISION:AGE (see Library interface versions (libtool)).
     The value for
     ‘buildstamp’ is the output of the command ‘date -u +'%Y-%m-%d %T'’
     (UTC).

     In the source, ‘%guile-build-info’ is initialized from
     libguile/libpath.h, which is completely generated, so deleting this
     file before a build guarantees up-to-date values for that build.

 -- Variable: %host-type
     The canonical host type (GNU triplet) of the host Guile was
     configured for, e.g., ‘"x86_64-unknown-linux-gnu"’ (see
     Canonicalizing (autoconf)).

6.22.2 Feature Tracking
-----------------------

Guile has a Scheme level variable ‘*features*’ that keeps track to some
extent of the features that are available in a running Guile.
‘*features*’ is a list of symbols, for example ‘threads’, each of which
describes a feature of the running Guile process.

 -- Variable: *features*
     A list of symbols describing available features of the Guile
     process.

   You shouldn’t modify the ‘*features*’ variable directly using ‘set!’.
Instead, see the procedures that are provided for this purpose in the
following subsection.

6.22.2.1 Feature Manipulation
.............................

To check whether a particular feature is available, use the ‘provided?’
procedure:

 -- Scheme Procedure: provided? feature
 -- Deprecated Scheme Procedure: feature? feature
     Return ‘#t’ if the specified FEATURE is available, otherwise ‘#f’.

   To advertise a feature from your own Scheme code, you can use the
‘provide’ procedure:

 -- Scheme Procedure: provide feature
     Add FEATURE to the list of available features in this Guile
     process.

   For C code, the equivalent function takes its feature name as a ‘char
*’ argument for convenience:

 -- C Function: void scm_add_feature (const char *str)
     Add a symbol with name STR to the list of available features in
     this Guile process.

6.22.2.2 Common Feature Symbols
...............................

In general, a particular feature may be available for one of two
reasons.  Either because the Guile library was configured and compiled
with that feature enabled — i.e. the feature is built into the library
on your system.  Or because some C or Scheme code that was dynamically
loaded by Guile has added that feature to the list.

   In the first category, here are the features that the current version
of Guile may define (depending on how it is built), and what they mean.

‘array’
     Indicates support for arrays (see Arrays).

‘array-for-each’
     Indicates availability of ‘array-for-each’ and other array mapping
     procedures (see Arrays).

‘char-ready?’
     Indicates that the ‘char-ready?’ function is available (see
     Reading).

‘complex’
     Indicates support for complex numbers.

‘current-time’
     Indicates availability of time-related functions: ‘times’,
     ‘get-internal-run-time’ and so on (see Time).

‘debug-extensions’
     Indicates that the debugging evaluator is available, together with
     the options for controlling it.

‘delay’
     Indicates support for promises (see Delayed Evaluation).

‘EIDs’
     Indicates that the ‘geteuid’ and ‘getegid’ really return effective
     user and group IDs (see Processes).

‘inexact’
     Indicates support for inexact numbers.

‘i/o-extensions’
     Indicates availability of the following extended I/O procedures:
     ‘ftell’, ‘redirect-port’, ‘dup->fdes’, ‘dup2’, ‘fileno’, ‘isatty?’,
     ‘fdopen’, ‘primitive-move->fdes’ and ‘fdes->ports’ (see Ports and File Descriptors).

‘net-db’
     Indicates availability of network database functions:
     ‘scm_gethost’, ‘scm_getnet’, ‘scm_getproto’, ‘scm_getserv’,
     ‘scm_sethost’, ‘scm_setnet’, ‘scm_setproto’, ‘scm_setserv’, and
     their ‘byXXX’ variants (see Network Databases).

‘posix’
     Indicates support for POSIX functions: ‘pipe’, ‘getgroups’, ‘kill’,
     ‘execl’ and so on (see POSIX).

‘fork’
     Indicates support for the POSIX ‘fork’ function (see
     ‘primitive-fork’).

‘popen’
     Indicates support for ‘open-pipe’ in the ‘(ice-9 popen)’ module
     (see Pipes).

‘random’
     Indicates availability of random number generation functions:
     ‘random’, ‘copy-random-state’, ‘random-uniform’ and so on (see
     Random).

‘reckless’
     Indicates that Guile was built with important checks omitted — you
     should never see this!

‘regex’
     Indicates support for POSIX regular expressions using
     ‘make-regexp’, ‘regexp-exec’ and friends (see Regexp Functions).

‘socket’
     Indicates availability of socket-related functions: ‘socket’,
     ‘bind’, ‘connect’ and so on (see Network Sockets and Communication).

‘sort’
     Indicates availability of sorting and merging functions (see
     Sorting).

‘system’
     Indicates that the ‘system’ function is available (see
     Processes).

‘threads’
     Indicates support for multithreading (see Threads).

‘values’
     Indicates support for multiple return values using ‘values’ and
     ‘call-with-values’ (see Multiple Values).

   Available features in the second category depend, by definition, on
what additional code your Guile process has loaded in.  The following
table lists features that you might encounter for this reason.

‘defmacro’
     Indicates that the ‘defmacro’ macro is available (see Macros).

‘describe’
     Indicates that the ‘(oop goops describe)’ module has been loaded,
     which provides a procedure for describing the contents of GOOPS
     instances.

‘readline’
     Indicates that Guile has loaded in Readline support, for command
     line editing (see Readline Support).

‘record’
     Indicates support for record definition using ‘make-record-type’
     and friends (see Records).

   Although these tables may seem exhaustive, it is probably unwise in
practice to rely on them, as the correspondences between feature symbols
and available procedures/behaviour are not strictly defined.  If you are
writing code that needs to check for the existence of some procedure, it
is probably safer to do so directly using the ‘defined?’ procedure than
to test for the corresponding feature using ‘provided?’.

6.22.3 Runtime Options
----------------------

There are a number of runtime options available for paramaterizing
built-in procedures, like ‘read’, and built-in behavior, like what
happens on an uncaught error.

   For more information on reader options, see Scheme Read.

   For more information on print options, see Scheme Write.

   Finally, for more information on debugger options, see Debug Options.

6.22.3.1 Examples of option use
...............................

Here is an example of a session in which some read and debug option
handling procedures are used.  In this example, the user

  1. Notices that the symbols ‘abc’ and ‘aBc’ are not the same
  2. Examines the ‘read-options’, and sees that ‘case-insensitive’ is
     set to “no”.
  3. Enables ‘case-insensitive’
  4. Quits the recursive prompt
  5. Verifies that now ‘aBc’ and ‘abc’ are the same

     scheme@(guile-user)> (define abc "hello")
     scheme@(guile-user)> abc
     $1 = "hello"
     scheme@(guile-user)> aBc
     <unknown-location>: warning: possibly unbound variable `aBc'
     ERROR: In procedure module-lookup:
     ERROR: Unbound variable: aBc
     Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
     scheme@(guile-user) [1]> (read-options 'help)
     copy              no    Copy source code expressions.
     positions         yes   Record positions of source code expressions.
     case-insensitive  no    Convert symbols to lower case.
     keywords          #f    Style of keyword recognition: #f, 'prefix or 'postfix.
     r6rs-hex-escapes  no    Use R6RS variable-length character and string hex escapes.
     square-brackets   yes   Treat `[' and `]' as parentheses, for R6RS compatibility.
     hungry-eol-escapes no   In strings, consume leading whitespace after an
                             escaped end-of-line.
     curly-infix       no    Support SRFI-105 curly infix expressions.
     scheme@(guile-user) [1]> (read-enable 'case-insensitive)
     $2 = (square-brackets keywords #f case-insensitive positions)
     scheme@(guile-user) [1]> ,q
     scheme@(guile-user)> aBc
     $3 = "hello"

6.23 Support for Other Languages
================================

In addition to Scheme, a user may write a Guile program in an increasing
number of other languages.  Currently supported languages include Emacs
Lisp and ECMAScript.

   Guile is still fundamentally a Scheme, but it tries to support a wide
variety of language building-blocks, so that other languages can be
implemented on top of Guile.  This allows users to write or extend
applications in languages other than Scheme, too.  This section
describes the languages that have been implemented.

   (For details on how to implement a language, see Compiling to the Virtual Machine.)

6.23.1 Using Other Languages
----------------------------

There are currently only two ways to access other languages from within
Guile: at the REPL, and programmatically, via ‘compile’,
‘read-and-compile’, and ‘compile-file’.

   The REPL is Guile’s command prompt (see Using Guile Interactively).
The REPL has a concept of the “current language”,
which defaults to Scheme.  The user may change that language, via the
meta-command ‘,language’.

   For example, the following meta-command enables Emacs Lisp input:

     scheme@(guile-user)> ,language elisp
     Happy hacking with Emacs Lisp!  To switch back, type `,L scheme'.
     elisp@(guile-user)> (eq 1 2)
     $1 = #nil

   Each language has its short name: for example, ‘elisp’, for Elisp.
The same short name may be used to compile source code programmatically,
via ‘compile’:

     elisp@(guile-user)> ,L scheme
     Happy hacking with Guile Scheme!  To switch back, type `,L elisp'.
     scheme@(guile-user)> (compile '(eq 1 2) #:from 'elisp)
     $2 = #nil

   Granted, as the input to ‘compile’ is a datum, this works best for
Lispy languages, which have a straightforward datum representation.
Other languages that need more parsing are better dealt with as strings.

   The easiest way to deal with syntax-heavy language is with files, via
‘compile-file’ and friends.  However it is possible to invoke a
language’s reader on a port, and then compile the resulting expression
(which is a datum at that point).  For more information, see
Compilation.

   For more details on introspecting aspects of different languages,
see Compiler Tower.

6.23.2 Emacs Lisp
-----------------

Emacs Lisp (Elisp) is a dynamically-scoped Lisp dialect used in the
Emacs editor.  See Overview (elisp), for more information on Emacs
Lisp.

   We hope that eventually Guile’s implementation of Elisp will be good
enough to replace Emacs’ own implementation of Elisp.  For that reason,
we have thought long and hard about how to support the various features
of Elisp in a performant and compatible manner.

   Readers familiar with Emacs Lisp might be curious about how exactly
these various Elisp features are supported in Guile.  The rest of this
section focuses on addressing these concerns of the Elisp elect.

6.23.2.1 Nil
............

‘nil’ in ELisp is an amalgam of Scheme’s ‘#f’ and ‘'()’.  It is false,
and it is the end-of-list; thus it is a boolean, and a list as well.

   Guile has chosen to support ‘nil’ as a separate value, distinct from
‘#f’ and ‘'()’.  This allows existing Scheme and Elisp code to maintain
their current semantics.  ‘nil’, which in Elisp would just be written
and read as ‘nil’, in Scheme has the external representation ‘#nil’.

   This decision to have ‘nil’ as a low-level distinct value facilitates
interoperability between the two languages.  Guile has chosen to have
Scheme deal with ‘nil’ as follows:

     (boolean? #nil) ⇒ #t
     (not #nil) ⇒ #t
     (null? #nil) ⇒ #t

   And in C, one has:

     scm_is_bool (SCM_ELISP_NIL) ⇒ 1
     scm_is_false (SCM_ELISP_NIL) ⇒ 1
     scm_is_null (SCM_ELISP_NIL) ⇒ 1

   In this way, a version of ‘fold’ written in Scheme can correctly fold
a function written in Elisp (or in fact any other language) over a
nil-terminated list, as Elisp makes.  The converse holds as well; a
version of ‘fold’ written in Elisp can fold over a ‘'()’-terminated
list, as made by Scheme.

   On a low level, the bit representations for ‘#f’, ‘#t’, ‘nil’, and
‘'()’ are made in such a way that they differ by only one bit, and so a
test for, for example, ‘#f’-or-‘nil’ may be made very efficiently.  See
‘libguile/boolean.h’, for more information.

6.23.2.2 Equality
.................

Since Scheme’s ‘equal?’ must be transitive, and ‘'()’ is not ‘equal?’ to
‘#f’, to Scheme ‘nil’ is not ‘equal?’ to ‘#f’ or ‘'()’.

     (eq? #f '()) ⇒ #f
     (eq? #nil '()) ⇒ #f
     (eq? #nil #f) ⇒ #f
     (eqv? #f '()) ⇒ #f
     (eqv? #nil '()) ⇒ #f
     (eqv? #nil #f) ⇒ #f
     (equal? #f '()) ⇒ #f
     (equal? #nil '()) ⇒ #f
     (equal? #nil #f) ⇒ #f

   However, in Elisp, ‘'()’, ‘#f’, and ‘nil’ are all ‘equal’ (though not
‘eq’).

     (defvar f (make-scheme-false))
     (defvar eol (make-scheme-null))
     (eq f eol) ⇒ nil
     (eq nil eol) ⇒ nil
     (eq nil f) ⇒ nil
     (equal f eol) ⇒ t
     (equal nil eol) ⇒ t
     (equal nil f) ⇒ t

   These choices facilitate interoperability between Elisp and Scheme
code, but they are not perfect.  Some code that is correct standard
Scheme is not correct in the presence of a second false and null value.
For example:

     (define (truthiness x)
       (if (eq? x #f)
           #f
           #t))

   This code seems to be meant to test a value for truth, but now that
there are two false values, ‘#f’ and ‘nil’, it is no longer correct.

   Similarly, there is the loop:

     (define (my-length l)
       (let lp ((l l) (len 0))
         (if (eq? l '())
             len
             (lp (cdr l) (1+ len)))))

   Here, ‘my-length’ will raise an error if L is a ‘nil’-terminated
list.

   Both of these examples are correct standard Scheme, but, depending on
what they really want to do, they are not correct Guile Scheme.
Correctly written, they would test the _properties_ of falsehood or
nullity, not the individual members of that set.  That is to say, they
should use ‘not’ or ‘null?’ to test for falsehood or nullity, not ‘eq?’
or ‘memv’ or the like.

   Fortunately, using ‘not’ and ‘null?’ is in good style, so all
well-written standard Scheme programs are correct, in Guile Scheme.

   Here are correct versions of the above examples:

     (define (truthiness* x)
       (if (not x)
           #f
           #t))
     ;; or: (define (t* x) (not (not x)))
     ;; or: (define (t** x) x)

     (define (my-length* l)
       (let lp ((l l) (len 0))
         (if (null? l)
             len
             (lp (cdr l) (1+ len)))))

   This problem has a mirror-image case in Elisp:

     (deffn my-falsep (x)
       (if (eq x nil)
           t
           nil))

   Guile can warn when compiling code that has equality comparisons with
‘#f’, ‘'()’, or ‘nil’.  See Compilation, for details.

6.23.2.3 Dynamic Binding
........................

In contrast to Scheme, which uses “lexical scoping”, Emacs Lisp scopes
its variables dynamically.  Guile supports dynamic scoping with its
“fluids” facility.  See Fluids and Dynamic States, for more
information.

6.23.2.4 Other Elisp Features
.............................

Buffer-local and mode-local variables should be mentioned here, along
with buckybits on characters, Emacs primitive data types, the
Lisp-2-ness of Elisp, and other things.  Contributions to the
documentation are most welcome!

6.23.3 ECMAScript
-----------------

ECMAScript
(http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf)
was not the first non-Schemey language implemented by Guile, but it was
the first implemented for Guile’s bytecode compiler.  The goal was to
support ECMAScript version 3.1, a relatively small language, but the
implementor was completely irresponsible and got distracted by other
things before finishing the standard library, and even some bits of the
syntax.  So, ECMAScript does deserve a mention in the manual, but it
doesn’t deserve an endorsement until its implementation is completed,
perhaps by some more responsible hacker.

   In the meantime, the charitable user might investigate such
invocations as ‘,L ecmascript’ and ‘cat
test-suite/tests/ecmascript.test’.

6.24 Support for Internationalization
=====================================

Guile provides internationalization(1) support for Scheme programs in
two ways.  First, procedures to manipulate text and data in a way that
conforms to particular cultural conventions (i.e., in a
“locale-dependent” way) are provided in the ‘(ice-9 i18n)’.  Second,
Guile allows the use of GNU ‘gettext’ to translate program message
strings.

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

   (1) For concision and style, programmers often like to refer to
internationalization as “i18n”.

6.24.1 Internationalization with Guile
--------------------------------------

In order to make use of the functions described thereafter, the ‘(ice-9
i18n)’ module must be imported in the usual way:

     (use-modules (ice-9 i18n))

   The ‘(ice-9 i18n)’ module provides procedures to manipulate text and
other data in a way that conforms to the cultural conventions chosen by
the user.  Each region of the world or language has its own customs to,
for instance, represent real numbers, classify characters, collate text,
etc.  All these aspects comprise the so-called “cultural conventions” of
that region or language.

   Computer systems typically refer to a set of cultural conventions as
a “locale”.  For each particular aspect that comprise those cultural
conventions, a “locale category” is defined.  For instance, the way
characters are classified is defined by the ‘LC_CTYPE’ category, while
the language in which program messages are issued to the user is defined
by the ‘LC_MESSAGES’ category (see General Locale Information
for details).

   The procedures provided by this module allow the development of
programs that adapt automatically to any locale setting.  As we will see
later, many of these procedures can optionally take a “locale object”
argument.  This additional argument defines the locale settings that
must be followed by the invoked procedure.  When it is omitted, then the
current locale settings of the process are followed (see ‘setlocale’).

   The following procedures allow the manipulation of such locale
objects.

 -- Scheme Procedure: make-locale category-list locale-name
          [base-locale]
 -- C Function: scm_make_locale (category_list, locale_name,
          base_locale)
     Return a reference to a data structure representing a set of locale
     datasets.  LOCALE-NAME should be a string denoting a particular
     locale (e.g., ‘"aa_DJ"’) and CATEGORY-LIST should be either a list
     of locale categories or a single category as used with ‘setlocale’
     (see ‘setlocale’).  Optionally, if ‘base-locale’ is
     passed, it should be a locale object denoting settings for
     categories not listed in CATEGORY-LIST.

     The following invocation creates a locale object that combines the
     use of Swedish for messages and character classification with the
     default settings for the other categories (i.e., the settings of
     the default ‘C’ locale which usually represents conventions in use
     in the USA):

          (make-locale (list LC_MESSAGES LC_CTYPE) "sv_SE")

     The following example combines the use of Esperanto messages and
     conventions with monetary conventions from Croatia:

          (make-locale LC_MONETARY "hr_HR"
                       (make-locale LC_ALL "eo_EO"))

     A ‘system-error’ exception (see Handling Errors) is raised by
     ‘make-locale’ when LOCALE-NAME does not match any of the locales
     compiled on the system.  Note that on non-GNU systems, this error
     may be raised later, when the locale object is actually used.

 -- Scheme Procedure: locale? obj
 -- C Function: scm_locale_p (obj)
     Return true if OBJ is a locale object.

 -- Scheme Variable: %global-locale
 -- C Variable: scm_global_locale
     This variable is bound to a locale object denoting the current
     process locale as installed using ‘setlocale ()’ (see Locales).
     It may be used like any other locale object, including as a third
     argument to ‘make-locale’, for instance.