This manual documents Guile version 3.0.10.

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

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

7.2.11.5 Network Socket Examples
................................

The following give examples of how to use network sockets.

Internet Socket Client Example
..............................

The following example demonstrates an Internet socket client.  It
connects to the HTTP daemon running on the local machine and returns the
contents of the root index URL.

     (let ((s (socket PF_INET SOCK_STREAM 0)))
       (connect s AF_INET (inet-pton AF_INET "127.0.0.1") 80)
       (display "GET / HTTP/1.0\r\n\r\n" s)

       (do ((line (read-line s) (read-line s)))
           ((eof-object? line))
         (display line)
         (newline)))

Internet Socket Server Example
..............................

The following example shows a simple Internet server which listens on
port 2904 for incoming connections and sends a greeting back to the
client.

     (let ((s (socket PF_INET SOCK_STREAM 0)))
       (setsockopt s SOL_SOCKET SO_REUSEADDR 1)
       ;; Specific address?
       ;; (bind s AF_INET (inet-pton AF_INET "127.0.0.1") 2904)
       (bind s AF_INET INADDR_ANY 2904)
       (listen s 5)

       (simple-format #t "Listening for clients in pid: ~S" (getpid))
       (newline)

       (while #t
         (let* ((client-connection (accept s))
                (client-details (cdr client-connection))
                (client (car client-connection)))
           (simple-format #t "Got new client connection: ~S"
                          client-details)
           (newline)
           (simple-format #t "Client address: ~S"
                          (gethostbyaddr
                           (sockaddr:addr client-details)))
           (newline)
           ;; Send back the greeting to the client port
           (display "Hello client\r\n" client)
           (close client))))

7.2.12 System Identification
----------------------------

This section lists the various procedures Guile provides for accessing
information about the system it runs on.

 -- Scheme Procedure: uname
 -- C Function: scm_uname ()
     Return an object with some information about the computer system
     the program is running on.

     The following procedures accept an object as returned by ‘uname’
     and return a selected component (all of which are strings).

      -- Scheme Procedure: utsname:sysname un
          The name of the operating system.
      -- Scheme Procedure: utsname:nodename un
          The network name of the computer.
      -- Scheme Procedure: utsname:release un
          The current release level of the operating system
          implementation.
      -- Scheme Procedure: utsname:version un
          The current version level within the release of the operating
          system.
      -- Scheme Procedure: utsname:machine un
          A description of the hardware.

 -- Scheme Procedure: gethostname
 -- C Function: scm_gethostname ()
     Return the host name of the current processor.

 -- Scheme Procedure: sethostname name
 -- C Function: scm_sethostname (name)
     Set the host name of the current processor to NAME.  May only be
     used by the superuser.  The return value is not specified.

7.2.13 Locales
--------------

 -- Scheme Procedure: setlocale category [locale]
 -- C Function: scm_setlocale (category, locale)
     Get or set the current locale, used for various
     internationalizations.  Locales are strings, such as ‘sv_SE’.

     If LOCALE is given then the locale for the given CATEGORY is set
     and the new value returned.  If LOCALE is not given then the
     current value is returned.  CATEGORY should be one of the following
     values (see Categories of Activities that Locales Affect (libc)):

      -- Variable: LC_ALL
      -- Variable: LC_COLLATE
      -- Variable: LC_CTYPE
      -- Variable: LC_MESSAGES
      -- Variable: LC_MONETARY
      -- Variable: LC_NUMERIC
      -- Variable: LC_TIME

     A common usage is ‘(setlocale LC_ALL "")’, which initializes all
     categories based on standard environment variables (‘LANG’ etc).
     For full details on categories and locale names Locales and Internationalization (libc).

     Note that ‘setlocale’ affects locale settings for the whole
     process.  See locale objects and ‘make-locale’,
     for a thread-safe alternative.

7.2.14 Encryption
-----------------

Please note that the procedures in this section are not suited for
strong encryption, they are only interfaces to the well-known and common
system library functions of the same name.  They are just as good (or
bad) as the underlying functions, so you should refer to your system
documentation before using them (see Encrypting Passwords (libc)).

 -- Scheme Procedure: crypt key salt
 -- C Function: scm_crypt (key, salt)
     Encrypt KEY, with the addition of SALT (both strings), using the
     ‘crypt’ C library call.

   Although ‘getpass’ is not an encryption procedure per se, it appears
here because it is often used in combination with ‘crypt’:

 -- Scheme Procedure: getpass prompt
 -- C Function: scm_getpass (prompt)
     Display PROMPT to the standard error output and read a password
     from ‘/dev/tty’.  If this file is not accessible, it reads from
     standard input.  The password may be up to 127 characters in
     length.  Additional characters and the terminating newline
     character are discarded.  While reading the password, echoing and
     the generation of signals by special characters is disabled.

7.3 HTTP, the Web, and All That
===============================

It has always been possible to connect computers together and share
information between them, but the rise of the World Wide Web over the
last couple of decades has made it much easier to do so.  The result is
a richly connected network of computation, in which Guile forms a part.

   By "the web", we mean the HTTP protocol(1) as handled by servers,
clients, proxies, caches, and the various kinds of messages and message
components that can be sent and received by that protocol, notably HTML.

   On one level, the web is text in motion: the protocols themselves are
textual (though the payload may be binary), and it's possible to create
a socket and speak text to the web.  But such an approach is obviously
primitive.  This section details the higher-level data types and
operations provided by Guile: URIs, HTTP request and response records,
and a conventional web server implementation.

   The material in this section is arranged in ascending order, in which
later concepts build on previous ones.  If you prefer to start with the
highest-level perspective, see Web Examples, and work your way back.

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

   (1) Yes, the P is for protocol, but this phrase appears repeatedly in
RFC 2616.

7.3.1 Types and the Web
-----------------------

It is a truth universally acknowledged, that a program with good use of
data types, will be free from many common bugs.  Unfortunately, the
common practice in web programming seems to ignore this maxim.  This
subsection makes the case for expressive data types in web programming.

   By "expressive data types", we mean that the data types _say_
something about how a program solves a problem.  For example, if we
choose to represent dates using SRFI 19 date records (see SRFI-19),
this indicates that there is a part of the program that will always have
valid dates.  Error handling for a number of basic cases, like invalid
dates, occurs on the boundary in which we produce a SRFI 19 date record
from other types, like strings.

   With regards to the web, data types are helpful in the two broad
phases of HTTP messages: parsing and generation.

   Consider a server, which has to parse a request, and produce a
response.  Guile will parse the request into an HTTP request object
(see Requests), with each header parsed into an appropriate Scheme
data type.  This transition from an incoming stream of characters to
typed data is a state change in a program--the strings might parse, or
they might not, and something has to happen if they do not.  (Guile
throws an error in this case.)  But after you have the parsed request,
"client" code (code built on top of the Guile web framework) will not
have to check for syntactic validity.  The types already make this
information manifest.

   This state change on the parsing boundary makes programs more robust,
as they themselves are freed from the need to do a number of common
error checks, and they can use normal Scheme procedures to handle a
request instead of ad-hoc string parsers.

   The need for types on the response generation side (in a server) is
more subtle, though not less important.  Consider the example of a POST
handler, which prints out the text that a user submits from a form.
Such a handler might include a procedure like this:

     ;; First, a helper procedure
     (define (para . contents)
       (string-append "<p>" (string-concatenate contents) "</p>"))

     ;; Now the meat of our simple web application
     (define (you-said text)
       (para "You said: " text))

     (display (you-said "Hi!"))
     ⊣ <p>You said: Hi!</p>

   This is a perfectly valid implementation, provided that the incoming
text does not contain the special HTML characters ‘<’, ‘>’, or ‘&’.  But
this provision of a restricted character set is not reflected anywhere
in the program itself: we must _assume_ that the programmer understands
this, and performs the check elsewhere.

   Unfortunately, the short history of the practice of programming does
not bear out this assumption.  A “cross-site scripting” (XSS)
vulnerability is just such a common error in which unfiltered user input
is allowed into the output.  A user could submit a crafted comment to
your web site which results in visitors running malicious Javascript,
within the security context of your domain:

     (display (you-said "<script src=\"http://bad.com/nasty.js\" />"))
     ⊣ <p>You said: <script src="http://bad.com/nasty.js" /></p>

   The fundamental problem here is that both user data and the program
template are represented using strings.  This identity means that types
can't help the programmer to make a distinction between these two, so
they get confused.

   There are a number of possible solutions, but perhaps the best is to
treat HTML not as strings, but as native s-expressions: as SXML. The
basic idea is that HTML is either text, represented by a string, or an
element, represented as a tagged list.  So ‘foo’ becomes ‘"foo"’, and
‘<b>foo</b>’ becomes ‘(b "foo")’.  Attributes, if present, go in a
tagged list headed by ‘@’, like ‘(img (@ (src
"http://example.com/foo.png")))’.  See SXML, for more information.

   The good thing about SXML is that HTML elements cannot be confused
with text.  Let's make a new definition of ‘para’:

     (define (para . contents)
       `(p ,@contents))

     (use-modules (sxml simple))
     (sxml->xml (you-said "Hi!"))
     ⊣ <p>You said: Hi!</p>

     (sxml->xml (you-said "<i>Rats, foiled again!</i>"))
     ⊣ <p>You said: &lt;i&gt;Rats, foiled again!&lt;/i&gt;</p>

   So we see in the second example that HTML elements cannot be
unwittingly introduced into the output.  However it is now perfectly
acceptable to pass SXML to ‘you-said’; in fact, that is the big
advantage of SXML over everything-as-a-string.

     (sxml->xml (you-said (you-said "<Hi!>")))
     ⊣ <p>You said: <p>You said: &lt;Hi!&gt;</p></p>

   The SXML types allow procedures to _compose_.  The types make
manifest which parts are HTML elements, and which are text.  So you
needn't worry about escaping user input; the type transition back to a
string handles that for you.  XSS vulnerabilities are a thing of the
past.

   Well.  That's all very nice and opinionated and such, but how do I
use the thing?  Read on!

7.3.2 Universal Resource Identifiers
------------------------------------

Guile provides a standard data type for Universal Resource Identifiers
(URIs), as defined in RFC 3986.

   The generic URI syntax is as follows:

     URI-reference := [scheme ":"] ["//" [userinfo "@"] host [":" port]] path \
                      [ "?" query ] [ "#" fragment ]

   For example, in the URI, ‘http://www.gnu.org/help/’, the scheme is
‘http’, the host is ‘www.gnu.org’, the path is ‘/help/’, and there is no
userinfo, port, query, or fragment.

   Userinfo is something of an abstraction, as some legacy URI schemes
allowed userinfo of the form ‘USERNAME:PASSWD’.  But since passwords do
not belong in URIs, the RFC does not want to condone this practice, so
it calls anything before the ‘@’ sign “userinfo”.

     (use-modules (web uri))

   The following procedures can be found in the ‘(web uri)’ module.
Load it into your Guile, using a form like the above, to have access to
them.

   The most common way to build a URI from Scheme is with the
‘build-uri’ function.

 -- Scheme Procedure: build-uri scheme [#:userinfo=#f] [#:host=#f]
          [#:port=#f] [#:path=""] [#:query=#f] [#:fragment=#f]
          [#:validate?=#t]
     Construct a URI. SCHEME should be a symbol, PORT either a positive,
     exact integer or ‘#f’, and the rest of the fields are either
     strings or ‘#f’.  If VALIDATE? is true, also run some consistency
     checks to make sure that the constructed URI is valid.
 -- Scheme Procedure: uri? obj
     Return ‘#t’ if OBJ is a URI.

   Guile, URIs are represented as URI records, with a number of
associated accessors.

 -- Scheme Procedure: uri-scheme uri
 -- Scheme Procedure: uri-userinfo uri
 -- Scheme Procedure: uri-host uri
 -- Scheme Procedure: uri-port uri
 -- Scheme Procedure: uri-path uri
 -- Scheme Procedure: uri-query uri
 -- Scheme Procedure: uri-fragment uri
     Field accessors for the URI record type.  The URI scheme will be a
     symbol, or ‘#f’ if the object is a relative-ref (see below).  The
     port will be either a positive, exact integer or ‘#f’, and the rest
     of the fields will be either strings or ‘#f’ if not present.

 -- Scheme Procedure: string->uri string
     Parse STRING into a URI object.  Return ‘#f’ if the string could
     not be parsed.

 -- Scheme Procedure: uri->string uri [#:include-fragment?=#t]
     Serialize URI to a string.  If the URI has a port that is the
     default port for its scheme, the port is not included in the
     serialization.  If INCLUDE-FRAGMENT? is given as false, the
     resulting string will omit the fragment (if any).

 -- Scheme Procedure: declare-default-port! scheme port
     Declare a default port for the given URI scheme.

 -- Scheme Procedure: uri-decode str [#:encoding="utf-8"]
          [#:decode-plus-to-space? #t]
     Percent-decode the given STR, according to ENCODING, which should
     be the name of a character encoding.

     Note that this function should not generally be applied to a full
     URI string.  For paths, use ‘split-and-decode-uri-path’ instead.
     For query strings, split the query on ‘&’ and ‘=’ boundaries, and
     decode the components separately.

     Note also that percent-encoded strings encode _bytes_, not
     characters.  There is no guarantee that a given byte sequence is a
     valid string encoding.  Therefore this routine may signal an error
     if the decoded bytes are not valid for the given encoding.  Pass
     ‘#f’ for ENCODING if you want decoded bytes as a bytevector
     directly.  See ‘set-port-encoding!’, for more information
     on character encodings.

     If DECODE-PLUS-TO-SPACE? is true, which is the default, also
     replace instances of the plus character ‘+’ with a space character.
     This is needed when parsing ‘application/x-www-form-urlencoded’
     data.

     Returns a string of the decoded characters, or a bytevector if
     ENCODING was ‘#f’.

 -- Scheme Procedure: uri-encode str [#:encoding="utf-8"]
          [#:unescaped-chars]
     Percent-encode any character not in the character set,
     UNESCAPED-CHARS.

     The default character set includes alphanumerics from ASCII, as
     well as the special characters ‘-’, ‘.’, ‘_’, and ‘~’.  Any other
     character will be percent-encoded, by writing out the character to
     a bytevector within the given ENCODING, then encoding each byte as
     ‘%HH’, where HH is the hexadecimal representation of the byte.

 -- Scheme Procedure: split-and-decode-uri-path path
     Split PATH into its components, and decode each component, removing
     empty components.

     For example, ‘"/foo/bar%20baz/"’ decodes to the two-element list,
     ‘("foo" "bar baz")’.

 -- Scheme Procedure: encode-and-join-uri-path parts
     URI-encode each element of PARTS, which should be a list of
     strings, and join the parts together with ‘/’ as a delimiter.

     For example, the list ‘("scrambled eggs" "biscuits&gravy")’ encodes
     as ‘"scrambled%20eggs/biscuits%26gravy"’.

Subtypes of URI
...............

As we noted above, not all URI objects have a scheme.  You might have
noted in the "generic URI syntax" example that the left-hand side of
that grammar definition was URI-reference, not URI. A “URI-reference” is
a generalization of a URI where the scheme is optional.  If no scheme is
specified, it is taken to be relative to some other related URI. A
common use of URI references is when you want to be vague regarding the
choice of HTTP or HTTPS - serving a web page referring to ‘/foo.css’
will use HTTPS if loaded over HTTPS, or HTTP otherwise.

 -- Scheme Procedure: build-uri-reference [#:scheme=#f] [#:userinfo=#f]
          [#:host=#f] [#:port=#f] [#:path=""] [#:query=#f]
          [#:fragment=#f] [#:validate?=#t]
     Like ‘build-uri’, but with an optional scheme.
 -- Scheme Procedure: uri-reference? obj
     Return ‘#t’ if OBJ is a URI-reference.  This is the most general
     URI predicate, as it includes not only full URIs that have schemes
     (those that match ‘uri?’) but also URIs without schemes.

   It's also possible to build a “relative-ref”: a URI-reference that
explicitly lacks a scheme.

 -- Scheme Procedure: build-relative-ref [#:userinfo=#f] [#:host=#f]
          [#:port=#f] [#:path=""] [#:query=#f] [#:fragment=#f]
          [#:validate?=#t]
     Like ‘build-uri’, but with no scheme.
 -- Scheme Procedure: relative-ref? obj
     Return ‘#t’ if OBJ is a "relative-ref": a URI-reference that has no
     scheme.  Every URI-reference will either match ‘uri?’ or
     ‘relative-ref?’ (but not both).

   In case it's not clear from the above, the most general of these URI
types is the URI-reference, with ‘build-uri-reference’ as the most
general constructor.  ‘build-uri’ and ‘build-relative-ref’ enforce
enforce specific restrictions on the URI-reference.  The most generic
URI parser is then ‘string->uri-reference’, and there is also a parser
for when you know that you want a relative-ref.

   Note that ‘uri?’ will only return ‘#t’ for URI objects that have
schemes; that is, it rejects relative-refs.

 -- Scheme Procedure: string->uri-reference string
     Parse STRING into a URI object, while not requiring a scheme.
     Return ‘#f’ if the string could not be parsed.

 -- Scheme Procedure: string->relative-ref string
     Parse STRING into a URI object, while asserting that no scheme is
     present.  Return ‘#f’ if the string could not be parsed.

7.3.3 The Hyper-Text Transfer Protocol
--------------------------------------

The initial motivation for including web functionality in Guile, rather
than rely on an external package, was to establish a standard base on
which people can share code.  To that end, we continue the focus on data
types by providing a number of low-level parsers and unparsers for
elements of the HTTP protocol.

   If you are want to skip the low-level details for now and move on to
web pages, see Web Client, and Web Server.  Otherwise, load
the HTTP module, and read on.

     (use-modules (web http))

   The focus of the ‘(web http)’ module is to parse and unparse standard
HTTP headers, representing them to Guile as native data structures.  For
example, a ‘Date:’ header will be represented as a SRFI-19 date record
(see SRFI-19), rather than as a string.

   Guile tries to follow RFCs fairly strictly--the road to perdition
being paved with compatibility hacks--though some allowances are made
for not-too-divergent texts.

   Header names are represented as lower-case symbols.

 -- Scheme Procedure: string->header name
     Parse NAME to a symbolic header name.

 -- Scheme Procedure: header->string sym
     Return the string form for the header named SYM.

   For example:

     (string->header "Content-Length")
     ⇒ content-length
     (header->string 'content-length)
     ⇒ "Content-Length"

     (string->header "FOO")
     ⇒ foo
     (header->string 'foo)
     ⇒ "Foo"

   Guile keeps a registry of known headers, their string names, and some
parsing and serialization procedures.  If a header is unknown, its
string name is simply its symbol name in title-case.

 -- Scheme Procedure: known-header? sym
     Return ‘#t’ if SYM is a known header, with associated parsers and
     serialization procedures, or ‘#f’ otherwise.

 -- Scheme Procedure: header-parser sym
     Return the value parser for headers named SYM.  The result is a
     procedure that takes one argument, a string, and returns the parsed
     value.  If the header isn't known to Guile, a default parser is
     returned that passes through the string unchanged.

 -- Scheme Procedure: header-validator sym
     Return a predicate which returns ‘#t’ if the given value is valid
     for headers named SYM.  The default validator for unknown headers
     is ‘string?’.

 -- Scheme Procedure: header-writer sym
     Return a procedure that writes values for headers named SYM to a
     port.  The resulting procedure takes two arguments: a value and a
     port.  The default writer is ‘display’.

   For more on the set of headers that Guile knows about out of the box,
see HTTP Headers.  To add your own, use the ‘declare-header!’
procedure:

 -- Scheme Procedure: declare-header! name parser validator writer
          [#:multiple?=#f]
     Declare a parser, validator, and writer for a given header.

   For example, let's say you are running a web server behind some sort
of proxy, and your proxy adds an ‘X-Client-Address’ header, indicating
the IPv4 address of the original client.  You would like for the HTTP
request record to parse out this header to a Scheme value, instead of
leaving it as a string.  You could register this header with Guile's
HTTP stack like this:

     (declare-header! "X-Client-Address"
       (lambda (str)
         (inet-pton AF_INET str))
       (lambda (ip)
         (and (integer? ip) (exact? ip) (<= 0 ip #xffffffff)))
       (lambda (ip port)
         (display (inet-ntop AF_INET ip) port)))

 -- Scheme Procedure: declare-opaque-header! name
     A specialised version of ‘declare-header!’ for the case in which
     you want a header's value to be returned/written "as-is".

 -- Scheme Procedure: valid-header? sym val
     Return a true value if VAL is a valid Scheme value for the header
     with name SYM, or ‘#f’ otherwise.

   Now that we have a generic interface for reading and writing headers,
we do just that.

 -- Scheme Procedure: read-header port
     Read one HTTP header from PORT.  Return two values: the header name
     and the parsed Scheme value.  May raise an exception if the header
     was known but the value was invalid.

     Returns the end-of-file object for both values if the end of the
     message body was reached (i.e., a blank line).

 -- Scheme Procedure: parse-header name val
     Parse VAL, a string, with the parser for the header named NAME.
     Returns the parsed value.

 -- Scheme Procedure: write-header name val port
     Write the given header name and value to PORT, using the writer
     from ‘header-writer’.

 -- Scheme Procedure: read-headers port
     Read the headers of an HTTP message from PORT, returning them as an
     ordered alist.

 -- Scheme Procedure: write-headers headers port
     Write the given header alist to PORT.  Doesn't write the final
     ‘\r\n’, as the user might want to add another header.

   The ‘(web http)’ module also has some utility procedures to read and
write request and response lines.

 -- Scheme Procedure: parse-http-method str [start] [end]
     Parse an HTTP method from STR.  The result is an upper-case symbol,
     like ‘GET’.

 -- Scheme Procedure: parse-http-version str [start] [end]
     Parse an HTTP version from STR, returning it as a major-minor pair.
     For example, ‘HTTP/1.1’ parses as the pair of integers, ‘(1 . 1)’.

 -- Scheme Procedure: parse-request-uri str [start] [end]
     Parse a URI from an HTTP request line.  Note that URIs in requests
     do not have to have a scheme or host name.  The result is a URI
     object.

 -- Scheme Procedure: read-request-line port
     Read the first line of an HTTP request from PORT, returning three
     values: the method, the URI, and the version.

 -- Scheme Procedure: write-request-line method uri version port
     Write the first line of an HTTP request to PORT.

 -- Scheme Procedure: read-response-line port
     Read the first line of an HTTP response from PORT, returning three
     values: the HTTP version, the response code, and the "reason
     phrase".

 -- Scheme Procedure: write-response-line version code reason-phrase
          port
     Write the first line of an HTTP response to PORT.

7.3.4 HTTP Headers
------------------

In addition to defining the infrastructure to parse headers, the ‘(web
http)’ module defines specific parsers and unparsers for all headers
defined in the HTTP/1.1 standard.

   For example, if you receive a header named ‘Accept-Language’ with a
value ‘en, es;q=0.8’, Guile parses it as a quality list (defined below):

     (parse-header 'accept-language "en, es;q=0.8")
     ⇒ ((1000 . "en") (800 . "es"))

   The format of the value for ‘Accept-Language’ headers is defined
below, along with all other headers defined in the HTTP standard.  (If
the header were unknown, the value would have been returned as a
string.)

   For brevity, the header definitions below are given in the form, TYPE
‘NAME’, indicating that values for the header ‘NAME’ will be of the
given TYPE.  Since Guile internally treats header names in lower case,
in this document we give types title-cased names.  A short description
of the each header's purpose and an example follow.

   For full details on the meanings of all of these headers, see the
HTTP 1.1 standard, RFC 2616.

7.3.4.1 HTTP Header Types
.........................

Here we define the types that are used below, when defining headers.

 -- HTTP Header Type: Date
     A SRFI-19 date.

 -- HTTP Header Type: KVList
     A list whose elements are keys or key-value pairs.  Keys are parsed
     to symbols.  Values are strings by default.  Non-string values are
     the exception, and are mentioned explicitly below, as appropriate.

 -- HTTP Header Type: SList
     A list of strings.

 -- HTTP Header Type: Quality
     An exact integer between 0 and 1000.  Qualities are used to express
     preference, given multiple options.  An option with a quality of
     870, for example, is preferred over an option with quality 500.

     (Qualities are written out over the wire as numbers between 0.0 and
     1.0, but since the standard only allows three digits after the
     decimal, it's equivalent to integers between 0 and 1000, so that's
     what Guile uses.)

 -- HTTP Header Type: QList
     A quality list: a list of pairs, the car of which is a quality, and
     the cdr a string.  Used to express a list of options, along with
     their qualities.

 -- HTTP Header Type: ETag
     An entity tag, represented as a pair.  The car of the pair is an
     opaque string, and the cdr is ‘#t’ if the entity tag is a "strong"
     entity tag, and ‘#f’ otherwise.

7.3.4.2 General Headers
.......................

General HTTP headers may be present in any HTTP message.

 -- HTTP Header: KVList cache-control
     A key-value list of cache-control directives.  See RFC 2616, for
     more details.

     If present, parameters to ‘max-age’, ‘max-stale’, ‘min-fresh’, and
     ‘s-maxage’ are all parsed as non-negative integers.

     If present, parameters to ‘private’ and ‘no-cache’ are parsed as
     lists of header names, as symbols.

          (parse-header 'cache-control "no-cache,no-store"
          ⇒ (no-cache no-store)
          (parse-header 'cache-control "no-cache=\"Authorization,Date\",no-store"
          ⇒ ((no-cache . (authorization date)) no-store)
          (parse-header 'cache-control "no-cache=\"Authorization,Date\",max-age=10"
          ⇒ ((no-cache . (authorization date)) (max-age . 10))

 -- HTTP Header: List connection
     A list of header names that apply only to this HTTP connection, as
     symbols.  Additionally, the symbol ‘close’ may be present, to
     indicate that the server should close the connection after
     responding to the request.
          (parse-header 'connection "close")
          ⇒ (close)

 -- HTTP Header: Date date
     The date that a given HTTP message was originated.
          (parse-header 'date "Tue, 15 Nov 1994 08:12:31 GMT")
          ⇒ #<date ...>

 -- HTTP Header: KVList pragma
     A key-value list of implementation-specific directives.
          (parse-header 'pragma "no-cache, broccoli=tasty")
          ⇒ (no-cache (broccoli . "tasty"))

 -- HTTP Header: List trailer
     A list of header names which will appear after the message body,
     instead of with the message headers.
          (parse-header 'trailer "ETag")
          ⇒ (etag)

 -- HTTP Header: List transfer-encoding
     A list of transfer codings, expressed as key-value lists.  The only
     transfer coding defined by the specification is ‘chunked’.
          (parse-header 'transfer-encoding "chunked")
          ⇒ ((chunked))

 -- HTTP Header: List upgrade
     A list of strings, indicating additional protocols that a server
     could use in response to a request.
          (parse-header 'upgrade "WebSocket")
          ⇒ ("WebSocket")

   FIXME: parse out more fully?
 -- HTTP Header: List via
     A list of strings, indicating the protocol versions and hosts of
     intermediate servers and proxies.  There may be multiple ‘via’
     headers in one message.
          (parse-header 'via "1.0 venus, 1.1 mars")
          ⇒ ("1.0 venus" "1.1 mars")

 -- HTTP Header: List warning
     A list of warnings given by a server or intermediate proxy.  Each
     warning is a itself a list of four elements: a code, as an exact
     integer between 0 and 1000, a host as a string, the warning text as
     a string, and either ‘#f’ or a SRFI-19 date.

     There may be multiple ‘warning’ headers in one message.
          (parse-header 'warning "123 foo \"core breach imminent\"")
          ⇒ ((123 "foo" "core-breach imminent" #f))

7.3.4.3 Entity Headers
......................

Entity headers may be present in any HTTP message, and refer to the
resource referenced in the HTTP request or response.

 -- HTTP Header: List allow
     A list of allowed methods on a given resource, as symbols.
          (parse-header 'allow "GET, HEAD")
          ⇒ (GET HEAD)

 -- HTTP Header: List content-encoding
     A list of content codings, as symbols.
          (parse-header 'content-encoding "gzip")
          ⇒ (gzip)

 -- HTTP Header: List content-language
     The languages that a resource is in, as strings.
          (parse-header 'content-language "en")
          ⇒ ("en")

 -- HTTP Header: UInt content-length
     The number of bytes in a resource, as an exact, non-negative
     integer.
          (parse-header 'content-length "300")
          ⇒ 300

 -- HTTP Header: URI content-location
     The canonical URI for a resource, in the case that it is also
     accessible from a different URI.
          (parse-header 'content-location "http://example.com/foo")
          ⇒ #<<uri> ...>

 -- HTTP Header: String content-md5
     The MD5 digest of a resource.
          (parse-header 'content-md5 "ffaea1a79810785575e29e2bd45e2fa5")
          ⇒ "ffaea1a79810785575e29e2bd45e2fa5"

 -- HTTP Header: List content-range
     Range specification as a list of three elements: the symbol
     ‘bytes’, either the symbol ‘*’ or a pair of integers indicating the
     byte range, and either ‘*’ or an integer indicating the instance
     length.  Used to indicate that a response only includes part of a
     resource.
          (parse-header 'content-range "bytes 10-20/*")
          ⇒ (bytes (10 . 20) *)

 -- HTTP Header: List content-type
     The MIME type of a resource, as a symbol, along with any
     parameters.
          (parse-header 'content-type "text/plain")
          ⇒ (text/plain)
          (parse-header 'content-type "text/plain;charset=utf-8")
          ⇒ (text/plain (charset . "utf-8"))
     Note that the ‘charset’ parameter is something of a misnomer, and
     the HTTP specification admits this.  It specifies the _encoding_ of
     the characters, not the character set.

 -- HTTP Header: Date expires
     The date/time after which the resource given in a response is
     considered stale.
          (parse-header 'expires "Tue, 15 Nov 1994 08:12:31 GMT")
          ⇒ #<date ...>

 -- HTTP Header: Date last-modified
     The date/time on which the resource given in a response was last
     modified.
          (parse-header 'expires "Tue, 15 Nov 1994 08:12:31 GMT")
          ⇒ #<date ...>

7.3.4.4 Request Headers
.......................

Request headers may only appear in an HTTP request, not in a response.

 -- HTTP Header: List accept
     A list of preferred media types for a response.  Each element of
     the list is itself a list, in the same format as ‘content-type’.
          (parse-header 'accept "text/html,text/plain;charset=utf-8")
          ⇒ ((text/html) (text/plain (charset . "utf-8")))
     Preference is expressed with quality values:
          (parse-header 'accept "text/html;q=0.8,text/plain;q=0.6")
          ⇒ ((text/html (q . 800)) (text/plain (q . 600)))

 -- HTTP Header: QList accept-charset
     A quality list of acceptable charsets.  Note again that what HTTP
     calls a "charset" is what Guile calls a "character encoding".
          (parse-header 'accept-charset "iso-8859-5, unicode-1-1;q=0.8")
          ⇒ ((1000 . "iso-8859-5") (800 . "unicode-1-1"))

 -- HTTP Header: QList accept-encoding
     A quality list of acceptable content codings.
          (parse-header 'accept-encoding "gzip,identity=0.8")
          ⇒ ((1000 . "gzip") (800 . "identity"))

 -- HTTP Header: QList accept-language
     A quality list of acceptable languages.
          (parse-header 'accept-language "cn,en=0.75")
          ⇒ ((1000 . "cn") (750 . "en"))

 -- HTTP Header: Pair authorization
     Authorization credentials.  The car of the pair indicates the
     authentication scheme, like ‘basic’.  For basic authentication, the
     cdr of the pair will be the base64-encoded ‘USER:PASS’ string.  For
     other authentication schemes, like ‘digest’, the cdr will be a
     key-value list of credentials.
          (parse-header 'authorization "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
          ⇒ (basic . "QWxhZGRpbjpvcGVuIHNlc2FtZQ==")

 -- HTTP Header: List expect
     A list of expectations that a client has of a server.  The
     expectations are key-value lists.
          (parse-header 'expect "100-continue")
          ⇒ ((100-continue))

 -- HTTP Header: String from
     The email address of a user making an HTTP request.
          (parse-header 'from "bob@example.com")
          ⇒ "bob@example.com"

 -- HTTP Header: Pair host
     The host for the resource being requested, as a hostname-port pair.
     If no port is given, the port is ‘#f’.
          (parse-header 'host "gnu.org:80")
          ⇒ ("gnu.org" . 80)
          (parse-header 'host "gnu.org")
          ⇒ ("gnu.org" . #f)

 -- HTTP Header: *|List if-match
     A set of etags, indicating that the request should proceed if and
     only if the etag of the resource is in that set.  Either the symbol
     ‘*’, indicating any etag, or a list of entity tags.
          (parse-header 'if-match "*")
          ⇒ *
          (parse-header 'if-match "asdfadf")
          ⇒ (("asdfadf" . #t))
          (parse-header 'if-match W/"asdfadf")
          ⇒ (("asdfadf" . #f))

 -- HTTP Header: Date if-modified-since
     Indicates that a response should proceed if and only if the
     resource has been modified since the given date.
          (parse-header 'if-modified-since "Tue, 15 Nov 1994 08:12:31 GMT")
          ⇒ #<date ...>

 -- HTTP Header: *|List if-none-match
     A set of etags, indicating that the request should proceed if and
     only if the etag of the resource is not in the set.  Either the
     symbol ‘*’, indicating any etag, or a list of entity tags.
          (parse-header 'if-none-match "*")
          ⇒ *

 -- HTTP Header: ETag|Date if-range
     Indicates that the range request should proceed if and only if the
     resource matches a modification date or an etag.  Either an entity
     tag, or a SRFI-19 date.
          (parse-header 'if-range "\"original-etag\"")
          ⇒ ("original-etag" . #t)

 -- HTTP Header: Date if-unmodified-since
     Indicates that a response should proceed if and only if the
     resource has not been modified since the given date.
          (parse-header 'if-not-modified-since "Tue, 15 Nov 1994 08:12:31 GMT")
          ⇒ #<date ...>

 -- HTTP Header: UInt max-forwards
     The maximum number of proxy or gateway hops that a request should
     be subject to.
          (parse-header 'max-forwards "10")
          ⇒ 10

 -- HTTP Header: Pair proxy-authorization
     Authorization credentials for a proxy connection.  See the
     documentation for ‘authorization’ above for more information on the
     format.
          (parse-header 'proxy-authorization "Digest foo=bar,baz=qux"
          ⇒ (digest (foo . "bar") (baz . "qux"))

 -- HTTP Header: Pair range
     A range request, indicating that the client wants only part of a
     resource.  The car of the pair is the symbol ‘bytes’, and the cdr
     is a list of pairs.  Each element of the cdr indicates a range; the
     car is the first byte position and the cdr is the last byte
     position, as integers, or ‘#f’ if not given.
          (parse-header 'range "bytes=10-30,50-")
          ⇒ (bytes (10 . 30) (50 . #f))

 -- HTTP Header: URI referer
     The URI of the resource that referred the user to this resource.
     The name of the header is a misspelling, but we are stuck with it.
          (parse-header 'referer "http://www.gnu.org/")
          ⇒ #<uri ...>

 -- HTTP Header: List te
     A list of transfer codings, expressed as key-value lists.  A common
     transfer coding is ‘trailers’.
          (parse-header 'te "trailers")
          ⇒ ((trailers))

 -- HTTP Header: String user-agent
     A string indicating the user agent making the request.  The
     specification defines a structured format for this header, but it
     is widely disregarded, so Guile does not attempt to parse strictly.
          (parse-header 'user-agent "Mozilla/5.0")
          ⇒ "Mozilla/5.0"

7.3.4.5 Response Headers
........................

 -- HTTP Header: List accept-ranges
     A list of range units that the server supports, as symbols.
          (parse-header 'accept-ranges "bytes")
          ⇒ (bytes)

 -- HTTP Header: UInt age
     The age of a cached response, in seconds.
          (parse-header 'age "3600")
          ⇒ 3600

 -- HTTP Header: ETag etag
     The entity-tag of the resource.
          (parse-header 'etag "\"foo\"")
          ⇒ ("foo" . #t)

 -- HTTP Header: URI-reference location
     A URI reference on which a request may be completed.  Used in
     combination with a redirecting status code to perform client-side
     redirection.
          (parse-header 'location "http://example.com/other")
          ⇒ #<uri ...>

 -- HTTP Header: List proxy-authenticate
     A list of challenges to a proxy, indicating the need for
     authentication.
          (parse-header 'proxy-authenticate "Basic realm=\"foo\"")
          ⇒ ((basic (realm . "foo")))

 -- HTTP Header: UInt|Date retry-after
     Used in combination with a server-busy status code, like 503, to
     indicate that a client should retry later.  Either a number of
     seconds, or a date.
          (parse-header 'retry-after "60")
          ⇒ 60

 -- HTTP Header: String server
     A string identifying the server.
          (parse-header 'server "My first web server")
          ⇒ "My first web server"

 -- HTTP Header: *|List vary
     A set of request headers that were used in computing this response.
     Used to indicate that server-side content negotiation was
     performed, for example in response to the ‘accept-language’ header.
     Can also be the symbol ‘*’, indicating that all headers were
     considered.
          (parse-header 'vary "Accept-Language, Accept")
          ⇒ (accept-language accept)

 -- HTTP Header: List www-authenticate
     A list of challenges to a user, indicating the need for
     authentication.
          (parse-header 'www-authenticate "Basic realm=\"foo\"")
          ⇒ ((basic (realm . "foo")))

7.3.5 Transfer Codings
----------------------

HTTP 1.1 allows for various transfer codings to be applied to message
bodies.  These include various types of compression, and HTTP chunked
encoding.  Currently, only chunked encoding is supported by guile.

   Chunked coding is an optional coding that may be applied to message
bodies, to allow messages whose length is not known beforehand to be
returned.  Such messages can be split into chunks, terminated by a final
zero length chunk.

   In order to make dealing with encodings more simple, guile provides
procedures to create ports that "wrap" existing ports, applying
transformations transparently under the hood.

   These procedures are in the ‘(web http)’ module.

     (use-modules (web http))

 -- Scheme Procedure: make-chunked-input-port port [#:keep-alive?=#f]
     Returns a new port, that transparently reads and decodes
     chunk-encoded data from PORT.  If no more chunk-encoded data is
     available, it returns the end-of-file object.  When the port is
     closed, PORT will also be closed, unless KEEP-ALIVE? is true.

     If the chunked input ends prematurely, a
     ‘&chunked-input-ended-promaturely’ exception will be raised.

     (use-modules (ice-9 rdelim))

     (define s "5\r\nFirst\r\nA\r\n line\n Sec\r\n8\r\nond line\r\n0\r\n")
     (define p (make-chunked-input-port (open-input-string s)))
     (read-line s)
     ⇒ "First line"
     (read-line s)
     ⇒ "Second line"

 -- Scheme Procedure: make-chunked-output-port port [#:keep-alive?=#f]
     Returns a new port, which transparently encodes data as
     chunk-encoded before writing it to PORT.  Whenever a write occurs
     on this port, it buffers it, until the port is flushed, at which
     point it writes a chunk containing all the data written so far.
     When the port is closed, the data remaining is written to PORT, as
     is the terminating zero chunk.  It also causes PORT to be closed,
     unless KEEP-ALIVE? is true.

     Note.  Forcing a chunked output port when there is no data is
     buffered does not write a zero chunk, as this would cause the data
     to be interpreted incorrectly by the client.

     (call-with-output-string
       (lambda (out)
         (define out* (make-chunked-output-port out #:keep-alive? #t))
         (display "first chunk" out*)
         (force-output out*)
         (force-output out*) ; note this does not write a zero chunk
         (display "second chunk" out*)
         (close-port out*)))
     ⇒ "b\r\nfirst chunk\r\nc\r\nsecond chunk\r\n0\r\n"

7.3.6 HTTP Requests
-------------------

     (use-modules (web request))

   The request module contains a data type for HTTP requests.

7.3.6.1 An Important Note on Character Sets
...........................................

HTTP requests consist of two parts: the request proper, consisting of a
request line and a set of headers, and (optionally) a body.  The body
might have a binary content-type, and even in the textual case its
length is specified in bytes, not characters.

   Therefore, HTTP is a fundamentally binary protocol.  However the
request line and headers are specified to be in a subset of ASCII, so
they can be treated as text, provided that the port's encoding is set to
an ASCII-compatible one-byte-per-character encoding.  ISO-8859-1
(latin-1) is just such an encoding, and happens to be very efficient for
Guile.

   So what Guile does when reading requests from the wire, or writing
them out, is to set the port's encoding to latin-1, and treating the
request headers as text.

   The request body is another issue.  For binary data, the data is
probably in a bytevector, so we use the R6RS binary output procedures to
write out the binary payload.  Textual data usually has to be written
out to some character encoding, usually UTF-8, and then the resulting
bytevector is written out to the port.

   In summary, Guile reads and writes HTTP over latin-1 sockets, without
any loss of generality.

7.3.6.2 Request API
...................

 -- Scheme Procedure: request? obj
 -- Scheme Procedure: request-method request
 -- Scheme Procedure: request-uri request
 -- Scheme Procedure: request-version request
 -- Scheme Procedure: request-headers request
 -- Scheme Procedure: request-meta request
 -- Scheme Procedure: request-port request
     A predicate and field accessors for the request type.  The fields
     are as follows:
     ‘method’
          The HTTP method, for example, ‘GET’.
     ‘uri’
          The URI as a URI record.
     ‘version’
          The HTTP version pair, like ‘(1 . 1)’.
     ‘headers’
          The request headers, as an alist of parsed values.
     ‘meta’
          An arbitrary alist of other data, for example information
          returned in the ‘sockaddr’ from ‘accept’ (see Network Sockets and Communication).
     ‘port’
          The port on which to read or write a request body, if any.

 -- Scheme Procedure: read-request port [meta='()]
     Read an HTTP request from PORT, optionally attaching the given
     metadata, META.

     As a side effect, sets the encoding on PORT to ISO-8859-1
     (latin-1), so that reading one character reads one byte.  See the
     discussion of character sets above, for more information.

     Note that the body is not part of the request.  Once you have read
     a request, you may read the body separately, and likewise for
     writing requests.

 -- Scheme Procedure: build-request uri [#:method='GET] [#:version='(1 .
          1)] [#:headers='()] [#:port=#f] [#:meta='()]
          [#:validate-headers?=#t]
     Construct an HTTP request object.  If VALIDATE-HEADERS? is true,
     the headers are each run through their respective validators.

 -- Scheme Procedure: write-request r port
     Write the given HTTP request to PORT.

     Return a new request, whose ‘request-port’ will continue writing on
     PORT, perhaps using some transfer encoding.

 -- Scheme Procedure: read-request-body r
     Reads the request body from R, as a bytevector.  Return ‘#f’ if
     there was no request body.

 -- Scheme Procedure: write-request-body r bv
     Write BV, a bytevector, to the port corresponding to the HTTP
     request R.

   The various headers that are typically associated with HTTP requests
may be accessed with these dedicated accessors.  See HTTP Headers,
for more information on the format of parsed headers.

 -- Scheme Procedure: request-accept request [default='()]
 -- Scheme Procedure: request-accept-charset request [default='()]
 -- Scheme Procedure: request-accept-encoding request [default='()]
 -- Scheme Procedure: request-accept-language request [default='()]
 -- Scheme Procedure: request-allow request [default='()]
 -- Scheme Procedure: request-authorization request [default=#f]
 -- Scheme Procedure: request-cache-control request [default='()]
 -- Scheme Procedure: request-connection request [default='()]
 -- Scheme Procedure: request-content-encoding request [default='()]
 -- Scheme Procedure: request-content-language request [default='()]
 -- Scheme Procedure: request-content-length request [default=#f]
 -- Scheme Procedure: request-content-location request [default=#f]
 -- Scheme Procedure: request-content-md5 request [default=#f]
 -- Scheme Procedure: request-content-range request [default=#f]
 -- Scheme Procedure: request-content-type request [default=#f]
 -- Scheme Procedure: request-date request [default=#f]
 -- Scheme Procedure: request-expect request [default='()]
 -- Scheme Procedure: request-expires request [default=#f]
 -- Scheme Procedure: request-from request [default=#f]
 -- Scheme Procedure: request-host request [default=#f]
 -- Scheme Procedure: request-if-match request [default=#f]
 -- Scheme Procedure: request-if-modified-since request [default=#f]
 -- Scheme Procedure: request-if-none-match request [default=#f]
 -- Scheme Procedure: request-if-range request [default=#f]
 -- Scheme Procedure: request-if-unmodified-since request [default=#f]
 -- Scheme Procedure: request-last-modified request [default=#f]
 -- Scheme Procedure: request-max-forwards request [default=#f]
 -- Scheme Procedure: request-pragma request [default='()]
 -- Scheme Procedure: request-proxy-authorization request [default=#f]
 -- Scheme Procedure: request-range request [default=#f]
 -- Scheme Procedure: request-referer request [default=#f]
 -- Scheme Procedure: request-te request [default=#f]
 -- Scheme Procedure: request-trailer request [default='()]
 -- Scheme Procedure: request-transfer-encoding request [default='()]
 -- Scheme Procedure: request-upgrade request [default='()]
 -- Scheme Procedure: request-user-agent request [default=#f]
 -- Scheme Procedure: request-via request [default='()]
 -- Scheme Procedure: request-warning request [default='()]
     Return the given request header, or DEFAULT if none was present.

 -- Scheme Procedure: request-absolute-uri r [default-host=#f]
          [default-port=#f] [default-scheme=#f]
     A helper routine to determine the absolute URI of a request, using
     the ‘host’ header and the default scheme, host and port.  If there
     is no default scheme and the URI is not itself absolute, an error
     is signaled.

7.3.7 HTTP Responses
--------------------

     (use-modules (web response))

   As with requests (see Requests), Guile offers a data type for
HTTP responses.  Again, the body is represented separately from the
request.

 -- Scheme Procedure: response? obj
 -- Scheme Procedure: response-version response
 -- Scheme Procedure: response-code response
 -- Scheme Procedure: response-reason-phrase response
 -- Scheme Procedure: response-headers response
 -- Scheme Procedure: response-port response
     A predicate and field accessors for the response type.  The fields
     are as follows:
     ‘version’
          The HTTP version pair, like ‘(1 . 1)’.
     ‘code’
          The HTTP response code, like ‘200’.
     ‘reason-phrase’
          The reason phrase, or the standard reason phrase for the
          response's code.
     ‘headers’
          The response headers, as an alist of parsed values.
     ‘port’
          The port on which to read or write a response body, if any.

 -- Scheme Procedure: read-response port
     Read an HTTP response from PORT.

     As a side effect, sets the encoding on PORT to ISO-8859-1
     (latin-1), so that reading one character reads one byte.  See the
     discussion of character sets in Responses, for more
     information.

 -- Scheme Procedure: build-response [#:version='(1 . 1)] [#:code=200]
          [#:reason-phrase=#f] [#:headers='()] [#:port=#f]
          [#:validate-headers?=#t]
     Construct an HTTP response object.  If VALIDATE-HEADERS? is true,
     the headers are each run through their respective validators.

 -- Scheme Procedure: adapt-response-version response version
     Adapt the given response to a different HTTP version.  Return a new
     HTTP response.

     The idea is that many applications might just build a response for
     the default HTTP version, and this method could handle a number of
     programmatic transformations to respond to older HTTP versions (0.9
     and 1.0).  But currently this function is a bit heavy-handed, just
     updating the version field.

 -- Scheme Procedure: write-response r port
     Write the given HTTP response to PORT.

     Return a new response, whose ‘response-port’ will continue writing
     on PORT, perhaps using some transfer encoding.

 -- Scheme Procedure: response-must-not-include-body? r
     Some responses, like those with status code 304, are specified as
     never having bodies.  This predicate returns ‘#t’ for those
     responses.

     Note also, though, that responses to ‘HEAD’ requests must also not
     have a body.

 -- Scheme Procedure: response-body-port r [#:decode?=#t]
          [#:keep-alive?=#t]
     Return an input port from which the body of R can be read.  The
     encoding of the returned port is set according to R's
     ‘content-type’ header, when it's textual, except if DECODE? is
     ‘#f’.  Return ‘#f’ when no body is available.

     When KEEP-ALIVE? is ‘#f’, closing the returned port also closes R's
     response port.

 -- Scheme Procedure: read-response-body r
     Read the response body from R, as a bytevector.  Returns ‘#f’ if
     there was no response body.

 -- Scheme Procedure: write-response-body r bv
     Write BV, a bytevector, to the port corresponding to the HTTP
     response R.

   As with requests, the various headers that are typically associated
with HTTP responses may be accessed with these dedicated accessors.
See HTTP Headers, for more information on the format of parsed
headers.

 -- Scheme Procedure: response-accept-ranges response [default=#f]
 -- Scheme Procedure: response-age response [default='()]
 -- Scheme Procedure: response-allow response [default='()]
 -- Scheme Procedure: response-cache-control response [default='()]
 -- Scheme Procedure: response-connection response [default='()]
 -- Scheme Procedure: response-content-encoding response [default='()]
 -- Scheme Procedure: response-content-language response [default='()]
 -- Scheme Procedure: response-content-length response [default=#f]
 -- Scheme Procedure: response-content-location response [default=#f]
 -- Scheme Procedure: response-content-md5 response [default=#f]
 -- Scheme Procedure: response-content-range response [default=#f]
 -- Scheme Procedure: response-content-type response [default=#f]
 -- Scheme Procedure: response-date response [default=#f]
 -- Scheme Procedure: response-etag response [default=#f]
 -- Scheme Procedure: response-expires response [default=#f]
 -- Scheme Procedure: response-last-modified response [default=#f]
 -- Scheme Procedure: response-location response [default=#f]
 -- Scheme Procedure: response-pragma response [default='()]
 -- Scheme Procedure: response-proxy-authenticate response [default=#f]
 -- Scheme Procedure: response-retry-after response [default=#f]
 -- Scheme Procedure: response-server response [default=#f]
 -- Scheme Procedure: response-trailer response [default='()]
 -- Scheme Procedure: response-transfer-encoding response [default='()]
 -- Scheme Procedure: response-upgrade response [default='()]
 -- Scheme Procedure: response-vary response [default='()]
 -- Scheme Procedure: response-via response [default='()]
 -- Scheme Procedure: response-warning response [default='()]
 -- Scheme Procedure: response-www-authenticate response [default=#f]
     Return the given response header, or DEFAULT if none was present.

 -- Scheme Procedure: text-content-type? TYPE
     Return ‘#t’ if TYPE, a symbol as returned by
     ‘response-content-type’, represents a textual type such as
     ‘text/plain’.

7.3.8 Web Client
----------------

‘(web client)’ provides a simple, synchronous HTTP client, built on the
lower-level HTTP, request, and response modules.

     (use-modules (web client))

 -- Scheme Procedure: open-socket-for-uri uri [#:verify-certificate? #t]
     Return an open input/output port for a connection to URI. Guile
     dynamically loads Guile-GnuTLS for HTTPS support.

     See the Web site of Guile-GnuTLS
     (https://gitlab.com/gnutls/guile/), and how to install the GnuTLS bindings for Guile (gnutls-guile),
     for
     more information.

     When VERIFY-CERTIFICATE? is true, verify the server's X.509
     certificates against those read from ‘x509-certificate-directory’.
     When an error occurs--e.g., the server's certificate has expired,
     or its host name does not match--raise a ‘tls-certificate-error’
     exception.  The arguments to the ‘tls-certificate-error’ exception
     are:

       1. a symbol indicating the failure cause, ‘host-mismatch’ if the
          certificate's host name does not match the server's host name,
          and ‘invalid-certificate’ for other causes;

       2. the server's X.509 certificate (see GnuTLS Guile reference (gnutls-guile));

       3. the server's host name (a string);

       4. in the case of ‘invalid-certificate’ errors, a list of GnuTLS
          certificate status values--one of the ‘certificate-status/’
          constants, such as ‘certificate-status/signer-not-found’ or
          ‘certificate-status/revoked’.

 -- Scheme Procedure: http-request URI ARG...

     Connect to the server corresponding to URI and make a request over
     HTTP, using METHOD (‘GET’, ‘HEAD’, ‘POST’, etc.).

     The following keyword arguments allow you to modify the requests in
     various ways, for example attaching a body to the request, or
     setting specific headers.  The following table lists the keyword
     arguments and their default values.

     ‘#:method 'GET’
     ‘#:body #f’
     ‘#:verify-certificate? #t’
     ‘#:port (open-socket-for-uri URI #:verify-certificate? VERIFY-CERTIFICATE?)’
     ‘#:version '(1 . 1)’
     ‘#:keep-alive? #f’
     ‘#:headers '()’
     ‘#:decode-body? #t’
     ‘#:streaming? #f’

     If you already have a port open, pass it as PORT.  Otherwise, a
     connection will be opened to the server corresponding to URI.  Any
     extra headers in the alist HEADERS will be added to the request.

     If BODY is not ‘#f’, a message body will also be sent with the HTTP
     request.  If BODY is a string, it is encoded according to the
     content-type in HEADERS, defaulting to UTF-8.  Otherwise BODY
     should be a bytevector, or ‘#f’ for no body.  Although a message
     body may be sent with any request, usually only ‘POST’ and ‘PUT’
     requests have bodies.

     If DECODE-BODY? is true, as is the default, the body of the
     response will be decoded to string, if it is a textual
     content-type.  Otherwise it will be returned as a bytevector.

     However, if STREAMING? is true, instead of eagerly reading the
     response body from the server, this function only reads off the
     headers.  The response body will be returned as a port on which the
     data may be read.

     Unless KEEP-ALIVE? is true, the port will be closed after the full
     response body has been read.

     If PORT is false, URI denotes an HTTPS URL, and VERIFY-CERTIFICATE?
     is true, verify X.509 certificates against those available in
     ‘x509-certificate-directory’.

     Returns two values: the response read from the server, and the
     response body as a string, bytevector, #f value, or as a port (if
     STREAMING? is true).

 -- Scheme Procedure: http-get URI ARG...
 -- Scheme Procedure: http-head URI ARG...
 -- Scheme Procedure: http-post URI ARG...
 -- Scheme Procedure: http-put URI ARG...
 -- Scheme Procedure: http-delete URI ARG...
 -- Scheme Procedure: http-trace URI ARG...
 -- Scheme Procedure: http-options URI ARG...
     Connect to the server corresponding to URI and make a request over
     HTTP, using the appropriate method (‘GET’, ‘HEAD’, ‘POST’, etc.).

     These procedures are variants of ‘http-request’ specialized with a
     specific METHOD argument, and have the same prototype: a URI
     followed by an optional sequence of keyword arguments.  See
     http-request, for full documentation on the various keyword
     arguments.

 -- Scheme Parameter: x509-certificate-directory
     This parameter gives the name of the directory where X.509
     certificates for HTTPS connections should be looked for.

     Its default value is one of:

        • the value of the ‘GUILE_TLS_CERTIFICATE_DIRECTORY’ environment
          variable;

        • or the value of the ‘SSL_CERT_DIR’ environment variable (also
          honored by the OpenSSL library);

        • or, as a last resort, ‘"/etc/ssl/certs"’.

     X.509 certificates are used when authenticating the identity of a
     remote site, when the ‘#:verify-certificate?’ argument to
     ‘open-socket-for-uri’, to ‘http-request’, or to related procedures
     is true.

   ‘http-get’ is useful for making one-off requests to web sites.  If
you are writing a web spider or some other client that needs to handle a
number of requests in parallel, it's better to build an event-driven URL
fetcher, similar in structure to the web server (see Web Server).

   Another option, good but not as performant, would be to use threads,
possibly via par-map or futures.

 -- Scheme Parameter: current-http-proxy
 -- Scheme Parameter: current-https-proxy
     Either ‘#f’ or a non-empty string containing the URL of the HTTP or
     HTTPS proxy server to be used by the procedures in the ‘(web
     client)’ module, including ‘open-socket-for-uri’.  Its initial
     value is based on the ‘http_proxy’ and ‘https_proxy’ environment
     variables.

          (current-http-proxy) ⇒ "http://localhost:8123/"
          (parameterize ((current-http-proxy #f))
            (http-get "http://example.com/"))  ; temporarily bypass proxy
          (current-http-proxy) ⇒ "http://localhost:8123/"

7.3.9 Web Server
----------------

‘(web server)’ is a generic web server interface, along with a main loop
implementation for web servers controlled by Guile.

     (use-modules (web server))

   The lowest layer is the ‘<server-impl>’ object, which defines a set
of hooks to open a server, read a request from a client, write a
response to a client, and close a server.  These hooks - ‘open’, ‘read’,
‘write’, and ‘close’, respectively - are bound together in a
‘<server-impl>’ object.  Procedures in this module take a
‘<server-impl>’ object, if needed.

   A ‘<server-impl>’ may also be looked up by name.  If you pass the
‘http’ symbol to ‘run-server’, Guile looks for a variable named ‘http’
in the ‘(web server http)’ module, which should be bound to a
‘<server-impl>’ object.  Such a binding is made by instantiation of the
‘define-server-impl’ syntax.  In this way the run-server loop can
automatically load other backends if available.

   The life cycle of a server goes as follows:

  1. The ‘open’ hook is called, to open the server.  ‘open’ takes zero
     or more arguments, depending on the backend, and returns an opaque
     server socket object, or signals an error.

  2. The ‘read’ hook is called, to read a request from a new client.
     The ‘read’ hook takes one argument, the server socket.  It should
     return three values: an opaque client socket, the request, and the
     request body.  The request should be a ‘<request>’ object, from
     ‘(web request)’.  The body should be a string or a bytevector, or
     ‘#f’ if there is no body.

     If the read failed, the ‘read’ hook may return #f for the client
     socket, request, and body.

  3. A user-provided handler procedure is called, with the request and
     body as its arguments.  The handler should return two values: the
     response, as a ‘<response>’ record from ‘(web response)’, and the
     response body as bytevector, or ‘#f’ if not present.

     The respose and response body are run through ‘sanitize-response’,
     documented below.  This allows the handler writer to take some
     convenient shortcuts: for example, instead of a ‘<response>’, the
     handler can simply return an alist of headers, in which case a
     default response object is constructed with those headers.  Instead
     of a bytevector for the body, the handler can return a string,
     which will be serialized into an appropriate encoding; or it can
     return a procedure, which will be called on a port to write out the
     data.  See the ‘sanitize-response’ documentation, for more.

  4. The ‘write’ hook is called with three arguments: the client socket,
     the response, and the body.  The ‘write’ hook returns no values.

  5. At this point the request handling is complete.  For a loop, we
     loop back and try to read a new request.

  6. If the user interrupts the loop, the ‘close’ hook is called on the
     server socket.

   A user may define a server implementation with the following form:

 -- Scheme Syntax: define-server-impl name open read write close
     Make a ‘<server-impl>’ object with the hooks OPEN, READ, WRITE, and
     CLOSE, and bind it to the symbol NAME in the current module.

 -- Scheme Procedure: lookup-server-impl impl
     Look up a server implementation.  If IMPL is a server
     implementation already, it is returned directly.  If it is a
     symbol, the binding named IMPL in the ‘(web server IMPL)’ module is
     looked up.  Otherwise an error is signaled.

     Currently a server implementation is a somewhat opaque type, useful
     only for passing to other procedures in this module, like
     ‘read-client’.

   The ‘(web server)’ module defines a number of routines that use
‘<server-impl>’ objects to implement parts of a web server.  Given that
we don't expose the accessors for the various fields of a
‘<server-impl>’, indeed these routines are the only procedures with any
access to the impl objects.

 -- Scheme Procedure: open-server impl open-params
     Open a server for the given implementation.  Return one value, the
     new server object.  The implementation's ‘open’ procedure is
     applied to OPEN-PARAMS, which should be a list.

 -- Scheme Procedure: read-client impl server
     Read a new client from SERVER, by applying the implementation's
     ‘read’ procedure to the server.  If successful, return three
     values: an object corresponding to the client, a request object,
     and the request body.  If any exception occurs, return ‘#f’ for all
     three values.

 -- Scheme Procedure: handle-request handler request body state
     Handle a given request, returning the response and body.

     The response and response body are produced by calling the given
     HANDLER with REQUEST and BODY as arguments.

     The elements of STATE are also passed to HANDLER as arguments, and
     may be returned as additional values.  The new STATE, collected
     from the HANDLER's return values, is then returned as a list.  The
     idea is that a server loop receives a handler from the user, along
     with whatever state values the user is interested in, allowing the
     user's handler to explicitly manage its state.

 -- Scheme Procedure: sanitize-response request response body
     "Sanitize" the given response and body, making them appropriate for
     the given request.

     As a convenience to web handler authors, RESPONSE may be given as
     an alist of headers, in which case it is used to construct a
     default response.  Ensures that the response version corresponds to
     the request version.  If BODY is a string, encodes the string to a
     bytevector, in an encoding appropriate for RESPONSE.  Adds a
     ‘content-length’ and ‘content-type’ header, as necessary.

     If BODY is a procedure, it is called with a port as an argument,
     and the output collected as a bytevector.  In the future we might
     try to instead use a compressing, chunk-encoded port, and call this
     procedure later, in the write-client procedure.  Authors are
     advised not to rely on the procedure being called at any particular
     time.

 -- Scheme Procedure: write-client impl server client response body
     Write an HTTP response and body to CLIENT.  If the server and
     client support persistent connections, it is the implementation's
     responsibility to keep track of the client thereafter, presumably
     by attaching it to the SERVER argument somehow.

 -- Scheme Procedure: close-server impl server
     Release resources allocated by a previous invocation of
     ‘open-server’.

   Given the procedures above, it is a small matter to make a web
server:

 -- Scheme Procedure: serve-one-client handler impl server state
     Read one request from SERVER, call HANDLER on the request and body,
     and write the response to the client.  Return the new state
     produced by the handler procedure.

 -- Scheme Procedure: run-server handler [impl='http] [open-params='()]
          arg ...
     Run Guile's built-in web server.

     HANDLER should be a procedure that takes two or more arguments, the
     HTTP request and request body, and returns two or more values, the
     response and response body.

     For examples, skip ahead to the next section, see Web Examples.

     The response and body will be run through ‘sanitize-response’
     before sending back to the client.

     Additional arguments to HANDLER are taken from ARG ....  These
     arguments comprise a “state”.  Additional return values are
     accumulated into a new state, which will be used for subsequent
     requests.  In this way a handler can explicitly manage its state.

   The default web server implementation is ‘http’, which binds to a
socket, listening for request on that port.

 -- HTTP Implementation: http [#:host=#f] [#:family=AF_INET]
          [#:addr=INADDR_LOOPBACK] [#:port 8080] [#:socket]
     The default HTTP implementation.  We document it as a function with
     keyword arguments, because that is precisely the way that it is -
     all of the OPEN-PARAMS to ‘run-server’ get passed to the
     implementation's open function.

          ;; The defaults: localhost:8080
          (run-server handler)
          ;; Same thing
          (run-server handler 'http '())
          ;; On a different port
          (run-server handler 'http '(#:port 8081))
          ;; IPv6
          (run-server handler 'http '(#:family AF_INET6 #:port 8081))
          ;; Custom socket
          (run-server handler 'http `(#:socket ,(sudo-make-me-a-socket)))

7.3.10 Web Examples
-------------------

Well, enough about the tedious internals.  Let's make a web application!

7.3.10.1 Hello, World!
......................

The first program we have to write, of course, is "Hello, World!".  This
means that we have to implement a web handler that does what we want.

   Now we define a handler, a function of two arguments and two return
values:

     (define (handler request request-body)
       (values RESPONSE RESPONSE-BODY))

   In this first example, we take advantage of a short-cut, returning an
alist of headers instead of a proper response object.  The response body
is our payload:

     (define (hello-world-handler request request-body)
       (values '((content-type . (text/plain)))
               "Hello World!"))

   Now let's test it, by running a server with this handler.  Load up
the web server module if you haven't yet done so, and run a server with
this handler:

     (use-modules (web server))
     (run-server hello-world-handler)

   By default, the web server listens for requests on ‘localhost:8080’.
Visit that address in your web browser to test.  If you see the string,
‘Hello World!’, sweet!

7.3.10.2 Inspecting the Request
...............................

The Hello World program above is a general greeter, responding to all
URIs.  To make a more exclusive greeter, we need to inspect the request
object, and conditionally produce different results.  So let's load up
the request, response, and URI modules, and do just that.

     (use-modules (web server)) ; you probably did this already
     (use-modules (web request)
                  (web response)
                  (web uri))

     (define (request-path-components request)
       (split-and-decode-uri-path (uri-path (request-uri request))))

     (define (hello-hacker-handler request body)
       (if (equal? (request-path-components request)
                   '("hacker"))
           (values '((content-type . (text/plain)))
                   "Hello hacker!")
           (not-found request)))

     (run-server hello-hacker-handler)

   Here we see that we have defined a helper to return the components of
the URI path as a list of strings, and used that to check for a request
to ‘/hacker/’.  Then the success case is just as before - visit
‘http://localhost:8080/hacker/’ in your browser to check.

   You should always match against URI path components as decoded by
‘split-and-decode-uri-path’.  The above example will work for
‘/hacker/’, ‘//hacker///’, and ‘/h%61ck%65r’.

   But we forgot to define ‘not-found’!  If you are pasting these
examples into a REPL, accessing any other URI in your web browser will
drop your Guile console into the debugger:

     <unnamed port>:38:7: In procedure module-lookup:
     <unnamed port>:38:7: Unbound variable: not-found

     Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
     scheme@(guile-user) [1]>

   So let's define the function, right there in the debugger.  As you
probably know, we'll want to return a 404 response.

     ;; Paste this in your REPL
     (define (not-found request)
       (values (build-response #:code 404)
               (string-append "Resource not found: "
                              (uri->string (request-uri request)))))

     ;; Now paste this to let the web server keep going:
     ,continue

   Now if you access ‘http://localhost/foo/’, you get this error
message.  (Note that some popular web browsers won't show
server-generated 404 messages, showing their own instead, unless the 404
message body is long enough.)

7.3.10.3 Higher-Level Interfaces
................................

The web handler interface is a common baseline that all kinds of Guile
web applications can use.  You will usually want to build something on
top of it, however, especially when producing HTML. Here is a simple
example that builds up HTML output using SXML (see SXML).

   First, load up the modules:

     (use-modules (web server)
                  (web request)
                  (web response)
                  (sxml simple))

   Now we define a simple templating function that takes a list of HTML
body elements, as SXML, and puts them in our super template:

     (define (templatize title body)
       `(html (head (title ,title))
              (body ,@body)))

   For example, the simplest Hello HTML can be produced like this:

     (sxml->xml (templatize "Hello!" '((b "Hi!"))))
     ⊣
     <html><head><title>Hello!</title></head><body><b>Hi!</b></body></html>

   Much better to work with Scheme data types than to work with HTML as
strings.  Now we define a little response helper:

     (define* (respond #:optional body #:key
                       (status 200)
                       (title "Hello hello!")
                       (doctype "<!DOCTYPE html>\n")
                       (content-type-params '((charset . "utf-8")))
                       (content-type 'text/html)
                       (extra-headers '())
                       (sxml (and body (templatize title body))))
       (values (build-response
                #:code status
                #:headers `((content-type
                             . (,content-type ,@content-type-params))
                            ,@extra-headers))
               (lambda (port)
                 (if sxml
                     (begin
                       (if doctype (display doctype port))
                       (sxml->xml sxml port))))))

   Here we see the power of keyword arguments with default initializers.
By the time the arguments are fully parsed, the ‘sxml’ local variable
will hold the templated SXML, ready for sending out to the client.

   Also, instead of returning the body as a string, ‘respond’ gives a
procedure, which will be called by the web server to write out the
response to the client.

   Now, a simple example using this responder, which lays out the
incoming headers in an HTML table.

     (define (debug-page request body)
       (respond
        `((h1 "hello world!")
          (table
           (tr (th "header") (th "value"))
           ,@(map (lambda (pair)
                    `(tr (td (tt ,(with-output-to-string
                                    (lambda () (display (car pair))))))
                         (td (tt ,(with-output-to-string
                                    (lambda ()
                                      (write (cdr pair))))))))
                  (request-headers request))))))

     (run-server debug-page)

   Now if you visit any local address in your web browser, we actually
