Guile Library
*************

This manual is for Guile Library (version 0.2.7, updated March 2021)

   Copyright 2003,2007,2010,2011,2016,2017,2018,2021 Andreas Rottmann,
Andy Wingo, Richard Todd, Neil W. Van Dyke, David Pirotte, Christopher
Baines, Göran Weinhold, Ricardo Wurmus, Ludovic Courtès, Maxim Cournoyer

     Permission is granted to copy, distribute and/or modify this
     document under the terms of the GNU Free Documentation License,
     Version 1.2 or any later version published y 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".

1 (apicheck)
************

1.1 Overview
============

'(apicheck)' exports two routines.  'apicheck-generate' produces a
description of the Scheme API exported by a set of modules as an
S-expression.  'apicheck-validate' verifies that the API exported by a
set of modules is compatible with an API description generated by
'apicheck-generate'.

   It would be nice to have Makefile.am fragments here, but for now, see
the Guile-Library source distribution for information on how to
integrate apicheck with your module's unit test suite.

1.2 Usage
=========

 -- Function: apicheck-generate a
     Generate a description of the API exported by the set of modules
     MODULE-NAMES.

 -- Function: apicheck-validate a b
     Validate that the API exported by the set of modules MODULE-NAMES
     is compatible with the recorded API description API.  Raises an
     exception if the interface is incompatible.

2 (config load)
***************

2.1 Overview
============

 This module needs to be documented.

2.2 Usage
=========

 -- Class: <configuration>

 -- Generic: load-config!

 -- Method: load-config! (CFG '<configuration>') (COMMANDS '<list>')
          (FILE-NAME '<string>')

 -- Variable: &config-error

 -- Function: config-error-arguments a

3 (container async-queue)
*************************

3.1 Overview
============

A asynchronous queue can be used to safely send messages from one thread
to another.

3.2 Usage
=========

 -- Function: make-async-queue
     Create a new asynchronous queue.

 -- Function: async-enqueue! a b
     Enqueue ELT into Q.

 -- Function: async-dequeue! a
     Dequeue a single element from Q.  If the queue is empty, the
     calling thread is blocked until an element is enqueued by another
     thread.

4 (container nodal-tree)
************************

4.1 Overview
============

A nodal tree is a tree composed of nodes, each of which may have
children.  Nodes are represented as alists.  The only alist entry that
is specified is 'children', which must hold a list of child nodes.
Other entries are intentionally left unspecified, so as to allow for
extensibility.

4.2 Usage
=========

 -- Function: nodal-tree? a
     Predicate to determine if X is a nodal tree.  Not particularly
     efficient: intended for debugging purposes.

 -- Function: make-node . rest

 -- Function: node-ref a b

 -- Function: node-set! a b c

 -- Function: node-children a

5 (container delay-tree)
************************

5.1 Overview
============

A delay tree is a superset of a nodal tree (see (container nodal-tree)).
It extends nodal trees to allow any entry of the node to be a promise
created with the 'delay' operator.

5.2 Usage
=========

 -- Function: force-ref a b
     Access a field in a node of a delay tree.  If the value of the
     field is a promise, the promise will be forced, and the value will
     be replaced with the forced value.

6 (debugging assert)
********************

6.1 Overview
============

Defines an 'assert' macro, and the 'cout' and 'cerr' utility functions.

6.2 Usage
=========

 -- Special Form: assert doit (expr ...) (r-exp ...)
 -- Special Form: assert collect (expr ...)
 -- Special Form: assert collect (expr ...) report: r-exp ...
 -- Special Form: assert collect (expr ...) expr1 stuff ...
 -- Special Form: assert stuff ...
     Assert the truth of an expression (or of a sequence of
     expressions).

     syntax: 'assert ?EXPR ?EXPR ... [report: ?R-EXP ?R-EXP ...]'

     If '(and ?EXPR ?EXPR ...)' evaluates to anything but '#f', the
     result is the value of that expression.  Otherwise, an error is
     reported.

     The error message will show the failed expressions, as well as the
     values of selected variables (or expressions, in general).  The
     user may explicitly specify the expressions whose values are to be
     printed upon assertion failure - as ?R-EXP that follow the
     identifier 'report:'.

     Typically, ?R-EXP is either a variable or a string constant.  If
     the user specified no ?R-EXP, the values of variables that are
     referenced in ?EXPR will be printed upon the assertion failure.

 -- Function: cout . rest
     Similar to 'cout << arguments << args', where ARGUMENT can be any
     Scheme object.  If it's a procedure (e.g.  'newline'), it's called
     without args rather than printed.

 -- Function: cerr . rest
     Similar to 'cerr << arguments << args', where ARGUMENT can be any
     Scheme object.  If it's a procedure (e.g.  'newline'), it's called
     without args rather than printed.

7 (debugging time)
******************

7.1 Overview
============

Defines a macro to time execution of a body of expressions.  Each
element is timed individually.

7.2 Usage
=========

 -- Special Form: time args
     syntax: '(time EXPR1 EXPR2...)'

     Times the execution of a list of expressions, in milliseconds.  The
     resolution is limited to guile's 'internal-time-units-per-second'.
     Disregards the expressions' return value(s) (FIXME).

8 (graph topological-sort)
**************************

8.1 Overview
============

 The algorithm is inspired by Cormen, Leiserson and Rivest (1990)
 ``Introduction to Algorithms'', chapter 23.

8.2 Usage
=========

 -- Function: topological-sort a
     Returns a list of the objects in the directed acyclic graph, DAG,
     topologically sorted.  Objects are compared using 'equal?'.  The
     graph has the form:

           (list (obj1 . (dependents-of-obj1))
                 (obj2 . (dependents-of-obj2)) ...)

     ...specifying, for example, that 'obj1' must come before all the
     objects in '(dependents-of-obj1)' in the sort.

 -- Function: topological-sortq a
     Returns a list of the objects in the directed acyclic graph, DAG,
     topologically sorted.  Objects are compared using 'eq?'.  The graph
     has the form:

           (list (obj1 . (dependents-of-obj1))
                 (obj2 . (dependents-of-obj2)) ...)

     ...specifying, for example, that 'obj1' must come before all the
     objects in '(dependents-of-obj1)' in the sort.

 -- Function: topological-sortv a
     Returns a list of the objects in the directed acyclic graph, DAG,
     topologically sorted.  Objects are compared using 'eqv?'.  The
     graph has the form:

           (list (obj1 . (dependents-of-obj1))
                 (obj2 . (dependents-of-obj2)) ...)

     ...specifying, for example, that 'obj1' must come before all the
     objects in '(dependents-of-obj1)' in the sort.

9 (htmlprag)
************

9.1 Overview
============

HtmlPrag provides permissive HTML parsing capability to Scheme programs,
which is useful for software agent extraction of information from Web
pages, for programmatically transforming HTML files, and for
implementing interactive Web browsers.  HtmlPrag emits "SHTML," which is
an encoding of HTML in [SXML], so that conventional HTML may be
processed with XML tools such as [SXPath] and [SXML-Tools].  Like
[SSAX-HTML], HtmlPrag provides a permissive tokenizer, but also attempts
to recover structure.  HtmlPrag also includes procedures for encoding
SHTML in HTML syntax.

   The HtmlPrag parsing behavior is permissive in that it accepts
erroneous HTML, handling several classes of HTML syntax errors
gracefully, without yielding a parse error.  This is crucial for parsing
arbitrary real-world Web pages, since many pages actually contain syntax
errors that would defeat a strict or validating parser.  HtmlPrag's
handling of errors is intended to generally emulate popular Web
browsers' interpretation of the structure of erroneous HTML. We
euphemistically term this kind of parse "pragmatic."  To disable the
pragmatic behavior and parse HTML more rigidly, the '%strict-tokenizer?'
parameter can be set to '#true'.  In this mode of operation, one ended
HTML tags will not be treated specially, for example, and their content
will be coalesced.  On the other side, valid HTML will parse more
accurately.  When working with HTML known to be valid, it makes sense to
use this mode of operation.

   HtmlPrag also has some support for [XHTML], although XML namespace
