Extensions to Scheme
********************

The current ``standard'' for the Scheme language is the Revised^4 Report on the Algorithmic Language Scheme (r4rs), and it is commonly referred to as R4RS.  Most Scheme implementations conform to all the required features in R4RS as well as the optional ones.

But most Scheme implementations go beyond R4RS in some ways, mostly because R4RS does not give specifications (or even recommendations) regarding some issues that are quite important in practical programming.

[FIXME: hmm; what else goes in this chapter?  we have chapters for just about everything.  I'll put a reference to R4RS and leave it.]

The Scheme language implemented in Guile is R4RS compliant, so R4RS is a valid document describing the basic Guile language.  This part of the Guile Reference Manual describes the extensions to Scheme provided in Guile.

In this chapter we describe some minor configurable differences from R4RS, mostly introduced to make eventual Emacs Lisp translation easier. Later chapters will introduce major extensions to Scheme.

Guile options interface
=======================

Guile's behaviour can be modified by setting options.  For example, is the language that Guile accepts case sensitive, or should the debugger automatically show a backtrace on error?

Guile has two levels of interface for managing options: a low-level control interface, and a user-level interface which allows the enabling or disabling of options.

Moreover, the options are classified in groups according to whether they configure reading, printing, debugging or evaluating.

General option interface
------------------------

We will use the expression <group> to represent read, print, debug or evaluator.

Low level
.........

 -- primitive: <group>-options-interface
 -- primitive: read-options-interface [SOME-INT]
 -- primitive: print-options-interface [SOME-INT]
 -- primitive: evaluator-traps-interface [SOME-INT]
 -- primitive: read-options-interface [SOME-INT]
     [FIXME: I have just taken the comments for C routine scm_options that implements all of these.  It needs to be presented better.]

     If scm_options is called without arguments, the current option setting is returned.  If the argument is an option setting, options are altered and the old setting is returned.  If the argument isn't a list, a list of sublists is returned, where each sublist contains option name, value and documentation string.

User level
..........

 -- procedure: <group>-options [arg]
 -- procedure: read-options [arg]
 -- procedure: print-options [arg]
 -- procedure: debug-options [arg]
 -- procedure: traps [arg]
     These functions list the options in their group.  The optional argument ARG is a symbol which modifies the form in which the options are presented.

     With no arguments, <group>-options returns the values of the options in that particular group.  If ARG is 'help, a description of each option is given.  If ARG is 'full, programmers' options are also shown.

     ARG can also be a list representing the state of all options.  In this case, the list contains single symbols (for enabled boolean options) and symbols followed by values.

[FIXME: I don't think 'full is ever any different from 'help.  What's up?]

 -- procedure: <group>-enable option-symbol
 -- procedure: read-enable option-symbol
 -- procedure: print-enable option-symbol
 -- procedure: debug-enable option-symbol
 -- procedure: trap-enable option-symbol
     These functions set the specified OPTION-SYMBOL in their options group.  They only work if the option is boolean, and throw an error otherwise.

 -- procedure: <group>-disable option-symbol
 -- procedure: read-disable option-symbol
 -- procedure: print-disable option-symbol
 -- procedure: debug-disable option-symbol
 -- procedure: trap-disable option-symbol
     These functions turn off the specified OPTION-SYMBOL in their options group.  They only work if the option is boolean, and throw an error otherwise.

 -- syntax: <group>-set! option-symbol value
 -- syntax: read-set! option-symbol value
 -- syntax: print-set! option-symbol value
 -- syntax: debug-set! option-symbol value
 -- syntax: trap-set! option-symbol value
     These functions set a non-boolean OPTION-SYMBOL to the specified VALUE.

Reader options
--------------

Here is the list of reader options generated by typing (read-options 'full) in Guile.  You can also see the default values.

     keywords         #f      Style of keyword recognition: #f or 'prefix
     case-insensitive no      Convert symbols to lower case.
     positions        yes     Record positions of source code expressions.
     copy             no      Copy source code expressions.

Notice that while Standard Scheme is case insensitive, to ease translation of other Lisp dialects, notably Emacs Lisp, into Guile, Guile is case-sensitive by default.

To make Guile case insensitive, you can type

     (read-enable 'case-insensitive)

Printing options
----------------

Here is the list of print options generated by typing (print-options 'full) in Guile.  You can also see the default values.

     source          no      Print closures with source.
     closure-hook    #f      Hook for printing closures.

Evaluator options
-----------------

Here is the list of print options generated by typing (traps 'full) in Guile.  You can also see the default values.

     exit-frame      no      Trap when exiting eval or apply.
     apply-frame     no      Trap when entering apply.
     enter-frame     no      Trap when eval enters new frame.

Debugger options
----------------

Here is the list of print options generated by typing (debug-options 'full) in Guile.  You can also see the default values.

     stack           20000   Stack size limit (0 = no check).
     debug           yes     Use the debugging evaluator.
     backtrace       no      Show backtrace on error.
     depth           20      Maximal length of printed backtrace.
     maxdepth        1000    Maximal number of stored backtrace frames.
     frames          3       Maximum number of tail-recursive frames in backtrace.
     indent          10      Maximal indentation in backtrace.
     backwards       no      Display backtrace in anti-chronological order.
     procnames       yes     Record procedure names at definition.
     trace           no      *Trace mode.
     breakpoints     no      *Check for breakpoints.
     cheap           yes     *Flyweight representation of the stack at traps.

Examples of option use
----------------------

Here is an example of a session in which some read and debug option handling procedures are used.  In this example, the user

 1. Notices that the symbols abc and aBc are not the same

 2. Examines the read-options, and sees that case-insensitive is set to ``no''.

 3. Enables case-insensitive

 4. Verifies that now aBc and abc are the same

 5. Disables case-insensitive and enables debugging backtrace

 6. Reproduces the error of displaying aBc with backtracing enabled [FIXME: this last example is lame because there is no depth in the backtrace.  Need to give a better example, possibly putting debugging option examples in a separate session.]

     guile> (define abc "hello")
     guile> abc
     "hello"
     guile> aBc
     ERROR: In expression aBc:
     ERROR: Unbound variable: aBc
     ABORT: (misc-error)

     Type "(backtrace)" to get more information.
     guile> (read-options 'help)
     keywords	#f	Style of keyword recognition: #f or 'prefix
     case-insensitive	no	Convert symbols to lower case.
     positions	yes	Record positions of source code expressions.
     copy		no	Copy source code expressions.
     guile> (debug-options 'help)
     stack		20000	Stack size limit (0 = no check).
     debug		yes	Use the debugging evaluator.
     backtrace	no	Show backtrace on error.
     depth		20	Maximal length of printed backtrace.
     maxdepth	1000	Maximal number of stored backtrace frames.
     frames		3	Maximum number of tail-recursive frames in backtrace.
     indent		10	Maximal indentation in backtrace.
     backwards	no	Display backtrace in anti-chronological order.
     procnames	yes	Record procedure names at definition.
     trace		no	*Trace mode.
     breakpoints	no	*Check for breakpoints.
     cheap		yes	*Flyweight representation of the stack at traps.
     guile> (read-enable 'case-insensitive)
     (keywords #f case-insensitive positions)
     guile> aBc
     "hello"
     guile> (read-disable 'case-insensitive)
     (keywords #f positions)
     guile> (debug-enable 'backtrace)
     (stack 20000 debug backtrace depth 20 maxdepth 1000 frames 3 indent 10 procnames cheap)
     guile> aBc

     Backtrace:
     0* aBc

     ERROR: In expression aBc:
     ERROR: Unbound variable: aBc
     ABORT: (misc-error)
     guile>

SLIB
****

Before the the SLIB facilities can be used, the following Scheme expression must be executed:

     (use-modules (ice-9 slib))

require can then be used as described in SLIB (The SLIB Manual).  For example:

     (require 'format)
     (format "~8,48D" 10)

JACAL
=====

Jacal is a symbolic math package written in Scheme by Aubrey Jaffer.  It is usually installed as an extra package in SLIB (see Packages not shipped with Guile).

You can use Guile's interface to SLIB to invoke Jacal:

     (use-modules (ice-9 slib))
     (slib:load "math")
     (math)

For complete documentation on Jacal, please read the Jacal manual.  If it has been installed on line, you can look at Jacal (The SLIB Manual).  Otherwise you can find it on the web at http://www-swiss.ai.mit.edu/~jaffer/JACAL.html

Evaluation
**********

This chapter describes Guile functions that are concerned with loading and evaluating Scheme code at run time.  R4RS Scheme, because of strong differences in opinion among implementors, only provides a load function.  There are many useful programs that are difficult or impossible to write without more powerful evaluation procedures, so we have provided some.

[FIXME: This needs some more text on the difference between procedures, macros and memoizing macros.  Also, any definitions listed here should be double-checked by someone who knows what's going on.  Ask Mikael, Jim or Aubrey for help. -twp]

 -- primitive: procedure-documentation proc
     Return the documentation string associated with proc.  By convention, if a procedure contains more than one expression and the first expression is a string constant, that string is assumed to contain documentation for that procedure.

 -- primitive: procedure->syntax proc
     [FIXME: Get documentation from SCM/SLIB.]

 -- primitive: procedure->macro proc
     [FIXME: Get documentation from SCM/SLIB.]

 -- primitive: procedure->memoizing-macro proc
     [FIXME: Get documentation from SCM/SLIB.]

 -- primitive: macro? obj
     Return #t if OBJ is a regular macro, a memoizing macro or a syntax transformer.

 -- primitive: macro-type obj
     Return one of the symbols syntax, macro or macro!, depending on whether OBJ is a syntax tranformer, a regular macro, or a memoizing macro, respectively.  If OBJ is not a macro, #f is returned.

 -- primitive: macro-name

 -- primitive: macro-transformer

 -- primitive: promise? obj
     Return true if OBJ is a promise, i.e. a delayed computation (see Delayed evaluation (The Revised^4 Report on Scheme)).

 -- primitive: copy-tree obj
     Recursively copy the data tree that is bound to OBJ, and return a pointer to the new data structure.  copy-tree recurses down the contents of both pairs and vectors (since both cons cells and vector cells may point to arbitrary objects), and stops recursing when it hits any other object.

 -- primitive: eval exp
     Evaluate EXP, a list representing a Scheme expression, in the top-level environment.

 -- primitive: eval2 exp lookup
     Evaluate EXP, a Scheme expression, in the environment designated by LOOKUP, a symbol-lookup function.  (eval exp) is equivalent to (eval2 exp *top-level-lookup-closure*).

 -- primitive: local-eval! exp [env]
     Evaluate EXP in its environment.  If ENV is supplied, it is the environment in which to evaluate EXP.  Otherwise, EXP must be a memoized code object (in which case, its environment is implicit).

 -- primitive: eval-string string
     Evaluate STRING as the text representation of a Scheme form or forms, and return whatever value they produce.

 -- primitive: defined? sym
     Return #t if SYM is defined in the top-level environment.

 -- primitive: read-and-eval! [port]
     Read a form from PORT (standard input by default), and evaluate it (memoizing it in the process) in the top-level environment.  If no data is left to be read from PORT, an end-of-file error is signalled.

 -- primitive: primitive-load file
     Load FILE and evaluate its contents in the top-level environment. The load paths are not searched; FILE must either be a full pathname or be a pathname relative to the current directory.  If the variable %load-hook is defined, it should be bound to a procedure that will be called before any code is loaded.  See documentation for %load-hook later in this section.

 -- primitive: primitive-load-path file
     Search %LOAD-PATH for FILE and load it into the top-level environment.  If FILE is a relative pathname and is not found in the list of search paths, an error is signalled.

 -- primitive: %search-load-path file
     Search %LOAD-PATH for FILE, which must be readable by the current user.  If FILE is found in the list of paths to search or is an absolute pathname, return its full pathname.  Otherwise, return #f.  Filenames may have any of the optional extensions in the %load-extensions list; %search-load-path will try each extension automatically.

 -- Variable: %load-hook
     A procedure to be run whenever primitive-load is called.  If this procedure is defined, it will be called with the filename argument that was passed to primitive-load.

          (define %load-hook (lambda (file)
                               (display "Loading ")
                               (display file)
                               (write-line "...."))) => undefined
          (load-from-path "foo.scm")
          -| Loading /usr/local/share/guile/site/foo.scm....

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

Lists
*****

This chapter describes Guile list functions not found in standard Scheme.

 -- primitive: append! [lst...]
     A destructive version of append (see Pairs and Lists (The Revised^4 Report on Scheme)).  The cdr field of each list's final pair is changed to point to the head of the next list, so no consing is performed.  Return a pointer to the mutated list.

 -- primitive: last-pair lst
     Return a pointer to the last pair in LST, signalling an error if LST is circular.

 -- primitive: reverse! lst [newtail]
     A destructive version of reverse (see Pairs and Lists (The Revised^4 Report on Scheme)).  The cdr of each cell in LST is modified to point to the previous list element.  Return a pointer to the head of the reversed list.

     Caveat: because the list is modified in place, the tail of the original list now becomes its head, and the head of the original list now becomes the tail.  Therefore, the LST symbol to which the head of the original list was bound now points to the tail.  To ensure that the head of the modified list is not lost, it is wise to save the return value of reverse!

 -- primitive: list-set! lst k val
     Set the Kth element of LST to VAL.

 -- primitive: list-cdr-ref lst k
 -- primitive: list-tail lst k
     Return the "tail" of LST beginning with its Kth element. The first element of the list is considered to be element 0.

     list-cdr-ref and list-tail are identical.  It may help to think of list-cdr-ref as accessing the Kth cdr of the list, or returning the results of cdring K times down LST.

 -- primitive: list-cdr-set! lst k val
     Set the Kth cdr of LST to VAL.

 -- primitive: list-head lst k
     Copy the first K elements from LST into a new list, and return it.

 -- primitive: list-copy lst
     Return a (newly-created) copy of LST.

 -- primitive: delq item lst
 -- primitive: delv item lst
 -- primitive: delete item lst
     Return a newly-created copy of LST with ITEM removed.  These procedures mirror memq, memv and member: delq compares elements of LST against ITEM with eq?, delv uses eqv? and delete uses equal?

 -- primitive: delq! item lst
 -- primitive: delv! item lst
 -- primitive: delete! item lst
     These procedures are destructive versions of delq, delv and delete: they modify the pointers in the existing LST rather than creating a new list.  Caveat evaluator: Like other destructive list functions, these functions cannot modify the binding of LST, and so cannot be used to delete the first element of LST destructively.

[FIXME: is there any reason to have the `sloppy' functions available at high level at all?  Maybe these docs should be relegated to a "Guile Internals" node or something. -twp]

 -- primitive: sloppy-memq
 -- primitive: sloppy-memv
 -- primitive: sloppy-member
     These procedures behave like memq, memv and member (see Pairs and Lists (The Revised^4 Report on Scheme)), but do not perform any type or error checking.  Their use is recommended only in writing Guile internals, not for high-level Scheme programs.

Data Structures
***************

To make it easier to write powerful applications, Guile provides many data structures not found in standard Scheme.

Records
=======

[FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed]

A record type is a first class object representing a user-defined data type.  A record is an instance of a record type.

 -- procedure: record? obj
     Returns #t if OBJ is a record of any type and #f otherwise.

     Note that record? may be true of any Scheme value; there is no promise that records are disjoint with other Scheme types.

 -- procedure: make-record-type type-name field-names
     Returns a record-type descriptor, a value representing a new data type disjoint from all others.  The TYPE-NAME argument must be a string, but is only used for debugging purposes (such as the printed representation of a record of the new type).  The FIELD-NAMES argument is a list of symbols naming the fields of a record of the new type.  It is an error if the list contains any duplicates.  It is unspecified how record-type descriptors are represented.

 -- procedure: record-constructor rtd [field-names]
     Returns a procedure for constructing new members of the type represented by RTD.  The returned procedure accepts exactly as many arguments as there are symbols in the given list, FIELD-NAMES; these are used, in order, as the initial values of those fields in a new record, which is returned by the constructor procedure.  The values of any fields not named in that list are unspecified.  The FIELD-NAMES argument defaults to the list of field names in the call to make-record-type that created the type represented by RTD; if the FIELD-NAMES argument is provided, it is an error if it contains any duplicates or any symbols not in the default list.

 -- procedure: record-predicate rtd
     Returns a procedure for testing membership in the type represented by RTD.  The returned procedure accepts exactly one argument and returns a true value if the argument is a member of the indicated record type; it returns a false value otherwise.

 -- procedure: record-accessor rtd field-name
     Returns a procedure for reading the value of a particular field of a member of the type represented by RTD.  The returned procedure accepts exactly one argument which must be a record of the appropriate type; it returns the current value of the field named by the symbol FIELD-NAME in that record.  The symbol FIELD-NAME must be a member of the list of field-names in the call to make-record-type that created the type represented by RTD.

 -- procedure: record-modifier rtd field-name
     Returns a procedure for writing the value of a particular field of a member of the type represented by RTD.  The returned procedure accepts exactly two arguments: first, a record of the appropriate type, and second, an arbitrary Scheme value; it modifies the field named by the symbol FIELD-NAME in that record to contain the given value. The returned value of the modifier procedure is unspecified.  The symbol FIELD-NAME must be a member of the list of field-names in the call to make-record-type that created the type represented by RTD.

 -- procedure: record-type-descriptor record
     Returns a record-type descriptor representing the type of the given record.  That is, for example, if the returned descriptor were passed to record-predicate, the resulting predicate would return a true value when passed the given record.  Note that it is not necessarily the case that the returned descriptor is the one that was passed to record-constructor in the call that created the constructor procedure that created the given record.

 -- procedure: record-type-name rtd
     Returns the type-name associated with the type represented by rtd.  The returned value is eqv? to the TYPE-NAME argument given in the call to make-record-type that created the type represented by RTD.

 -- procedure: record-type-fields rtd
     Returns a list of the symbols naming the fields in members of the type represented by RTD.  The returned value is equal? to the field-names argument given in the call to make-record-type that created the type represented by RTD.

Structures
==========

[FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed]

A structure type is a first class user-defined data type.  A structure is an instance of a structure type.  A structure type is itself a structure.

Structures are less abstract and more general than traditional records. In fact, in Guile Scheme, records are implemented using structures.

Structure Concepts
------------------

A structure object consists of a handle, structure data, and a vtable. The handle is a Scheme value which points to both the vtable and the structure's data.  Structure data is a dynamically allocated region of memory, private to the structure, divided up into typed fields.  A vtable is another structure used to hold type-specific data.  Multiple structures can share a common vtable.

Three concepts are key to understanding structures.

  * layout specifications

     Layout specifications determine how memory allocated to structures is divided up into fields.  Programmers must write a layout specification whenever a new type of structure is defined.

  * structural accessors

     Structure access is by field number.   There is only one set of accessors common to all structure objects.

  * vtables

     Vtables, themselves structures, are first class representations of
     disjoint sub-types of structures in general.   In most cases, when a
     new structure is created, programmers must specifiy a vtable for the
     new structure.   Each vtable has a field describing the layout of its
     instances.   Vtables can have additional, user-defined fields as well.

Structure Layout
----------------

When a structure is created, a region of memory is allocated to hold its state.  The layout of the structure's type determines how that memory is divided into fields.

Each field has a specified type.  There are only three types allowed, each corresponding to a one letter code.  The allowed types are:

  * 'u' -- unprotected

     The field holds binary data that is not GC protected.

  * 'p' -- protected

     The field holds a Scheme value and is GC protected.

  * 's' -- self

     The field holds a Scheme value and is GC protected.  When a structure is created with this type of field, the field is initialized to refer to the structure's own handle.  This kind of field is mainly useful when mixing Scheme and C code in which the C code may need to compute a structure's handle given only the address of its malloced data.

Each field also has an associated access protection.   There are only three kinds of protection, each corresponding to a one letter code. The allowed protections are:

  * 'w' -- writable

     The field can be read and written.

  * 'r' -- readable

     The field can be read, but not written.

  * 'o' -- opaque

     The field can be neither read nor written.   This kind of protection is for fields useful only to built-in routines.

A layout specification is described by stringing together pairs of letters: one to specify a field type and one to specify a field protection.    For example, a traditional cons pair type object could be described as:

     ; cons pairs have two writable fields of Scheme data
     "pwpw"

A pair object in which the first field is held constant could be:

     "prpw"

Binary fields, (fields of type "u"), hold one word each.  The size of a word is a machine dependent value defined to be equal to the value of the C expression: sizeof (long).

The last field of a structure layout may specify a tail array. A tail array is indicated by capitalizing the field's protection code ('W', 'R' or 'O').   A tail-array field is replaced by a read-only binary data field containing an array size.   The array size is determined at the time the structure is created.  It is followed by a corresponding number of fields of the type specified for the tail array.   For example, a conventional Scheme vector can be described as:

     ; A vector is an arbitrary number of writable fields holding Scheme
     ; values:
     "pW"

In the above example, field 0 contains the size of the vector and fields beginning at 1 contain the vector elements.

A kind of tagged vector (a constant tag followed by conventioal vector elements) might be:

     "prpW"

Structure layouts are represented by specially interned symbols whose name is a string of type and protection codes.  To create a new structure layout, use this procedure:

 -- primitive: make-struct-layout fields
     Return a new structure layout object.

     FIELDS must be a read-only string made up of pairs of characters strung together.  The first character of each pair describes a field type, the second a field protection.  Allowed types are 'p' for GC-protected Scheme data, 'u' for unprotected binary data, and 's' for fields that should point to the structure itself.    Allowed protections are 'w' for mutable fields, 'r' for read-only fields, and 'o' for opaque fields.  The last field protection specification may be capitalized to indicate that the field is a tail-array.

Structure Basics
----------------

This section describes the basic procedures for creating and accessing structures.

 -- primitive: make-struct type tail-elts . inits
     Create a new structure.

     TYPE must be a vtable structure (see Vtables).

     TAIL-ELTS must be a non-negative integer.  If the layout specification indicated by TYPE includes a tail-array, this is the number of elements allocated to that array.

     The INITS are optional arguments describing how successive fields of the structure should be initialized.  Only fields with protection 'r' or 'w' can be initialized -- fields of protection 's' are automatically initialized to point to the new structure itself;  fields of protection 'o' can not be initialized by Scheme programs.

 -- primitive: struct? obj
     Return #t iff OBJ is a structure object.

 -- primitive: struct-ref struct n
 -- primitive: struct-set! struct n value
     Access (or modify) the Nth field of STRUCT.

     If the field is of type 'p', then it can be set to an arbitrary value.

     If the field is of type 'u', then it can only be set to a non-negative integer value small enough to fit in one machine word.

Vtables
-------

Vtables are structures that are used to represent structure types.  Each vtable contains a layout specification in field vtable-index-layout -- instances of the type are laid out according to that specification.  Vtables contain additional fields which are used only internally to libguile.  The variable vtable-offset-user is bound to a field number.  Vtable fields at that position or greater are user definable.

 -- primitive: struct-vtable struct
     Return the vtable structure that describes the type of STRUCT.

 -- primitive: struct-vtable? obj
     Return #t iff obj is a vtable structure.

If you have a vtable structure, V, you can create an instance of the type it describes by using (make-struct V ...).  But where does V itself come from?  One possibility is that V is an instance of a user-defined vtable type, V', so that V is created by using (make-struct V' ...).  Another possibility is that V is an instance of the type it itself describes.  Vtable structures of the second sort are created by this procedure:

 -- primitive: make-vtable-vtable new-fields tail-size . inits
     Return a new, self-describing vtable structure.

     NEW-FIELDS is a layout specification describing fields of the resulting structure beginning at the position bound to vtable-offset-user.

     TAIL-SIZE specifies the size of the tail-array (if any) of this vtable.

     INITS initializes the fields of the vtable.  Minimally, one initializer must be provided: the layout specification for instances of the type this vtable will describe.  If a second initializer is provided, it will be interpreted as a print call-back function.

          ;;; loading ,a...
          (define x
            (make-vtable-vtable (make-struct-layout (quote pw))
                                0
                                'foo))

          (struct? x)
          => #t
          (struct-vtable? x)
          => #t
          (eq? x (struct-vtable x))
          => #t
          (struct-ref x vtable-offset-user)
          => foo
          (struct-ref x 0)
          => pruosrpwpw

          (define y
            (make-struct x
                         0
                         (make-struct-layout (quote pwpwpw))
                         'bar))

          (struct? y)
          => #t
          (struct-vtable? y)
          => #t
          (eq? x y)
          => ()
          (eq? x (struct-vtable y))
          => #t
          (struct-ref y 0)
          => pwpwpw
          (struct-ref y vtable-offset-user)
          => bar

          (define z (make-struct y 0 'a 'b 'c))

          (struct? z)
          => #t
          (struct-vtable? z)
          => ()
          (eq? y (struct-vtable z))
          => #t
          (map (lambda (n) (struct-ref z n)) '(0 1 2))
          => (a b c)

Arrays
======

[FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed]

Conventional Arrays
-------------------

Arrays read and write as a # followed by the rank (number of dimensions) followed by what appear as lists (of lists) of elements.  The lists must be nested to the depth of the rank.  For each depth, all lists must be the same length.

     (make-array 'ho 3 3) =>
     #2((ho ho ho) (ho ho ho) (ho ho ho))

Unshared conventional (not uniform) 0-based arrays of rank 1 (dimension) are equivalent to (and can't be distinguished from) vectors.

     (make-array 'ho 3) => (ho ho ho)

When constructing an array, BOUND is either an inclusive range of indices expressed as a two element list, or an upper bound expressed as a single integer.  So

     (make-array 'foo 3 3) == (make-array 'foo '(0 2) '(0 2))

 -- primitive: array? obj
     Returns #t if the OBJ is an array, and #f if not.

 -- procedure: make-array initial-value bound1 bound2 ...
     Creates and returns an array that has as many dimensions as there are BOUNDs and fills it with INITIAL-VALUE.

 -- primitive: array-ref array index1 index2 ...
     Returns the element at the (index1, index2) element in ARRAY.

 -- primitive: array-in-bounds? array index1 index2 ...
     Returns #t if its arguments would be acceptable to array-ref.

 -- primitive: array-set! array new-value index1 index2 ...
     Sets the element at the (index1, index2) element in ARRAY to NEW-VALUE.  The value returned by array-set! is unspecified.

 -- primitive: make-shared-array array mapper bound1 bound2 ...
     make-shared-array can be used to create shared subarrays of other arrays.  The MAPPER is a function that translates coordinates in the new array into coordinates in the old array.  A MAPPER must be linear, and its range must stay within the bounds of the old array, but it can be otherwise arbitrary.  A simple example:

          (define fred (make-array #f 8 8))
          (define freds-diagonal
            (make-shared-array fred (lambda (i) (list i i)) 8))
          (array-set! freds-diagonal 'foo 3)
          (array-ref fred 3 3) => foo
          (define freds-center
            (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))
          (array-ref freds-center 0 0) => foo

 -- primitive: transpose-array array dim0 dim1 ...
     Returns an array sharing contents with ARRAY, but with dimensions arranged in a different order.  There must be one DIM argument for each dimension of ARRAY.  DIM0, DIM1, ... should be integers between 0 and the rank of the array to be returned.  Each integer in that range must appear at least once in the argument list.

     The values of DIM0, DIM1, ... correspond to dimensions in the array to be returned, their positions in the argument list to dimensions of ARRAY.  Several DIMs may have the same value, in which case the returned array will have smaller rank than ARRAY.

     examples:

          (transpose-array '#2((a b) (c d)) 1 0) => #2((a c) (b d))
          (transpose-array '#2((a b) (c d)) 0 0) => #1(a d)
          (transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) =>
                          #2((a 4) (b 5) (c 6))

 -- primitive: enclose-array array dim0 dim1 ...
     DIM0, DIM1 ... should be nonnegative integers less than the rank of ARRAY.  ENCLOSE-ARRAY returns an array resembling an array of shared arrays.  The dimensions of each shared array are the same as the DIMth dimensions of the original array, the dimensions of the outer array are the same as those of the original array that did not match a DIM.

     An enclosed array is not a general Scheme array.  Its elements may not be set using array-set!.  Two references to the same element of an enclosed array will be equal? but will not in general be eq?.  The value returned by ARRAY-PROTOTYPE when given an enclosed array is unspecified.

     examples:

          (enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) =>
             #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>

          (enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) =>
             #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>

 -- procedure: array-shape array
     Returns a list of inclusive bounds of integers.

          (array-shape (make-array 'foo '(-1 3) 5)) => ((-1 3) (0 4))

 -- primitive: array-dimensions array
     Array-dimensions is similar to array-shape but replaces elements with a 0 minimum with one greater than the maximum. So:

          (array-dimensions (make-array 'foo '(-1 3) 5)) => ((-1 3) 5)

 -- primitive: array-rank obj
     Returns the number of dimensions of OBJ.  If OBJ is not an array, 0 is returned.

 -- primitive: array->list array
     Returns a list consisting of all the elements, in order, of ARRAY.

 -- primitive: array-copy! source destination
     Copies every element from vector or array SOURCE to the corresponding element of DESTINATION.  DESTINATION must have the same rank as SOURCE, and be at least as large in each dimension.  The order is unspecified.

 -- primitive: serial-array-copy! source destination
     Same as array-copy! but guaranteed to copy in row-major order.

 -- primitive: array-fill! array fill
     Stores FILL in every element of ARRAY.  The value returned is unspecified.

 -- primitive: array-equal? array0 array1 ...
     Returns #t iff all arguments are arrays with the same shape, the same type, and have corresponding elements which are either equal?  or array-equal?.  This function differs from equal? in that a one dimensional shared array may be ARRAY-EQUAL? but not EQUAL? to a vector or uniform vector.

 -- primitive: array-contents array
 -- primitive: array-contents array strict
     If ARRAY may be unrolled into a one dimensional shared array without changing their order (last subscript changing fastest), then array-contents returns that shared array, otherwise it returns #f.  All arrays made by MAKE-ARRAY and MAKE-UNIFORM-ARRAY may be unrolled, some arrays made by MAKE-SHARED-ARRAY may not be.

     If the optional argument STRICT is provided, a shared array will be returned only if its elements are stored internally contiguous in memory.

Array Mapping
-------------

 -- primitive: array-map! array0 proc array1 ...
     ARRAY1, ... must have the same number of dimensions as ARRAY0 and have a range for each index which includes the range for the corresponding index in ARRAY0.  PROC is applied to each tuple of elements of ARRAY1 ... and the result is stored as the corresponding element in ARRAY0.  The value returned is unspecified.  The order of application is unspecified.

 -- primitive: serial-array-map! array0 proc array1 ...
     Same as ARRAY-MAP!, but guaranteed to apply PROC in row-major order.

 -- primitive: array-for-each proc array0 ...
     PROC is applied to each tuple of elements of ARRAY0 ... in row-major order.  The value returned is unspecified.

 -- primitive: array-index-map! array proc
     applies PROC to the indices of each element of ARRAY in turn, storing the result in the corresponding element.  The value returned and the order of application are unspecified.

     One can implement ARRAY-INDEXES as

          (define (array-indexes array)
              (let ((ra (apply make-array #f (array-shape array))))
                (array-index-map! ra (lambda x x))
                ra))

     Another example:

          (define (apl:index-generator n)
              (let ((v (make-uniform-vector n 1)))
                (array-index-map! v (lambda (i) i))
                v))

Uniform Array
-------------

Uniform Array and vectors are arrays whose elements are all of the same type.  Uniform vectors occupy less storage than conventional vectors.  Uniform Array procedures also work on vectors, uniform-vectors, bit-vectors, and strings.

PROTOTYPE arguments in the following procedures are interpreted according to the table:

     prototype       type                            printing character

     #t              boolean (bit-vector)                    b
     #\a             char (string)                           a
     integer >0      unsigned integer                        u
     integer <0      signed integer                          e
     1.0             float (single precision)                s
     1/3             double (double precision float)         i
     +i              complex (double precision)              c
     ()              conventional vector

Unshared uniform character 0-based arrays of rank 1 (dimension) are equivalent to (and can't be distinguished from) strings.

     (make-uniform-array #\a 3) => "$q2"

Unshared uniform boolean 0-based arrays of rank 1 (dimension) are equivalent to (and can't be distinguished from) bit-vectors.

     (make-uniform-array #t 3) => #*000
     ==
     #b(#f #f #f) => #*000
     ==
     #1b(#f #f #f) => #*000

Other uniform vectors are written in a form similar to that of vectors, except that a single character from the above table is put between # and (.  For example, '#e(3 5 9) returns a uniform vector of signed integers.

 -- primitive: array? obj prototype
     Returns #t if the OBJ is an array of type corresponding to PROTOTYPE, and #f if not.

 -- procedure: make-uniform-array prototype bound1 bound2 ...
     Creates and returns a uniform array of type corresponding to PROTOTYPE that has as many dimensions as there are BOUNDs and fills it with PROTOTYPE.

 -- primitive: array-prototype array
     Returns an object that would produce an array of the same type as ARRAY, if used as the PROTOTYPE for make-uniform-array.

 -- primitive: list->uniform-array rank prot lst
 -- procedure: list->uniform-vector prot lst
     Returns a uniform array of the type indicated by prototype PROT with elements the same as those of LST.  Elements must be of the appropriate type, no coercions are done.

 -- primitive: uniform-vector-fill! uve fill
     Stores FILL in every element of UVE.  The value returned is unspecified.

 -- primitive: uniform-vector-length uve
     Returns the number of elements in UVE.

 -- primitive: dimensions->uniform-array dims prototype [fill]
 -- primitive: make-uniform-vector length prototype [fill]
     Creates and returns a uniform array or vector of type corresponding to PROTOTYPE with dimensions DIMS or length LENGTH.  If the FILL argument is supplied, the returned array is filled with this value.

 -- primitive: uniform-array-read! ura [port-or-fdes] [start] [end]
 -- primitive: uniform-vector-read! uve [port-or-fdes] [start] [end]
     Attempts to read all elements of URA, in lexicographic order, as binary objects from PORT-OR-FDES. If an end of file is encountered during uniform-array-read! the objects up to that point only are put into URA (starting at the beginning) and the remainder of the array is unchanged.

     The optional arguments START and END allow a specified region of a vector (or linearized array) to be read, leaving the remainder of the vector unchanged.

     uniform-array-read! returns the number of objects read. PORT-OR-FDES may be omitted, in which case it defaults to the value returned by (current-input-port).

 -- primitive: uniform-array-write ura [port-or-fdes] [start] [end]
 -- primitive: uniform-vector-write uve [port-or-fdes] [start] [end]
     Writes all elements of URA as binary objects to PORT-OR-FDES.

     The optional arguments START and END allow a specified region of a vector (or linearized array) to be written.

     The number of objects actually written is returned. PORT-OR-FDES may be omitted, in which case it defaults to the value returned by (current-output-port).

Bit Vectors
-----------

Bit vectors can be written and read as a sequence of 0s and 1s prefixed by #*.

     #b(#f #f #f #t #f #t #f) => #*0001010

Some of these operations will eventually be generalized to other uniform-arrays.

 -- primitive: bit-count bool bv
     Returns the number occurrences of BOOL in BV.

 -- primitive: bit-position bool bv k
     Returns the minimum index of an occurrence of BOOL in BV which is at least K.  If no BOOL occurs within the specified range #f is returned.

 -- primitive: bit-invert! bv
     Modifies BV by replacing each element with its negation.

 -- primitive: bit-set*! bv uve bool
     If uve is a bit-vector BV and uve must be of the same length.  If BOOL is #t, uve is OR'ed into BV; If BOOL is #f, the inversion of uve is AND'ed into BV.

     If uve is a unsigned integer vector all the elements of uve must be between 0 and the LENGTH of BV.  The bits of BV corresponding to the indexes in uve are set to BOOL.

     The return value is unspecified.

 -- primitive: bit-count* bv uve bool
     Returns

          (bit-count (bit-set*! (if bool bv (bit-invert! bv)) uve #t) #t).

     BV is not modified.

Association Lists and Hash Tables
=================================

This chapter discusses dictionary objects: data structures that are useful for organizing and indexing large bodies of information.

Dictionary Types
----------------

A dictionary object is a data structure used to index information in a user-defined way.  In standard Scheme, the main aggregate data types are lists and vectors.  Lists are not really indexed at all, and vectors are indexed only by number (e.g. (vector-ref foo 5)).  Often you will find it useful to index your data on some other type; for example, in a library catalog you might want to look up a book by the name of its author.  Dictionaries are used to help you organize information in such a way.

An association list (or alist for short) is a list of key-value pairs.  Each pair represents a single quantity or object; the car of the pair is a key which is used to identify the object, and the cdr is the object's value.

A hash table also permits you to index objects with arbitrary keys, but in a way that makes looking up any one object extremely fast.  A well-designed hash system makes hash table lookups almost as fast as conventional array or vector references.

Alists are popular among Lisp programmers because they use only the language's primitive operations (lists, car, cdr and the equality primitives).  No changes to the language core are necessary.  Therefore, with Scheme's built-in list manipulation facilities, it is very convenient to handle data stored in an association list.  Also, alists are highly portable and can be easily implemented on even the most minimal Lisp systems.

However, alists are inefficient, especially for storing large quantities of data.  Because we want Guile to be useful for large software systems as well as small ones, Guile provides a rich set of tools for using either association lists or hash tables.

Association Lists
-----------------

 -- primitive: acons key value alist
     Adds a new key-value pair to ALIST.  A new pair is created whose car is KEY and whose cdr is VALUE, and the pair is consed onto ALIST, and the new list is returned.  This function is not destructive; ALIST is not modified.

 -- primitive: assq key alist
 -- primitive: assv key alist
 -- primitive: assoc key alist
     Fetches the entry in ALIST that is associated with KEY.  To decide whether the argument KEY matches a particular entry in ALIST, assq compares keys with eq?, assv uses eqv? and assoc uses equal?.  If KEY cannot be found in ALIST (according to whichever equality predicate is in use), then #f is returned.  These functions return the entire alist entry found (i.e. both the key and the value).

 -- primitive: assq-ref alist key
 -- primitive: assv-ref alist key
 -- primitive: assoc-ref alist key
     Like assq, assv and assoc, except that only the value associated with KEY in ALIST is returned.  These functions are equivalent to

          (let ((ent (ASSOCIATOR KEY ALIST)))
            (and ent (cdr ent)))

     where ASSOCIATOR is one of assq, assv or assoc.

 -- primitive: assq-set! alist key value
 -- primitive: assv-set! alist key value
 -- primitive: assoc-set! alist key value
     Reassociate KEY in ALIST with VALUE: find any existing ALIST entry for KEY and associate it with the new VALUE.  If ALIST does not contain an entry for KEY, add a new one.  Return the (possibly new) alist.

     These functions do not attempt to verify the structure of ALIST, and so may cause unusual results if passed an object that is not an association list.

 -- primitive: assq-remove! alist key
 -- primitive: assv-remove! alist key
 -- primitive: assoc-remove! alist key
     Delete any entry in ALIST associated with KEY, and return the resulting alist.

Caution: it is important to remember that the SET! and REMOVE! functions do not always operate as intended.  In some circumstances, the functions will try to modify the first element in the list; for example, when adding a new entry to an alist, assoc-set! conses the new key-value pair on to the beginning of the alist.  However, when this happens, the symbol to which the alist is bound has not been modified---it still points to the old ``beginning'' of the list, which still does not contain the new entry.  In order to be sure that these functions always succeed, even when modifying the beginning of the alist, you will have to rebind the alist symbol explicitly to point to the value returned by assoc-set!, like so:

     (set! my-alist
           (assq-set! my-alist 'sun4 "sparc-sun-solaris"))

Because of this restriction, you may find it more convenient to use hash tables to store dictionary data.  If your application will not be modifying the contents of an alist very often, this may not make much difference to you.

Here is a longer example of how alists may be used in practice.

     (define capitals '(("New York" . "Albany")
                        ("Oregon"   . "Salem")
                        ("Florida"  . "Miami")))

     ;; What's the capital of Oregon?
     (assoc "Oregon" capitals)       => ("Oregon" . "Salem")
     (assoc-ref capitals "Oregon")   => "Salem"

     ;; We left out South Dakota.
     (set! capitals
           (assoc-set! capitals "South Dakota" "Bismarck"))
     capitals
     => (("South Dakota" . "Bismarck")
         ("New York" . "Albany")
         ("Oregon" . "Salem")
         ("Florida" . "Miami"))

     ;; And we got Florida wrong.
     (set! capitals
           (assoc-set! capitals "Florida" "Tallahassee"))
     capitals
     => (("South Dakota" . "Bismarck")
         ("New York" . "Albany")
         ("Oregon" . "Salem")
         ("Florida" . "Tallahassee"))

     ;; After Oregon secedes, we can remove it.
     (set! capitals
           (assoc-remove! capitals "Oregon"))
     capitals
     => (("South Dakota" . "Bismarck")
         ("New York" . "Albany")
         ("Florida" . "Tallahassee"))

Hash Tables
-----------

Like the association list functions, the hash table functions come in several varieties: hashq, hashv, and hash. The hashq functions use eq? to determine whether two keys match.  The hashv functions use eqv?, and the hash functions use equal?.

In each of the functions that follow, the TABLE argument must be a vector.  The KEY and VALUE arguments may be any Scheme object.

 -- primitive: hashq-ref table key [default]
 -- primitive: hashv-ref table key [default]
 -- primitive: hash-ref table key [default]
     Look up KEY in the hash table TABLE, and return the value (if any) associated with it.  If KEY is not found, return DEFAULT (or #f if no DEFAULT argument is supplied).

 -- primitive: hashq-set! table key value
 -- primitive: hashv-set! table key value
 -- primitive: hash-set! table key value
     Find the entry in TABLE associated with KEY, and store VALUE there.

 -- primitive: hashq-remove! table key
 -- primitive: hashv-remove! table key
 -- primitive: hash-remove! table key
     Remove KEY (and any value associated with it) from TABLE.

The standard hash table functions may be too limited for some applications.  For example, you may want a hash table to store strings in a case-insensitive manner, so that references to keys named ``foobar'', ``FOOBAR'' and ``FooBaR'' will all yield the same item.  Guile provides you with extended hash tables that permit you to specify a hash function and associator function of your choosing.  The functions described in the rest of this section can be used to implement such custom hash table structures.

If you are unfamiliar with the inner workings of hash tables, then this facility will probably be a little too abstract for you to use comfortably.  If you are interested in learning more, see an introductory textbook on data structures or algorithms for an explanation of how hash tables are implemented.

 -- primitive: hashq key size
 -- primitive: hashv key size
 -- primitive: hash key size
     Default hash functions for Guile hash tables.  KEY is the object to be hashed, and SIZE is the size of the target hash table.  Each function returns an integer in the range 0 to SIZE-1.

 -- primitive: hashx-ref hasher assoc table key [default]
 -- primitive: hashx-set! hasher assoc table key value
 -- primitive: hashx-remove! hasher assoc table key
     These behave the same way as the corresponding ref and set! functions described above, but use HASHER as a hash function and ASSOC to compare keys.  hasher must be a function that takes two arguments, a key to be hashed and a table size.  assoc must be an associator function, like assoc, assq or assv.

     By way of illustration, hashq-ref table key is equivalent to hashx-ref hashq assq table key.

 -- primitive: hashq-get-handle table key
 -- primitive: hashv-get-handle table key
 -- primitive: hash-get-handle table key
 -- primitive: hashx-get-handle hasher assoc table key
     These procedures are similar to their -ref cousins, but return a handle from the hash table rather than the value associated with KEY.  By convention, a handle in a hash table is the pair which associates a key with a value.  Where hashq-ref table key returns only a value, hashq-get-handle table key returns the pair (key . value).

 -- primitive: hashq-create-handle! table key init
 -- primitive: hashv-create-handle! table key init
 -- primitive: hash-create-handle! table key init
 -- primitive: hashx-create-handle! hasher assoc table key init
     These functions look up KEY in TABLE and return its handle, If KEY is not already present, a new handle is created which associates KEY with INIT.

Strings
*******

[FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed]

For the sake of efficiency, two special kinds of strings are available in Guile: shared substrings and the misleadingly named ``read-only'' strings.  It is not necessary to know about these to program in Guile, but you are likely to run into one or both of these special string types eventually, and it will be helpful to know how they work.

String Fun
==========

 -- primitive: string-index str chr [frm [to]]
     Return the index of the first occurrence of CHR in STR.  The optional integer arguments FRM and TO limit the search to a portion of the string.  This procedure essentially implements the index or strchr functions from the C library.

 -- primitive: string-rindex str chr [frm [to]]
     Like string-index, but search from the right of the string rather than from the left.  This procedure essentially implements the rindex or strrchr functions from the C library.

 -- primitive: substring-move-right! str1 start1 end1 str2 start2
 -- primitive: substring-move-left! str1 start1 end1 str2 start2
     Copy the substring of STR1 bounded by START1 and END1 into STR2 beginning at position END2. substring-move-right! begins copying from the rightmost character and moves left, and substring-move-left! copies from the leftmost character moving right.

     It is useful to have two functions that copy in different directions so that substrings can be copied back and forth within a single string.  If you wish to copy text from the left-hand side of a string to the right-hand side of the same string, and the source and destination overlap, you must be careful to copy the rightmost characters of the text first, to avoid clobbering your data.  Hence, when STR1 and STR2 are the same string, you should use substring-move-right! when moving text from left to right, and substring-move-left!  otherwise.  If str1 and str2 are different strings, it does not matter which function you use.

 -- primitive: vector-move-right! vec1 start1 end1 vec2 start2
 -- primitive: vector-move-left! vec1 start1 end1 vec2 start2
     Vector versions of substring-move-right! and substring-move-left!

 -- primitive: substring-fill! str start end fill-char
     Change every character in STR between START and END to FILL-CHAR.

 -- primitive: string-null? str
     Return #t if STR's length is nonzero, and #f otherwise.

 -- primitive: string-upcase! str
 -- primitive: string-downcase! str
     Upcase or downcase every character in str, respectively.

Shared Substrings
=================

Whenever you extract a substring using substring, the Scheme interpreter allocates a new string and copies data from the old string. This is expensive, but substring is so convenient for manipulating text that programmers use it often.

Guile Scheme provides the concept of the shared substring to improve performance of many substring-related operations.  A shared substring is an object that mostly behaves just like an ordinary substring, except that it actually shares storage space with its parent string.

 -- primitive: make-shared-substring str start [end]
     Return a shared substring of STR.  The semantics are the same as for the substring function: the shared substring returned includes all of the text from STR between indexes START (inclusive) and END (exclusive).  If END is omitted, it defaults to the end of STR.  The shared substring returned by make-shared-substring occupies the same storage space as STR.

Example:

     (define foo "the quick brown fox")
     (define bar (make-shared-substring some-string 4 9))

     foo => "t h e   q u i c k   b r o w n   f o x"
     bar =========> |---------|

The shared substring BAR is not given its own storage space. Instead, the Guile interpreter notes internally that BAR points to a portion of the memory allocated to FOO.  However, BAR behaves like an ordinary string in most respects: it may be used with string primitives like string-length, string-ref, string=?.  Guile makes the necessary translation between indices of BAR and indices of FOO automatically.

     (string-length? bar) => 5	; bar only extends from indices 4 to 9
     (string-ref bar 3)  => #\c	; same as (string-ref foo 7)
     (make-shared-substring bar 2)
       => "ick"			; can even make a shared substring!

Because creating a shared substring does not require allocating new storage from the heap, it is a very fast operation.  However, because it shares memory with its parent string, a change to the contents of the parent string will implicitly change the contents of its shared substrings.

     (string-set! foo 7 #\r)
     bar => "quirk"

Guile considers shared substrings to be immutable.  This is because programmers might not always be aware that a given string is really a shared substring, and might innocently try to mutate it without realizing that the change would affect its parent string.  (We are currently considering a "copy-on-write" strategy that would permit modifying shared substrings without affecting the parent string.)

In general, shared substrings are useful in circumstances where it is important to divide a string into smaller portions, but you do not expect to change the contents of any of the strings involved.

Read Only Strings
=================

Type-checking in Guile primitives distinguishes between mutable strings and read only strings.  Mutable strings answer #t to string?  while read only strings may or may not.   All kinds of strings, whether or not they are mutable return #t to this:

 -- primitive: read-only-string? OBJ
     Return true of OBJ can be read as a string,

     This illustrates the difference between string? and read-only-string?:

          (string? "a string") => #t
          (string? 'a-symbol") => #f

          (read-only-string? "a string") => #t
          (read-only-string? 'a-symbol") => #t

"Read-only" refers to how the string will be used, not how the string is permitted to be used.  In particular, all strings are "read-only strings" even if they are mutable, because a function that only reads from a string can certainly operate on even a mutable string.

Symbols are an example of read-only strings.  Many string functions, such as string-append are happy to operate on symbols.  Many functions that expect a string argument, such as open-file, will accept a symbol as well.

Shared substrings, discussed in the previous chapter, also happen to be read-only strings.

Characters
**********

Most of the characters in the ASCII character set may be referred to by name: for example, #\tab, #\esc, #\stx, and so on. The following table describes the ASCII names for each character.

0 = #\nul
1 = #\soh
2 = #\stx
3 = #\etx
4 = #\eot
5 = #\enq
6 = #\ack
7 = #\bel
8 = #\bs
9 = #\ht
10 = #\nl
11 = #\vt
12 = #\np
13 = #\cr
14 = #\so
15 = #\si
16 = #\dle
17 = #\dc1
18 = #\dc2
19 = #\dc3
20 = #\dc4
21 = #\nak
22 = #\syn
23 = #\etb
24 = #\can
25 = #\em
26 = #\sub
27 = #\esc
28 = #\fs
29 = #\gs
30 = #\rs
31 = #\us
32 = #\sp

The delete character (octal 177) may be referred to with the name #\del.

Several characters have more than one name:

  * #\space, #\sp

  * #\newline, #\nl

  * #\tab, #\ht

  * #\backspace, #\bs

  * #\return, #\cr

  * #\page, #\np

  * #\null, #\nul

Property Lists
**************

Every object in the system can have a property list that may be used for information about that object.  For example, a function may have a property list that includes information about the source file in which it is defined.

Property lists are implemented as assq lists (see Association Lists).

Currently, property lists are implemented differently for procedures and closures than for other kinds of objects.  Therefore, when manipulating a property list associated with a procedure object, use the procedure functions; otherwise, use the object functions.

 -- primitive: object-properties obj
 -- primitive: procedure-properties obj
     Return OBJ's property list.

 -- primitive: set-object-properties! obj alist
 -- primitive: set-procedure-properties! obj alist
     Set OBJ's property list to ALIST.

 -- primitive: object-property obj key
 -- primitive: procedure-property obj key
     Return the property of OBJ with name KEY.

 -- primitive: set-object-property! obj key value
 -- primitive: set-procedure-property! obj key value
     In OBJ's property list, set the property named KEY to VALUE.

[Interface bug:  there should be a second level of interface in which the user provides a "property table" that is possibly private.]

Ports
*****

Sequential input/output in Scheme is represented by operations on a port.  Characters can be read from an input port and written to an output port.  This chapter explains the operations that Guile provides for working with ports.

The formal definition of a port is very generic: an input port is simply ``an object which can deliver characters on command,'' and an output port is ``an object which can accept characters.'' Because this definition is so loose, it is easy to write functions that simulate ports in software.  Soft ports and string ports are two interesting and powerful examples of this technique.

File Ports
==========

The following procedures are used to open file ports. See also open, for an interface to the Unix open system call.

 -- primitive: open-file string mode
     Open the file whose name is STRING, and return a port representing that file.  The attributes of the port are determined by the MODE string.  The way in which this is interpreted is similar to C stdio:

     The first character must be one of the following:

     r
          Open an existing file for input.

     w
          Open a file for output, creating it if it doesn't already exist or removing its contents if it does.

     a
          Open a file for output, creating it if it doesn't already exist. All writes to the port will go to the end of the file. The "append mode" can be turned off while the port is in use see fcntl

     The following additional characters can be appended:

     +
          Open the port for both input and output.  E.g., r+: open an existing file for both input and output.

     0
          Create an "unbuffered" port.  In this case input and output operations are passed directly to the underlying port implementation without additional buffering.  This is likely to slow down I/O operations. The buffering mode can be changed while a port is in use see setvbuf

     l
          Add line-buffering to the port.  The port output buffer will be automatically flushed whenever a newline character is written.

     In theory we could create read/write ports which were buffered in one direction only.  However this isn't included in the current interfaces.

     If a file cannot be opened with the access requested, open-file throws an exception.

 -- procedure: open-input-file filename
     Open FILENAME for input.  Equivalent to

          (open-file FILENAME "r")

 -- procedure: open-output-file filename
     Open FILENAME for output.  Equivalent to

          (open-file FILENAME "w")

 -- primitive: port-mode port
     Return the mode flags from the open PORT.

 -- primitive: port-filename [port]
     Return the filename associated with PORT.  This function returns the strings "standard input", "standard output" and "standard error" when called on the current input, output and error ports respectively.

 -- primitive: set-port-filename! [port] filename
     Change the filename associated with PORT, using the current input port if none is specified.  Note that this does not change the port's source of data, but only the value that is returned by port-filename and reported in diagnostic output.

String Ports
============

 -- primitive: call-with-output-string proc
     PROC must be a procedure of one argument.  This procedure calls PROC with one argument: a (newly created) output port.  When the function returns, the string composed of the characters written into the port is returned.

 -- primitive: call-with-input-string string proc
     PROC must be a procedure of one argument.  This procedure calls PROC with one argument: an (newly created) input port from which STRING's contents may be read.  When PROC returns, the port is closed and the value yielded by the procedure PROC is returned.

Soft Ports
==========

A soft-port is a port based on a vector of procedures capable of accepting or delivering characters.  It allows emulation of I/O ports.

 -- primitive: make-soft-port vector modes
     Returns a port capable of receiving or delivering characters as specified by the MODES string (see open-file).  VECTOR must be a vector of length 6.  Its components are as follows:

      0. procedure accepting one character for output

      1. procedure accepting a string for output

      2. thunk for flushing output

      3. thunk for getting one character

      4. thunk for closing port (not by garbage collection)

     For an output-only port only elements 0, 1, 2, and 4 need be procedures.  For an input-only port only elements 3 and 4 need be procedures.  Thunks 2 and 4 can instead be #f if there is no useful operation for them to perform.

     If thunk 3 returns #f or an eof-object (see eof-object? (The Revised^4 Report on Scheme)) it indicates that the port has reached end-of-file.  For example:

          (define stdout (current-output-port))
          (define p (make-soft-port
                     (vector
                      (lambda (c) (write c stdout))
                      (lambda (s) (display s stdout))
                      (lambda () (display "." stdout))
                      (lambda () (char-upcase (read-char)))
                      (lambda () (display "@" stdout)))
                     "rw"))

          (write p p) => #<input-output-soft#\space45d10#\>

Void Ports
==========

This kind of port just causes errors if you try to use it in a normal way.

 -- primitive: %make-void-port mode
     Create and return a new void port.  The MODE argument describes the input/output modes for this port; for a description, see the documentation for open-file in File Ports.

Generic Port Operations
=======================

This section describes port maintainence procedures which are not specific to a single port type.

 -- primitive: close-port port
     Close the specified port object.  Returns #t if it successfully closes a port or #f if it was already closed.  An exception may be raised if an error occurs, for example when flushing buffered output. See also close, for a procedure which can close file descriptors.

 -- primitive: close-input-port port
     A wrapper for close-port.  This procedure is required by R4RS.

 -- primitive: close-output-port port
     A wrapper for close-port.  This procedure is required by R4RS.

 -- primitive: current-error-port
     Return the port to which errors and warnings should be sent (the standard error in Unix and C terminology).

 -- primitive: set-current-input-port port
 -- primitive: set-current-output-port port
 -- primitive: set-current-error-port port
     Change the ports returned by current-input-port, current-output-port and current-error-port, respectively, so that they use the supplied PORT for input or output.

 -- primitive: force-output [port]
     Flush the specified output port, or the current output port if PORT is omitted.  The current output buffer contents are passed to the underlying port implementation (e.g., in the case of fports, the data will be written to the file and the output buffer will be cleared.) It has no effect on an unbuffered port.

     The return value is unspecified.

 -- primitive: flush-all-ports
     Equivalent to calling force-output on all open output ports.  The return value is unspecified.

 -- primitive: drain-input port
     Drains PORT's read buffers (including any pushed-back characters) and returns the contents as a single string.

 -- primitive: seek fd/port offset whence
     Sets the current position of FD/PORT to the integer OFFSET, which is interpreted according to the value of WHENCE.

     One of the following variables should be supplied for WHENCE:
      -- Variable: SEEK_SET
          Seek from the beginning of the file.

      -- Variable: SEEK_CUR
          Seek from the current position.

      -- Variable: SEEK_END
          Seek from the end of the file.

     If FD/PORT is a file descriptor, the underlying system call is lseek.  PORT may be a string port.

     The value returned is the new position in the file.  This means that the current position of a port can be obtained using:

          (seek port 0 SEEK_CUR)

 -- primitive: fseek fd/port offset whence
     Obsolete.  Almost the same as seek, above, but the return value is unspecified.

 -- primitive: ftell fd/port
     Returns an integer representing the current position of FD/PORT, measured from the beginning.  Equivalent to:

          (seek port 0 SEEK_CUR)

 -- primitive: truncate-file obj [size]
     Truncates the object referred to by OBJ to at most SIZE bytes. OBJ can be a string containing a file name or an integer file descriptor or a port.  SIZE may be omitted if OBJ is not a file name, in which case the truncation occurs at the current port. position.

     The return value is unspecified.

 -- primitive: port-mode port
     Returns the port modes associated with the open port PORT.  These will not necessarily be identical to the modes used when the port was opened, since modes such as "append" which are used only during port creation are not retained.

 -- primitive: close-all-ports-except port ...
     Close all open file ports used by the interpreter except for those supplied as arguments.  This procedure is intended to be used before an exec call to close file descriptors which are not needed in the new process.

 -- primitive: setvbuf port mode [size]
     Set the buffering mode for PORT.  MODE can be:

     _IONBF
          non-buffered

     _IOLBF
          line buffered

     _IOFBF
          block buffered, using a newly allocated buffer of SIZE bytes. If SIZE is omitted, a default size will be used.

 -- primitive: port-column [input-port]
 -- primitive: port-line [input-port]
     Return the current column number or line number of INPUT-PORT, using the current input port if none is specified.  If the number is unknown, the result is #f.  Otherwise, the result is a 0-origin integer - i.e. the first character of the first line is line 0, column 0. (However, when you display a file position, for example in an error message, we recommand you add 1 to get 1-origin integers.  This is because lines and column numbers traditionally start with 1, and that is what non-programmers will find most natural.)

 -- primitive: set-port-column! [input-port] column
 -- primitive: set-port-line! [input-port] line
     Set the current column or line number of INPUT-PORT, using the current input port if none is specified.

Extended I/O
============

Extended I/O procedures are available which read or write lines of text or read text delimited by a specified set of characters.

Interfaces to read/fread and write/fwrite are also available, as uniform-array-read! and uniform-array-write!, Uniform Array.

 -- procedure: read-line [port] [handle-delim]
     Return a line of text from PORT if specified, otherwise from the value returned by (current-input-port).  Under Unix, a line of text is terminated by the first end-of-line character or by end-of-file.

     If HANDLE-DELIM is specified, it should be one of the following symbols:

     trim
          Discard the terminating delimiter.  This is the default, but it will be impossible to tell whether the read terminated with a delimiter or end-of-file.

     concat
          Append the terminating delimiter (if any) to the returned string.

     peek
          Push the terminating delimiter (if any) back on to the port.

     split
          Return a pair containing the string read from the port and the terminating delimiter or end-of-file object.

          NOTE: if the scsh module is loaded then multiple values are returned instead of a pair.

 -- procedure: read-line! buf [port]
     Read a line of text into the supplied string BUF and return the number of characters added to BUF.  If BUF is filled, then #f is returned. Read from PORT if specified, otherwise from the value returned by (current-input-port).

 -- procedure: read-delimited delims [port] [handle-delim]
     Read text until one of the characters in the string DELIMS is found or end-of-file is reached.  Read from PORT if supplied, otherwise from the value returned by (current-input-port). HANDLE-DELIM takes the same values as described for read-line.

     NOTE: if the scsh module is loaded then DELIMS must be an scsh char-set, not a string.

 -- procedure: read-delimited! delims buf [port] [handle-delim] [start] [end]
     Read text into the supplied string BUF and return the number of characters added to BUF (subject to HANDLE-DELIM, which takes the same values specified for read-line.  If BUF is filled, #f is returned for both the number of characters read and the delimiter.  Also terminates if one of the characters in the string DELIMS is found or end-of-file is reached.  Read from PORT if supplied, otherwise from the value returned by (current-input-port).

     NOTE: if the scsh module is loaded then DELIMS must be an scsh char-set, not a string.

 -- primitive: write-line obj [port]
     Display OBJ and a newline character to PORT.  If PORT is not specified, (current-output-port) is used.  This function is equivalent to:

          (display obj [port])
          (newline [port])

Some of the abovementioned I/O functions rely on the following C primitives.  These will mainly be of interest to people hacking Guile internals.

 -- primitive: %read-delimited! delims buf gobble? [port [start [end]]]
     Read characters from PORT into BUF until one of the characters in the DELIMS string is encountered.  If GOBBLE? is true, store the delimiter character in BUF as well; otherwise, discard it.  If PORT is not specified, use the value of (current-input-port).  If START or END are specified, store data only into the substring of BUF bounded by START and END (which default to the beginning and end of the buffer, respectively).

     Return a pair consisting of the delimiter that terminated the string and the number of characters read.  If reading stopped at the end of file, the delimiter returned is the EOF-OBJECT; if the buffer was filled without encountering a delimiter, this value is #F.

 -- primitive: %read-line [port]
     Read a newline-terminated line from PORT, allocating storage as necessary.  The newline terminator (if any) is removed from the string, and a pair consisting of the line and its delimiter is returned.  The delimiter may be either a newline or the EOF-OBJECT; if %read-line is called at the end of file, it returns the pair (#<eof> . #<eof>).

C Port Interface
================

This section describes how to use Scheme ports from C.

Port basics
-----------

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

Port buffers
------------

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

The rw_random flag
------------------

Special treatment is required for ports which can be seeked at random and which are open for both reading and writing.  The port implemention must be given a chance to update its state, by calling the flush or end_input ptob procedures.  E.g., in the case of an fport, flush causes buffered output to be written to the file descriptor, while end_input causes the descriptor position to be adjusted to account for buffered input which was never read.

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

The rw_active variable
----------------------

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

SCM_PORT_READ
     the read buffer may have unread data.

SCM_PORT_WRITE
     the write buffer may have unwritten data.

SCM_PORT_NEITHER
     neither the write nor the read buffer has unprocessed data.

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

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

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

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

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

 4. Set rw_active to SCM_PORT_READ if rw_random is set.

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

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

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

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

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

 3. Set rw_active to SCM_PORT_WRITE if rw_random is set.

Port Implementation
===================

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

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

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

scm_make_port_type initialises three elements of the structure (name, fill_input and write) from its arguments. The remaining elements are initialised with default values and can be set later if required.

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

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

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

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

equalp
     Not used at present.  Set using scm_set_port_equalp.

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

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

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

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

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

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

seek
     Set the current position of the port.  It can be assumed that the current state of rw_active is SCM_PORT_NEITHER. Set using scm_set_port_seek.

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

Bitwise Operations
******************

 -- primitive: logand n1 n2
     Returns the integer which is the bit-wise AND of the two integer arguments.

     Example:

          (number->string (logand #b1100 #b1010) 2)
             => "1000"

 -- primitive: logior n1 n2
     Returns the integer which is the bit-wise OR of the two integer arguments.

     Example:

          (number->string (logior #b1100 #b1010) 2)
             => "1110"

 -- primitive: logxor n1 n2
     Returns the integer which is the bit-wise XOR of the two integer arguments.

     Example:

          (number->string (logxor #b1100 #b1010) 2)
             => "110"

 -- primitive: lognot n
     Returns the integer which is the 2s-complement of the integer argument.

     Example:

          (number->string (lognot #b10000000) 2)
             => "-10000001"
          (number->string (lognot #b0) 2)
             => "-1"

 -- primitive: logtest j k

          (logtest j k) == (not (zero? (logand j k)))

          (logtest #b0100 #b1011) => #f
          (logtest #b0100 #b0111) => #t

 -- primitive: logbit? index j

          (logbit? index j) == (logtest (integer-expt 2 index) j)

          (logbit? 0 #b1101) => #t
          (logbit? 1 #b1101) => #f
          (logbit? 2 #b1101) => #t
          (logbit? 3 #b1101) => #t
          (logbit? 4 #b1101) => #f

 -- primitive: ash int count
     Returns an integer equivalent to (inexact->exact (floor (* INT (expt 2 COUNT)))).

     Example:

          (number->string (ash #b1 3) 2)
             => "1000"
          (number->string (ash #b1010 -1) 2)
             => "101"

 -- primitive: logcount n
     Returns the number of bits in integer N.  If integer is positive, the 1-bits in its binary representation are counted.  If negative, the 0-bits in its two's-complement binary representation are counted.  If 0, 0 is returned.

     Example:

          (logcount #b10101010)
             => 4
          (logcount 0)
             => 0
          (logcount -2)
             => 1

 -- primitive: integer-length n
     Returns the number of bits neccessary to represent N.

     Example:

          (integer-length #b10101010)
             => 8
          (integer-length 0)
             => 0
          (integer-length #b1111)
             => 4

 -- primitive: integer-expt n k
     Returns N raised to the non-negative integer exponent K.

     Example:

          (integer-expt 2 5)
             => 32
          (integer-expt -3 3)
             => -27

 -- primitive: bit-extract n start end
     Returns the integer composed of the START (inclusive) through END (exclusive) bits of N.  The STARTth bit becomes the 0-th bit in the result.

     Example:

          (number->string (bit-extract #b1101101010 0 4) 2)
             => "1010"
          (number->string (bit-extract #b1101101010 4 9) 2)
             => "10110"

Regular Expressions
*******************

A regular expression (or regexp) is a pattern that describes a whole class of strings.  A full description of regular expressions and their syntax is beyond the scope of this manual; an introduction can be found in the Emacs manual (see Syntax of Regular Expressions (The GNU Emacs Manual), or in many general Unix reference books.

If your system does not include a POSIX regular expression library, and you have not linked Guile with a third-party regexp library such as Rx, these functions will not be available.  You can tell whether your Guile installation includes regular expression support by checking whether the *features* list includes the regex symbol.

[FIXME: it may be useful to include an Examples section.  Parts of this interface are bewildering on first glance.]

Regexp Functions
================

By default, Guile supports POSIX extended regular expressions. That means that the characters (, ), + and ? are special, and must be escaped if you wish to match the literal characters.

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

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

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

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

 -- primitive: make-regexp str [flag ...]
     Compile the regular expression described by STR, and return the compiled regexp structure.  If STR does not describe a legal regular expression, make-regexp throws a regular-expression-syntax error.

     The FLAG arguments change the behavior of the compiled regexp. The following flags may be supplied:

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

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

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

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

 -- primitive: regexp-exec regexp str [start]
     Match the compiled regular expression REGEXP against str. If the optional integer START argument is provided, begin matching from that position in the string.  Return a match structure describing the results of the match, or #f if no match could be found.

 -- primitive: regexp? obj
     Return #t if OBJ is a compiled regular expression, or #f otherwise.

Regular expressions are commonly used to find patterns in one string and replace them with the contents of another string.

 -- procedure: regexp-substitute port match [item...]
     Write to the output port PORT selected contents of the match structure MATCH.  Each ITEM specifies what should be written, and may be one of the following arguments:

       * A string.  String arguments are written out verbatim.

       * An integer.  The submatch with that number is written.

       * The symbol pre.  The portion of the matched string preceding the regexp match is written.

       * The symbol post.  The portion of the matched string following the regexp match is written.

     PORT may be #f, in which case nothing is written; instead, regexp-substitute constructs a string from the specified ITEMs and returns that.

 -- procedure: regexp-substitute/global port regexp target [item...]
     Similar to regexp-substitute, but can be used to perform global substitutions on STR.  Instead of taking a match structure as an argument, regexp-substitute/global takes two string arguments: a REGEXP string describing a regular expression, and a TARGET string which should be matched against this regular expression.

     Each ITEM behaves as in REGEXP-SUBSTITUTE, with the following exceptions:

       * A function may be supplied.  When this function is called, it will be passed one argument: a match structure for a given regular expression match.  It should return a string to be written out to PORT.

       * The post symbol causes regexp-substitute/global to recurse on the unmatched portion of STR.  This must be supplied in order to perform global search-and-replace on STR; if it is not present among the ITEMs, then regexp-substitute/global will return after processing a single match.

Match Structures
================

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

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

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

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

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

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

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

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

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

 -- procedure: match:string match
     Return the original TARGET string.

Backslash Escapes
=================

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

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

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

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

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

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

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

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

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

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

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

Rx Interface
============

[FIXME: this is taken from Gary and Mark's quick summaries and should be reviewed and expanded.  Rx is pretty stable, so could already be done!]

Guile includes an interface to Tom Lord's Rx library (currently only to POSIX regular expressions).  Use of the library requires a two step process: compile a regular expression into an efficient structure, then use the structure in any number of string comparisons.

For example, given the regular expression abc. (which matches any string containing abc followed by any single character):

     guile> (define r (regcomp "abc."))
     guile> r
     #<rgx abc.>
     guile> (regexec r "abc")
     #f
     guile> (regexec r "abcd")
     #((0 . 4))
     guile>

The definitions of regcomp and regexec are as follows:

 -- primitive: regcomp pattern [flags]
     Compile the regular expression pattern using POSIX rules.  Flags is optional and should be specified using symbolic names:
      -- Variable: REG_EXTENDED
          use extended POSIX syntax

      -- Variable: REG_ICASE
          use case-insensitive matching

      -- Variable: REG_NEWLINE
          allow anchors to match after newline characters in the string and prevents . or [^...] from matching newlines.

     The logior procedure can be used to combine multiple flags. The default is to use POSIX basic syntax, which makes + and ?  literals and \+ and \? operators.  Backslashes in PATTERN must be escaped if specified in a literal string e.g., "\\(a\\)\\?".

 -- primitive: regexec regex string [match-pick] [flags]

     Match STRING against the compiled POSIX regular expression REGEX. MATCH-PICK and FLAGS are optional.  Possible flags (which can be combined using the logior procedure) are:

      -- Variable: REG_NOTBOL
          The beginning of line operator won't match the beginning of STRING (presumably because it's not the beginning of a line)

      -- Variable: REG_NOTEOL
          Similar to REG_NOTBOL, but prevents the end of line operator from matching the end of STRING.

     If no match is possible, regexec returns #f.  Otherwise MATCH-PICK determines the return value:

     #t or unspecified: a newly-allocated vector is returned, containing pairs with the indices of the matched part of STRING and any substrings.

     "": a list is returned: the first element contains a nested list with the matched part of STRING surrounded by the the unmatched parts. Remaining elements are matched substrings (if any).  All returned substrings share memory with STRING.

     #f: regexec returns #t if a match is made, otherwise #f.

     vector: the supplied vector is returned, with the first element replaced by a pair containing the indices of the matched portion of STRING and further elements replaced by pairs containing the indices of matched substrings (if any).

     list: a list will be returned, with each member of the list specified by a code in the corresponding position of the supplied list:

     a number: the numbered matching substring (0 for the entire match).

     #\<: the beginning of STRING to the beginning of the part matched by regex.

     #\>: the end of the matched part of STRING to the end of STRING.

     #\c: the "final tag", which seems to be associated with the "cut operator", which doesn't seem to be available through the posix interface.

     e.g., (list #\< 0 1 #\>).  The returned substrings share memory with STRING.

Here are some other procedures that might be used when using regular expressions:

 -- primitive: compiled-regexp? obj
     Test whether obj is a compiled regular expression.

 -- primitive: regexp->dfa regex [flags]

 -- primitive: dfa-fork dfa

 -- primitive: reset-dfa! dfa

 -- primitive: dfa-final-tag dfa

 -- primitive: dfa-continuable? dfa

 -- primitive: advance-dfa! dfa string

Keywords
********

[FIXME: need some initial schmooze about keywords; this is all taken from the NEWS file, and is accurate but not very useful to someone who has not used keywords before.]

Guile supports a new R4RS--compliant syntax for keywords.  A token of the form #:NAME, where NAME has the same syntax as a Scheme symbol, is the external representation of the keyword named NAME.  Keyword objects print using this syntax as well, so values containing keyword objects can be read back into Guile.  When used in an expression, keywords are self-quoting objects.

Guile suports this read syntax, and uses this print syntax, regardless of the current setting of the `keyword' read option.  The `keyword' read option only controls whether Guile recognizes the `:NAME' syntax, which is incompatible with R4RS.  (R4RS says such token represent symbols.)

The default behaviour is the R4RS--compliant one (#:xxx instead of :xxx).

To change between the two keyword syntaxes you use the read-options procedure documented in General option interface and Reader options.

To use the :xxx keyword syntax, use

     (read-set! keywords 'prefix)

To make keyword syntax R4RS compliant, with the #:xxx syntax, use:

     (read-set! keywords #f)

[FIXME: in state of flux right now; here are the Scheme primitives defined in kw.c:]

 -- primitive: keyword? kw
     keyword? returns #t if the argument KW is a keyword; it returns #f otherwise.

 -- primitive: keyword-dash-symbol arg
     keyword-dash-symbol [FIXME: have no idea what this does; it is not commented.]

Exceptions
**********

 -- primitive: catch key thunk handler
     Invoke THUNK in the dynamic context of HANDLER for exceptions matching KEY.  If thunk throws to the symbol KEY, then HANDLER is invoked this way:

          (handler key args ...)

     KEY is a symbol or #t.

     THUNK takes no arguments.  If THUNK returns normally, that is the return value of catch.

     Handler is invoked outside the scope of its own catch.  If HANDLER again throws to the same key, a new handler from further up the call chain is invoked.

     If the key is #t, then a throw to any symbol will match this call to catch.

 -- primitive: throw key &rest args ...
     Invoke the catch form matching KEY, passing ARGS to the HANDLER.

     KEY is a symbol.  It will match catches of the same symbol or of #t.

     If there is no handler at all, an error is signaled.

 -- procedure: error msg args ...
     Raise an error with key misc-error and a message constructed by displaying MSG and writing ARGS.

 -- primitive: scm-error key subr message args data
     Raise an error with key KEY.  SUBR can be a string naming the procedure associated with the error, or #f.  MESSAGE is the error message string, possibly containing %S and %s escapes.  When an error is reported, these are replaced by formating the corresponding members of ARGS: %s formats using display and %S formats using write.  DATA is a list or #f depending on KEY: if KEY is system-error then it should be a list containing the Unix errno value;  If KEY is signal then it should be a list containing the Unix signal number; otherwise it will usually be #f.

 -- primitive: strerror errno
     Returns the Unix error message corresponding to ERRNO, an integer.

 -- syntax: false-if-exception expr
     Returns the result of evaluating its argument; however if an exception occurs then #f is returned instead.

It is traditional in Scheme to implement exception systems using call-with-current-continuation, but his has not been done, for performance reasons.  The implementation of call-with-current-continuation is a stack copying implementation. This allows it to interact well with ordinary C code.  Unfortunately, a stack-copying implementation can be slow -- creating a new continuation involves a block copy of the stack.

Instead of using call-with-current-continuation, the exception primitives are implemented as built-ins that take advantage of the upward only nature of exceptions.

Modules
*******

[FIXME: somewhat babbling; should be reviewed by someone who understands modules, once the new module system is in place]

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

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

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

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

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

Scheme and modules
==================

Scheme, as defined in R4RS, does not have a module system at all.

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

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

     (provide 'random)

so to use its procedures, a user would type

     (require 'random)

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

The Guile module system
=======================

In 1996 Tom Lord implemented a full-featured module system for Guile which allows loading Scheme source files into a private name space.

This module system is regarded as being rather idiosyncratic, and will probably change to something more like the ML module system, so for now I will simply descrive how it works for a couple of simple cases.

First of all, the Guile module system sets up a hierarchical name space, and that name space can be represented like Unix pathnames preceded by a # character.  The root name space for all Guile-supplied modules is called ice-9.

So for example, the SLIB interface, contained in $srcdir/ice-9/slib.scm, starts out with

     (define-module (ice-9 slib))

and a user program can use

     (use-modules (ice-9 slib))

to have access to all procedures and variables defined within the slib module with (define-public ...).

So here are the functions involved:
 -- syntax: define-module module-specification
     MODULE-SPECIFICATION is of the form (hierarchy file).  One example of this is

          (use-modules (ice-9 slib))

     define-module makes this module available to Guile programs under the given MODULE-SPECIFICATION.

 -- syntax: define-public ...
     Makes a procedure or variable available to programs that use the current module.

 -- syntax: use-modules module-specification
     MODULE-SPECIFICATION is of the form (hierarchy file).  One example of this is

          (use-modules (ice-9 slib))

     use-modules allows the current Guile program to use all publicly defined procedures and variables in the module denoted by MODULE-SPECIFICATION.

[FIXME: must say more, and explain, and also demonstrate a private name space use, and demonstrate how one would do Python's "from Tkinter import *" versus "import Tkinter".  Must also add something about paths and standards for contributed modules.]

Some modules are included in the Guile distribution; here are references to the entries in this manual which describe them in more detail:

boot-9
     boot-9 is Guile's initialization module, and it is always loaded when Guile starts up.

(ice-9 debug)
     Mikael Djurfeldt's source-level debugging support for Guile (see debugger user interface).

(ice-9 threads)
     Guile's support for multi threaded execution (see Threads and Dynamic Roots).

(ice-9 slib)
     This module contains hooks for using Aubrey Jaffer's portable Scheme library SLIB from Guile (see SLIB).

(ice-9 jacal)
     This module contains hooks for using Aubrey Jaffer's symbolic math packge Jacal from Guile (see JACAL).

Module Internals
****************

First-class Variables
=====================

First-class Modules
===================

Dynamic Libraries
=================

Often you will want to extend Guile by linking it with some existing system library.  For example, linking Guile with a curses or termcap library would be useful if you want to implement a full-screen user interface for a Guile application.  However, if you were to link Guile with these libraries at compile time, it would bloat the interpreter considerably, affecting everyone on the system even if the new libraries are useful only to you.  Also, every time a new library is installed, you would have to reconfigure, recompile and relink Guile merely in order to provide a new interface.

Many Unix systems permit you to get around this problem by using dynamic loading.  When a new library is linked, it can be made a dynamic library by passing certain switches to the linker.  A dynamic library does not need to be linked with an executable image at link time; instead, the executable may choose to load it dynamically at run time.  This is a powerful concept that permits an executable to link itself with almost any library without reconfiguration, if it has been written properly.

Guile's dynamic linking functions make it relatively easy to write a module that incorporates code from third-party object code libraries.

 -- primitive: dynamic-link library-file
     Open the dynamic library LIBRARY-FILE.  A library handle representing the opened library is returned; this handle should be used as the LIB argument to the following functions.

 -- primitive: dynamic-object? obj
     Return #t if OBJ is a dynamic library handle, or #f otherwise.

 -- primitive: dynamic-unlink lib
     Unlink the library represented by LIBRARY-HANDLE, and remove any imported symbols from the address space.

 -- primitive: dynamic-func func lib
     Import the symbol FUNC from LIB (a dynamic library handle). A function handle representing the imported function is returned.

 -- primitive: dynamic-call lib-thunk lib
     Call LIB-THUNK, a procedure of no arguments.  If LIB-THUNK is a string, it is assumed to be a symbol found in the dynamic library LIB and is fetched with dynamic-func.  Otherwise, it should be a function handle returned by a previous call to dynamic-func. The return value is unspecified.

 -- primitive: dynamic-args-call proc lib args
     Call PROC, a dynamically loaded function, passing it the argument list ARGS (a list of strings).  As with dynamic-call, PROC should be either a function handle or a string, in which case it is first fetched from LIB with dynamic-func.

     PROC is assumed to return an integer, which is used as the return value from dynamic-args-call.

 -- primitive: c-registered-modules
     Return a list of the object code modules that have been imported into the current Guile process.  Each element of the list is a pair whose car is the name of the module (as it might be used by use-modules, for instance), and whose cdr is the function handle for that module's initializer function.

 -- primitive: c-clear-registered-modules
     Destroy the list of modules registered with the current Guile process. The return value is unspecified.  Warning: this function does not actually unlink or deallocate these modules, but only destroys the records of which modules have been loaded.  It should therefore be used only by module bookkeeping operations.

[FIXME: provide a brief example here of writing the C hooks for an object code module, and using dynamic-link and dynamic-call to load the module.]

Dynamic Linking from Marius
***************************

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

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

Now, when all the necessary machinery is there to perform part of the linking at run-time, why not take the next step and allow the programmer to explicitly take advantage of it from within his program?  Of course, many operating systems that support shared libraries do just that, and chances are that Guile will allow you to access this feature from within your Scheme programs.  As you might have guessed already, this feature is called dynamic linking (Some people also refer to the final linking stage at program startup as `dynamic linking', so if you want to make yourself perfectly clear, it is probably best to use the more technical term dlopening, as suggested by Gordon Matzigkeit in his libtool documentation.)

As with many aspects of Guile, there is a low-level way to access the dynamic linking apparatus, and a more high-level interface that integrates dynamically linked libraries into the module system.

Low level dynamic linking
=========================

When using the low level procedures to do your dynamic linking, you have complete control over which library is loaded when and what get's done with it.

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

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

 -- primitive: dynamic-object? val
     Determine whether VAL represents a dynamically linked object file.

 -- primitive: dynamic-unlink dynobj
     Unlink the indicated object file from the application.  The argument DYNOBJ should be one of the values returned by dynamic-link.  When dynamic-unlink has been called on DYNOBJ, it is no longer usable as an argument to the functions below and you will get type mismatch errors when you try to.

 -- primitive: dynamic-func function dynobj
     Search the C function indicated by FUNCTION (a string or symbol) in DYNOBJ and return some Scheme object that can later be used with dynamic-call to actually call this function.  Right now, these Scheme objects are formed by casting the address of the function to long and converting this number to its Scheme representation.

     Regardless whether your C compiler prepends an underscore _ to the global names in a program, you should not include this underscore in FUNCTION.  Guile knows whether the underscore is needed or not and will add it when necessary.

 -- primitive: dynamic-call function dynobj
     Call the C function indicated by FUNCTION and DYNOBJ.  The function is passed no arguments and its return value is ignored.  When FUNCTION is something returned by dynamic-func, call that function and ignore DYNOBJ.  When FUNCTION is a string (or symbol, etc.), look it up in DYNOBJ; this is equivalent to

          (dynamic-call (dynamic-func FUNCTION DYNOBJ #f))

     Interrupts are deferred while the C function is executing (with SCM_DEFER_INTS/SCM_ALLOW_INTS).

 -- primitive: dynamic-args-call function dynobj args
     Call the C function indicated by FUNCTION and DYNOBJ, just like dynamic-call, but pass it some arguments and return its return value.  The C function is expected to take two arguments and return an int, just like main:

          int c_func (int argc, char **argv);

     The parameter ARGS must be a list of strings and is converted into an array of char *.  The array is passed in ARGV and its size in ARGC.  The return value is converted to a Scheme number and returned from the call to dynamic-args-call.

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

Here is a small example that works on GNU/Linux:

     (define libc-obj (dynamic-link "libc.so"))
     libc-obj
     => #<dynamic-object "libc.so">
     (dynamic-args-call 'rand libc-obj '())
     => 269167349
     (dynamic-unlink libc-obj)
     libc-obj
     => #<dynamic-object "libc.so" (unlinked)>

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

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

>From this setup the next logical step is to integrate these glue libraries into the module system of Guile so that you can load new primitives into a running system just as you can load new Scheme code.

There is, however, another possibility to get a more thorough access to the functions contained in a dynamically linked library.  Anthony Green has written libffi, a library that implements a foreign function interface for a number of different platforms.  With it, you can extend the Spartan functionality of dynamic-call and dynamic-args-call considerably.  There is glue code available in the Guile contrib archive to make libffi accessible from Guile.

Putting Compiled Code into Modules
==================================

The new primitives that you add to Guile with gh_new_procedure or with any of the other mechanisms are normally placed into the same module as all the other builtin procedures (like display). However, it is also possible to put new primitives into their own module.

The mechanism for doing so is not very well thought out and is likely to change when the module system of Guile itself is revised, but it is simple and useful enough to document it as it stands.

What gh_new_procedure and the functions used by the snarfer really do is to add the new primitives to whatever module is the current module when they are called.  This is analogous to the way Scheme code is put into modules: the define-module expression at the top of a Scheme source file creates a new module and makes it the current module while the rest of the file is evaluated.  The define expressions in that file then add their new definitions to this current module.

Therefore, all we need to do is to make sure that the right module is current when calling gh_new_procedure for our new primitives. Unfortunately, there is not yet an easy way to access the module system from C, so we are better off with a more indirect approach.  Instead of adding our primitives at initialization time we merely register with Guile that we are ready to provide the contents of a certain module, should it ever be needed.

 -- Function: void scm_register_module_xxx (char *NAME, void (*INITFUNC)(void))
     Register with Guile that INITFUNC will provide the contents of the module NAME.

     The function INITFUNC should perform the usual initialization actions for your new primitives, like calling gh_new_procedure or including the file produced by the snarfer.  When INITFUNC is called, the current module is a newly created module with a name as indicated by NAME.  Each definition that is added to it will be automatically exported.

     The string NAME indicates the hierachical name of the new module. It should consist of the individual components of the module name separated by single spaces.  That is, the Scheme module name (foo bar), which is a list, should be written as "foo bar" for the NAME parameter.

     You can call scm_register_module_xxx at any time, even before Guile has been initialized.  This might be useful when you want to put the call to it in some initialization code that is magically called before main, like constructors for global C++ objects.

     An example for scm_register_module_xxx appears in the next section.

Now, instead of calling the initialization function at program startup, you should simply call scm_register_module_xxx and pass it the initialization function.  When the named module is later requested by Scheme code with use-modules for example, Guile will notice that it knows how to create this module and will call the initialization function at the right time in the right context.

Dynamic Linking and Compiled Code Modules
=========================================

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

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

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

     #include <math.h>
     #include <guile/gh.h>

     SCM
     j0_wrapper (SCM x)
     {
       return gh_double2scm (j0 (gh_scm2double (x)));
     }

     void
     init_math_bessel ()
     {
       gh_new_procedure1_0 ("j0", j0_wrapper);
     }

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

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

Now fire up Guile:

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

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

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

     (apropos 'j0)
     -| the-root-module: j0     #<primitive-procedure j0>

As you can see, j0 is contained in the root module, where all the other Guile primitives like display, etc live.  In general, a primitive is put into whatever module is the current module at the time gh_new_procedure is called.  To put j0 into its own module named (math bessel), we need to make a call to scm_register_module_xxx.  Additionally, to have Guile perform the dynamic linking automatically, we need to put libbessel.so into a place where Guile can find it.  The call to scm_register_module_xxx should be contained in a specially named module init function.  Guile knows about this special name and will call that function automatically after having linked in the shared library.  For our example, we add the following code to bessel.c:

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

The general pattern for the name of a module init function is: scm_init_, followed by the name of the module where the individual hierarchical components are concatenated with underscores, followed by _module.  It should call scm_register_module_xxx with the correct module name and the appropriate initialization function.  When that initialization function will be called, a newly created module with the right name will be the current module so that all definitions that the initialization functions makes will end up in the correct module.

After libbessel.so has been rebuild, we need to place the shared library into the right place.  When Guile tries to autoload the (math bessel) module, it looks not only for a file called math/bessel.scm in its %load-path, but also for math/libbessel.so.  So all we need to do is to create a directory called math somewhere in Guile's %load-path and place libbessel.so there.  Normally, the current directory . is in the %load-path, so we just use that for this example.

     % mkdir maths
     % cd maths
     % ln -s ../libbessel.so .
     % cd ..
     % guile
     guile> (use-modules (math bessel))
     guile> (j0 2)
     0.223890779141236
     guile> (apropos 'j0)
     -| bessel: j0      #<primitive-procedure j0>

That's it!

Note that we used a symlink to make libbessel.so appear in the right spot.  This is probably not a bad idea in general.  The directories that the %load-path normally contains are supposed to contain only architecture independent files.  They are not really the right place for a shared library.  You might want to install the libraries somewhere below exec_prefix and then symlink to them from the architecture independent directory.  This will at least work on heterogenous systems where the architecture dependent stuff resides in the same place on all machines (which seems like a good idea to me anyway).

Dynamic Wind
************

[FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed]

 -- primitive: dynamic-wind in-guard thunk out-guard
     All three arguments must be 0-argument procedures.

     IN-GUARD is called, then THUNK, then OUT-GUARD.

     If, any time during the execution of THUNK, the continuation of the dynamic-wind expression is escaped non-locally, OUT-GUARD is called.   If the continuation of the dynamic-wind is re-entered, IN-GUARD is called.   Thus IN-GUARD and OUT-GUARD may be called any number of times.

          (define x 'normal-binding)
          => x

          (define a-cont  (call-with-current-continuation
          		  (lambda (escape)
          		     (let ((old-x x))
          		       (dynamic-wind
          			  ;; in-guard:
          			  ;;
          			  (lambda () (set! x 'special-binding))

          			  ;; thunk
          			  ;;
          		 	  (lambda () (display x) (newline)
          				     (call-with-current-continuation escape)
          				     (display x) (newline)
          				     x)

          			  ;; out-guard:
          			  ;;
          			  (lambda () (set! x old-x)))))))

          ;; Prints:
          special-binding
          ;; Evaluates to:
          => a-cont

          x
          => normal-binding

          (a-cont #f)
          ;; Prints:
          special-binding
          ;; Evaluates to:
          => a-cont  ;; the value of the (define a-cont...)

          x
          => normal-binding

          a-cont
          => special-binding

Threads and Dynamic Roots
*************************

[FIXME: This is pasted in from Tom Lord's original guile.texi chapter plus the Cygnus programmer's manual; it should be *very* carefully reviewed and largely reorganized.]

Dynamic Roots
=============

A dynamic root is a root frame of Scheme evaluation. The top-level repl, for example, is an instance of a dynamic root.

Each dynamic root has its own chain of dynamic-wind information.  Each has its own set of continuations, jump-buffers, and pending CATCH statements which are inaccessible from the dynamic scope of any other dynamic root.

In a thread-based system, each thread has its own dynamic root.  Therefore, continuations created by one thread may not be invoked by another.

Even in a single-threaded system, it is sometimes useful to create a new dynamic root.  For example, if you want to apply a procedure, but to not allow that procedure to capture the current continuation, calling the procedure under a new dynamic root will do the job.

 -- primitive: call-with-dynamic-root thunk handler
     Evaluate (THUNK) in a new dynamic context, returning its value.

     If an error occurs during evaluation, apply HANDLER to the arguments to the throw, just as throw would.  If this happens, HANDLER is called outside the scope of the new root -- it is called in the same dynamic context in which call-with-dynamic-root was evaluated.

     If THUNK captures a continuation, the continuation is rooted at the call to THUNK.  In particular, the call to call-with-dynamic-root is not captured.  Therefore, call-with-dynamic-root always returns at most one time.

     Before calling THUNK, the dynamic-wind chain is un-wound back to the root and a new chain started for THUNK.  Therefore, this call may not do what you expect:

          ;; Almost certainly a bug:
          (with-output-to-port
           some-port

           (lambda ()
             (call-with-dynamic-root
              (lambda ()
                (display 'fnord)
                (newline))
              (lambda (errcode) errcode))))

     The problem is, on what port will fnord\n be displayed?  You might expect that because of the with-output-to-port that it will be displayed on the port bound to some-port.  But it probably won't -- before evaluating the thunk, dynamic winds are unwound, including those created by with-output-to-port. So, the standard output port will have been re-set to its default value before display is evaluated.

     (This function was added to Guile mostly to help calls to functions in C libraries that can not tolerate non-local exits or calls that return multiple times.  If such functions call back to the interpreter, it should be under a new dynamic root.)

 -- primitive: dynamic-root
     Return an object representing the current dynamic root.

     These objects are only useful for comparison using eq?. They are currently represented as numbers, but your code should in no way depend on this.

 -- procedure: quit [exit_val]
     Throw back to the error handler of the current dynamic root.

     If integer EXIT_VAL is specified and if Guile is being used stand-alone and if quit is called from the initial dynamic-root, EXIT_VAL becomes the exit status of the Guile process and the process exits.

When Guile is run interactively, errors are caught from within the read-eval-print loop.  An error message will be printed and abort called.  A default set of signal handlers is installed, e.g., to allow user interrupt of the interpreter.

It is possible to switch to a "batch mode", in which the interpreter will terminate after an error and in which all signals cause their default actions.  Switching to batch mode causes any handlers installed from Scheme code to be removed.  An example of where this is useful is after forking a new process intended to run non-interactively.

 -- procedure: batch-mode?
     Returns a boolean indicating whether the interpreter is in batch mode.

 -- procedure: set-batch-mode?! arg
     If ARG is true, switches the interpreter to batch mode. The #f case has not been implemented.

Threads
=======

[NOTE: this chapter was written for Cygnus Guile and has not yet been updated for the Guile 1.x release.]

Here is a the reference for Guile's threads.  In this chapter I simply quote verbatim Tom Lord's description of the low-level primitives written in C (basically an interface to the POSIX threads library) and Anthony Green's description of the higher-level thread procedures written in scheme.

When using Guile threads, keep in mind that each guile thread is executed in a new dynamic root.

Low level thread primitives
---------------------------

 -- primitive: call-with-new-thread thunk error-thunk
     Evaluate (THUNK) in a new thread, and new dynamic context, returning a new thread object representing the thread.

     If an error occurs during evaluation, call error-thunk, passing it an error code describing the condition.  [Error codes are currently meaningless integers.  In the future, real values will be specified.] If this happens, the error-thunk is called outside the scope of the new root -- it is called in the same dynamic context in which with-new-thread was evaluated, but not in the callers thread.

     All the evaluation rules for dynamic roots apply to threads.

 -- primitive: join-thread thread
     Suspend execution of the calling thread until the target THREAD terminates, unless the target THREAD has already terminated.

 -- primitive: yield
     If one or more threads are waiting to execute, calling yield forces an immediate context switch to one of them. Otherwise, yield has no effect.

 -- primitive: make-mutex
     Create a new mutex object.

 -- primitive: lock-mutex mutex
     Lock MUTEX. If the mutex is already locked, the calling thread blocks until the mutex becomes available. The function returns when the calling thread owns the lock on MUTEX.

 -- primitive: unlock-mutex mutex
     Unlocks MUTEX if the calling thread owns the lock on MUTEX. Calling unlock-mutex on a mutex not owned by the current thread results in undefined behaviour. Once a mutex has been unlocked, one thread blocked on MUTEX is awakened and grabs the mutex lock.

Higher level thread procedures
------------------------------

 -- primitive: call-with-new-thread thunk error-thunk
     Evaluate (THUNK) in a new thread, and new dynamic context, returning a new thread object representing the thread.

     If an error occurs during evaluation, call error-thunk, passing it an error code describing the condition.  [Error codes are currently meaningless integers.  In the future, real values will be specified.] If this happens, the error-thunk is called outside the scope of the new root -- it is called in the same dynamic context in which with-new-thread was evaluated, but not in the callers thread.

     All the evaluation rules for dynamic roots apply to threads.

 -- primitive: join-thread thread
     Suspend execution of the calling thread until the target THREAD terminates, unless the target THREAD has already terminated.

 -- primitive: yield
     If one or more threads are waiting to execute, calling yield forces an immediate context switch to one of them. Otherwise, yield has no effect.

 -- primitive: make-mutex
     Create a new mutex object.

 -- primitive: lock-mutex mutex
     Lock MUTEX. If the mutex is already locked, the calling thread blocks until the mutex becomes available. The function returns when the calling thread owns the lock on MUTEX.

 -- primitive: unlock-mutex mutex
     Unlocks MUTEX if the calling thread owns the lock on MUTEX. Calling unlock-mutex on a mutex not owned by the current thread results in undefined behaviour. Once a mutex has been unlocked, one thread blocked on MUTEX is awakened and grabs the mutex lock.

Reflection
**********

[FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed]

eval
====

Tag Values
==========

Weak References
***************

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

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

Property lists offer the same kind of functionality as weak key hashes in many situations. (see Property Lists)

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

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

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

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

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

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

Weak key hashes
===============

 -- primitive: make-weak-key-hash-table size
 -- primitive: make-weak-value-hash-table size
 -- primitive: make-doubly-weak-hash-table size
     Return a weak hash table with SIZE buckets. As with any hash table, choosing a good size for the table requires some caution.

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

 -- primitive: weak-key-hash-table? obj
 -- primitive: weak-value-hash-table? obj
 -- primitive: doubly-weak-hash-table? obj
     Return #T if OBJ is the specified weak hash table. Note that a doubly weak hash table is neither a weak key nor a weak value hash table.

Weak vectors
============

Weak vectors are mainly useful in Guile's implementation of weak hash tables.
 -- primitive: make-weak-vector size [fill]
     Return a weak vector with SIZE elements. If the optional argument FILL is given, all entries in the vector will be set to FILL. The default value for FILL is the empty list.

 -- primitive: weak-vector . rest
 -- primitive: list->weak-vector l
     Construct a weak vector from a list: weak-vector uses the list of its arguments while list->weak-vector uses its only argument L (a list) to construct a weak vector the same way vector->list would.

 -- primitive: weak-vector? obj
     Return #T if OBJ is a weak vector. Note that all weak hashes are also weak vectors.

Garbage Collection
******************

[FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed]

 -- primitive: gc
     Scans all of SCM objects and reclaims for further use those that are no longer accessible.

 -- primitive: gc-stats
     Returns an association list of statistics about Guile's current use of storage.

 -- primitive: object-address obj
     Return an integer that for the lifetime of OBJ is uniquely returned by this function for OBJ

Configuration Data
******************

It is often useful to have site-specific information about the current Guile installation.  This chapter describes how to find out about Guile's configuration at run time.

 -- primitive: version
 -- primitive: major-version
 -- primitive: minor-version
     Return a string describing Guile's version number, or its major or minor version numbers, respectively.

          (version) => "1.3a"
          (major-version) => "1"
          (minor-version) => "3a"

 -- primitive: libguile-config-stamp
     Return a string describing the date on which libguile was configured.  This is used to determine whether the Guile core interpreter and the ice-9 runtime have grown out of date with one another.

 -- primitive: %package-data-dir
     Return the name of the directory where Scheme packages, modules and libraries are kept.  On most Unix systems, this will be /usr/local/share/guile.

 -- Variable: %load-path
     Return the list of directories which should be searched for Scheme modules and libraries.

Internal Debugging Interface
****************************

--- The name of this chapter needs to clearly distinguish it from the appendix describing the debugger UI.  The intro should have a pointer to the UI appendix.