see some HTML, finally.

7.3.10.4 Conclusion
...................

Well, this is about as far as Guile's built-in web support goes, for
now.  There are many ways to make a web application, but hopefully by
standardizing the most fundamental data types, users will be able to
choose the approach that suits them best, while also being able to
switch between implementations of the server.  This is a relatively new
part of Guile, so if you have feedback, let us know, and we can take it
into account.  Happy hacking on the web!

7.4 The (ice-9 getopt-long) Module
==================================

The ‘(ice-9 getopt-long)’ facility is designed to help parse arguments
that are passed to Guile programs on the command line, and is modelled
after the C library's facility of the same name (see Getopt (libc)).
For a more low-level interface to command-line argument parsing, see
SRFI-37.

   The ‘(ice-9 getopt-long)’ module exports two procedures:
‘getopt-long’ and ‘option-ref’.

   • ‘getopt-long’ takes a list of strings -- the command line arguments
     -- an “option specification”, and some optional keyword parameters.
     It parses the command line arguments according to the option
     specification and keyword parameters, and returns a data structure
     that encapsulates the results of the parsing.

   • ‘option-ref’ then takes the parsed data structure and a specific
     option's name, and returns information about that option in
     particular.

   To make these procedures available to your Guile script, include the
expression ‘(use-modules (ice-9 getopt-long))’ somewhere near the top,
before the first usage of ‘getopt-long’ or ‘option-ref’.