qualifiers [XML-Names] are currently accepted but stripped from the
resulting SHTML. Note that valid XHTML input is of course better handled
by a validating XML parser like [SSAX].

   To receive notification of new versions of HtmlPrag, and to be polled
for input on changes to HtmlPrag being considered, ask the author to add
you to the moderated, announce-only email list, 'htmlprag-announce'.

   Thanks to Oleg Kiselyov and Kirill Lisovsky for their help with SXML.

9.2 Usage
=========

 -- Variable: %default-parent-constraints

 -- Variable: %parent-constraints

 -- Variable: %strict-tokenizer?

 -- Variable: shtml-comment-symbol

 -- Variable: shtml-decl-symbol

 -- Variable: shtml-empty-symbol

 -- Variable: shtml-end-symbol

 -- Variable: shtml-entity-symbol

 -- Variable: shtml-named-char-id

 -- Variable: shtml-numeric-char-id

 -- Variable: shtml-pi-symbol

 -- Variable: shtml-start-symbol

 -- Variable: shtml-text-symbol

 -- Variable: shtml-top-symbol

 -- Function: html->shtml _ [#:strict?]

 -- Function: html->sxml _ [#:strict?]

 -- Function: html->sxml-0nf _ [#:strict?]

 -- Function: html->sxml-1nf _ [#:strict?]

 -- Function: html->sxml-2nf _ [#:strict?]

 -- Function: make-html-tokenizer a b

 -- Function: parse-html/tokenizer _ _ [#:strict?]

 -- Function: shtml->html a

 -- Function: shtml-entity-value a

 -- Function: shtml-token-kind a

 -- Function: sxml->html a

 -- Function: test-htmlprag

 -- Function: tokenize-html a b

 -- Function: write-shtml-as-html a b

 -- Function: write-sxml-html a b

10 (io string)
**************

10.1 Overview
=============

Procedures that do io with strings.

10.2 Usage
==========

 -- Function: find-string-from-port? a b . rest
     Looks for STR in <INPUT-PORT>, optionally within the first
     MAX-NO-CHAR characters.

11 (logging logger)
*******************

11.1 Overview
=============

This is a logging subsystem similar to the one in the python standard
library.  There are two main concepts to understand when working with
the logging modules.  These are loggers and log handlers.

Loggers
     Loggers are the front end interfaces for program logging.  They can
     be registered by name so that no part of a program needs to be
     concerned with passing around loggers.  In addition, a default
     logger can be designated so that, for most applications, the
     program does not need to be concerned with logger instances at all
     beyond the initial setup.

     Log messages all flow through a logger.  Messages carry with them a
     level (for example: 'WARNING, 'ERROR, 'CRITICAL), and loggers can
     filter out messages on a level basis at runtime.  This way, the
     amount of logging can be turned up during development and bug
     investigation, but turned back down on stable releases.

     Loggers depend on Log Handlers to actually get text to the log's
     destination (for example, a disk file).  A single Logger can send
     messages through multiple Log Handlers, effectively multicasting
     logs to multiple destinations.

Log Handlers
     Log Handlers actually route text to a destination.  One or more
     handlers must be attached to a logger for any text to actually
     appear in a log.

     Handlers apply a configurable transformation to the text so that it
     is formatted properly for the destination (for instance: syslogs,
     or a text file).  Like the loggers, they can filter out messages
     based on log levels.  By using filters on both the Logger and the
     Handlers, precise controls can be put on which log messages go
     where, even within a single logger.

11.2 Example use of logger
==========================

Here is an example program that sets up a logger with two handlers.  One
handler sends the log messages to a text log that rotates its logs.  The
other handler sends logs to standard error, and has its levels set so
that INFO and WARN-level logs don't get through.

     (use-modules (logging logger)
                  (logging rotating-log)
                  (logging port-log)
                  (scheme documentation)
                  (oop goops))

      ----------------------------------------------------------------------
      Support functions
      ----------------------------------------------------------------------
     (define (setup-logging)
       (let ((lgr       (make <logger>))
             (rotating  (make <rotating-log>
                          #:num-files 3
                          #:size-limit 1024
                          #:file-name "test-log-file"))
             (err       (make <port-log> #:port (current-error-port))))

         ;; don't want to see warnings or info on the screen!!
         (disable-log-level! err 'WARN)
         (disable-log-level! err 'INFO)

         ;; add the handlers to our logger
         (add-handler! lgr rotating)
         (add-handler! lgr err)

         ;; make this the application's default logger
         (set-default-logger! lgr)
         (open-log! lgr)))

     (define (shutdown-logging)
       (flush-log)   ;; since no args, it uses the default
       (close-log!)  ;; since no args, it uses the default
       (set-default-logger! #f))

      ----------------------------------------------------------------------
      Main code
      ----------------------------------------------------------------------
     (setup-logging)

      Due to log levels, this will get to file,
      but not to stderr
     (log-msg 'WARN "This is a warning.")

      This will get to file AND stderr
     (log-msg 'CRITICAL "ERROR message!!!")

     (shutdown-logging)

11.3 Usage
==========

 -- Class: <log-handler>
     This is the base class for all of the log handlers, and encompasses
     the basic functionality that all handlers are expected to have.
     Keyword arguments recognized by the '<log-handler>' at creation
     time are:

     '#:formatter'
          This optional parameter must be a function that takes three
          arguments: the log level, the time (as from 'current-time'),
          and the log string itself.  The function must return a string
          representing the formatted log.

          Here is an example invokation of the default formatter, and
          what it's output looks like:

                (default-log-formatter 'CRITICAL
                                      (current-time)
                                      "The servers are melting!")
               ==> "2003/12/29 14:53:02 (CRITICAL): The servers are melting!"

 -- Generic: emit-log
     'emit-log handler str'.  This method should be implemented for all
     the handlers.  This sends a string to their output media.  All
     level checking and formatting has already been done by
     'accept-log'.

 -- Generic: accept-log
     'accept-log handler lvl time str'.  If LVL is enabled for HANDLER,
     then STR will be formatted and sent to the log via the 'emit-log'
     method.  Formatting is done via the formatting function given at
     HANDLER's creation time, or by the default if none was given.

     This method should not normally need to be overridden by
     subclasses.  This method should not normally be called by users of
     the logging system.  It is only exported so that writers of log
     handlers can override this behavior.

 -- Method: accept-log (SELF '<log-handler>') (LEVEL '<top>') (TIME
          '<top>') (STR '<top>')

 -- Class: <logger>
     This is the class that aggregates and manages log handlers.  It
     also maintains the global information about which levels of log
     messages are enabled, and which have been suppressed.  Keyword
     arguments accepted on creation are:

     '#:handlers'
          This optional parameter must be a list of objects derived from
          '<log-handler>'.  Handlers can always be added later via
          'add-handler!' calls.

 -- Generic: add-handler!
     'add-handler! lgr handler'.  Adds HANDLER to LGR's list of
     handlers.  All subsequent logs will be sent through the new
     handler, as well as any previously registered handlers.

 -- Method: add-handler! (LGR '<logger>') (HANDLER '<log-handler>')

 -- Generic: log-msg
     'log-msg [lgr] lvl arg1 arg2 ...'.  Send a log message made up of
     the 'display''ed representation of the given arguments.  The log is
     generated at level LVL, which should be a symbol.  If the LVL is
     disabled, the log message is not generated.  Generated log messages
     are sent through each of LGR's handlers.

     If the LGR parameter is omitted, then the default logger is used,
     if one is set.

     As the args are 'display''ed, a large string is built up.  Then,
     the string is split at newlines and sent through the log handlers
     as independent log messages.  The reason for this behavior is to
     make output nicer for log handlers that prepend information like
     pid and timestamps to log statements.

          ;; logging to default logger, level of WARN
           (log-msg 'WARN "Warning! " x " is bigger than " y "!!!")

          ;; looking up a logger and logging to it
           (let ((l (lookup-logger "main")))
               (log-msg l 'CRITICAL "FAILURE TO COMMUNICATE!")
               (log-msg l 'CRITICAL "ABORTING NOW"))

 -- Method: log-msg (LGR '<logger>') (LVL '<top>') (OBJS '<top>')...

 -- Method: log-msg (LVL '<symbol>') (OBJS '<top>')...

 -- Function: set-default-logger! a
     Sets the given logger, LGR, as the default for logging methods
     where a logger is not given.  LGR can be an instance of '<logger>',
     a string that has been registered via 'register-logger!', or '#f'
     to remove the default logger.

     With this mechanism, most applications will never need to worry
     about logger registration or lookup.

          ;; example 1
           (set-default-logger! "main")  ;; look up "main" logger and make it the default

          ;; example 2
           (define lgr (make  <logger>))
           (add-handler! lgr
                        (make <port-handler>
                              #:port (current-error-port)))
           (set-default-logger! lgr)
           (log-msg 'CRITICAL "This is a message to the default logger!!!")
           (log-msg lgr 'CRITICAL "This is a message to a specific logger!!!")

 -- Function: register-logger! a b
     Makes LGR accessible from other parts of the program by a name
     given in STR.  STR should be a string, and LGR should be an
     instance of class '<logger>'.

           (define main-log  (make <logger>))
           (define corba-log (make <logger>))
           (register-logger! "main" main-log)
           (register-logger! "corba" corba-log)

          ;; in a completely different part of the program....
           (log-msg (lookup-logger "corba") 'WARNING "This is a corba warning.")

 -- Function: lookup-logger a
     Looks up an instance of class '<logger>' by the name given in STR.
     The string should have already been registered via a call to
     'register-logger!'.

 -- Function: enable-log-level! a b
     Enables a specific logging level given by the symbol LVL, such that
     messages at that level will be sent to the log handlers.  LGR can
     be of type '<logger>' or '<log-handler>'.

     Note that any levels that are neither enabled or disabled are
     treated as enabled by the logging system.  This is so that misspelt
     level names do not cause a logging blackout.

 -- Function: disable-log-level! a b
     Disables a specific logging level, such that messages at that level
     will not be sent to the log handlers.  LGR can be of type
     '<logger>' or '<log-handler>'.

     Note that any levels that are neither enabled or disabled are
     treated as enabled by the logging system.  This is so that misspelt
     level names do not cause a logging blackout.

 -- Generic: flush-log
     'flush-log handler'.  Tells the 'handler' to output any log
     statements it may have buffered up.  Handlers for which a flush
     operation doesn't make sense can choose not to implement this
     method.  The default implementation just returns '#t'.

 -- Method: flush-log (LGR '<logger>')

 -- Method: flush-log

 -- Method: flush-log (LH '<log-handler>')

 -- Generic: open-log!
     'open-log! handler'.  Tells the 'handler' to open its log.
     Handlers for which an open operation doesn't make sense can choose
     not to implement this method.  The default implementation just
     returns '#t'.

 -- Method: open-log!

 -- Method: open-log! (LGR '<logger>')

 -- Method: open-log! (LH '<log-handler>')

 -- Generic: close-log!
     'open-log! handler'.  Tells the 'handler' to close its log.
     Handlers for which a close operation doesn't make sense can choose
     not to implement this method.  The default implementation just
     returns '#t'.

 -- Method: close-log!

 -- Method: close-log! (LGR '<logger>')

 -- Method: close-log! (LH '<log-handler>')

12 (logging port-log)
*********************

12.1 Overview
=============

This module defines a log handler that writes to an arbitrary port of
the user's choice.  Uses of this handler could include:

   * Sending logs across a socket to a network log collector.

   * Sending logs to the screen

   * Sending logs to a file

   * Collecting logs in memory in a string port for later use

12.2 Usage
==========

 -- Class: <port-log>
     This is a log handler which writes logs to a user-provided port.

     Keywords recognized by '<port-log>' on creation are:

     '#:port'
          This is the port to which the log handler will write.

     '#:formatter'
          Allows the user to provide a function to use as the log
          formatter for this handler.  See logging logger <log-handler>,
          for details.

     Example of creating a '<port-log>':

           (make <port-log> #:port (current-error-port))

13 (logging rotating-log)
*************************

13.1 Overview
=============

This module defines a log handler for text logs that rotate when they
get to be a user-defined size.  This is similar to the behavior of many
UNIX standard log files.  See logging logger, for more information
in general on log handlers.

13.2 Usage
==========

 -- Class: <rotating-log>
     This is a log handler which writes text logs that rotate when they
     reach a configurable size limit.

     Keywords recognized by '<rotating-log>' on creation are:

     '#:num-files'
          This is the number of log files you want the logger to use.
          Default is 4.

     '#:size-limit'
          This is the size, in bytes, a log file must get before the
          logs get rotated.  Default is 1MB (104876 bytes).

     '#:file-name'
          This is the base of the log file name.  Default is "logfile".
          Numbers will be appended to the file name representing the log
          number.  The newest log file is always "NAME.1".

     '#:formatter'
          Allows the user to provide a function to use as the log
          formatter for this handler.  See logging logger <log-handler>,
          for details.

     Example of creating a '<rotating-log>':

           (make <rotating-log>
                #:num-files 3
                #:size-limit 1024
                #:file-name "test-log-file"))

14 (match-bind)
***************

14.1 Overview
=============

Utility functions and syntax constructs for dealing with regular
expressions in a concise manner.  Will be submitted to Guile for
inclusion.

14.2 Usage
==========

 -- Special Form: match-bind
     Match a string against a regular expression, binding lexical
     variables to the various parts of the match.

     VARS is a list of names to which to bind the parts of the match.
     The first variable of the list will be bound to the entire match,
     so the number of variables needed will be equal to the number of
     open parentheses ('(') in the pattern, plus one for the whole
     match.

     CONSEQUENT is executed if the given expression STR matches REGEX.
     If the string does not match, ALTERNATE will be executed if
     present.  If ALTERNATE is not present, the result of 'match-bind'
     is unspecified.

     Here is a short example:

           (define (star-indent line)
             "Returns the number of spaces until the first
              star (`*') in the input, or #f if the first
              non-space character is not a star."
             (match-bind "^( *)\*.*$" line (_ spaces)
                         (string-length spaces)
                         #f))

     'match-bind' compiles the regular expression REGEX at macro
     expansion time.  For this reason, REGEX must be a string literal,
     not an arbitrary expression.

 -- Function: s/// a b
     Make a procedure that performs perl-like regular expression
     search-and-replace on an input string.

     The regular expression pattern PAT is in the standard regular
     expression syntax accepted by 'make-regexp'.  The substitution
     string is very similar to perl's 's///' operator.  Backreferences
     are indicated with a dollar sign ('$'), and characters can be
     escaped with the backslash.

     's///' returns a procedure of one argument, the input string to be
     matched.  If the string matches the pattern, it will be returned
     with the first matching segment replaced as per the substitution
     string.  Otherwise the string will be returned unmodified.

     Here are some examples:

           ((s/// "foo" "bar") "foo bar baz qux foo")
              => "bar bar baz qux foo"

           ((s/// "zag" "bar") "foo bar baz qux foo")
              => "foo bar baz qux foo"

           ((s/// "(f(o+)) (zag)?" "$1 $2 $3")
            "foo bar baz qux foo")
              => "foo oo bar baz qux foo"

 -- Function: s///g a b
     Make a procedure that performs perl-like global search-and-replace
     on an input string.

     The PAT and SUBST arguments are as in the non-global 's///'.  See
     s///, for more information.

     's///g' differs from 's///' in that it does a global search and
     replace, not stopping at the first match.

15 (math minima)
****************

15.1 Overview
=============

This module contains functions for computing the minimum values of
mathematical expressions on an interval.

15.2 Usage
==========

 -- Function: golden-section-search a b c d
     The Golden Section Search algorithm finds minima of functions which
     are expensive to compute or for which derivatives are not
     available.  Although optimum for the general case, convergence is
     slow, requiring nearly 100 iterations for the example (x^3-2x-5).

     If the derivative is available, Newton-Raphson is probably a better
     choice.  If the function is inexpensive to compute, consider
     approximating the derivative.

     X0 and X1 are real numbers.  The (single argument) procedure FUNC
     is unimodal over the open interval (X0, X1).  That is, there is
     exactly one point in the interval for which the derivative of FUNC
     is zero.

     It returns a pair (X .  FUNC(X)) where FUNC(X) is the minimum.  The
     PREC parameter is the stop criterion.  If PREC is a positive
     number, then the iteration continues until X is within PREC from
     the true value.  If PREC is a negative integer, then the procedure
     will iterate -PREC times or until convergence.  If PREC is a
     procedure of seven arguments, X0, X1, A, B, FA, FB, and COUNT, then
     the iterations will stop when the procedure returns '#t'.

     Analytically, the minimum of x^3-2x-5 is 0.816497.

           (define func (lambda (x) (+ (* x (+ (* x x) -2)) -5)))
           (golden-section-search func 0 1 (/ 10000))
                ==> (816.4883855245578e-3 . -6.0886621077391165)
           (golden-section-search func 0 1 -5)
                ==> (819.6601125010515e-3 . -6.088637561916407)
           (golden-section-search func 0 1
                                 (lambda (a b c d e f g ) (= g 500)))
                ==> (816.4965933140557e-3 . -6.088662107903635)

16 (math primes)
****************

16.1 Overview
=============

This module defines functions related to prime numbers, and prime
factorization.

16.2 Usage
==========

 -- Variable: prime:trials
     This is the maximum number of iterations of Solovay-Strassen that
     will be done to test a number for primality.  The chance of error
     (a composite being labelled prime) is '(expt 2 (- prime:trials))'.

 -- Function: prime? a
     Returns '#f' if N is composite, and 't' if it is prime.  There is a
     slight chance, '(expt 2 (- prime:trials))', that a composite will
     return '#t'.

 -- Function: prime> a
     Return the first prime number greater than START.  It doesn't
     matter if START is prime or composite.

 -- Function: primes> a b
     Returns a list of the first COUNT prime numbers greater than START.

 -- Function: prime< a
     Return the first prime number less than START.  It doesn't matter
     if START is prime or composite.  If no primes are less than START,
     '#f' will be returned.

 -- Function: primes< a b
     Returns a list of the first COUNT prime numbers less than START.
     If there are fewer than COUNT prime numbers less than START, then
     the returned list will have fewer than START elements.

 -- Function: factor a
     Returns a list of the prime factors of K.  The order of the factors
     is unspecified.  In order to obtain a sorted list do '(sort!
     (factor K) <)'.

17 (os process)
***************

17.1 Overview
=============

This is a library for execution of other programs from Guile.  It also
allows communication using pipes (or a pseudo terminal device, but
that's not currently implemented).  This code originates in the
'(goosh)' modules, which itself was part of goonix in one of Guile's
past lives.

   The following will hold when starting programs:

  1. If the name of the program does not contain a '/' then the
     directories listed in the current 'PATH' environment variable are
     searched to locate the program.

  2. Unlike for the corresponding primitive exec procedures, e.g.,
     'execlp', the name of the program can not be set independently of
     the path to execute: the zeroth and first members of the argument
     vector are combined into one.

   All symbols exported with the prefix 'os:process:' are there in
support of macros that use them.  They should be ignored by users of
this module.

17.2 Usage
==========

 -- Special Form: os:process:pipe-fork-child

 -- Special Form: run+ args
     Evaluate an expression in a new foreground process and wait for its
     completion.  If no connection terms are specified, then all ports
     except 'current-input-port', 'current-output-port' and
     'current-error-port' will be closed in the new process.  The file
     descriptors underlying these ports will not be changed.

     The value returned is the exit status from the new process as
     returned by the 'waitpid' procedure.

     The KEYWORDS and CONNECTIONS arguments are optional: see
     'run-concurrently+', which is documented below.  The '#:foreground'
     keyword is implied.

           (run+ (begin (write (+ 2 2)) (newline) (quit 0)))

           (run+ (tail-call-program "cat" "/etc/passwd"))

 -- Special Form: run-concurrently+ args
     Evaluate an expression in a new background process.  If no
     connection terms are specified, then all ports except
     'current-input-port', 'current-output-port' and
     'current-error-port' will be closed in the new process.  The file
     descriptors underlying these ports will not be changed.

     The value returned in the parent is the pid of the new process.

     When the process terminates its exit status can be collected using
     the 'waitpid' procedure.

     Keywords can be specified before the connection list:

     '#:slave' causes the new process to be put into a new session.  If
     'current-input-port' (after redirections) is a tty it will be
     assigned as the controlling terminal.  This option is used when
     controlling a process via a pty.

     '#:no-auto-close' prevents the usual closing of ports which occurs
     by default.

     '#:foreground' makes the new process the foreground job of the
     controlling terminal, if the current process is using job control.
     (not currently implemented).  The default is to place it into the
     background

     The optional connection list can take several forms:

     '(port)' usually specifies that a given port not be closed.
     However if '#:no-auto-close' is present it specifies instead a port
     which should be closed.

     '(port 0)' specifies that a port be moved to a given file
     descriptor (e.g., 0) in the new process.  The order of the two
     components is not significant, but one must be a number and the
     other must evaluate to a port.  If the file descriptor is one of
     the standard set '(0, 1, 2)' then the corresponding standard port
     (e.g., 'current-input-port') will be set to the specified port.

     Example:

           (let ((p (open-input-file "/etc/passwd")))
             (run-concurrently+ (tail-call-program "cat") (p 0)))

 -- Special Form: tail-call-pipeline args
     Replace the current process image with a pipeline of connected
     processes.

     The expressions in the pipeline are run in new background
     processes.  The foreground process waits for them all to terminate.
     The exit status is derived from the status of the process at the
     tail of the pipeline: its exit status if it terminates normally,
     otherwise 128 plus the number of the signal that caused it to
     terminate.

     The signal handlers will be reset and file descriptors set up as
     for 'tail-call-program'.  Like 'tail-call-program' it does not
     close open ports or flush buffers.

     Example:

           (tail-call-pipeline ("ls" "/etc") ("grep" "passwd"))

 -- Special Form: tail-call-pipeline+ args
     Replace the current process image with a pipeline of connected
     processes.

     Each process is specified by an expression and each pair of
     processes has a connection list with pairs of file descriptors.
     E.g., '((1 0) (2 0))' specifies that file descriptors 1 and 2 are
     to be connected to file descriptor 0.  This may also be written as
     '((1 2 0))'.

     The expressions in the pipeline are run in new background
     processes.  The foreground process waits for them all to terminate.
     The exit status is derived from the status of the process at the
     tail of the pipeline: its exit status if it terminates normally,
     otherwise 128 plus the number of the signal that caused it to
     terminate.

     The signal handlers will be reset and file descriptors set up as
     for 'tail-call-program'.  Like 'tail-call-program' it does not
     close open ports or flush buffers.

     Example:

           (tail-call-pipeline+ (tail-call-program "ls" "/etc") ((1 0))
                                (tail-call-program "grep" "passwd"))

 -- Function: os:process:new-comm-pipes a b

 -- Function: os:process:pipe-make-commands a b c

 -- Function: os:process:pipe-make-redir-commands a b

 -- Function: os:process:setup-redirected-port a b

 -- Function: run a . rest
     Execute PROG in a new foreground process and wait for its
     completion.  The value returned is the exit status of the new
     process as returned by the 'waitpid' procedure.

     Example:

           (run "cat" "/etc/passwd")

 -- Function: run-concurrently . rest
     Start a program running in a new background process.  The value
     returned is the pid of the new process.

     When the process terminates its exit status can be collected using
     the 'waitpid' procedure.

     Example:

           (run-concurrently "cat" "/etc/passwd")

 -- Function: run-with-pipe a b . rest
     Start PROG running in a new background process.  The value returned
     is a pair: the CAR is the pid of the new process and the CDR is
     either a port or a pair of ports (with the CAR containing the input
     port and the CDR the output port).  The port(s) can be used to read
     from the standard output of the process and/or write to its
     standard input, depending on the MODE setting.  The value of MODE
     should be one of "r", "w" or "r+".

     When the process terminates its exit status can be collected using
     the 'waitpid' procedure.

     Example:

           (use-modules (ice-9 rdelim)) ; needed by read-line
           (define catport (cdr (run-with-pipe "r" "cat" "/etc/passwd")))
           (read-line catport)

 -- Function: tail-call-program a . rest
     Replace the current process image by executing PROG with the
     supplied list of arguments, ARGS.

     This procedure will reset the signal handlers and attempt to set up
     file descriptors as follows:

       1. File descriptor 0 is set from (current-input-port).

       2. File descriptor 1 is set from (current-output-port).

       3. File descriptor 2 is set from (current-error-port).

     If a port can not be used (e.g., because it's closed or it's a
     string port) then the file descriptor is opened on the file
     specified by '*null-device*' instead.

     Note that this procedure does not close any ports or flush output
     buffers.  Successfully executing PROG will prevent the normal
     flushing of buffers that occurs when Guile terminates.  Doing
     otherwise would be incorrect after forking a child process, since
     the buffers would be flushed in both parent and child.

     Examples:

           (tail-call-program "cat" "/etc/passwd")

           (with-input-from-file "/etc/passwd"
            (lambda ()
              (tail-call-program "cat")))

18 (scheme documentation)
*************************

18.1 Overview
=============

Defines some macros to help in documenting macros, variables, generic
functions, and classes.

18.2 Usage
==========

 -- Special Form: define-macro-with-docs args
     Define a macro with documentation.

 -- Special Form: define-with-docs args
     Define a variable with documentation.

 -- Special Form: define-generic-with-docs args
     Define a generic function with documentation.

 -- Special Form: define-class-with-docs args
     Define a class with documentation.

19 (scheme kwargs)
******************

19.1 Overview
=============

Support for defining functions that take python-like keyword arguments.
In one of his early talks, Paul Graham wrote about a large system called
"Rtml":

     Most of the operators in Rtml were designed to take keyword
     parameters, and what a help that turned out to be.  If I wanted to
     add another dimension to the behavior of one of the operators, I
     could just add a new keyword parameter, and everyone's existing
     templates would continue to work.  A few of the Rtml operators
     didn't take keyword parameters, because I didn't think I'd ever
     need to change them, and almost every one I ended up kicking myself
     about later.  If I could go back and start over from scratch, one
     of the things I'd change would be that I'd make every Rtml operator
     take keyword parameters.

   See lambda/kwargs, for documentation
and examples.

   See Optional Arguments (guile), for more information on Guile's
standard support for optional and keyword arguments.  Quote taken from
<http://lib.store.yahoo.net/lib/paulgraham/bbnexcerpts.txt>.

19.2 Usage
==========

 -- Special Form: define/kwargs args
     Defines a function that takes kwargs.  See scheme kwargs lambda/kwargs,
     for more information.

 -- Special Form: lambda/kwargs args
     Defines a function that takes keyword arguments.

     BINDINGS is a list of bindings, each of which may either be a
     symbol or a two-element symbol-and-default-value list.  Symbols
     without specified default values will default to '#f'.

     For example:

           (define frobulate (lambda/kwargs (foo (bar 13) (baz 42))
                               (list foo bar baz)))
           (frobulate) => (#f 13 42)
           (frobulate #:baz 3) => (#f 13 3)
           (frobulate #:foo 3) => (3 13 42)
           (frobulate 3 4) => (3 4 42)
           (frobulate 1 2 3) => (1 2 3)
           (frobulate #:baz 2 #:bar 1) => (#f 1 2)
           (frobulate 10 20 #:foo 3) => (3 20 42)

     This function differs from the standard 'lambda*' provided by Guile
     in that invoking the function will accept positional arguments.  As
     an example, the 'lambda/kwargs' behaves more intuitively in the
     following case:

           ((lambda* (#:optional (bar 42) #:key (baz 73))
              (list bar baz))
            1 2) => (1 73)
           ((lambda/kwargs ((bar 42) (baz 73))
              (list bar baz))
            1 2) => (1 2)

     The fact that 'lambda*' accepts the extra '2' argument is probably
     just a bug.  In any case, 'lambda/kwargs' does the right thing.

20 (search basic)
*****************

20.1 Overview
=============

 This module has the classic search functions in it.

20.2 Usage
==========

 -- Function: depth-first-search a b c
     Performs a depth-first search from initial state INIT.  It will
     return the first state it sees for which predicate DONE? returns
     '#t'.  It will use function EXPANDER to get a list of all states
     reacheable from a given state.

     INIT can take any form the user wishes.  This function treats it as
     opaque data to pass to DONE? and EXPANDER.

     DONE? takes one argument, of the same type as INIT, and returns
     either '#t' or '#f'.

     EXPANDER takes one argument, of the same type as INIT, and returns
     a list of states that can be reached from there.

 -- Function: breadth-first-search a b c
     Performs a breadth-first search from initial state INIT.  It will
     return the first state it sees for which predicate DONE? returns
     '#t'.  It will use function EXPANDER to get a list of all states
     reacheable from a given state.

     INIT can take any form the user wishes.  This function treats it as
     opaque data to pass to DONE? and EXPANDER.

     DONE? takes one argument, of the same type as INIT, and returns
     either '#t' or '#f'.

     EXPANDER takes one argument, of the same type as INIT, and returns
     a list of states that can be reached from there.

 -- Function: binary-search-sorted-vector _ _ [_] [_]
     Searches a sorted vector VEC for item TARGET.  A binary search is
     employed which should find an item in O(log n) time if it is
     present.  If TARGET is found, the index into VEC is returned.

     As part of the search, the function CMP is applied to determine
     whether a vector item is less than, greater than, or equal to the
     TARGET.  If TARGET cannot be found in the vector, then DEFAULT is
     returned.

     CMP defaults to '-', which gives a correct comparison for vectors
     of numbers.  DEFAULT will be '#f' if another value is not given.

           (binary-search-sorted-vector #(10 20 30) 20) => 1

21 (string completion)
**********************

21.1 Overview
=============

This module provides a facility that can be used to implement features
such as TAB-completion in programs.  A class '<string-completer>' tracks
all the potential complete strings.  Here is an example usage.

     (use-modules (string completion)
                  (oop goops)
                  (srfi srfi-11))      ;; for the (let-values)

     (define c (make <string-completer>))
     (add-strings! c "you your yourself yourselves")

     (let-values (((completions expansion exact? unique?) (complete c "yours")))
                 (display completions)(newline)
                 (display expansion) (newline)
                 (display exact?)(newline)
                 (display unique?)(newline))

     ==> ("yourself" "yourselves")
         "yoursel"
         #f
         #f

   There are several more options for usage, which are detailed in the
class and method documentation.

21.2 Usage
==========

 -- Class: <string-completer>
     This is the class that knows what the possible expansions are, and
     can determine the completions of given partial strings.  The
     following are the recognized keywords on the call to 'make':

     '#:strings'
          This gives the completer an initial set of strings.  It is
          optional, and the 'add-strings!' method can add strings to the
          completer later, whether these initial strings were given or
          not.  The strings that follow this keyword can take any form
          that the 'add-strings!' method can take (see below).

     '#:case-sensitive?'
          This is a boolean that directs the completer to do its
          comparisons in a case sensiteve way or not.  The default value
          is '#t', for case-sensitive behavior.

 -- Generic: case-sensitive-completion?
     'case-sensitive-completion? completer'.  Returns '#t' if the
     completer is case-sensitive, and '#f' otherwise.

 -- Method: case-sensitive-completion?

 -- Generic: add-strings!
     'add-strings! completer strings'.  Adds the given strings to the
     set of possible comletions known to COMPLETER.  STRINGS can either
     be a list of strings, or a single string of words separated by
     spaces.  The order of the words given is not important.

 -- Method: add-strings! (SC '<string-completer>') (STRINGS '<top>')

 -- Function: all-completions a b
     Returns a list of all possible completions for the given string
     STR.  The returned list will be in alphabetical order.

     Note that users wanting to customize the completion algorithm can
     subclass '<string-completer>' and override this method.

 -- Generic: complete
     'complete completer str'.  Accepts a string, STR, and returns four
     values via a 'values' call.  These are:

     COMPLETIONS
          This is the same list that would be returned from a call to
          'all-completions'.

     EXPANSION
          This is the longest string that would have returned identical
          results.  In other words, this is what most programs replace
          your string with when you press TAB once.  This value will be
          equal to STR if there were no known completionss.

                ("wonders" "wonderment" "wondering")
               completed against "won" yields an expansion
               of "wonder"

     EXACT?
          This will be '#t' if the returned EXPANSION is an exact match
          of one of the possible completions.

     UNIQUE?
          This will be #t if there is only one possible completion.
          Note that when UNIQUE? is '#t', then EXACT? will also be '#t'.

 -- Method: complete (SC '<string-completer>') (STR '<top>')

22 (string soundex)
*******************

22.1 Overview
=============

Soundex algorithm, taken from Knuth, Vol.  3 "Sorting and searching", pp
391-2

22.2 Usage
==========

 -- Function: soundex a
     Performs the original soundex algorithm on the input NAME.  Returns
     the encoded string.  The idea is for similar sounding sames to end
     up with the same encoding.

           (soundex "Aiza")
          => "A200"
           (soundex "Aisa")
          => "A200"
           (soundex "Aesha")
          => "A200"

23 (string transform)
*********************

23.1 Overview
=============

Module '(string transform)' provides functions for modifying strings
beyond that which is provided in the guile core and '(srfi srfi-13)'.

23.2 Usage
==========

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

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

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

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

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

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

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

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

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

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

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

     Assuming tab size of 8, this is equivalent to:

           (transform-string str #\tab "        ")

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

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

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

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

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

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

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

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

24 (string wrap)
****************

24.1 Overview
=============

Module '(string wrap)' provides functions for formatting text strings
such that they fill a given width field.  A class, '<text-wrapper>',
does the work, but two convenience methods create instances of it for
one-shot use, and in the process make for a more "schemey" interface.
If many strings will be formatted with the same parameters, it might be
better performance-wise to create and use a single '<text-wrapper>'.

24.2 Usage
==========

 -- Class: <text-wrapper>
     This class encapsulates the parameters needing to be fed to the
     text wrapping algorithm.  The following are the recognized keywords
     on the call to 'make':

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

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

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

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

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

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

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

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

     Here's an example of creating a '<text-wrapper>':

           (make <text-wrapper> #:line-width 48 #:break-long-words? #f)

 -- Generic: fill-string
     'fill-string str keywds ...'.  Wraps the text given in string STR
     according to the parameters provided in KEYWDS, or the default
     setting if they are not given.  Returns a single string with the
     wrapped text.  Valid keyword arguments are discussed with the
     '<text-wrapper>' class.

     'fill-string tw str'.  fills STR using the instance of
     '<text-wrapper>' given as TW.

 -- Method: fill-string (TW '<text-wrapper>') (STR '<top>')

 -- Method: fill-string (STR '<top>') (KEYWDS '<top>')...

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

     'string->wrapped-lines tw str'.  Wraps the text given in string STR
     according to the given '<text-wrapper>' TW.  Returns a list of
     strings representing the formatted lines.  Valid keyword arguments
     are discussed with the '<text-wrapper>' class.

 -- Method: string->wrapped-lines (TW '<text-wrapper>') (STR '<top>')

 -- Method: string->wrapped-lines (STR '<top>') (KEYWDS '<top>')...

25 (term ansi-color)
********************

25.1 Overview
=============

The '(term ansi-color)' module generates ANSI escape sequences for
colors.  Here is an example of the module's use:

      method one: safer, since you know the colors
      will get reset
     (display (colorize-string "Hello!\n" 'RED 'BOLD 'ON-BLUE))

      method two: insert the colors by hand
     (for-each display
               (list (color 'RED 'BOLD 'ON-BLUE)
                     "Hello!"
                      (color 'RESET)))

25.2 Usage
==========

 -- Function: color . rest
     Returns a string containing the ANSI escape sequence for producing
     the requested set of attributes.

     The allowed values for the attributes are listed below.  Unknown
     attributes are ignored.

     Reset Attributes
          'CLEAR' and 'RESET' are allowed and equivalent.

     Non-Color Attributes
          'BOLD' makes text bold, and 'DARK' reverses this.  'UNDERLINE'
          and 'UNDERSCORE' are equivalent.  'BLINK' makes the text
          blink.  'REVERSE' invokes reverse video.  'CONCEALED' hides
          output (as for getting passwords, etc.).

     Foregrond Color Attributes
          'BLACK', 'RED', 'GREEN', 'YELLOW', 'BLUE', 'MAGENTA', 'CYAN',
          'WHITE'

     Background Color Attributes
          'ON-BLACK', 'ON-RED', 'ON-GREEN', 'ON-YELLOW', 'ON-BLUE',
          'ON-MAGENTA', 'ON-CYAN', 'ON-WHITE'

 -- Function: colorize-string a . rest
     Returns a copy of STR colorized using ANSI escape sequences
     according to the attributes specified in COLOR-LIST.  At the end of
     the returned string, the color attributes will be reset such that
     subsequent output will not have any colors in effect.

     The allowed values for the attributes are listed in the
     documentation for the 'color' function.

26 (unit-test)
**************

26.1 Overview
=============

26.2 Usage
==========

 -- Function: assert-equal a b

 -- Function: assert-true a

 -- Function: assert-false a

 -- Function: assert-numeric-= a b c

 -- Class: <test-result>

 -- Generic: tests-run

 -- Method: tests-run

 -- Generic: tests-failed

 -- Method: tests-failed

 -- Generic: tests-log

 -- Method: tests-log

 -- Generic: failure-messages

 -- Method: failure-messages

 -- Generic: test-started

 -- Method: test-started (SELF '<test-result>') (DESCRIPTION '<string>')

 -- Generic: test-failed

 -- Method: test-failed (SELF '<test-result>') (DESCRIPTION '<string>')

 -- Generic: summary

 -- Method: summary (SELF '<test-result>')

 -- Class: <test-case>

 -- Generic: name

 -- Method: name

 -- Method: name

 -- Generic: set-up-test

 -- Method: set-up-test (SELF '<test-case>')

 -- Generic: tear-down-test

 -- Method: tear-down-test (SELF '<test-case>')

 -- Generic: run

 -- Method: run (SELF '<test-suite>') (RESULT '<test-result>')

 -- Method: run (SELF '<test-case>') (RESULT '<test-result>')

 -- Class: <test-suite>

 -- Generic: tests

 -- Method: tests

 -- Generic: add

 -- Method: add (SELF '<test-suite>') (SUITE '<test-suite>')

 -- Method: add (SELF '<test-suite>') (TEST '<test-case>')

 -- Function: run-all-defined-test-cases

 -- Function: exit-with-summary a

 -- Special Form: assert

 -- Special Form: assert-exception

Appendix A Copying This Manual
******************************

This manual is covered under the GNU Free Documentation License.  A copy
of the FDL is provided here.

A.1 GNU Free Documentation License
==================================

                      Version 1.2, November 2002

     Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
     59 Temple Place, Suite 330, Boston, MA  02111-1307, USA

     Everyone is permitted to copy and distribute verbatim copies
     of this license document, but changing it is not allowed.

  0. PREAMBLE

     The purpose of this License is to make a manual, textbook, or other
     functional and useful document "free" in the sense of freedom: to
     assure everyone the effective freedom to copy and redistribute it,
     with or without modifying it, either commercially or
     noncommercially.  Secondarily, this License preserves for the
     author and publisher a way to get credit for their work, while not
     being considered responsible for modifications made by others.

     This License is a kind of "copyleft", which means that derivative
     works of the document must themselves be free in the same sense.
     It complements the GNU General Public License, which is a copyleft
     license designed for free software.

     We have designed this License in order to use it for manuals for
     free software, because free software needs free documentation: a
     free program should come with manuals providing the same freedoms
     that the software does.  But this License is not limited to
     software manuals; it can be used for any textual work, regardless
     of subject matter or whether it is published as a printed book.  We
     recommend this License principally for works whose purpose is
     instruction or reference.

  1. APPLICABILITY AND DEFINITIONS

     This License applies to any manual or other work, in any medium,
     that contains a notice placed by the copyright holder saying it can
     be distributed under the terms of this License.  Such a notice
     grants a world-wide, royalty-free license, unlimited in duration,
     to use that work under the conditions stated herein.  The
     "Document", below, refers to any such manual or work.  Any member
     of the public is a licensee, and is addressed as "you".  You accept
     the license if you copy, modify or distribute the work in a way
     requiring permission under copyright law.

     A "Modified Version" of the Document means any work containing the
     Document or a portion of it, either copied verbatim, or with
     modifications and/or translated into another language.

     A "Secondary Section" is a named appendix or a front-matter section
     of the Document that deals exclusively with the relationship of the
     publishers or authors of the Document to the Document's overall
     subject (or to related matters) and contains nothing that could
     fall directly within that overall subject.  (Thus, if the Document
     is in part a textbook of mathematics, a Secondary Section may not
     explain any mathematics.)  The relationship could be a matter of
     historical connection with the subject or with related matters, or
     of legal, commercial, philosophical, ethical or political position
     regarding them.

     The "Invariant Sections" are certain Secondary Sections whose
     titles are designated, as being those of Invariant Sections, in the
     notice that says that the Document is released under this License.
     If a section does not fit the above definition of Secondary then it
     is not allowed to be designated as Invariant.  The Document may
     contain zero Invariant Sections.  If the Document does not identify
     any Invariant Sections then there are none.

     The "Cover Texts" are certain short passages of text that are
     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
     that says that the Document is released under this License.  A
     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
     be at most 25 words.

     A "Transparent" copy of the Document means a machine-readable copy,
     represented in a format whose specification is available to the
     general public, that is suitable for revising the document
     straightforwardly with generic text editors or (for images composed
     of pixels) generic paint programs or (for drawings) some widely
     available drawing editor, and that is suitable for input to text
     formatters or for automatic translation to a variety of formats
     suitable for input to text formatters.  A copy made in an otherwise
     Transparent file format whose markup, or absence of markup, has
     been arranged to thwart or discourage subsequent modification by
     readers is not Transparent.  An image format is not Transparent if
     used for any substantial amount of text.  A copy that is not
     "Transparent" is called "Opaque".

     Examples of suitable formats for Transparent copies include plain
     ASCII without markup, Texinfo input format, LaTeX input format,
     SGML or XML using a publicly available DTD, and standard-conforming
     simple HTML, PostScript or PDF designed for human modification.
     Examples of transparent image formats include PNG, XCF and JPG.
     Opaque formats include proprietary formats that can be read and
     edited only by proprietary word processors, SGML or XML for which
     the DTD and/or processing tools are not generally available, and
     the machine-generated HTML, PostScript or PDF produced by some word
     processors for output purposes only.

     The "Title Page" means, for a printed book, the title page itself,
     plus such following pages as are needed to hold, legibly, the
     material this License requires to appear in the title page.  For
     works in formats which do not have any title page as such, "Title
     Page" means the text near the most prominent appearance of the
     work's title, preceding the beginning of the body of the text.

     A section "Entitled XYZ" means a named subunit of the Document
     whose title either is precisely XYZ or contains XYZ in parentheses
     following text that translates XYZ in another language.  (Here XYZ
     stands for a specific section name mentioned below, such as
     "Acknowledgements", "Dedications", "Endorsements", or "History".)
     To "Preserve the Title" of such a section when you modify the
     Document means that it remains a section "Entitled XYZ" according
     to this definition.

     The Document may include Warranty Disclaimers next to the notice
     which states that this License applies to the Document.  These
     Warranty Disclaimers are considered to be included by reference in
     this License, but only as regards disclaiming warranties: any other
     implication that these Warranty Disclaimers may have is void and
     has no effect on the meaning of this License.

  2. VERBATIM COPYING

     You may copy and distribute the Document in any medium, either
     commercially or noncommercially, provided that this License, the
     copyright notices, and the license notice saying this License
     applies to the Document are reproduced in all copies, and that you
     add no other conditions whatsoever to those of this License.  You
     may not use technical measures to obstruct or control the reading
     or further copying of the copies you make or distribute.  However,
     you may accept compensation in exchange for copies.  If you
     distribute a large enough number of copies you must also follow the
     conditions in section 3.

     You may also lend copies, under the same conditions stated above,
     and you may publicly display copies.

  3. COPYING IN QUANTITY

     If you publish printed copies (or copies in media that commonly
     have printed covers) of the Document, numbering more than 100, and
     the Document's license notice requires Cover Texts, you must
     enclose the copies in covers that carry, clearly and legibly, all
     these Cover Texts: Front-Cover Texts on the front cover, and
     Back-Cover Texts on the back cover.  Both covers must also clearly
     and legibly identify you as the publisher of these copies.  The
     front cover must present the full title with all words of the title
     equally prominent and visible.  You may add other material on the
     covers in addition.  Copying with changes limited to the covers, as
     long as they preserve the title of the Document and satisfy these
     conditions, can be treated as verbatim copying in other respects.

     If the required texts for either cover are too voluminous to fit
     legibly, you should put the first ones listed (as many as fit
     reasonably) on the actual cover, and continue the rest onto
     adjacent pages.

     If you publish or distribute Opaque copies of the Document
     numbering more than 100, you must either include a machine-readable
     Transparent copy along with each Opaque copy, or state in or with
     each Opaque copy a computer-network location from which the general
     network-using public has access to download using public-standard
     network protocols a complete Transparent copy of the Document, free
     of added material.  If you use the latter option, you must take
     reasonably prudent steps, when you begin distribution of Opaque
     copies in quantity, to ensure that this Transparent copy will
     remain thus accessible at the stated location until at least one
     year after the last time you distribute an Opaque copy (directly or
     through your agents or retailers) of that edition to the public.

     It is requested, but not required, that you contact the authors of
     the Document well before redistributing any large number of copies,
     to give them a chance to provide you with an updated version of the
     Document.

  4. MODIFICATIONS

     You may copy and distribute a Modified Version of the Document
     under the conditions of sections 2 and 3 above, provided that you
     release the Modified Version under precisely this License, with the
     Modified Version filling the role of the Document, thus licensing
     distribution and modification of the Modified Version to whoever
     possesses a copy of it.  In addition, you must do these things in
     the Modified Version:

       A. Use in the Title Page (and on the covers, if any) a title
          distinct from that of the Document, and from those of previous
          versions (which should, if there were any, be listed in the
          History section of the Document).  You may use the same title
          as a previous version if the original publisher of that
          version gives permission.

       B. List on the Title Page, as authors, one or more persons or
          entities responsible for authorship of the modifications in
          the Modified Version, together with at least five of the
          principal authors of the Document (all of its principal
          authors, if it has fewer than five), unless they release you
          from this requirement.

       C. State on the Title page the name of the publisher of the
          Modified Version, as the publisher.

       D. Preserve all the copyright notices of the Document.

       E. Add an appropriate copyright notice for your modifications
          adjacent to the other copyright notices.

       F. Include, immediately after the copyright notices, a license
          notice giving the public permission to use the Modified
          Version under the terms of this License, in the form shown in
          the Addendum below.

       G. Preserve in that license notice the full lists of Invariant
          Sections and required Cover Texts given in the Document's
          license notice.

       H. Include an unaltered copy of this License.

       I. Preserve the section Entitled "History", Preserve its Title,
          and add to it an item stating at least the title, year, new
          authors, and publisher of the Modified Version as given on the
          Title Page.  If there is no section Entitled "History" in the
          Document, create one stating the title, year, authors, and
          publisher of the Document as given on its Title Page, then add
          an item describing the Modified Version as stated in the
          previous sentence.

       J. Preserve the network location, if any, given in the Document
          for public access to a Transparent copy of the Document, and
          likewise the network locations given in the Document for
          previous versions it was based on.  These may be placed in the
          "History" section.  You may omit a network location for a work
          that was published at least four years before the Document
          itself, or if the original publisher of the version it refers
          to gives permission.

       K. For any section Entitled "Acknowledgements" or "Dedications",
          Preserve the Title of the section, and preserve in the section
          all the substance and tone of each of the contributor
          acknowledgements and/or dedications given therein.

       L. Preserve all the Invariant Sections of the Document, unaltered
          in their text and in their titles.  Section numbers or the
          equivalent are not considered part of the section titles.

       M. Delete any section Entitled "Endorsements".  Such a section
          may not be included in the Modified Version.

       N. Do not retitle any existing section to be Entitled
          "Endorsements" or to conflict in title with any Invariant
          Section.

       O. Preserve any Warranty Disclaimers.

     If the Modified Version includes new front-matter sections or
     appendices that qualify as Secondary Sections and contain no
     material copied from the Document, you may at your option designate
     some or all of these sections as invariant.  To do this, add their
     titles to the list of Invariant Sections in the Modified Version's
     license notice.  These titles must be distinct from any other
     section titles.

     You may add a section Entitled "Endorsements", provided it contains
     nothing but endorsements of your Modified Version by various
     parties--for example, statements of peer review or that the text
     has been approved by an organization as the authoritative
     definition of a standard.

     You may add a passage of up to five words as a Front-Cover Text,
     and a passage of up to 25 words as a Back-Cover Text, to the end of
     the list of Cover Texts in the Modified Version.  Only one passage
     of Front-Cover Text and one of Back-Cover Text may be added by (or
     through arrangements made by) any one entity.  If the Document
     already includes a cover text for the same cover, previously added
     by you or by arrangement made by the same entity you are acting on
     behalf of, you may not add another; but you may replace the old
     one, on explicit permission from the previous publisher that added
     the old one.

     The author(s) and publisher(s) of the Document do not by this
     License give permission to use their names for publicity for or to
     assert or imply endorsement of any Modified Version.

  5. COMBINING DOCUMENTS

     You may combine the Document with other documents released under
     this License, under the terms defined in section 4 above for
     modified versions, provided that you include in the combination all
     of the Invariant Sections of all of the original documents,
     unmodified, and list them all as Invariant Sections of your
     combined work in its license notice, and that you preserve all
     their Warranty Disclaimers.

     The combined work need only contain one copy of this License, and
     multiple identical Invariant Sections may be replaced with a single
     copy.  If there are multiple Invariant Sections with the same name
     but different contents, make the title of each such section unique
     by adding at the end of it, in parentheses, the name of the
     original author or publisher of that section if known, or else a
     unique number.  Make the same adjustment to the section titles in
     the list of Invariant Sections in the license notice of the
     combined work.

     In the combination, you must combine any sections Entitled
     "History" in the various original documents, forming one section
     Entitled "History"; likewise combine any sections Entitled
     "Acknowledgements", and any sections Entitled "Dedications".  You
     must delete all sections Entitled "Endorsements."

  6. COLLECTIONS OF DOCUMENTS

     You may make a collection consisting of the Document and other
     documents released under this License, and replace the individual
     copies of this License in the various documents with a single copy
     that is included in the collection, provided that you follow the
     rules of this License for verbatim copying of each of the documents
     in all other respects.

     You may extract a single document from such a collection, and
     distribute it individually under this License, provided you insert
     a copy of this License into the extracted document, and follow this
     License in all other respects regarding verbatim copying of that
     document.

  7. AGGREGATION WITH INDEPENDENT WORKS

     A compilation of the Document or its derivatives with other
     separate and independent documents or works, in or on a volume of a
     storage or distribution medium, is called an "aggregate" if the
     copyright resulting from the compilation is not used to limit the
     legal rights of the compilation's users beyond what the individual
     works permit.  When the Document is included in an aggregate, this
     License does not apply to the other works in the aggregate which
     are not themselves derivative works of the Document.

     If the Cover Text requirement of section 3 is applicable to these
     copies of the Document, then if the Document is less than one half
     of the entire aggregate, the Document's Cover Texts may be placed
     on covers that bracket the Document within the aggregate, or the
     electronic equivalent of covers if the Document is in electronic
     form.  Otherwise they must appear on printed covers that bracket
     the whole aggregate.

  8. TRANSLATION

     Translation is considered a kind of modification, so you may
     distribute translations of the Document under the terms of section
     4.  Replacing Invariant Sections with translations requires special
     permission from their copyright holders, but you may include
     translations of some or all Invariant Sections in addition to the
     original versions of these Invariant Sections.  You may include a
     translation of this License, and all the license notices in the
     Document, and any Warranty Disclaimers, provided that you also
     include the original English version of this License and the
     original versions of those notices and disclaimers.  In case of a
     disagreement between the translation and the original version of
     this License or a notice or disclaimer, the original version will
     prevail.

     If a section in the Document is Entitled "Acknowledgements",
     "Dedications", or "History", the requirement (section 4) to
     Preserve its Title (section 1) will typically require changing the
     actual title.

  9. TERMINATION

     You may not copy, modify, sublicense, or distribute the Document
     except as expressly provided for under this License.  Any other
     attempt to copy, modify, sublicense or distribute the Document is
     void, and will automatically terminate your rights under this
     License.  However, parties who have received copies, or rights,
     from you under this License will not have their licenses terminated
     so long as such parties remain in full compliance.

  10. FUTURE REVISIONS OF THIS LICENSE

     The Free Software Foundation may publish new, revised versions of
     the GNU Free Documentation License from time to time.  Such new
     versions will be similar in spirit to the present version, but may
     differ in detail to address new problems or concerns.  See
     <http://www.gnu.org/copyleft/>.

     Each version of the License is given a distinguishing version
     number.  If the Document specifies that a particular numbered
     version of this License "or any later version" applies to it, you
     have the option of following the terms and conditions either of
     that specified version or of any later version that has been
     published (not as a draft) by the Free Software Foundation.  If the
     Document does not specify a version number of this License, you may
     choose any version ever published (not as a draft) by the Free
     Software Foundation.

A.1.1 ADDENDUM: How to use this License for your documents
----------------------------------------------------------

To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and license
notices just after the title page:

       Copyright (C)  YEAR  YOUR NAME.
       Permission is granted to copy, distribute and/or modify this document
       under the terms of the GNU Free Documentation License, Version 1.2
       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''.

   If you have Invariant Sections, Front-Cover Texts and Back-Cover
Texts, replace the "with...Texts."  line with this:

         with the Invariant Sections being LIST THEIR TITLES, with
         the Front-Cover Texts being LIST, and with the Back-Cover Texts
         being LIST.

   If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.

   If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of free
software license, such as the GNU General Public License, to permit
their use in free software.