7.4.1 A Short getopt-long Example
---------------------------------

This section illustrates how ‘getopt-long’ is used by presenting and
dissecting a simple example.  The first thing that we need is an “option
specification” that tells ‘getopt-long’ how to parse the command line.
This specification is an association list with the long option name as
the key.  Here is how such a specification might look:

     (define option-spec
       '((version (single-char #\v) (value #f))
         (help    (single-char #\h) (value #f))))

   This alist tells ‘getopt-long’ that it should accept two long
options, called _version_ and _help_, and that these options can also be
selected by the single-letter abbreviations _v_ and _h_, respectively.
The ‘(value #f)’ clauses indicate that neither of the options accepts a
value.

   With this specification we can use ‘getopt-long’ to parse a given
command line:

     (define options (getopt-long (command-line) option-spec))

   After this call, ‘options’ contains the parsed command line and is
ready to be examined by ‘option-ref’.  ‘option-ref’ is called like this:

     (option-ref options 'help #f)

It expects the parsed command line, a symbol indicating the option to
examine, and a default value.  The default value is returned if the
option was not present in the command line, or if the option was present
but without a value; otherwise the value from the command line is
returned.  Usually ‘option-ref’ is called once for each possible option
that a script supports.

   The following example shows a main program which puts all this
together to parse its command line and figure out what the user wanted.

     (define (main args)
       (let* ((option-spec '((version (single-char #\v) (value #f))
                             (help    (single-char #\h) (value #f))))
              (options (getopt-long args option-spec))
              (help-wanted (option-ref options 'help #f))
              (version-wanted (option-ref options 'version #f)))
         (if (or version-wanted help-wanted)
             (begin
               (if version-wanted
                   (display "getopt-long-example version 0.3\n"))
               (if help-wanted
                   (display "\
     getopt-long-example [options]
       -v, --version    Display version
       -h, --help       Display this help
     ")))
             (begin
               (display "Hello, World!") (newline)))))

7.4.2 How to Write an Option Specification
------------------------------------------

An option specification is an association list (see Association Lists)
with one list element for each supported option.  The key of
each list element is a symbol that names the option, while the value is
a list of option properties:

     OPTION-SPEC ::=  '( (OPT-NAME1 (PROP-NAME PROP-VALUE) ...)
                         (OPT-NAME2 (PROP-NAME PROP-VALUE) ...)
                         (OPT-NAME3 (PROP-NAME PROP-VALUE) ...)
                         ...
                       )

   Each OPT-NAME specifies the long option name for that option.  For
example, a list element with OPT-NAME ‘background’ specifies an option
that can be specified on the command line using the long option
‘--background’.  Further information about the option -- whether it
takes a value, whether it is required to be present in the command line,
and so on -- is specified by the option properties.

   In the example of the preceding section, we already saw that a long
option name can have a equivalent “short option” character.  The
equivalent short option character can be set for an option by specifying
a ‘single-char’ property in that option's property list.  For example, a
list element like ‘'(output (single-char #\o) ...)’ specifies an option
with long name ‘--output’ that can also be specified by the equivalent
short name ‘-o’.

   The ‘value’ property specifies whether an option requires or accepts
a value.  If the ‘value’ property is set to ‘#t’, the option requires a
value: ‘getopt-long’ will signal an error if the option name is present
without a corresponding value.  If set to ‘#f’, the option does not take
a value; in this case, a non-option word that follows the option name in
the command line will be treated as a non-option argument.  If set to
the symbol ‘optional’, the option accepts a value but does not require
one: a non-option word that follows the option name in the command line
will be interpreted as that option's value.  If the option name for an
option with ‘'(value optional)’ is immediately followed in the command
line by _another_ option name, the value for the first option is
implicitly ‘#t’.

   The ‘required?’ property indicates whether an option is required to
be present in the command line.  If the ‘required?’ property is set to
‘#t’, ‘getopt-long’ will signal an error if the option is not specified.

   Finally, the ‘predicate’ property can be used to constrain the
possible values of an option.  If used, the ‘predicate’ property should
be set to a procedure that takes one argument -- the proposed option
value as a string -- and returns either ‘#t’ or ‘#f’ according as the
proposed value is or is not acceptable.  If the predicate procedure
returns ‘#f’, ‘getopt-long’ will signal an error.

   By default, options do not have single-character equivalents, are not
required, and do not take values.  Where the list element for an option
includes a ‘value’ property but no ‘predicate’ property, the option
values are unconstrained.

7.4.3 Expected Command Line Format
----------------------------------

In order for ‘getopt-long’ to correctly parse a command line, that
command line must conform to a standard set of rules for how command
line options are specified.  This section explains what those rules are.

   ‘getopt-long’ splits a given command line into several pieces.  All
elements of the argument list are classified to be either options or
normal arguments.  Options consist of two dashes and an option name
(so-called “long” options), or of one dash followed by a single letter
(“short” options).

   Options can behave as switches, when they are given without a value,
or they can be used to pass a value to the program.  The value for an
option may be specified using an equals sign, or else is simply the next
word in the command line, so the following two invocations are
equivalent:

     $ ./foo.scm --output=bar.txt
     $ ./foo.scm --output bar.txt

   Short options can be used instead of their long equivalents and can
be grouped together after a single dash.  For example, the following
commands are equivalent.

     $ ./foo.scm --version --help
     $ ./foo.scm -v --help
     $ ./foo.scm -vh

   If an option requires a value, it can only be grouped together with
other short options if it is the last option in the group; the value is
the next argument.  So, for example, with the following option
specification --

     ((apples    (single-char #\a))
      (blimps    (single-char #\b) (value #t))
      (catalexis (single-char #\c) (value #t)))

-- the following command lines would all be acceptable:

     $ ./foo.scm -a -b bang -c couth
     $ ./foo.scm -ab bang -c couth
     $ ./foo.scm -ac couth -b bang

   But the next command line is an error, because ‘-b’ is not the last
option in its combination, and because a group of short options cannot
include two options that both require values:

     $ ./foo.scm -abc couth bang

   If an option's value is optional, ‘getopt-long’ decides whether the
option has a value by looking at what follows it in the argument list.
If the next element is a string, and it does not appear to be an option
itself, then that string is the option's value.

   If the option ‘--’ appears in the argument list, argument parsing
stops there and subsequent arguments are returned as ordinary arguments,
even if they resemble options.  So, with the command line

     $ ./foo.scm --apples "Granny Smith" -- --blimp Goodyear

‘getopt-long’ will recognize the ‘--apples’ option as having the value
"Granny Smith", but will not treat ‘--blimp’ as an option.  The strings
‘--blimp’ and ‘Goodyear’ will be returned as ordinary argument strings.

7.4.4 Reference Documentation for ‘getopt-long’
-----------------------------------------------

 -- Scheme Procedure: getopt-long args grammar
          [#:stop-at-first-non-option #f]
     Parse the command line given in ARGS (which must be a list of
     strings) according to the option specification GRAMMAR.

     The GRAMMAR argument is expected to be a list of this form:

     ‘((OPTION (PROPERTY VALUE) ...) ...)’

     where each OPTION is a symbol denoting the long option, but without
     the two leading dashes (e.g. ‘version’ if the option is called
     ‘--version’).

     For each option, there may be list of arbitrarily many
     property/value pairs.  The order of the pairs is not important, but
     every property may only appear once in the property list.  The
     following table lists the possible properties:

     ‘(single-char CHAR)’
          Accept ‘-CHAR’ as a single-character equivalent to ‘--OPTION’.
          This is how to specify traditional Unix-style flags.
     ‘(required? BOOL)’
          If BOOL is true, the option is required.  ‘getopt-long’ will
          raise an error if it is not found in ARGS.
     ‘(value BOOL)’
          If BOOL is ‘#t’, the option accepts a value; if it is ‘#f’, it
          does not; and if it is the symbol ‘optional’, the option may
          appear in ARGS with or without a value.
     ‘(predicate FUNC)’
          If the option accepts a value (i.e. you specified ‘(value #t)’
          for this option), then ‘getopt-long’ will apply FUNC to the
          value, and throw an exception if it returns ‘#f’.  FUNC should
          be a procedure which accepts a string and returns a boolean
          value; you may need to use quasiquotes to get it into GRAMMAR.

     The ‘#:stop-at-first-non-option’ keyword, if specified with any
     true value, tells ‘getopt-long’ to stop when it gets to the first
     non-option in the command line.  That is, at the first word which
     is neither an option itself, nor the value of an option.
     Everything in the command line from that word onwards will be
     returned as non-option arguments.

   ‘getopt-long’'s ARGS parameter is expected to be a list of strings
like the one returned by ‘command-line’, with the first element being
the name of the command.  Therefore ‘getopt-long’ ignores the first
element in ARGS and starts argument interpretation with the second
element.

   ‘getopt-long’ signals an error if any of the following conditions
hold.

   • The option grammar has an invalid syntax.

   • One of the options in the argument list was not specified by the
     grammar.

   • A required option is omitted.

   • An option which requires an argument did not get one.

   • An option that doesn't accept an argument does get one (this can
     only happen using the long option ‘--opt=VALUE’ syntax).

   • An option predicate fails.

   ‘#:stop-at-first-non-option’ is useful for command line invocations
like ‘guild [--help | --version] [script [script-options]]’ and ‘cvs
[general-options] command [command-options]’, where there are options at
two levels: some generic and understood by the outer command, and some
that are specific to the particular script or command being invoked.  To
use ‘getopt-long’ in such cases, you would call it twice: firstly with
‘#:stop-at-first-non-option #t’, so as to parse any generic options and
identify the wanted script or sub-command; secondly, and after trimming
off the initial generic command words, with a script- or
sub-command-specific option grammar, so as to process those specific
options.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

The Guile core has the following features,

     guile
     guile-2   ;; starting from Guile 2.x
     guile-2.2 ;; starting from Guile 2.2
     guile-3   ;; starting from Guile 3.x
     guile-3.0 ;; starting from Guile 3.0
     r5rs
     r6rs
     r7rs
     exact-closed ieee-float full-unicode ratios ;; R7RS features
     srfi-0
     srfi-4
     srfi-6
     srfi-13
     srfi-14
     srfi-16
     srfi-23
     srfi-30
     srfi-39
     srfi-46
     srfi-55
     srfi-61
     srfi-62
     srfi-87
     srfi-105

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

The procedures in this section test specific properties of lists.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

     (car+cdr '(0 1 2 3))
     ⇒
     0
     (1 2 3)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

     P
          Determines when to stop unfolding.

     F
          Maps each seed value to the corresponding list element.

     G
          Maps each seed value to next seed value.

     SEED
          The state value for the unfold.

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

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

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

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

     P
          Determines when to stop unfolding.

     F
          Maps each seed value to the corresponding list element.

     G
          Maps each seed value to next seed value.

     SEED
          The state value for the unfold.

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

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

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

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

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

     and

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

     For example a case-insensitive string lookup,

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

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

          (cons (cons KEY DATUM) ALIST)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

The following syntax can be obtained with

     (use-modules (srfi srfi-2))

   or alternatively

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

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

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

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

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

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

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

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

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

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

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

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

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

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

     (use-modules (srfi srfi-4))

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

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

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

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

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

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

u8
     unsigned 8-bit integers

s8
     signed 8-bit integers

u16
     unsigned 16-bit integers

s16
     signed 16-bit integers

u32
     unsigned 32-bit integers

s32
     signed 32-bit integers

u64
     unsigned 64-bit integers

s64
     signed 64-bit integers

f32
     the C type ‘float’

f64
     the C type ‘double’

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   See Bytevectors, for more information.

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

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

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

 -- Scheme Procedure: srfi-4-vector-type-size obj
     Return the size, in bytes, of each element of SRFI-4 vector OBJ.
     For example, ‘(srfi-4-vector-type-size #u32())’ returns ‘4’.

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

 -- Scheme Procedure: u8vector-copy! dst at src [start [end]]
 -- Scheme Procedure: s8vector-copy! dst at src [start [end]]
 -- Scheme Procedure: u16vector-copy! dst at src [start [end]]
 -- Scheme Procedure: s16vector-copy! dst at src [start [end]]
 -- Scheme Procedure: u32vector-copy! dst at src [start [end]]
 -- Scheme Procedure: s32vector-copy! dst at src [start [end]]
 -- Scheme Procedure: u64vector-copy! dst at src [start [end]]
 -- Scheme Procedure: s64vector-copy! dst at src [start [end]]
 -- Scheme Procedure: f32vector-copy! dst at src [start [end]]
 -- Scheme Procedure: f64vector-copy! dst at src [start [end]]
 -- Scheme Procedure: c32vector-copy! dst at src [start [end]]
 -- Scheme Procedure: c64vector-copy! dst at src [start [end]]
     Copy a block of elements from SRC to DST, both of which must be
     vectors of the indicated type, starting in DST at AT and starting
     in SRC at START and ending at END.  It is an error for DST to have
     a length less than AT + (END - START).  AT and START default to 0
     and END defaults to the length of SRC.

     If source and destination overlap, copying takes place as if the
     source is first copied into a temporary vector and then into the
     destination.

     See also ‘vector-copy!’.

 -- Scheme Procedure: u8vector-copy src [start [end]]
 -- Scheme Procedure: s8vector-copy src [start [end]]
 -- Scheme Procedure: u16vector-copy src [start [end]]
 -- Scheme Procedure: s16vector-copy src [start [end]]
 -- Scheme Procedure: u32vector-copy src [start [end]]
 -- Scheme Procedure: s32vector-copy src [start [end]]
 -- Scheme Procedure: u64vector-copy src [start [end]]
 -- Scheme Procedure: s64vector-copy src [start [end]]
 -- Scheme Procedure: f32vector-copy src [start [end]]
 -- Scheme Procedure: f64vector-copy src [start [end]]
 -- Scheme Procedure: c32vector-copy src [start [end]]
 -- Scheme Procedure: c64vector-copy src [start [end]]
     Returns a freshly allocated vector of the indicated type, which
     must be the same as that of SRC, containing the elements of SRC
     between START and END.  START defaults to 0 and END defaults to the
     length of SRC.

     See also ‘vector-copy’.

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

SRFI-6 defines the procedures ‘open-input-string’, ‘open-output-string’
and ‘get-output-string’.  These procedures are included in the Guile
core, so using this module does not make any difference at the moment.
But it is possible that support for SRFI-6 will be factored out of the
core library in the future, so using this module does not hurt, after
all.

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

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

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

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

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

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

     (use-modules (srfi srfi-10))

The new read syntax is of the form

     #,(TAG ARG...)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

     (use-modules (srfi srfi-17))

For example ‘vector-ref’ is extended so that

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

is equivalent to

     (vector-set! vec idx new-value)

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

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

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

     string-ref, vector-ref

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

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

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

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

     (use-modules (srfi srfi-18))

   SRFI-18 defines facilities for threads, mutexes, condition variables,
time, and exception handling.  Because these facilities are at a higher
level than Guile's primitives, they are implemented as a layer on top of
what Guile provides.  In particular this means that a Guile mutex is not
a SRFI-18 mutex, and a Guile thread is not a SRFI-18 thread, and so on.
Guile provides a set of primitives and SRFI-18 is one of the systems
built in terms of those primitives.

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

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

   SRFI-18 threads are disjoint from Guile's primitive threads.  See
Threads, for more on Guile's primitive facility.

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

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

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

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

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

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

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

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

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

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

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

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

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

SRFI-18 mutexes are disjoint from Guile's primitive mutexes.  See
Mutexes and Condition Variables, for more on Guile's primitive
facility.

 -- Function: make-mutex [name]
     Returns a new mutex, optionally assigning it the object name NAME,
     which may be any Scheme object.  The returned mutex will be created
     with the configuration described above.

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

 -- Function: mutex-specific mutex
     Return the "object-specific" property of MUTEX, or ‘#f’ if none is
     set.

 -- Function: mutex-specific-set! mutex obj
     Set the "object-specific" property of MUTEX.

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

 -- Function: mutex-lock! mutex [timeout [thread]]
     Lock MUTEX, optionally specifying a time object TIMEOUT after which
     to abort the lock attempt and a thread THREAD giving a new owner
     for MUTEX different than the current thread.

 -- Function: mutex-unlock! mutex [condition-variable [timeout]]
     Unlock MUTEX, optionally specifying a condition variable
     CONDITION-VARIABLE on which to wait, either indefinitely or,
     optionally, until the time object TIMEOUT has passed, to be
     signaled.

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

SRFI-18 does not specify a "wait" function for condition variables.
Waiting on a condition variable can be simulated using the SRFI-18
‘mutex-unlock!’ function described in the previous section.

   SRFI-18 condition variables are disjoint from Guile's primitive
condition variables.  See Mutexes and Condition Variables, for more
on Guile's primitive facility.

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

 -- Function: make-condition-variable [name]
     Returns a new condition variable, optionally assigning it the
     object name NAME, which may be any Scheme object.

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

 -- Function: condition-variable-specific condition-variable
     Return the "object-specific" property of CONDITION-VARIABLE, or
     ‘#f’ if none is set.

 -- Function: condition-variable-specific-set! condition-variable obj
     Set the "object-specific" property of CONDITION-VARIABLE.

 -- Function: condition-variable-signal! condition-variable
 -- Function: condition-variable-broadcast! condition-variable
     Wake up one thread that is waiting for CONDITION-VARIABLE, in the
     case of ‘condition-variable-signal!’, or all threads waiting for
     it, in the case of ‘condition-variable-broadcast!’.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

     (use-modules (srfi srfi-19))

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

This module implements time and date representations and calculations,
in various time systems, including Coordinated Universal Time (UTC) and
International Atomic Time (TAI).

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

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

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

   Also, for those not familiar with the terminology, a “Julian Day”
represents a point in time as a real number of days since
-4713-11-24T12:00:00Z, i.e. midday UT on 24 November 4714 BC in the
proleptic Gregorian calendar (1 January 4713 BC in the proleptic Julian
calendar).

   A “Modified Julian Day” represents a point in time as a real number
of days since 1858-11-17T00:00:00Z, i.e. midnight UT on Wednesday 17
November AD 1858.  That time is julian day 2400000.5.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   Historically, the Gregorian calendar was only used from the latter
part of the year 1582 onwards, and not until even later in many
countries.  Prior to that most countries used the Julian calendar.
SRFI-19 does not deal with the Julian calendar at all, and so does not
reflect this historical calendar reform.  Instead it projects the
Gregorian calendar back proleptically as far as necessary.  When dealing
with historical data, especially prior to the British Empire's adoption
of the Gregorian calendar in 1752, one should be mindful of which
calendar is used in each context, and apply non-SRFI-19 facilities to
convert where necessary.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            Skip to            Read                        Set

     ~~     no skip            literal ~                   nothing

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

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

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

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

     ~H     char-numeric?      hour                        date-hour

     ~k     no skip            hour, blank padded          date-hour

     ~m     char-numeric?      month                       date-month

     ~M     char-numeric?      minute                      date-minute

     ~N     char-numeric?      nanosecond                  date-nanosecond

     ~S     char-numeric?      second                      date-second

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

     ~Y     char-numeric?      year                        date-year

     ~z     no skip            time zone                   date-zone-offset

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

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

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

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

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

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

     (use-modules (srfi srfi-26))

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

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

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

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

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

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

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

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

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

               (define my-lower-bound 123)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

     (use-modules (srfi srfi-28))

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

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

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

     ‘~%’
          Insert a newline.

     ‘~~’
          Insert a tilde.

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

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

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

7.5.22 SRFI-31 - A special form 'rec' for recursive evaluation
--------------------------------------------------------------

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

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

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

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

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

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

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

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

     (use-modules (srfi srfi-34))

   See Raising and Handling Exceptions, for more on
‘with-exception-handler’ and ‘raise’ (known as ‘raise-exception’ in core
Guile).

   SRFI-34's ‘guard’ form is syntactic sugar over
‘with-exception-handler’:

 -- Syntax: guard (var clause ...) body ...
     Evaluate BODY with an exception handler that binds the raised
     object to VAR and within the scope of that binding evaluates
     CLAUSE... as if they were the clauses of a cond expression.  That
     implicit cond expression is evaluated with the continuation and
     dynamic environment of the guard expression.

     If every CLAUSE's test evaluates to false and there is no ‘else’
     clause, then ‘raise’ is re-invoked on the raised object within the
     dynamic environment of the original call to ‘raise’ except that the
     current exception handler is that of the ‘guard’ expression.

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

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

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

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

   SRFI-35 conditions are made available using:

     (use-modules (srfi srfi-35))

   The procedures available to manipulate condition types are the
following:

 -- Scheme Procedure: make-condition-type id parent field-names
     Return a new condition type named ID, inheriting from PARENT, and
     with the fields whose names are listed in FIELD-NAMES.  FIELD-NAMES
     must be a list of symbols and must not contain names already used
     by PARENT or one of its supertypes.

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

   Conditions can be created and accessed with the following procedures:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

     The following example returns a simple condition:

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

     The one below returns a compound condition:

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

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

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

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

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

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

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

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

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

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

   As an implementation note, condition objects in Guile are the same as
"exception objects".  See Exception Objects.  The ‘&condition’,
‘&serious’, and ‘&error’ condition types are known in core Guile as
‘&exception’, ‘&error’, and ‘&external-error’, respectively.

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

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

     (use-modules (srfi srfi-37))

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   is replaced by the following five productions:

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

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

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

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

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

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

     For example, the code

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

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

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

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

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

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

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

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

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

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

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

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

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

     (use-modules (srfi srfi-41))

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

     (define evens (stream-add nats nats))

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

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

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

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

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

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

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

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

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

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

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

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

          (define strm123 (stream 1 2 3))

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        • () matches the null stream.

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

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

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

     Each pattern element may be either:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        • (): the end of the result stream.

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

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

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

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

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

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

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

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

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

     (use-modules (srfi srfi-43))

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

   This algorithm can be expressed as follows in Scheme:

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

   In other words, we

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

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

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

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

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

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

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

          (require-extension (srfi 1 6))

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

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

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

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

     (use-modules (srfi srfi-60))

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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