guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 02/02: Merge api-{data,compound}.texi


From: Andy Wingo
Subject: [Guile-commits] 02/02: Merge api-{data,compound}.texi
Date: Tue, 22 Nov 2016 22:12:56 +0000 (UTC)

wingo pushed a commit to branch master
in repository guile.

commit 8b5f323330b0dcab0f48579a89a60f9a7cab1c64
Author: Andy Wingo <address@hidden>
Date:   Tue Nov 22 23:11:37 2016 +0100

    Merge api-{data,compound}.texi
    
    * doc/ref/api-compound.texi: Remove.
    * doc/ref/api-data.texi: Fold "Compound Data Types" and "Simple Data
      Types" into just "Data Types".  The distinction didn't work.
    * doc/ref/guile.texi:
    * doc/ref/Makefile.am:
    * doc/ref/srfi-modules.texi: Adapt.
---
 doc/ref/Makefile.am       |    1 -
 doc/ref/api-compound.texi | 4022 -----------------------------
 doc/ref/api-data.texi     | 6282 ++++++++++++++++++++++++++++++++++++---------
 doc/ref/guile.texi        |    4 +-
 doc/ref/srfi-modules.texi |    4 +-
 5 files changed, 5128 insertions(+), 5185 deletions(-)

diff --git a/doc/ref/Makefile.am b/doc/ref/Makefile.am
index ada4f36..05393cd 100644
--- a/doc/ref/Makefile.am
+++ b/doc/ref/Makefile.am
@@ -75,7 +75,6 @@ guile_TEXINFOS = preface.texi                 \
                 r6rs.texi                      \
                 match.texi                     \
                 misc-modules.texi              \
-                api-compound.texi              \
                 libguile-autoconf.texi         \
                 autoconf-macros.texi           \
                 tools.texi                     \
diff --git a/doc/ref/api-compound.texi b/doc/ref/api-compound.texi
deleted file mode 100644
index 8277b35..0000000
--- a/doc/ref/api-compound.texi
+++ /dev/null
@@ -1,4022 +0,0 @@
address@hidden -*-texinfo-*-
address@hidden This is part of the GNU Guile Reference Manual.
address@hidden Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 
2006, 2007,
address@hidden   2009, 2010, 2011, 2012, 2013, 2014  Free Software Foundation, 
Inc.
address@hidden See the file guile.texi for copying conditions.
-
address@hidden Compound Data Types
address@hidden Compound Data Types
-
-This chapter describes Guile's compound data types.  By @dfn{compound}
-we mean that the primary purpose of these data types is to act as
-containers for other kinds of data (including other compound objects).
-For instance, a (non-uniform) vector with length 5 is a container that
-can hold five arbitrary Scheme objects.
-
-The various kinds of container object differ from each other in how
-their memory is allocated, how they are indexed, and how particular
-values can be looked up within them.
-
address@hidden
-* Pairs::                       Scheme's basic building block.
-* Lists::                       Special list functions supported by Guile.
-* Vectors::                     One-dimensional arrays of Scheme objects.
-* Bit Vectors::                 Vectors of bits.
-* Arrays::                      Matrices, etc.
-* VLists::                      Vector-like lists.
-* Record Overview::             Walking through the maze of record APIs.
-* SRFI-9 Records::              The standard, recommended record API.
-* Records::                     Guile's historical record API.
-* Structures::                  Low-level record representation.
-* Dictionary Types::            About dictionary types in general.
-* Association Lists::           List-based dictionaries.
-* VHashes::                     VList-based dictionaries.   
-* Hash Tables::                 Table-based dictionaries.
address@hidden menu
-
-
address@hidden Pairs
address@hidden Pairs
address@hidden Pairs
-
-Pairs are used to combine two Scheme objects into one compound object.
-Hence the name: A pair stores a pair of objects.
-
-The data type @dfn{pair} is extremely important in Scheme, just like in
-any other Lisp dialect.  The reason is that pairs are not only used to
-make two values available as one object, but that pairs are used for
-constructing lists of values.  Because lists are so important in Scheme,
-they are described in a section of their own (@pxref{Lists}).
-
-Pairs can literally get entered in source code or at the REPL, in the
-so-called @dfn{dotted list} syntax.  This syntax consists of an opening
-parentheses, the first element of the pair, a dot, the second element
-and a closing parentheses.  The following example shows how a pair
-consisting of the two numbers 1 and 2, and a pair containing the symbols
address@hidden and @code{bar} can be entered.  It is very important to write
-the whitespace before and after the dot, because otherwise the Scheme
-parser would not be able to figure out where to split the tokens.
-
address@hidden
-(1 . 2)
-(foo . bar)
address@hidden lisp
-
-But beware, if you want to try out these examples, you have to
address@hidden the expressions.  More information about quotation is
-available in the section @ref{Expression Syntax}.  The correct way
-to try these examples is as follows.
-
address@hidden
-'(1 . 2)
address@hidden
-(1 . 2)
-'(foo . bar)
address@hidden
-(foo . bar)
address@hidden lisp
-
-A new pair is made by calling the procedure @code{cons} with two
-arguments.  Then the argument values are stored into a newly allocated
-pair, and the pair is returned.  The name @code{cons} stands for
-"construct".  Use the procedure @code{pair?} to test whether a
-given Scheme object is a pair or not.
-
address@hidden cons
address@hidden {Scheme Procedure} cons x y
address@hidden {C Function} scm_cons (x, y)
-Return a newly allocated pair whose car is @var{x} and whose
-cdr is @var{y}.  The pair is guaranteed to be different (in the
-sense of @code{eq?}) from every previously existing object.
address@hidden deffn
-
address@hidden pair?
address@hidden {Scheme Procedure} pair? x
address@hidden {C Function} scm_pair_p (x)
-Return @code{#t} if @var{x} is a pair; otherwise return
address@hidden
address@hidden deffn
-
address@hidden {C Function} int scm_is_pair (SCM x)
-Return 1 when @var{x} is a pair; otherwise return 0.
address@hidden deftypefn
-
-The two parts of a pair are traditionally called @dfn{car} and
address@hidden  They can be retrieved with procedures of the same name
-(@code{car} and @code{cdr}), and can be modified with the procedures
address@hidden and @code{set-cdr!}.
-
-Since a very common operation in Scheme programs is to access the car of
-a car of a pair, or the car of the cdr of a pair, etc., the procedures
-called @code{caar}, @code{cadr} and so on are also predefined.  However,
-using these procedures is often detrimental to readability, and
-error-prone.  Thus, accessing the contents of a list is usually better
-achieved using pattern matching techniques (@pxref{Pattern Matching}).
-
address@hidden car
address@hidden cdr
address@hidden {Scheme Procedure} car pair
address@hidden {Scheme Procedure} cdr pair
address@hidden {C Function} scm_car (pair)
address@hidden {C Function} scm_cdr (pair)
-Return the car or the cdr of @var{pair}, respectively.
address@hidden deffn
-
address@hidden  {C Macro} SCM SCM_CAR (SCM pair)
address@hidden {C Macro} SCM SCM_CDR (SCM pair)
-These two macros are the fastest way to access the car or cdr of a
-pair; they can be thought of as compiling into a single memory
-reference.
-
-These macros do no checking at all.  The argument @var{pair} must be a
-valid pair.
address@hidden deftypefn
-
address@hidden  {Scheme Procedure} cddr pair
address@hidden {Scheme Procedure} cdar pair
address@hidden {Scheme Procedure} cadr pair
address@hidden {Scheme Procedure} caar pair
address@hidden {Scheme Procedure} cdddr pair
address@hidden {Scheme Procedure} cddar pair
address@hidden {Scheme Procedure} cdadr pair
address@hidden {Scheme Procedure} cdaar pair
address@hidden {Scheme Procedure} caddr pair
address@hidden {Scheme Procedure} cadar pair
address@hidden {Scheme Procedure} caadr pair
address@hidden {Scheme Procedure} caaar pair
address@hidden {Scheme Procedure} cddddr pair
address@hidden {Scheme Procedure} cdddar pair
address@hidden {Scheme Procedure} cddadr pair
address@hidden {Scheme Procedure} cddaar pair
address@hidden {Scheme Procedure} cdaddr pair
address@hidden {Scheme Procedure} cdadar pair
address@hidden {Scheme Procedure} cdaadr pair
address@hidden {Scheme Procedure} cdaaar pair
address@hidden {Scheme Procedure} cadddr pair
address@hidden {Scheme Procedure} caddar pair
address@hidden {Scheme Procedure} cadadr pair
address@hidden {Scheme Procedure} cadaar pair
address@hidden {Scheme Procedure} caaddr pair
address@hidden {Scheme Procedure} caadar pair
address@hidden {Scheme Procedure} caaadr pair
address@hidden {Scheme Procedure} caaaar pair
address@hidden {C Function} scm_cddr (pair)
address@hidden {C Function} scm_cdar (pair)
address@hidden {C Function} scm_cadr (pair)
address@hidden {C Function} scm_caar (pair)
address@hidden {C Function} scm_cdddr (pair)
address@hidden {C Function} scm_cddar (pair)
address@hidden {C Function} scm_cdadr (pair)
address@hidden {C Function} scm_cdaar (pair)
address@hidden {C Function} scm_caddr (pair)
address@hidden {C Function} scm_cadar (pair)
address@hidden {C Function} scm_caadr (pair)
address@hidden {C Function} scm_caaar (pair)
address@hidden {C Function} scm_cddddr (pair)
address@hidden {C Function} scm_cdddar (pair)
address@hidden {C Function} scm_cddadr (pair)
address@hidden {C Function} scm_cddaar (pair)
address@hidden {C Function} scm_cdaddr (pair)
address@hidden {C Function} scm_cdadar (pair)
address@hidden {C Function} scm_cdaadr (pair)
address@hidden {C Function} scm_cdaaar (pair)
address@hidden {C Function} scm_cadddr (pair)
address@hidden {C Function} scm_caddar (pair)
address@hidden {C Function} scm_cadadr (pair)
address@hidden {C Function} scm_cadaar (pair)
address@hidden {C Function} scm_caaddr (pair)
address@hidden {C Function} scm_caadar (pair)
address@hidden {C Function} scm_caaadr (pair)
address@hidden {C Function} scm_caaaar (pair)
-These procedures are compositions of @code{car} and @code{cdr}, where
-for example @code{caddr} could be defined by
-
address@hidden
-(define caddr (lambda (x) (car (cdr (cdr x)))))
address@hidden lisp
-
address@hidden, @code{caddr} and @code{cadddr} pick out the second, third
-or fourth elements of a list, respectively.  SRFI-1 provides the same
-under the names @code{second}, @code{third} and @code{fourth}
-(@pxref{SRFI-1 Selectors}).
address@hidden deffn
-
address@hidden set-car!
address@hidden {Scheme Procedure} set-car! pair value
address@hidden {C Function} scm_set_car_x (pair, value)
-Stores @var{value} in the car field of @var{pair}.  The value returned
-by @code{set-car!} is unspecified.
address@hidden deffn
-
address@hidden set-cdr!
address@hidden {Scheme Procedure} set-cdr! pair value
address@hidden {C Function} scm_set_cdr_x (pair, value)
-Stores @var{value} in the cdr field of @var{pair}.  The value returned
-by @code{set-cdr!} is unspecified.
address@hidden deffn
-
-
address@hidden Lists
address@hidden Lists
address@hidden Lists
-
-A very important data type in Scheme---as well as in all other Lisp
-dialects---is the data type @address@hidden speaking,
-Scheme does not have a real datatype @dfn{list}.  Lists are made up of
address@hidden pairs}, and only exist by definition---a list is a chain
-of pairs which looks like a list.}
-
-This is the short definition of what a list is:
-
address@hidden @bullet
address@hidden
-Either the empty list @code{()},
-
address@hidden
-or a pair which has a list in its cdr.
address@hidden itemize
-
address@hidden FIXME::martin: Describe the pair chaining in more detail.
-
address@hidden FIXME::martin: What is a proper, what an improper list?
address@hidden What is a circular list?
-
address@hidden FIXME::martin: Maybe steal some graphics from the Elisp 
reference 
address@hidden manual?
-
address@hidden
-* List Syntax::                 Writing literal lists.
-* List Predicates::             Testing lists.
-* List Constructors::           Creating new lists.
-* List Selection::              Selecting from lists, getting their length.
-* Append/Reverse::              Appending and reversing lists.
-* List Modification::           Modifying existing lists.
-* List Searching::              Searching for list elements
-* List Mapping::                Applying procedures to lists.
address@hidden menu
-
address@hidden List Syntax
address@hidden List Read Syntax
-
-The syntax for lists is an opening parentheses, then all the elements of
-the list (separated by whitespace) and finally a closing
address@hidden that there is no separation character between
-the list elements, like a comma or a semicolon.}.
-
address@hidden
-(1 2 3)            ; @r{a list of the numbers 1, 2 and 3}
-("foo" bar 3.1415) ; @r{a string, a symbol and a real number}
-()                 ; @r{the empty list}
address@hidden lisp
-
-The last example needs a bit more explanation.  A list with no elements,
-called the @dfn{empty list}, is special in some ways.  It is used for
-terminating lists by storing it into the cdr of the last pair that makes
-up a list.  An example will clear that up:
-
address@hidden
-(car '(1))
address@hidden
-1
-(cdr '(1))
address@hidden
-()
address@hidden lisp
-
-This example also shows that lists have to be quoted when written
-(@pxref{Expression Syntax}), because they would otherwise be
-mistakingly taken as procedure applications (@pxref{Simple
-Invocation}).
-
-
address@hidden List Predicates
address@hidden List Predicates
-
-Often it is useful to test whether a given Scheme object is a list or
-not.  List-processing procedures could use this information to test
-whether their input is valid, or they could do different things
-depending on the datatype of their arguments.
-
address@hidden list?
address@hidden {Scheme Procedure} list? x
address@hidden {C Function} scm_list_p (x)
-Return @code{#t} if @var{x} is a proper list, else @code{#f}.
address@hidden deffn
-
-The predicate @code{null?} is often used in list-processing code to
-tell whether a given list has run out of elements.  That is, a loop
-somehow deals with the elements of a list until the list satisfies
address@hidden  Then, the algorithm terminates.
-
address@hidden null?
address@hidden {Scheme Procedure} null? x
address@hidden {C Function} scm_null_p (x)
-Return @code{#t} if @var{x} is the empty list, else @code{#f}.
address@hidden deffn
-
address@hidden {C Function} int scm_is_null (SCM x)
-Return 1 when @var{x} is the empty list; otherwise return 0.
address@hidden deftypefn
-
-
address@hidden List Constructors
address@hidden List Constructors
-
-This section describes the procedures for constructing new lists.
address@hidden simply returns a list where the elements are the arguments,
address@hidden is similar, but the last argument is stored in the cdr of
-the last pair of the list.
-
address@hidden  C Function scm_list(rest) used to be documented here, but it's a
address@hidden  no-op since it does nothing but return the list the caller must
address@hidden  have already created.
address@hidden
address@hidden {Scheme Procedure} list elem @dots{}
address@hidden {C Function} scm_list_1 (elem1)
address@hidden {C Function} scm_list_2 (elem1, elem2)
address@hidden {C Function} scm_list_3 (elem1, elem2, elem3)
address@hidden {C Function} scm_list_4 (elem1, elem2, elem3, elem4)
address@hidden {C Function} scm_list_5 (elem1, elem2, elem3, elem4, elem5)
address@hidden {C Function} scm_list_n (elem1, @dots{}, elemN, 
@nicode{SCM_UNDEFINED})
address@hidden list
-Return a new list containing elements @var{elem} @enddots{}.
-
address@hidden takes a variable number of arguments, terminated by
-the special @code{SCM_UNDEFINED}.  That final @code{SCM_UNDEFINED} is
-not included in the list.  None of @var{elem} @dots{} can
-themselves be @code{SCM_UNDEFINED}, or @code{scm_list_n} will
-terminate at that point.
address@hidden deffn
-
address@hidden  C Function scm_cons_star(arg1,rest) used to be documented here,
address@hidden  but it's not really a useful interface, since it expects the
address@hidden  caller to have already consed up all but the first argument
address@hidden  already.
address@hidden
address@hidden {Scheme Procedure} cons* arg1 arg2 @dots{}
-Like @code{list}, but the last arg provides the tail of the
-constructed list, returning @code{(cons @var{arg1} (cons
address@hidden (cons @dots{} @var{argn})))}.  Requires at least one
-argument.  If given one argument, that argument is returned as
-result.  This function is called @code{list*} in some other
-Schemes and in Common LISP.
address@hidden deffn
-
address@hidden {Scheme Procedure} list-copy lst
address@hidden {C Function} scm_list_copy (lst)
-Return a (newly-created) copy of @var{lst}.
address@hidden deffn
-
address@hidden {Scheme Procedure} make-list n [init]
-Create a list containing of @var{n} elements, where each element is
-initialized to @var{init}.  @var{init} defaults to the empty list
address@hidden()} if not given.
address@hidden deffn
-
-Note that @code{list-copy} only makes a copy of the pairs which make up
-the spine of the lists.  The list elements are not copied, which means
-that modifying the elements of the new list also modifies the elements
-of the old list.  On the other hand, applying procedures like
address@hidden or @code{delv!} to the new list will not alter the old
-list.  If you also need to copy the list elements (making a deep copy),
-use the procedure @code{copy-tree} (@pxref{Copying}).
-
address@hidden List Selection
address@hidden List Selection
-
-These procedures are used to get some information about a list, or to
-retrieve one or more elements of a list.
-
address@hidden length
address@hidden {Scheme Procedure} length lst
address@hidden {C Function} scm_length (lst)
-Return the number of elements in list @var{lst}.
address@hidden deffn
-
address@hidden {Scheme Procedure} last-pair lst
address@hidden {C Function} scm_last_pair (lst)
-Return the last pair in @var{lst}, signalling an error if
address@hidden is circular.
address@hidden deffn
-
address@hidden list-ref
address@hidden {Scheme Procedure} list-ref list k
address@hidden {C Function} scm_list_ref (list, k)
-Return the @var{k}th element from @var{list}.
address@hidden deffn
-
address@hidden list-tail
address@hidden {Scheme Procedure} list-tail lst k
address@hidden {Scheme Procedure} list-cdr-ref lst k
address@hidden {C Function} scm_list_tail (lst, k)
-Return the "tail" of @var{lst} beginning with its @var{k}th element.
-The first element of the list is considered to be element 0.
-
address@hidden and @code{list-cdr-ref} are identical.  It may help to
-think of @code{list-cdr-ref} as accessing the @var{k}th cdr of the list,
-or returning the results of cdring @var{k} times down @var{lst}.
address@hidden deffn
-
address@hidden {Scheme Procedure} list-head lst k
address@hidden {C Function} scm_list_head (lst, k)
-Copy the first @var{k} elements from @var{lst} into a new list, and
-return it.
address@hidden deffn
-
address@hidden Append/Reverse
address@hidden Append and Reverse
-
address@hidden and @code{append!} are used to concatenate two or more
-lists in order to form a new list.  @code{reverse} and @code{reverse!}
-return lists with the same elements as their arguments, but in reverse
-order.  The procedure variants with an @code{!} directly modify the
-pairs which form the list, whereas the other procedures create new
-pairs.  This is why you should be careful when using the side-effecting
-variants.
-
address@hidden append
address@hidden {Scheme Procedure} append lst @dots{} obj
address@hidden {Scheme Procedure} append
address@hidden {Scheme Procedure} append! lst @dots{} obj
address@hidden {Scheme Procedure} append!
address@hidden {C Function} scm_append (lstlst)
address@hidden {C Function} scm_append_x (lstlst)
-Return a list comprising all the elements of lists @var{lst} @dots{}
address@hidden  If called with no arguments, return the empty list.
-
address@hidden
-(append '(x) '(y))          @result{}  (x y)
-(append '(a) '(b c d))      @result{}  (a b c d)
-(append '(a (b)) '((c)))    @result{}  (a (b) (c))
address@hidden lisp
-
-The last argument @var{obj} may actually be any object; an improper
-list results if the last argument is not a proper list.
-
address@hidden
-(append '(a b) '(c . d))    @result{}  (a b c . d)
-(append '() 'a)             @result{}  a
address@hidden lisp
-
address@hidden doesn't modify the given lists, but the return may share
-structure with the final @var{obj}.  @code{append!} is permitted, but
-not required, to modify the given lists to form its return.
-
-For @code{scm_append} and @code{scm_append_x}, @var{lstlst} is a list
-of the list operands @var{lst} @dots{} @var{obj}.  That @var{lstlst}
-itself is not modified or used in the return.
address@hidden deffn
-
address@hidden reverse
address@hidden {Scheme Procedure} reverse lst
address@hidden {Scheme Procedure} reverse! lst [newtail]
address@hidden {C Function} scm_reverse (lst)
address@hidden {C Function} scm_reverse_x (lst, newtail)
-Return a list comprising the elements of @var{lst}, in reverse order.
-
address@hidden constructs a new list.  @code{reverse!} is permitted, but
-not required, to modify @var{lst} in constructing its return.
-
-For @code{reverse!}, the optional @var{newtail} is appended to the
-result.  @var{newtail} isn't reversed, it simply becomes the list
-tail.  For @code{scm_reverse_x}, the @var{newtail} parameter is
-mandatory, but can be @code{SCM_EOL} if no further tail is required.
address@hidden deffn
-
address@hidden List Modification
address@hidden List Modification
-
-The following procedures modify an existing list, either by changing
-elements of the list, or by changing the list structure itself.
-
address@hidden {Scheme Procedure} list-set! list k val
address@hidden {C Function} scm_list_set_x (list, k, val)
-Set the @var{k}th element of @var{list} to @var{val}.
address@hidden deffn
-
address@hidden {Scheme Procedure} list-cdr-set! list k val
address@hidden {C Function} scm_list_cdr_set_x (list, k, val)
-Set the @var{k}th cdr of @var{list} to @var{val}.
address@hidden deffn
-
address@hidden {Scheme Procedure} delq item lst
address@hidden {C Function} scm_delq (item, lst)
-Return a newly-created copy of @var{lst} with elements
address@hidden to @var{item} removed.  This procedure mirrors
address@hidden: @code{delq} compares elements of @var{lst} against
address@hidden with @code{eq?}.
address@hidden deffn
-
address@hidden {Scheme Procedure} delv item lst
address@hidden {C Function} scm_delv (item, lst)
-Return a newly-created copy of @var{lst} with elements
address@hidden to @var{item} removed.  This procedure mirrors
address@hidden: @code{delv} compares elements of @var{lst} against
address@hidden with @code{eqv?}.
address@hidden deffn
-
address@hidden {Scheme Procedure} delete item lst
address@hidden {C Function} scm_delete (item, lst)
-Return a newly-created copy of @var{lst} with elements
address@hidden to @var{item} removed.  This procedure mirrors
address@hidden: @code{delete} compares elements of @var{lst}
-against @var{item} with @code{equal?}.
-
-See also SRFI-1 which has an extended @code{delete} (@ref{SRFI-1
-Deleting}), and also an @code{lset-difference} which can delete
-multiple @var{item}s in one call (@ref{SRFI-1 Set Operations}).
address@hidden deffn
-
address@hidden {Scheme Procedure} delq! item lst
address@hidden {Scheme Procedure} delv! item lst
address@hidden {Scheme Procedure} delete! item lst
address@hidden {C Function} scm_delq_x (item, lst)
address@hidden {C Function} scm_delv_x (item, lst)
address@hidden {C Function} scm_delete_x (item, lst)
-These procedures are destructive versions of @code{delq}, @code{delv}
-and @code{delete}: they modify the pointers in the existing @var{lst}
-rather than creating a new list.  Caveat evaluator: Like other
-destructive list functions, these functions cannot modify the binding of
address@hidden, and so cannot be used to delete the first element of
address@hidden destructively.
address@hidden deffn
-
address@hidden {Scheme Procedure} delq1! item lst
address@hidden {C Function} scm_delq1_x (item, lst)
-Like @code{delq!}, but only deletes the first occurrence of
address@hidden from @var{lst}.  Tests for equality using
address@hidden  See also @code{delv1!} and @code{delete1!}.
address@hidden deffn
-
address@hidden {Scheme Procedure} delv1! item lst
address@hidden {C Function} scm_delv1_x (item, lst)
-Like @code{delv!}, but only deletes the first occurrence of
address@hidden from @var{lst}.  Tests for equality using
address@hidden  See also @code{delq1!} and @code{delete1!}.
address@hidden deffn
-
address@hidden {Scheme Procedure} delete1! item lst
address@hidden {C Function} scm_delete1_x (item, lst)
-Like @code{delete!}, but only deletes the first occurrence of
address@hidden from @var{lst}.  Tests for equality using
address@hidden  See also @code{delq1!} and @code{delv1!}.
address@hidden deffn
-
address@hidden {Scheme Procedure} filter pred lst
address@hidden {Scheme Procedure} filter! pred lst
-Return a list containing all elements from @var{lst} which satisfy the
-predicate @var{pred}.  The elements in the result list have the same
-order as in @var{lst}.  The order in which @var{pred} is applied to
-the list elements is not specified.
-
address@hidden does not change @var{lst}, but the result may share a
-tail with it.  @code{filter!} may modify @var{lst} to construct its
-return.
address@hidden deffn
-
address@hidden List Searching
address@hidden List Searching
-
-The following procedures search lists for particular elements.  They use
-different comparison predicates for comparing list elements with the
-object to be searched.  When they fail, they return @code{#f}, otherwise
-they return the sublist whose car is equal to the search object, where
-equality depends on the equality predicate used.
-
address@hidden memq
address@hidden {Scheme Procedure} memq x lst
address@hidden {C Function} scm_memq (x, lst)
-Return the first sublist of @var{lst} whose car is @code{eq?}
-to @var{x} where the sublists of @var{lst} are the non-empty
-lists returned by @code{(list-tail @var{lst} @var{k})} for
address@hidden less than the length of @var{lst}.  If @var{x} does not
-occur in @var{lst}, then @code{#f} (not the empty list) is
-returned.
address@hidden deffn
-
address@hidden memv
address@hidden {Scheme Procedure} memv x lst
address@hidden {C Function} scm_memv (x, lst)
-Return the first sublist of @var{lst} whose car is @code{eqv?}
-to @var{x} where the sublists of @var{lst} are the non-empty
-lists returned by @code{(list-tail @var{lst} @var{k})} for
address@hidden less than the length of @var{lst}.  If @var{x} does not
-occur in @var{lst}, then @code{#f} (not the empty list) is
-returned.
address@hidden deffn
-
address@hidden member
address@hidden {Scheme Procedure} member x lst
address@hidden {C Function} scm_member (x, lst)
-Return the first sublist of @var{lst} whose car is
address@hidden to @var{x} where the sublists of @var{lst} are
-the non-empty lists returned by @code{(list-tail @var{lst}
address@hidden)} for @var{k} less than the length of @var{lst}.  If
address@hidden does not occur in @var{lst}, then @code{#f} (not the
-empty list) is returned.
-
-See also SRFI-1 which has an extended @code{member} function
-(@ref{SRFI-1 Searching}).
address@hidden deffn
-
-
address@hidden List Mapping
address@hidden List Mapping
-
-List processing is very convenient in Scheme because the process of
-iterating over the elements of a list can be highly abstracted.  The
-procedures in this section are the most basic iterating procedures for
-lists.  They take a procedure and one or more lists as arguments, and
-apply the procedure to each element of the list.  They differ in their
-return value.
-
address@hidden map
address@hidden begin (texi-doc-string "guile" "map")
address@hidden {Scheme Procedure} map proc arg1 arg2 @dots{}
address@hidden {Scheme Procedure} map-in-order proc arg1 arg2 @dots{}
address@hidden {C Function} scm_map (proc, arg1, args)
-Apply @var{proc} to each element of the list @var{arg1} (if only two
-arguments are given), or to the corresponding elements of the argument
-lists (if more than two arguments are given).  The result(s) of the
-procedure applications are saved and returned in a list.  For
address@hidden, the order of procedure applications is not specified,
address@hidden applies the procedure from left to right to the list
-elements.
address@hidden deffn
-
address@hidden for-each
address@hidden begin (texi-doc-string "guile" "for-each")
address@hidden {Scheme Procedure} for-each proc arg1 arg2 @dots{}
-Like @code{map}, but the procedure is always applied from left to right,
-and the result(s) of the procedure applications are thrown away.  The
-return value is not specified.
address@hidden deffn
-
-See also SRFI-1 which extends these functions to take lists of unequal
-lengths (@ref{SRFI-1 Fold and Map}).
-
address@hidden Vectors
address@hidden Vectors
address@hidden Vectors
-
-Vectors are sequences of Scheme objects.  Unlike lists, the length of a
-vector, once the vector is created, cannot be changed.  The advantage of
-vectors over lists is that the time required to access one element of a vector
-given its @dfn{position} (synonymous with @dfn{index}), a zero-origin number,
-is constant, whereas lists have an access time linear to the position of the
-accessed element in the list.
-
-Vectors can contain any kind of Scheme object; it is even possible to
-have different types of objects in the same vector.  For vectors
-containing vectors, you may wish to use arrays, instead.  Note, too,
-that vectors are the special case of one dimensional non-uniform arrays
-and that most array procedures operate happily on vectors
-(@pxref{Arrays}).
-
-Also see @ref{SRFI-43}, for a comprehensive vector library.
-
address@hidden
-* Vector Syntax::               Read syntax for vectors.
-* Vector Creation::             Dynamic vector creation and validation.
-* Vector Accessors::            Accessing and modifying vector contents.
-* Vector Accessing from C::     Ways to work with vectors from C.
-* Uniform Numeric Vectors::     Vectors of unboxed numeric values.
address@hidden menu
-
-
address@hidden Vector Syntax
address@hidden Read Syntax for Vectors
-
-Vectors can literally be entered in source code, just like strings,
-characters or some of the other data types.  The read syntax for vectors
-is as follows: A sharp sign (@code{#}), followed by an opening
-parentheses, all elements of the vector in their respective read syntax,
-and finally a closing parentheses.  Like strings, vectors do not have to
-be quoted.
-
-The following are examples of the read syntax for vectors; where the
-first vector only contains numbers and the second three different object
-types: a string, a symbol and a number in hexadecimal notation.
-
address@hidden
-#(1 2 3)
-#("Hello" foo #xdeadbeef)
address@hidden lisp
-
address@hidden Vector Creation
address@hidden Dynamic Vector Creation and Validation
-
-Instead of creating a vector implicitly by using the read syntax just
-described, you can create a vector dynamically by calling one of the
address@hidden and @code{list->vector} primitives with the list of Scheme
-values that you want to place into a vector.  The size of the vector
-thus created is determined implicitly by the number of arguments given.
-
address@hidden vector
address@hidden list->vector
address@hidden {Scheme Procedure} vector arg @dots{}
address@hidden {Scheme Procedure} list->vector l
address@hidden {C Function} scm_vector (l)
-Return a newly allocated vector composed of the
-given arguments.  Analogous to @code{list}.
-
address@hidden
-(vector 'a 'b 'c) @result{} #(a b c)
address@hidden lisp
address@hidden deffn
-
-The inverse operation is @code{vector->list}:
-
address@hidden vector->list
address@hidden {Scheme Procedure} vector->list v
address@hidden {C Function} scm_vector_to_list (v)
-Return a newly allocated list composed of the elements of @var{v}.
-
address@hidden
-(vector->list #(dah dah didah)) @result{}  (dah dah didah)
-(list->vector '(dididit dah)) @result{}  #(dididit dah)
address@hidden lisp
address@hidden deffn
-
-To allocate a vector with an explicitly specified size, use
address@hidden  With this primitive you can also specify an initial
-value for the vector elements (the same value for all elements, that
-is):
-
address@hidden make-vector
address@hidden {Scheme Procedure} make-vector len [fill]
address@hidden {C Function} scm_make_vector (len, fill)
-Return a newly allocated vector of @var{len} elements.  If a
-second argument is given, then each position is initialized to
address@hidden  Otherwise the initial contents of each position is
-unspecified.
address@hidden deffn
-
address@hidden {C Function} SCM scm_c_make_vector (size_t k, SCM fill)
-Like @code{scm_make_vector}, but the length is given as a @code{size_t}.
address@hidden deftypefn
-
-To check whether an arbitrary Scheme value @emph{is} a vector, use the
address@hidden primitive:
-
address@hidden vector?
address@hidden {Scheme Procedure} vector? obj
address@hidden {C Function} scm_vector_p (obj)
-Return @code{#t} if @var{obj} is a vector, otherwise return
address@hidden
address@hidden deffn
-
address@hidden {C Function} int scm_is_vector (SCM obj)
-Return non-zero when @var{obj} is a vector, otherwise return
address@hidden
address@hidden deftypefn
-
address@hidden Vector Accessors
address@hidden Accessing and Modifying Vector Contents
-
address@hidden and @code{vector-ref} return information about a
-given vector, respectively its size and the elements that are contained
-in the vector.
-
address@hidden vector-length
address@hidden {Scheme Procedure} vector-length vector
address@hidden {C Function} scm_vector_length (vector)
-Return the number of elements in @var{vector} as an exact integer.
address@hidden deffn
-
address@hidden {C Function} size_t scm_c_vector_length (SCM vec)
-Return the number of elements in @var{vec} as a @code{size_t}.
address@hidden deftypefn
-
address@hidden vector-ref
address@hidden {Scheme Procedure} vector-ref vec k
address@hidden {C Function} scm_vector_ref (vec, k)
-Return the contents of position @var{k} of @var{vec}.
address@hidden must be a valid index of @var{vec}.
address@hidden
-(vector-ref #(1 1 2 3 5 8 13 21) 5) @result{} 8
-(vector-ref #(1 1 2 3 5 8 13 21)
-    (let ((i (round (* 2 (acos -1)))))
-      (if (inexact? i)
-        (inexact->exact i)
-           i))) @result{} 13
address@hidden lisp
address@hidden deffn
-
address@hidden {C Function} SCM scm_c_vector_ref (SCM vec, size_t k)
-Return the contents of position @var{k} (a @code{size_t}) of
address@hidden
address@hidden deftypefn
-
-A vector created by one of the dynamic vector constructor procedures
-(@pxref{Vector Creation}) can be modified using the following
-procedures.
-
address@hidden:} According to R5RS, it is an error to use any of these
-procedures on a literally read vector, because such vectors should be
-considered as constants.  Currently, however, Guile does not detect this
-error.
-
address@hidden vector-set!
address@hidden {Scheme Procedure} vector-set! vec k obj
address@hidden {C Function} scm_vector_set_x (vec, k, obj)
-Store @var{obj} in position @var{k} of @var{vec}.
address@hidden must be a valid index of @var{vec}.
-The value returned by @samp{vector-set!} is unspecified.
address@hidden
-(let ((vec (vector 0 '(2 2 2 2) "Anna")))
-  (vector-set! vec 1 '("Sue" "Sue"))
-  vec) @result{}  #(0 ("Sue" "Sue") "Anna")
address@hidden lisp
address@hidden deffn
-
address@hidden {C Function} void scm_c_vector_set_x (SCM vec, size_t k, SCM obj)
-Store @var{obj} in position @var{k} (a @code{size_t}) of @var{vec}.
address@hidden deftypefn
-
address@hidden vector-fill!
address@hidden {Scheme Procedure} vector-fill! vec fill
address@hidden {C Function} scm_vector_fill_x (vec, fill)
-Store @var{fill} in every position of @var{vec}.  The value
-returned by @code{vector-fill!} is unspecified.
address@hidden deffn
-
address@hidden {Scheme Procedure} vector-copy vec
address@hidden {C Function} scm_vector_copy (vec)
-Return a copy of @var{vec}.
address@hidden deffn
-
address@hidden {Scheme Procedure} vector-move-left! vec1 start1 end1 vec2 start2
address@hidden {C Function} scm_vector_move_left_x (vec1, start1, end1, vec2, 
start2)
-Copy elements from @var{vec1}, positions @var{start1} to @var{end1},
-to @var{vec2} starting at position @var{start2}.  @var{start1} and
address@hidden are inclusive indices; @var{end1} is exclusive.
-
address@hidden copies elements in leftmost order.
-Therefore, in the case where @var{vec1} and @var{vec2} refer to the
-same vector, @code{vector-move-left!} is usually appropriate when
address@hidden is greater than @var{start2}.
address@hidden deffn
-
address@hidden {Scheme Procedure} vector-move-right! vec1 start1 end1 vec2 
start2
address@hidden {C Function} scm_vector_move_right_x (vec1, start1, end1, vec2, 
start2)
-Copy elements from @var{vec1}, positions @var{start1} to @var{end1},
-to @var{vec2} starting at position @var{start2}.  @var{start1} and
address@hidden are inclusive indices; @var{end1} is exclusive.
-
address@hidden copies elements in rightmost order.
-Therefore, in the case where @var{vec1} and @var{vec2} refer to the
-same vector, @code{vector-move-right!} is usually appropriate when
address@hidden is less than @var{start2}.
address@hidden deffn
-
address@hidden Vector Accessing from C
address@hidden Vector Accessing from C
-
-A vector can be read and modified from C with the functions
address@hidden and @code{scm_c_vector_set_x}, for example.  In
-addition to these functions, there are two more ways to access vectors
-from C that might be more efficient in certain situations: you can
-restrict yourself to @dfn{simple vectors} and then use the very fast
address@hidden vector macros}; or you can use the very general framework
-for accessing all kinds of arrays (@pxref{Accessing Arrays from C}),
-which is more verbose, but can deal efficiently with all kinds of
-vectors (and arrays).  For vectors, you can use the
address@hidden and @code{scm_vector_writable_elements}
-functions as shortcuts.
-
address@hidden {C Function} int scm_is_simple_vector (SCM obj)
-Return non-zero if @var{obj} is a simple vector, else return zero.  A
-simple vector is a vector that can be used with the @code{SCM_SIMPLE_*}
-macros below.
-
-The following functions are guaranteed to return simple vectors:
address@hidden, @code{scm_c_make_vector}, @code{scm_vector},
address@hidden
address@hidden deftypefn
-
address@hidden {C Macro} size_t SCM_SIMPLE_VECTOR_LENGTH (SCM vec)
-Evaluates to the length of the simple vector @var{vec}.  No type
-checking is done.
address@hidden deftypefn
-
address@hidden {C Macro} SCM SCM_SIMPLE_VECTOR_REF (SCM vec, size_t idx)
-Evaluates to the element at position @var{idx} in the simple vector
address@hidden  No type or range checking is done.
address@hidden deftypefn
-
address@hidden {C Macro} void SCM_SIMPLE_VECTOR_SET (SCM vec, size_t idx, SCM 
val)
-Sets the element at position @var{idx} in the simple vector
address@hidden to @var{val}.  No type or range checking is done.
address@hidden deftypefn
-
address@hidden {C Function} {const SCM *} scm_vector_elements (SCM vec, 
scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
-Acquire a handle for the vector @var{vec} and return a pointer to the
-elements of it.  This pointer can only be used to read the elements of
address@hidden  When @var{vec} is not a vector, an error is signaled.  The
-handle must eventually be released with
address@hidden
-
-The variables pointed to by @var{lenp} and @var{incp} are filled with
-the number of elements of the vector and the increment (number of
-elements) between successive elements, respectively.  Successive
-elements of @var{vec} need not be contiguous in their underlying
-``root vector'' returned here; hence the increment is not necessarily
-equal to 1 and may well be negative too (@pxref{Shared Arrays}).
-
-The following example shows the typical way to use this function.  It
-creates a list of all elements of @var{vec} (in reverse order).
-
address@hidden
-scm_t_array_handle handle;
-size_t i, len;
-ssize_t inc;
-const SCM *elt;
-SCM list;
-
-elt = scm_vector_elements (vec, &handle, &len, &inc);
-list = SCM_EOL;
-for (i = 0; i < len; i++, elt += inc)
-  list = scm_cons (*elt, list);
-scm_array_handle_release (&handle);
address@hidden example
-
address@hidden deftypefn
-
address@hidden {C Function} {SCM *} scm_vector_writable_elements (SCM vec, 
scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
-Like @code{scm_vector_elements} but the pointer can be used to modify
-the vector.
-
-The following example shows the typical way to use this function.  It
-fills a vector with @code{#t}.
-
address@hidden
-scm_t_array_handle handle;
-size_t i, len;
-ssize_t inc;
-SCM *elt;
-
-elt = scm_vector_writable_elements (vec, &handle, &len, &inc);
-for (i = 0; i < len; i++, elt += inc)
-  *elt = SCM_BOOL_T;
-scm_array_handle_release (&handle);
address@hidden example
-
address@hidden deftypefn
-
address@hidden Uniform Numeric Vectors
address@hidden Uniform Numeric Vectors
-
-A uniform numeric vector is a vector whose elements are all of a single
-numeric type.  Guile offers uniform numeric vectors for signed and
-unsigned 8-bit, 16-bit, 32-bit, and 64-bit integers, two sizes of
-floating point values, and complex floating-point numbers of these two
-sizes. @xref{SRFI-4}, for more information.
-
-For many purposes, bytevectors work just as well as uniform vectors, and have
-the advantage that they integrate well with binary input and output.
address@hidden, for more information on bytevectors.
-
address@hidden Bit Vectors
address@hidden Bit Vectors
-
address@hidden
-Bit vectors are zero-origin, one-dimensional arrays of booleans.  They
-are displayed as a sequence of @code{0}s and @code{1}s prefixed by
address@hidden, e.g.,
-
address@hidden
-(make-bitvector 8 #f) @result{}
-#*00000000
address@hidden example
-
-Bit vectors are the special case of one dimensional bit arrays, and can
-thus be used with the array procedures, @xref{Arrays}.
-
address@hidden {Scheme Procedure} bitvector? obj
address@hidden {C Function} scm_bitvector_p (obj)
-Return @code{#t} when @var{obj} is a bitvector, else
-return @code{#f}.
address@hidden deffn
-
address@hidden {C Function} int scm_is_bitvector (SCM obj)
-Return @code{1} when @var{obj} is a bitvector, else return @code{0}.
address@hidden deftypefn
-
address@hidden {Scheme Procedure} make-bitvector len [fill]
address@hidden {C Function} scm_make_bitvector (len, fill)
-Create a new bitvector of length @var{len} and
-optionally initialize all elements to @var{fill}.
address@hidden deffn
-
address@hidden {C Function} SCM scm_c_make_bitvector (size_t len, SCM fill)
-Like @code{scm_make_bitvector}, but the length is given as a
address@hidden
address@hidden deftypefn
-
address@hidden {Scheme Procedure} bitvector bit @dots{}
address@hidden {C Function} scm_bitvector (bits)
-Create a new bitvector with the arguments as elements.
address@hidden deffn
-
address@hidden {Scheme Procedure} bitvector-length vec
address@hidden {C Function} scm_bitvector_length (vec)
-Return the length of the bitvector @var{vec}.
address@hidden deffn
-
address@hidden {C Function} size_t scm_c_bitvector_length (SCM vec)
-Like @code{scm_bitvector_length}, but the length is returned as a
address@hidden
address@hidden deftypefn
-
address@hidden {Scheme Procedure} bitvector-ref vec idx
address@hidden {C Function} scm_bitvector_ref (vec, idx)
-Return the element at index @var{idx} of the bitvector
address@hidden
address@hidden deffn
-
address@hidden {C Function} SCM scm_c_bitvector_ref (SCM vec, size_t idx)
-Return the element at index @var{idx} of the bitvector
address@hidden
address@hidden deftypefn
-
address@hidden {Scheme Procedure} bitvector-set! vec idx val
address@hidden {C Function} scm_bitvector_set_x (vec, idx, val)
-Set the element at index @var{idx} of the bitvector
address@hidden when @var{val} is true, else clear it.
address@hidden deffn
-
address@hidden {C Function} SCM scm_c_bitvector_set_x (SCM vec, size_t idx, SCM 
val)
-Set the element at index @var{idx} of the bitvector
address@hidden when @var{val} is true, else clear it.
address@hidden deftypefn
-
address@hidden {Scheme Procedure} bitvector-fill! vec val
address@hidden {C Function} scm_bitvector_fill_x (vec, val)
-Set all elements of the bitvector
address@hidden when @var{val} is true, else clear them.
address@hidden deffn
-
address@hidden {Scheme Procedure} list->bitvector list
address@hidden {C Function} scm_list_to_bitvector (list)
-Return a new bitvector initialized with the elements
-of @var{list}.
address@hidden deffn
-
address@hidden {Scheme Procedure} bitvector->list vec
address@hidden {C Function} scm_bitvector_to_list (vec)
-Return a new list initialized with the elements
-of the bitvector @var{vec}.
address@hidden deffn
-
address@hidden {Scheme Procedure} bit-count bool bitvector
address@hidden {C Function} scm_bit_count (bool, bitvector)
-Return a count of how many entries in @var{bitvector} are equal to
address@hidden  For example,
-
address@hidden
-(bit-count #f #*000111000)  @result{} 6
address@hidden example
address@hidden deffn
-
address@hidden {Scheme Procedure} bit-position bool bitvector start
address@hidden {C Function} scm_bit_position (bool, bitvector, start)
-Return the index of the first occurrence of @var{bool} in
address@hidden, starting from @var{start}.  If there is no @var{bool}
-entry between @var{start} and the end of @var{bitvector}, then return
address@hidden  For example,
-
address@hidden
-(bit-position #t #*000101 0)  @result{} 3
-(bit-position #f #*0001111 3) @result{} #f
address@hidden example
address@hidden deffn
-
address@hidden {Scheme Procedure} bit-invert! bitvector
address@hidden {C Function} scm_bit_invert_x (bitvector)
-Modify @var{bitvector} by replacing each element with its negation.
address@hidden deffn
-
address@hidden {Scheme Procedure} bit-set*! bitvector uvec bool
address@hidden {C Function} scm_bit_set_star_x (bitvector, uvec, bool)
-Set entries of @var{bitvector} to @var{bool}, with @var{uvec}
-selecting the entries to change.  The return value is unspecified.
-
-If @var{uvec} is a bit vector, then those entries where it has
address@hidden are the ones in @var{bitvector} which are set to @var{bool}.
address@hidden and @var{bitvector} must be the same length.  When
address@hidden is @code{#t} it's like @var{uvec} is OR'ed into
address@hidden  Or when @var{bool} is @code{#f} it can be seen as an
-ANDNOT.
-
address@hidden
-(define bv #*01000010)
-(bit-set*! bv #*10010001 #t)
-bv
address@hidden #*11010011
address@hidden example
-
-If @var{uvec} is a uniform vector of unsigned long integers, then
-they're indexes into @var{bitvector} which are set to @var{bool}.  
-
address@hidden
-(define bv #*01000010)
-(bit-set*! bv #u(5 2 7) #t)
-bv
address@hidden #*01100111
address@hidden example
address@hidden deffn
-
address@hidden {Scheme Procedure} bit-count* bitvector uvec bool
address@hidden {C Function} scm_bit_count_star (bitvector, uvec, bool)
-Return a count of how many entries in @var{bitvector} are equal to
address@hidden, with @var{uvec} selecting the entries to consider.
-
address@hidden is interpreted in the same way as for @code{bit-set*!}
-above.  Namely, if @var{uvec} is a bit vector then entries which have
address@hidden there are considered in @var{bitvector}.  Or if @var{uvec}
-is a uniform vector of unsigned long integers then it's the indexes in
address@hidden to consider.
-
-For example,
-
address@hidden
-(bit-count* #*01110111 #*11001101 #t) @result{} 3
-(bit-count* #*01110111 #u32(7 0 4) #f)  @result{} 2
address@hidden example
address@hidden deffn
-
address@hidden {C Function} {const scm_t_uint32 *} scm_bitvector_elements (SCM 
vec, scm_t_array_handle *handle, size_t *offp, size_t *lenp, ssize_t *incp)
-Like @code{scm_vector_elements} (@pxref{Vector Accessing from C}), but
-for bitvectors.  The variable pointed to by @var{offp} is set to the
-value returned by @code{scm_array_handle_bit_elements_offset}.  See
address@hidden for how to use the returned
-pointer and the offset.
address@hidden deftypefn
-
address@hidden {C Function} {scm_t_uint32 *} scm_bitvector_writable_elements 
(SCM vec, scm_t_array_handle *handle, size_t *offp, size_t *lenp, ssize_t *incp)
-Like @code{scm_bitvector_elements}, but the pointer is good for reading
-and writing.
address@hidden deftypefn
-
address@hidden Arrays
address@hidden Arrays
address@hidden Arrays
-
address@hidden are a collection of cells organized into an arbitrary
-number of dimensions.  Each cell can be accessed in constant time by
-supplying an index for each dimension.
-
-In the current implementation, an array uses a vector of some kind for
-the actual storage of its elements.  Any kind of vector will do, so you
-can have arrays of uniform numeric values, arrays of characters, arrays
-of bits, and of course, arrays of arbitrary Scheme values.  For example,
-arrays with an underlying @code{c64vector} might be nice for digital
-signal processing, while arrays made from a @code{u8vector} might be
-used to hold gray-scale images.
-
-The number of dimensions of an array is called its @dfn{rank}.  Thus,
-a matrix is an array of rank 2, while a vector has rank 1.  When
-accessing an array element, you have to specify one exact integer for
-each dimension.  These integers are called the @dfn{indices} of the
-element.  An array specifies the allowed range of indices for each
-dimension via an inclusive lower and upper bound.  These bounds can
-well be negative, but the upper bound must be greater than or equal to
-the lower bound minus one.  When all lower bounds of an array are
-zero, it is called a @dfn{zero-origin} array.
-
-Arrays can be of rank 0, which could be interpreted as a scalar.
-Thus, a zero-rank array can store exactly one object and the list of
-indices of this element is the empty list.
-
-Arrays contain zero elements when one of their dimensions has a zero
-length.  These empty arrays maintain information about their shape: a
-matrix with zero columns and 3 rows is different from a matrix with 3
-columns and zero rows, which again is different from a vector of
-length zero.
-
-The array procedures are all polymorphic, treating strings, uniform
-numeric vectors, bytevectors, bit vectors and ordinary vectors as one
-dimensional arrays.
-
address@hidden
-* Array Syntax::                
-* Array Procedures::            
-* Shared Arrays::               
-* Accessing Arrays from C::     
address@hidden menu
-
address@hidden Array Syntax
address@hidden Array Syntax
-
-An array is displayed as @code{#} followed by its rank, followed by a
-tag that describes the underlying vector, optionally followed by
-information about its shape, and finally followed by the cells,
-organized into dimensions using parentheses.
-
-In more words, the array tag is of the form
-
address@hidden
-  #<rank><vectag><@@lower><:len><@@lower><:len>...
address@hidden example
-
-where @code{<rank>} is a positive integer in decimal giving the rank of
-the array.  It is omitted when the rank is 1 and the array is non-shared
-and has zero-origin (see below).  For shared arrays and for a non-zero
-origin, the rank is always printed even when it is 1 to distinguish
-them from ordinary vectors.
-
-The @code{<vectag>} part is the tag for a uniform numeric vector, like
address@hidden, @code{s16}, etc, @code{b} for bitvectors, or @code{a} for
-strings.  It is empty for ordinary vectors.
-
-The @code{<@@lower>} part is a @samp{@@} character followed by a signed
-integer in decimal giving the lower bound of a dimension.  There is one
address@hidden<@@lower>} for each dimension.  When all lower bounds are zero,
-all @code{<@@lower>} parts are omitted.
-
-The @code{<:len>} part is a @samp{:} character followed by an unsigned
-integer in decimal giving the length of a dimension.  Like for the lower
-bounds, there is one @code{<:len>} for each dimension, and the
address@hidden<:len>} part always follows the @code{<@@lower>} part for a
-dimension.  Lengths are only then printed when they can't be deduced
-from the nested lists of elements of the array literal, which can happen
-when at least one length is zero.
-
-As a special case, an array of rank 0 is printed as
address@hidden<vectag>(<scalar>)}, where @code{<scalar>} is the result of
-printing the single element of the array.
-
-Thus, 
-
address@hidden @code
address@hidden #(1 2 3)
-is an ordinary array of rank 1 with lower bound 0 in dimension 0.
-(I.e., a regular vector.)
-
address@hidden #@@2(1 2 3)
-is an ordinary array of rank 1 with lower bound 2 in dimension 0.
-
address@hidden #2((1 2 3) (4 5 6))
-is a non-uniform array of rank 2; a address@hidden matrix with index ranges 
0..1
-and 0..2.
-
address@hidden #u32(0 1 2)
-is a uniform u8 array of rank 1.
-
address@hidden #2u32@@2@@3((1 2) (2 3))
-is a uniform u32 array of rank 2 with index ranges 2..3 and 3..4.
-
address@hidden #2()
-is a two-dimensional array with index ranges 0..-1 and 0..-1, i.e.@:
-both dimensions have length zero.
-
address@hidden #2:0:2()
-is a two-dimensional array with index ranges 0..-1 and 0..1, i.e.@: the
-first dimension has length zero, but the second has length 2.
-
address@hidden #0(12)
-is a rank-zero array with contents 12.
-
address@hidden table
-
-In addition, bytevectors are also arrays, but use a different syntax
-(@pxref{Bytevectors}):
-
address@hidden @code
-
address@hidden #vu8(1 2 3)
-is a 3-byte long bytevector, with contents 1, 2, 3.
-
address@hidden table
-
address@hidden Array Procedures
address@hidden Array Procedures
-
-When an array is created, the range of each dimension must be
-specified, e.g., to create a address@hidden array with a zero-based index:
-
address@hidden
-(make-array 'ho 2 3) @result{} #2((ho ho ho) (ho ho ho))
address@hidden example
-
-The range of each dimension can also be given explicitly, e.g., another
-way to create the same array:
-
address@hidden
-(make-array 'ho '(0 1) '(0 2)) @result{} #2((ho ho ho) (ho ho ho))
address@hidden example
-
-The following procedures can be used with arrays (or vectors).  An
-argument shown as @address@hidden means one parameter for each
-dimension in the array.  A @var{idxlist} argument means a list of such
-values, one for each dimension.
-
-
address@hidden {Scheme Procedure} array? obj
address@hidden {C Function} scm_array_p (obj, unused)
-Return @code{#t} if the @var{obj} is an array, and @code{#f} if
-not.
-
-The second argument to scm_array_p is there for historical reasons,
-but it is not used.  You should always pass @code{SCM_UNDEFINED} as
-its value.
address@hidden deffn
-
address@hidden {Scheme Procedure} typed-array? obj type
address@hidden {C Function} scm_typed_array_p (obj, type)
-Return @code{#t} if the @var{obj} is an array of type @var{type}, and
address@hidden if not.
address@hidden deffn
-
address@hidden {C Function} int scm_is_array (SCM obj)
-Return @code{1} if the @var{obj} is an array and @code{0} if not.
address@hidden deftypefn
-
address@hidden {C Function} int scm_is_typed_array (SCM obj, SCM type)
-Return @code{0} if the @var{obj} is an array of type @var{type}, and
address@hidden if not.
address@hidden deftypefn
-
address@hidden {Scheme Procedure} make-array fill bound @dots{}
address@hidden {C Function} scm_make_array (fill, bounds)
-Equivalent to @code{(make-typed-array #t @var{fill} @var{bound} ...)}.
address@hidden deffn
-
address@hidden {Scheme Procedure} make-typed-array type fill bound @dots{}
address@hidden {C Function} scm_make_typed_array (type, fill, bounds)
-Create and return an array that has as many dimensions as there are
address@hidden and (maybe) fill it with @var{fill}.
-
-The underlying storage vector is created according to @var{type},
-which must be a symbol whose name is the `vectag' of the array as
-explained above, or @code{#t} for ordinary, non-specialized arrays.
-
-For example, using the symbol @code{f64} for @var{type} will create an
-array that uses a @code{f64vector} for storing its elements, and
address@hidden will use a string.
-
-When @var{fill} is not the special @emph{unspecified} value, the new
-array is filled with @var{fill}.  Otherwise, the initial contents of
-the array is unspecified.  The special @emph{unspecified} value is
-stored in the variable @code{*unspecified*} so that for example
address@hidden(make-typed-array 'u32 *unspecified* 4)} creates a uninitialized
address@hidden vector of length 4.
-
-Each @var{bound} may be a positive non-zero integer @var{n}, in which
-case the index for that dimension can range from 0 through @var{n}-1; or
-an explicit index range specifier in the form @code{(LOWER UPPER)},
-where both @var{lower} and @var{upper} are integers, possibly less than
-zero, and possibly the same number (however, @var{lower} cannot be
-greater than @var{upper}).
address@hidden deffn
-
address@hidden {Scheme Procedure} list->array dimspec list
-Equivalent to @code{(list->typed-array #t @var{dimspec}
address@hidden)}.
address@hidden deffn
-
address@hidden {Scheme Procedure} list->typed-array type dimspec list
address@hidden {C Function} scm_list_to_typed_array (type, dimspec, list)
-Return an array of the type indicated by @var{type} with elements the
-same as those of @var{list}.
-
-The argument @var{dimspec} determines the number of dimensions of the
-array and their lower bounds.  When @var{dimspec} is an exact integer,
-it gives the number of dimensions directly and all lower bounds are
-zero.  When it is a list of exact integers, then each element is the
-lower index bound of a dimension, and there will be as many dimensions
-as elements in the list.
address@hidden deffn
-
address@hidden {Scheme Procedure} array-type array
address@hidden {C Function} scm_array_type (array)
-Return the type of @var{array}.  This is the `vectag' used for
-printing @var{array} (or @code{#t} for ordinary arrays) and can be
-used with @code{make-typed-array} to create an array of the same kind
-as @var{array}.
address@hidden deffn
-
address@hidden {Scheme Procedure} array-ref array idx @dots{}
address@hidden {C Function} scm_array_ref (array, idxlist)
-Return the element at @code{(idx @dots{})} in @var{array}.
-
address@hidden
-(define a (make-array 999 '(1 2) '(3 4)))
-(array-ref a 2 4) @result{} 999
address@hidden example
address@hidden deffn
-
address@hidden {Scheme Procedure} array-in-bounds? array idx @dots{}
address@hidden {C Function} scm_array_in_bounds_p (array, idxlist)
-Return @code{#t} if the given indices would be acceptable to
address@hidden
-
address@hidden
-(define a (make-array #f '(1 2) '(3 4)))
-(array-in-bounds? a 2 3) @result{} #t
-(array-in-bounds? a 0 0) @result{} #f
address@hidden example
address@hidden deffn
-
address@hidden {Scheme Procedure} array-set! array obj idx @dots{}
address@hidden {C Function} scm_array_set_x (array, obj, idxlist)
-Set the element at @code{(idx @dots{})} in @var{array} to @var{obj}.
-The return value is unspecified.
-
address@hidden
-(define a (make-array #f '(0 1) '(0 1)))
-(array-set! a #t 1 1)
-a @result{} #2((#f #f) (#f #t))
address@hidden example
address@hidden deffn
-
address@hidden {Scheme Procedure} array-shape array
address@hidden {Scheme Procedure} array-dimensions array
address@hidden {C Function} scm_array_dimensions (array)
-Return a list of the bounds for each dimension of @var{array}.
-
address@hidden gives @code{(@var{lower} @var{upper})} for each
-dimension.  @code{array-dimensions} instead returns just
address@hidden@var{upper}+1} for dimensions with a 0 lower bound.  Both are
-suitable as input to @code{make-array}.
-
-For example,
-
address@hidden
-(define a (make-array 'foo '(-1 3) 5))
-(array-shape a)      @result{} ((-1 3) (0 4))
-(array-dimensions a) @result{} ((-1 3) 5)
address@hidden example
address@hidden deffn
-
address@hidden {Scheme Procedure} array-length array
address@hidden {C Function} scm_array_length (array)
address@hidden {C Function} size_t scm_c_array_length (array)
-Return the length of an array: its first dimension. It is an error to
-ask for the length of an array of rank 0.
address@hidden deffn
-
address@hidden {Scheme Procedure} array-rank array
address@hidden {C Function} scm_array_rank (array)
-Return the rank of @var{array}.
address@hidden deffn
-
address@hidden {C Function} size_t scm_c_array_rank (SCM array)
-Return the rank of @var{array} as a @code{size_t}.
address@hidden deftypefn
-
address@hidden {Scheme Procedure} array->list array
address@hidden {C Function} scm_array_to_list (array)
-Return a list consisting of all the elements, in order, of
address@hidden
address@hidden deffn
-
address@hidden  FIXME: Describe how the order affects the copying (it matters 
for
address@hidden  shared arrays with the same underlying root vector, presumably).
address@hidden
address@hidden {Scheme Procedure} array-copy! src dst
address@hidden {Scheme Procedure} array-copy-in-order! src dst
address@hidden {C Function} scm_array_copy_x (src, dst)
-Copy every element from vector or array @var{src} to the corresponding
-element of @var{dst}.  @var{dst} must have the same rank as @var{src},
-and be at least as large in each dimension.  The return value is
-unspecified.
address@hidden deffn
-
address@hidden {Scheme Procedure} array-fill! array fill
address@hidden {C Function} scm_array_fill_x (array, fill)
-Store @var{fill} in every element of @var{array}.  The value returned
-is unspecified.
address@hidden deffn
-
address@hidden begin (texi-doc-string "guile" "array-equal?")
address@hidden {Scheme Procedure} array-equal? array @dots{}
-Return @code{#t} if all arguments are arrays with the same shape, the
-same type, and have corresponding elements which are either
address@hidden or @code{array-equal?}.  This function differs from
address@hidden (@pxref{Equality}) in that all arguments must be arrays.
address@hidden deffn
-
address@hidden  FIXME: array-map! accepts no source arrays at all, and in that
address@hidden  case makes calls "(proc)".  Is that meant to be a documented
address@hidden  feature?
address@hidden
address@hidden  FIXME: array-for-each doesn't say what happens if the sources 
have
address@hidden  different index ranges.  The code currently iterates over the
address@hidden  indices of the first and expects the others to cover those.  
That
address@hidden  at least vaguely matches array-map!, but is it meant to be a
address@hidden  documented feature?
-
address@hidden {Scheme Procedure} array-map! dst proc src @dots{}
address@hidden {Scheme Procedure} array-map-in-order! dst proc src1 @dots{} srcN
address@hidden {C Function} scm_array_map_x (dst, proc, srclist)
-Set each element of the @var{dst} array to values obtained from calls
-to @var{proc}.  The value returned is unspecified.
-
-Each call is @code{(@var{proc} @var{elem1} @dots{} @var{elemN})},
-where each @var{elem} is from the corresponding @var{src} array, at
-the @var{dst} index.  @code{array-map-in-order!} makes the calls in
-row-major order, @code{array-map!} makes them in an unspecified order.
-
-The @var{src} arrays must have the same number of dimensions as
address@hidden, and must have a range for each dimension which covers the
-range in @var{dst}.  This ensures all @var{dst} indices are valid in
-each @var{src}.
address@hidden deffn
-
address@hidden {Scheme Procedure} array-for-each proc src1 src2 @dots{}
address@hidden {C Function} scm_array_for_each (proc, src1, srclist)
-Apply @var{proc} to each tuple of elements of @var{src1} @var{src2}
address@hidden, in row-major order.  The value returned is unspecified.
address@hidden deffn
-
address@hidden {Scheme Procedure} array-index-map! dst proc
address@hidden {C Function} scm_array_index_map_x (dst, proc)
-Set each element of the @var{dst} array to values returned by calls to
address@hidden  The value returned is unspecified.
-
-Each call is @code{(@var{proc} @var{i1} @dots{} @var{iN})}, where
address@hidden@address@hidden is the destination index, one parameter for
-each dimension.  The order in which the calls are made is unspecified.
-
-For example, to create a @m{4\times4, 4x4} matrix representing a
-cyclic group,
-
address@hidden
-\advance\leftskip by 2\lispnarrowing {
-$\left(\matrix{%
-0 & 1 & 2 & 3 \cr
-1 & 2 & 3 & 0 \cr
-2 & 3 & 0 & 1 \cr
-3 & 0 & 1 & 2 \cr
-}\right)$} \par
address@hidden tex
address@hidden
address@hidden
-    / 0 1 2 3 \
-    | 1 2 3 0 |
-    | 2 3 0 1 |
-    \ 3 0 1 2 /
address@hidden example
address@hidden ifnottex
-
address@hidden
-(define a (make-array #f 4 4))
-(array-index-map! a (lambda (i j)
-                      (modulo (+ i j) 4)))
address@hidden example
address@hidden deffn
-
address@hidden {Scheme Procedure} uniform-array-read! ra [port_or_fd [start 
[end]]]
address@hidden {C Function} scm_uniform_array_read_x (ra, port_or_fd, start, 
end)
-Attempt to read all elements of array @var{ra}, in lexicographic order, as
-binary objects from @var{port_or_fd}.
-If an end of file is encountered,
-the objects up to that point are put into @var{ra}
-(starting at the beginning) and the remainder of the array is
-unchanged.
-
-The optional arguments @var{start} and @var{end} allow
-a specified region of a vector (or linearized array) to be read,
-leaving the remainder of the vector unchanged.
-
address@hidden returns the number of objects read.
address@hidden may be omitted, in which case it defaults to the value
-returned by @code{(current-input-port)}.
address@hidden deffn
-
address@hidden {Scheme Procedure} uniform-array-write ra [port_or_fd [start 
[end]]]
address@hidden {C Function} scm_uniform_array_write (ra, port_or_fd, start, end)
-Writes all elements of @var{ra} as binary objects to
address@hidden
-
-The optional arguments @var{start}
-and @var{end} allow
-a specified region of a vector (or linearized array) to be written.
-
-The number of objects actually written is returned.
address@hidden may be
-omitted, in which case it defaults to the value returned by
address@hidden(current-output-port)}.
address@hidden deffn
-
address@hidden Shared Arrays
address@hidden Shared Arrays
-
address@hidden {Scheme Procedure} make-shared-array oldarray mapfunc bound 
@dots{}
address@hidden {C Function} scm_make_shared_array (oldarray, mapfunc, boundlist)
-Return a new array which shares the storage of @var{oldarray}.
-Changes made through either affect the same underlying storage.  The
address@hidden @dots{} arguments are the shape of the new array, the same
-as @code{make-array} (@pxref{Array Procedures}).
-
address@hidden translates coordinates from the new array to the
address@hidden  It's called as @code{(@var{mapfunc} newidx1 @dots{})}
-with one parameter for each dimension of the new array, and should
-return a list of indices for @var{oldarray}, one for each dimension of
address@hidden
-
address@hidden must be affine linear, meaning that each @var{oldarray}
-index must be formed by adding integer multiples (possibly negative)
-of some or all of @var{newidx1} etc, plus a possible integer offset.
-The multiples and offset must be the same in each call.
-
address@hidden 1
-One good use for a shared array is to restrict the range of some
-dimensions, so as to apply say @code{array-for-each} or
address@hidden to only part of an array.  The plain @code{list}
-function can be used for @var{mapfunc} in this case, making no changes
-to the index values.  For example,
-
address@hidden
-(make-shared-array #2((a b c) (d e f) (g h i)) list 3 2)
address@hidden #2((a b) (d e) (g h))
address@hidden example
-
-The new array can have fewer dimensions than @var{oldarray}, for
-example to take a column from an array.
-
address@hidden
-(make-shared-array #2((a b c) (d e f) (g h i))
-                   (lambda (i) (list i 2))
-                   '(0 2))
address@hidden #1(c f i)
address@hidden example
-
-A diagonal can be taken by using the single new array index for both
-row and column in the old array.  For example,
-
address@hidden
-(make-shared-array #2((a b c) (d e f) (g h i))
-                   (lambda (i) (list i i))
-                   '(0 2))
address@hidden #1(a e i)
address@hidden example
-
-Dimensions can be increased by for instance considering portions of a
-one dimensional array as rows in a two dimensional array.
-(@code{array-contents} below can do the opposite, flattening an
-array.)
-
address@hidden
-(make-shared-array #1(a b c d e f g h i j k l)
-                   (lambda (i j) (list (+ (* i 3) j)))
-                   4 3)
address@hidden #2((a b c) (d e f) (g h i) (j k l))
address@hidden example
-
-By negating an index the order that elements appear can be reversed.
-The following just reverses the column order,
-
address@hidden
-(make-shared-array #2((a b c) (d e f) (g h i))
-                   (lambda (i j) (list i (- 2 j)))
-                   3 3)
address@hidden #2((c b a) (f e d) (i h g))
address@hidden example
-
-A fixed offset on indexes allows for instance a change from a 0 based
-to a 1 based array,
-
address@hidden
-(define x #2((a b c) (d e f) (g h i)))
-(define y (make-shared-array x
-                             (lambda (i j) (list (1- i) (1- j)))
-                             '(1 3) '(1 3)))
-(array-ref x 0 0) @result{} a
-(array-ref y 1 1) @result{} a
address@hidden example
-
-A multiple on an index allows every Nth element of an array to be
-taken.  The following is every third element,
-
address@hidden
-(make-shared-array #1(a b c d e f g h i j k l)
-                   (lambda (i) (list (* i 3)))
-                   4)
address@hidden #1(a d g j)
address@hidden example
-
-The above examples can be combined to make weird and wonderful
-selections from an array, but it's important to note that because
address@hidden must be affine linear, arbitrary permutations are not
-possible.
-
-In the current implementation, @var{mapfunc} is not called for every
-access to the new array but only on some sample points to establish a
-base and stride for new array indices in @var{oldarray} data.  A few
-sample points are enough because @var{mapfunc} is linear.
address@hidden deffn
-
address@hidden {Scheme Procedure} shared-array-increments array
address@hidden {C Function} scm_shared_array_increments (array)
-For each dimension, return the distance between elements in the root vector.
address@hidden deffn
-
address@hidden {Scheme Procedure} shared-array-offset array
address@hidden {C Function} scm_shared_array_offset (array)
-Return the root vector index of the first element in the array.
address@hidden deffn
-
address@hidden {Scheme Procedure} shared-array-root array
address@hidden {C Function} scm_shared_array_root (array)
-Return the root vector of a shared array.
address@hidden deffn
-
address@hidden {Scheme Procedure} array-contents array [strict]
address@hidden {C Function} scm_array_contents (array, strict)
-If @var{array} may be @dfn{unrolled} into a one dimensional shared array
-without changing their order (last subscript changing fastest), then
address@hidden returns that shared array, otherwise it returns
address@hidden  All arrays made by @code{make-array} and
address@hidden may be unrolled, some arrays made by
address@hidden may not be.
-
-If the optional argument @var{strict} is provided, a shared array will
-be returned only if its elements are stored internally contiguous in
-memory.
address@hidden deffn
-
address@hidden {Scheme Procedure} transpose-array array dim1 dim2 @dots{}
address@hidden {C Function} scm_transpose_array (array, dimlist)
-Return an array sharing contents with @var{array}, but with
-dimensions arranged in a different order.  There must be one
address@hidden argument for each dimension of @var{array}.
address@hidden, @var{dim2}, @dots{} 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 @var{dim1}, @var{dim2}, @dots{} correspond to
-dimensions in the array to be returned, and their positions in the
-argument list to dimensions of @var{array}.  Several @var{dim}s
-may have the same value, in which case the returned array will
-have smaller rank than @var{array}.
-
address@hidden
-(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d))
-(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d)
-(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{}
-                #2((a 4) (b 5) (c 6))
address@hidden lisp
address@hidden deffn
-
address@hidden Accessing Arrays from C
address@hidden Accessing Arrays from C
-
-For interworking with external C code, Guile provides an API to allow C
-code to access the elements of a Scheme array.  In particular, for
-uniform numeric arrays, the API exposes the underlying uniform data as a
-C array of numbers of the relevant type.
-
-While pointers to the elements of an array are in use, the array itself
-must be protected so that the pointer remains valid.  Such a protected
-array is said to be @dfn{reserved}.  A reserved array can be read but
-modifications to it that would cause the pointer to its elements to
-become invalid are prevented.  When you attempt such a modification, an
-error is signalled.
-
-(This is similar to locking the array while it is in use, but without
-the danger of a deadlock.  In a multi-threaded program, you will need
-additional synchronization to avoid modifying reserved arrays.)
-
-You must take care to always unreserve an array after reserving it,
-even in the presence of non-local exits.  If a non-local exit can
-happen between these two calls, you should install a dynwind context
-that releases the array when it is left (@pxref{Dynamic Wind}).
-
-In addition, array reserving and unreserving must be properly
-paired.  For instance, when reserving two or more arrays in a certain
-order, you need to unreserve them in the opposite order.
-
-Once you have reserved an array and have retrieved the pointer to its
-elements, you must figure out the layout of the elements in memory.
-Guile allows slices to be taken out of arrays without actually making a
-copy, such as making an alias for the diagonal of a matrix that can be
-treated as a vector.  Arrays that result from such an operation are not
-stored contiguously in memory and when working with their elements
-directly, you need to take this into account.
-
-The layout of array elements in memory can be defined via a
address@hidden function} that computes a scalar position from a vector of
-indices.  The scalar position then is the offset of the element with the
-given indices from the start of the storage block of the array.
-
-In Guile, this mapping function is restricted to be @dfn{affine}: all
-mapping functions of Guile arrays can be written as @code{p = b +
-c[0]*i[0] + c[1]*i[1] + ... + c[n-1]*i[n-1]} where @code{i[k]} is the
address@hidden index and @code{n} is the rank of the array.  For
-example, a matrix of size 3x3 would have @code{b == 0}, @code{c[0] ==
-3} and @code{c[1] == 1}.  When you transpose this matrix (with
address@hidden, say), you will get an array whose mapping
-function has @code{b == 0}, @code{c[0] == 1} and @code{c[1] == 3}.
-
-The function @code{scm_array_handle_dims} gives you (indirect) access to
-the coefficients @code{c[k]}.
-
address@hidden XXX
-Note that there are no functions for accessing the elements of a
-character array yet.  Once the string implementation of Guile has been
-changed to use Unicode, we will provide them.
-
address@hidden {C Type} scm_t_array_handle
-This is a structure type that holds all information necessary to manage
-the reservation of arrays as explained above.  Structures of this type
-must be allocated on the stack and must only be accessed by the
-functions listed below.
address@hidden deftp
-
address@hidden {C Function} void scm_array_get_handle (SCM array, 
scm_t_array_handle *handle)
-Reserve @var{array}, which must be an array, and prepare @var{handle} to
-be used with the functions below.  You must eventually call
address@hidden on @var{handle}, and do this in a
-properly nested fashion, as explained above.  The structure pointed to
-by @var{handle} does not need to be initialized before calling this
-function.
address@hidden deftypefn
-
address@hidden {C Function} void scm_array_handle_release (scm_t_array_handle 
*handle)
-End the array reservation represented by @var{handle}.  After a call to
-this function, @var{handle} might be used for another reservation.
address@hidden deftypefn
-
address@hidden {C Function} size_t scm_array_handle_rank (scm_t_array_handle 
*handle)
-Return the rank of the array represented by @var{handle}.
address@hidden deftypefn
-
address@hidden {C Type} scm_t_array_dim
-This structure type holds information about the layout of one dimension
-of an array.  It includes the following fields:
-
address@hidden @code
address@hidden  ssize_t lbnd
address@hidden ssize_t ubnd
-The lower and upper bounds (both inclusive) of the permissible index
-range for the given dimension.  Both values can be negative, but
address@hidden is always less than or equal to @var{ubnd}.
-
address@hidden ssize_t inc
-The distance from one element of this dimension to the next.  Note, too,
-that this can be negative.
address@hidden table
address@hidden deftp
-
address@hidden {C Function} {const scm_t_array_dim *} scm_array_handle_dims 
(scm_t_array_handle *handle)
-Return a pointer to a C vector of information about the dimensions of
-the array represented by @var{handle}.  This pointer is valid as long as
-the array remains reserved.  As explained above, the
address@hidden structures returned by this function can be used
-calculate the position of an element in the storage block of the array
-from its indices.
-
-This position can then be used as an index into the C array pointer
-returned by the various @code{scm_array_handle_<foo>_elements}
-functions, or with @code{scm_array_handle_ref} and
address@hidden
-
-Here is how one can compute the position @var{pos} of an element given
-its indices in the vector @var{indices}:
-
address@hidden
-ssize_t indices[RANK];
-scm_t_array_dim *dims;
-ssize_t pos;
-size_t i;
-
-pos = 0;
-for (i = 0; i < RANK; i++)
-  @{
-    if (indices[i] < dims[i].lbnd || indices[i] > dims[i].ubnd)
-      out_of_range ();
-    pos += (indices[i] - dims[i].lbnd) * dims[i].inc;
-  @}
address@hidden example
address@hidden deftypefn
-
address@hidden {C Function} ssize_t scm_array_handle_pos (scm_t_array_handle 
*handle, SCM indices)
-Compute the position corresponding to @var{indices}, a list of
-indices.  The position is computed as described above for
address@hidden  The number of the indices and their
-range is checked and an appropriate error is signalled for invalid
-indices.
address@hidden deftypefn
-
address@hidden {C Function} SCM scm_array_handle_ref (scm_t_array_handle 
*handle, ssize_t pos)
-Return the element at position @var{pos} in the storage block of the
-array represented by @var{handle}.  Any kind of array is acceptable.  No
-range checking is done on @var{pos}.
address@hidden deftypefn
-
address@hidden {C Function} void scm_array_handle_set (scm_t_array_handle 
*handle, ssize_t pos, SCM val)
-Set the element at position @var{pos} in the storage block of the array
-represented by @var{handle} to @var{val}.  Any kind of array is
-acceptable.  No range checking is done on @var{pos}.  An error is
-signalled when the array can not store @var{val}.
address@hidden deftypefn
-
address@hidden {C Function} {const SCM *} scm_array_handle_elements 
(scm_t_array_handle *handle)
-Return a pointer to the elements of a ordinary array of general Scheme
-values (i.e., a non-uniform array) for reading.  This pointer is valid
-as long as the array remains reserved.
address@hidden deftypefn
-
address@hidden {C Function} {SCM *} scm_array_handle_writable_elements 
(scm_t_array_handle *handle)
-Like @code{scm_array_handle_elements}, but the pointer is good for
-reading and writing.
address@hidden deftypefn
-
address@hidden {C Function} {const void *} scm_array_handle_uniform_elements 
(scm_t_array_handle *handle)
-Return a pointer to the elements of a uniform numeric array for reading.
-This pointer is valid as long as the array remains reserved.  The size
-of each element is given by @code{scm_array_handle_uniform_element_size}.
address@hidden deftypefn
-
address@hidden {C Function} {void *} scm_array_handle_uniform_writable_elements 
(scm_t_array_handle *handle)
-Like @code{scm_array_handle_uniform_elements}, but the pointer is good
-reading and writing.
address@hidden deftypefn
-
address@hidden {C Function} size_t scm_array_handle_uniform_element_size 
(scm_t_array_handle *handle)
-Return the size of one element of the uniform numeric array represented
-by @var{handle}.
address@hidden deftypefn
-
address@hidden  {C Function} {const scm_t_uint8 *} scm_array_handle_u8_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_int8 *} scm_array_handle_s8_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_uint16 *} 
scm_array_handle_u16_elements (scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_int16 *} scm_array_handle_s16_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_uint32 *} 
scm_array_handle_u32_elements (scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_int32 *} scm_array_handle_s32_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_uint64 *} 
scm_array_handle_u64_elements (scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_int64 *} scm_array_handle_s64_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const float *} scm_array_handle_f32_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const double *} scm_array_handle_f64_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const float *} scm_array_handle_c32_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const double *} scm_array_handle_c64_elements 
(scm_t_array_handle *handle)
-Return a pointer to the elements of a uniform numeric array of the
-indicated kind for reading.  This pointer is valid as long as the array
-remains reserved.
-
-The pointers for @code{c32} and @code{c64} uniform numeric arrays point
-to pairs of floating point numbers.  The even index holds the real part,
-the odd index the imaginary part of the complex number.
address@hidden deftypefn
-
address@hidden {C Function} {scm_t_uint8 *} 
scm_array_handle_u8_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_int8 *} 
scm_array_handle_s8_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_uint16 *} 
scm_array_handle_u16_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_int16 *} 
scm_array_handle_s16_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_uint32 *} 
scm_array_handle_u32_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_int32 *} 
scm_array_handle_s32_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_uint64 *} 
scm_array_handle_u64_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_int64 *} 
scm_array_handle_s64_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {float *} scm_array_handle_f32_writable_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {double *} scm_array_handle_f64_writable_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {float *} scm_array_handle_c32_writable_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {double *} scm_array_handle_c64_writable_elements 
(scm_t_array_handle *handle)
-Like @code{scm_array_handle_<kind>_elements}, but the pointer is good
-for reading and writing.
address@hidden deftypefn
-
address@hidden {C Function} {const scm_t_uint32 *} 
scm_array_handle_bit_elements (scm_t_array_handle *handle)
-Return a pointer to the words that store the bits of the represented
-array, which must be a bit array.
-
-Unlike other arrays, bit arrays have an additional offset that must be
-figured into index calculations.  That offset is returned by
address@hidden
-
-To find a certain bit you first need to calculate its position as
-explained above for @code{scm_array_handle_dims} and then add the
-offset.  This gives the absolute position of the bit, which is always a
-non-negative integer.
-
-Each word of the bit array storage block contains exactly 32 bits, with
-the least significant bit in that word having the lowest absolute
-position number.  The next word contains the next 32 bits.
-
-Thus, the following code can be used to access a bit whose position
-according to @code{scm_array_handle_dims} is given in @var{pos}:
-
address@hidden
-SCM bit_array;
-scm_t_array_handle handle;
-scm_t_uint32 *bits;
-ssize_t pos;
-size_t abs_pos;
-size_t word_pos, mask;
-
-scm_array_get_handle (&bit_array, &handle);
-bits = scm_array_handle_bit_elements (&handle);
-
-pos = ...
-abs_pos = pos + scm_array_handle_bit_elements_offset (&handle);
-word_pos = abs_pos / 32;
-mask = 1L << (abs_pos % 32);
-
-if (bits[word_pos] & mask)
-  /* bit is set. */
-
-scm_array_handle_release (&handle);
address@hidden example
-
address@hidden deftypefn
-
address@hidden {C Function} {scm_t_uint32 *} 
scm_array_handle_bit_writable_elements (scm_t_array_handle *handle)
-Like @code{scm_array_handle_bit_elements} but the pointer is good for
-reading and writing.  You must take care not to modify bits outside of
-the allowed index range of the array, even for contiguous arrays.
address@hidden deftypefn
-
address@hidden VLists
address@hidden VLists
-
address@hidden vlist
-
-The @code{(ice-9 vlist)} module provides an implementation of the @dfn{VList}
-data structure designed by Phil Bagwell in 2002.  VLists are immutable lists,
-which can contain any Scheme object.  They improve on standard Scheme linked
-lists in several areas:
-
address@hidden
address@hidden
-Random access has typically constant-time complexity.
-
address@hidden
-Computing the length of a VList has time complexity logarithmic in the number 
of
-elements.
-
address@hidden
-VLists use less storage space than standard lists.
-
address@hidden
-VList elements are stored in contiguous regions, which improves memory locality
-and leads to more efficient use of hardware caches.
address@hidden itemize
-
-The idea behind VLists is to store vlist elements in increasingly large
-contiguous blocks (implemented as vectors here).  These blocks are linked to 
one
-another using a pointer to the next block and an offset within that block.  The
-size of these blocks form a geometric series with ratio
address@hidden (2 by default).
-
-The VList structure also serves as the basis for the @dfn{VList-based hash
-lists} or ``vhashes'', an immutable dictionary type (@pxref{VHashes}).
-
-However, the current implementation in @code{(ice-9 vlist)} has several
-noteworthy shortcomings:
-
address@hidden
-
address@hidden
-It is @emph{not} thread-safe.  Although operations on vlists are all
address@hidden transparent} (i.e., purely functional), adding elements to a
-vlist with @code{vlist-cons} mutates part of its internal structure, which 
makes
-it non-thread-safe.  This could be fixed, but it would slow down
address@hidden
-
address@hidden
address@hidden always allocates at least as much memory as @code{cons}.
-Again, Phil Bagwell describes how to fix it, but that would require tuning the
-garbage collector in a way that may not be generally beneficial.
-
address@hidden
address@hidden is a Scheme procedure compiled to bytecode, and it does not
-compete with the straightforward C implementation of @code{cons}, and with the
-fact that the VM has a special @code{cons} instruction.
-
address@hidden itemize
-
-We hope to address these in the future.
-
-The programming interface exported by @code{(ice-9 vlist)} is defined below.
-Most of it is the same as SRFI-1 with an added @code{vlist-} prefix to function
-names.
-
address@hidden {Scheme Procedure} vlist? obj
-Return true if @var{obj} is a VList.
address@hidden deffn
-
address@hidden {Scheme Variable} vlist-null
-The empty VList.  Note that it's possible to create an empty VList not
address@hidden to @code{vlist-null}; thus, callers should always use
address@hidden when testing whether a VList is empty.
address@hidden defvr
-
address@hidden {Scheme Procedure} vlist-null? vlist
-Return true if @var{vlist} is empty.
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-cons item vlist
-Return a new vlist with @var{item} as its head and @var{vlist} as its tail.
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-head vlist
-Return the head of @var{vlist}.
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-tail vlist
-Return the tail of @var{vlist}.
address@hidden deffn
-
address@hidden {Scheme Variable} block-growth-factor
-A fluid that defines the growth factor of VList blocks, 2 by default.
address@hidden defvr
-
-The functions below provide the usual set of higher-level list operations.
-
address@hidden {Scheme Procedure} vlist-fold proc init vlist
address@hidden {Scheme Procedure} vlist-fold-right proc init vlist
-Fold over @var{vlist}, calling @var{proc} for each element, as for SRFI-1
address@hidden and @code{fold-right} (@pxref{SRFI-1, @code{fold}}).
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-ref vlist index
-Return the element at index @var{index} in @var{vlist}.  This is typically a
-constant-time operation.
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-length vlist
-Return the length of @var{vlist}.  This is typically logarithmic in the number
-of elements in @var{vlist}.
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-reverse vlist
-Return a new @var{vlist} whose content are those of @var{vlist} in reverse
-order.
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-map proc vlist
-Map @var{proc} over the elements of @var{vlist} and return a new vlist.
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-for-each proc vlist
-Call @var{proc} on each element of @var{vlist}.  The result is unspecified.
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-drop vlist count
-Return a new vlist that does not contain the @var{count} first elements of
address@hidden  This is typically a constant-time operation.
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-take vlist count
-Return a new vlist that contains only the @var{count} first elements of
address@hidden
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-filter pred vlist
-Return a new vlist containing all the elements from @var{vlist} that satisfy
address@hidden
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-delete x vlist [equal?]
-Return a new vlist corresponding to @var{vlist} without the elements
address@hidden to @var{x}.
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-unfold p f g seed [tail-gen]
address@hidden {Scheme Procedure} vlist-unfold-right p f g seed [tail]
-Return a new vlist, as for SRFI-1 @code{unfold} and @code{unfold-right}
-(@pxref{SRFI-1, @code{unfold}}).
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist-append vlist @dots{}
-Append the given vlists and return the resulting vlist.
address@hidden deffn
-
address@hidden {Scheme Procedure} list->vlist lst
-Return a new vlist whose contents correspond to @var{lst}.
address@hidden deffn
-
address@hidden {Scheme Procedure} vlist->list vlist
-Return a new list whose contents match those of @var{vlist}.
address@hidden deffn
-
address@hidden Record Overview
address@hidden Record Overview
-
address@hidden record
address@hidden structure
-
address@hidden, also called @dfn{structures}, are Scheme's primary
-mechanism to define new disjoint types.  A @dfn{record type} defines a
-list of @dfn{fields} that instances of the type consist of.  This is like
-C's @code{struct}.
-
-Historically, Guile has offered several different ways to define record
-types and to create records, offering different features, and making
-different trade-offs.  Over the years, each ``standard'' has also come
-with its own new record interface, leading to a maze of record APIs.
-
-At the highest level is SRFI-9, a high-level record interface
-implemented by most Scheme implementations (@pxref{SRFI-9 Records}).  It
-defines a simple and efficient syntactic abstraction of record types and
-their associated type predicate, fields, and field accessors.  SRFI-9 is
-suitable for most uses, and this is the recommended way to create record
-types in Guile.  Similar high-level record APIs include SRFI-35
-(@pxref{SRFI-35}) and R6RS records (@pxref{rnrs records syntactic}).
-
-Then comes Guile's historical ``records'' API (@pxref{Records}).  Record
-types defined this way are first-class objects.  Introspection
-facilities are available, allowing users to query the list of fields or
-the value of a specific field at run-time, without prior knowledge of
-the type.
-
-Finally, the common denominator of these interfaces is Guile's
address@hidden API (@pxref{Structures}).  Guile's structures are the
-low-level building block for all other record APIs.  Application writers
-will normally not need to use it.
-
-Records created with these APIs may all be pattern-matched using Guile's
-standard pattern matcher (@pxref{Pattern Matching}).
-
-
address@hidden SRFI-9 Records
address@hidden SRFI-9 Records
-
address@hidden SRFI-9
address@hidden record
-
-SRFI-9 standardizes a syntax for defining new record types and creating
-predicate, constructor, and field getter and setter functions.  In Guile
-this is the recommended option to create new record types (@pxref{Record
-Overview}).  It can be used with:
-
address@hidden
-(use-modules (srfi srfi-9))
address@hidden example
-
address@hidden {Scheme Syntax} define-record-type type @* (constructor 
fieldname @dots{}) @* predicate @* (fieldname accessor [modifier]) @dots{}
address@hidden 1
-Create a new record type, and make various @code{define}s for using
-it.  This syntax can only occur at the top-level, not nested within
-some other form.
-
address@hidden is bound to the record type, which is as per the return
-from the core @code{make-record-type}.  @var{type} also provides the
-name for the record, as per @code{record-type-name}.
-
address@hidden is bound to a function to be called as
address@hidden(@var{constructor} fieldval @dots{})} to create a new record of
-this type.  The arguments are initial values for the fields, one
-argument for each field, in the order they appear in the
address@hidden form.
-
-The @var{fieldname}s provide the names for the record fields, as per
-the core @code{record-type-fields} etc, and are referred to in the
-subsequent accessor/modifier forms.
-
address@hidden is bound to a function to be called as
address@hidden(@var{predicate} obj)}.  It returns @code{#t} or @code{#f}
-according to whether @var{obj} is a record of this type.
-
-Each @var{accessor} is bound to a function to be called
address@hidden(@var{accessor} record)} to retrieve the respective field from a
address@hidden  Similarly each @var{modifier} is bound to a function to
-be called @code{(@var{modifier} record val)} to set the respective
-field in a @var{record}.
address@hidden deffn
-
address@hidden
-An example will illustrate typical usage,
-
address@hidden
-(define-record-type <employee>
-  (make-employee name age salary)
-  employee?
-  (name    employee-name)
-  (age     employee-age    set-employee-age!)
-  (salary  employee-salary set-employee-salary!))
address@hidden example
-
-This creates a new employee data type, with name, age and salary
-fields.  Accessor functions are created for each field, but no
-modifier function for the name (the intention in this example being
-that it's established only when an employee object is created).  These
-can all then be used as for example,
-
address@hidden
-<employee> @result{} #<record-type <employee>>
-
-(define fred (make-employee "Fred" 45 20000.00))
-
-(employee? fred)        @result{} #t
-(employee-age fred)     @result{} 45
-(set-employee-salary! fred 25000.00)  ;; pay rise
address@hidden example
-
-The functions created by @code{define-record-type} are ordinary
-top-level @code{define}s.  They can be redefined or @code{set!} as
-desired, exported from a module, etc.
-
address@hidden Non-toplevel Record Definitions
-
-The SRFI-9 specification explicitly disallows record definitions in a
-non-toplevel context, such as inside @code{lambda} body or inside a
address@hidden block.  However, Guile's implementation does not enforce that
-restriction.
-
address@hidden Custom Printers
-
-You may use @code{set-record-type-printer!} to customize the default printing
-behavior of records.  This is a Guile extension and is not part of SRFI-9.  It
-is located in the @nicode{(srfi srfi-9 gnu)} module.
-
address@hidden {Scheme Syntax} set-record-type-printer! type proc
-Where @var{type} corresponds to the first argument of 
@code{define-record-type},
-and @var{proc} is a procedure accepting two arguments, the record to print, and
-an output port.
address@hidden deffn
-
address@hidden
-This example prints the employee's name in brackets, for instance 
@code{[Fred]}.
-
address@hidden
-(set-record-type-printer! <employee>
-  (lambda (record port)
-    (write-char #\[ port)
-    (display (employee-name record) port)
-    (write-char #\] port)))
address@hidden example
-
address@hidden Functional ``Setters''
-
address@hidden functional setters
-
-When writing code in a functional style, it is desirable to never alter
-the contents of records.  For such code, a simple way to return new
-record instances based on existing ones is highly desirable.
-
-The @code{(srfi srfi-9 gnu)} module extends SRFI-9 with facilities to
-return new record instances based on existing ones, only with one or
-more field values address@hidden setters}.  First, the
address@hidden works like
address@hidden, except that fields are immutable and setters
-are defined as functional setters.
-
address@hidden {Scheme Syntax} define-immutable-record-type type @* 
(constructor fieldname @dots{}) @* predicate @* (fieldname accessor [modifier]) 
@dots{}
-Define @var{type} as a new record type, like @code{define-record-type}.
-However, the record type is made @emph{immutable} (records may not be
-mutated, even with @code{struct-set!}), and any @var{modifier} is
-defined to be a functional setter---a procedure that returns a new
-record instance with the specified field changed, and leaves the
-original unchanged (see example below.)
address@hidden deffn
-
address@hidden
-In addition, the generic @code{set-field} and @code{set-fields} macros
-may be applied to any SRFI-9 record.
-
address@hidden {Scheme Syntax} set-field record (field sub-fields ...) value
-Return a new record of @var{record}'s type whose fields are equal to
-the corresponding fields of @var{record} except for the one specified by
address@hidden
-
address@hidden must be the name of the getter corresponding to the field of
address@hidden being ``set''.  Subsequent @var{sub-fields} must be record
-getters designating sub-fields within that field value to be set (see
-example below.)
address@hidden deffn
-
address@hidden {Scheme Syntax} set-fields record ((field sub-fields ...) value) 
...
-Like @code{set-field}, but can be used to set more than one field at a
-time.  This expands to code that is more efficient than a series of
-single @code{set-field} calls.
address@hidden deffn
-
-To illustrate the use of functional setters, let's assume these two
-record type definitions:
-
address@hidden
-(define-record-type <address>
-  (address street city country)
-  address?
-  (street  address-street)
-  (city    address-city)
-  (country address-country))
-
-(define-immutable-record-type <person>
-  (person age email address)
-  person?
-  (age     person-age set-person-age)
-  (email   person-email set-person-email)
-  (address person-address set-person-address))
address@hidden example
-
address@hidden
-First, note that the @code{<person>} record type definition introduces
-named functional setters.  These may be used like this:
-
address@hidden
-(define fsf-address
-  (address "Franklin Street" "Boston" "USA"))
-
-(define rms
-  (person 30 "rms@@gnu.org" fsf-address))
-
-(and (equal? (set-person-age rms 60)
-             (person 60 "rms@@gnu.org" fsf-address))
-     (= (person-age rms) 30))
address@hidden #t
address@hidden example
-
address@hidden
-Here, the original @code{<person>} record, to which @var{rms} is bound,
-is left unchanged.
-
-Now, suppose we want to change both the street and age of @var{rms}.
-This can be achieved using @code{set-fields}:
-
address@hidden
-(set-fields rms
-  ((person-age) 60)
-  ((person-address address-street) "Temple Place"))
address@hidden #<<person> age: 60 email: "rms@@gnu.org"
-  address: #<<address> street: "Temple Place" city: "Boston" country: "USA">>
address@hidden example
-
address@hidden
-Notice how the above changed two fields of @var{rms}, including the
address@hidden field of its @code{address} field, in a concise way.  Also
-note that @code{set-fields} works equally well for types defined with
-just @code{define-record-type}.
-
address@hidden Records
address@hidden Records
-
-A @dfn{record type} is a first class object representing a user-defined
-data type.  A @dfn{record} is an instance of a record type.
-
-Note that in many ways, this interface is too low-level for every-day
-use.  Most uses of records are better served by SRFI-9 records.
address@hidden Records}.
-
address@hidden {Scheme Procedure} record? obj
-Return @code{#t} if @var{obj} is a record of any type and @code{#f}
-otherwise.
-
-Note that @code{record?} may be true of any Scheme value; there is no
-promise that records are disjoint with other Scheme types.
address@hidden deffn
-
address@hidden {Scheme Procedure} make-record-type type-name field-names [print]
-Create and return a new @dfn{record-type descriptor}.
-
address@hidden is a string naming the type.  Currently it's only used
-in the printed representation of records, and in diagnostics.
address@hidden is a list of symbols naming the fields of a record
-of the type.  Duplicates are not allowed among these symbols.
-
address@hidden
-(make-record-type "employee" '(name age salary))
address@hidden example
-
-The optional @var{print} argument is a function used by
address@hidden, @code{write}, etc, for printing a record of the new
-type.  It's called as @code{(@var{print} record port)} and should look
-at @var{record} and write to @var{port}.
address@hidden deffn
-
address@hidden {Scheme Procedure} record-constructor rtd [field-names]
-Return a procedure for constructing new members of the type represented
-by @var{rtd}.  The returned procedure accepts exactly as many arguments
-as there are symbols in the given list, @var{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 @var{field-names}
-argument defaults to the list of field names in the call to
address@hidden that created the type represented by @var{rtd};
-if the @var{field-names} argument is provided, it is an error if it
-contains any duplicates or any symbols not in the default list.
address@hidden deffn
-
address@hidden {Scheme Procedure} record-predicate rtd
-Return a procedure for testing membership in the type represented by
address@hidden  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.
address@hidden deffn
-
address@hidden {Scheme Procedure} record-accessor rtd field-name
-Return a procedure for reading the value of a particular field of a
-member of the type represented by @var{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
address@hidden in that record.  The symbol @var{field-name} must be a
-member of the list of field-names in the call to @code{make-record-type}
-that created the type represented by @var{rtd}.
address@hidden deffn
-
address@hidden {Scheme Procedure} record-modifier rtd field-name
-Return a procedure for writing the value of a particular field of a
-member of the type represented by @var{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 @var{field-name} in that record to contain the given value.
-The returned value of the modifier procedure is unspecified.  The symbol
address@hidden must be a member of the list of field-names in the call
-to @code{make-record-type} that created the type represented by
address@hidden
address@hidden deffn
-
address@hidden {Scheme Procedure} record-type-descriptor record
-Return a record-type descriptor representing the type of the given
-record.  That is, for example, if the returned descriptor were passed to
address@hidden, 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
address@hidden in the call that created the constructor
-procedure that created the given record.
address@hidden deffn
-
address@hidden {Scheme Procedure} record-type-name rtd
-Return the type-name associated with the type represented by rtd.  The
-returned value is @code{eqv?} to the @var{type-name} argument given in
-the call to @code{make-record-type} that created the type represented by
address@hidden
address@hidden deffn
-
address@hidden {Scheme Procedure} record-type-fields rtd
-Return a list of the symbols naming the fields in members of the type
-represented by @var{rtd}.  The returned value is @code{equal?} to the
-field-names argument given in the call to @code{make-record-type} that
-created the type represented by @var{rtd}.
address@hidden deffn
-
-
address@hidden Structures
address@hidden Structures
address@hidden Structures
-
-A @dfn{structure} is a first class data type which holds Scheme values
-or C words in fields numbered 0 upwards.  A @dfn{vtable} is a structure
-that represents a structure type, giving field types and permissions,
-and an optional print function for @code{write} etc.
-
-Structures are lower level than records (@pxref{Records}).  Usually,
-when you need to represent structured data, you just want to use
-records.  But sometimes you need to implement new kinds of structured
-data abstractions, and for that purpose structures are useful.  Indeed,
-records in Guile are implemented with structures.
-
address@hidden
-* Vtables::
-* Structure Basics::
-* Vtable Contents::
-* Meta-Vtables::
-* Vtable Example::
-* Tail Arrays::
address@hidden menu
-
address@hidden Vtables
address@hidden Vtables
-
-A vtable is a structure type, specifying its layout, and other
-information.  A vtable is actually itself a structure, but there's no
-need to worry about that initially (@pxref{Vtable Contents}.)
-
address@hidden {Scheme Procedure} make-vtable fields [print]
-Create a new vtable.
-
address@hidden is a string describing the fields in the structures to be
-created.  Each field is represented by two characters, a type letter
-and a permissions letter, for example @code{"pw"}.  The types are as
-follows.
-
address@hidden @bullet{}
address@hidden
address@hidden -- a Scheme value.  ``p'' stands for ``protected'' meaning
-it's protected against garbage collection.
-
address@hidden
address@hidden -- an arbitrary word of data (an @code{scm_t_bits}).  At the
-Scheme level it's read and written as an unsigned integer.  ``u''
-stands for ``uninterpreted'' (it's not treated as a Scheme value), or
-``unprotected'' (it's not marked during GC), or ``unsigned long'' (its
-size), or all of these things.
-
address@hidden
address@hidden -- a self-reference.  Such a field holds the @code{SCM} value
-of the structure itself (a circular reference).  This can be useful in
-C code where you might have a pointer to the data array, and want to
-get the Scheme @code{SCM} handle for the structure.  In Scheme code it
-has no use.
address@hidden itemize
-
-The second letter for each field is a permission code,
-
address@hidden @bullet{}
address@hidden
address@hidden -- writable, the field can be read and written.
address@hidden
address@hidden -- read-only, the field can be read but not written.
address@hidden
address@hidden -- opaque, the field can be neither read nor written at the
-Scheme level.  This can be used for fields which should only be used
-from C code.
address@hidden itemize
-
-Here are some examples.  @xref{Tail Arrays}, for information on the
-legacy tail array facility.
-
address@hidden
-(make-vtable "pw")      ;; one writable field
-(make-vtable "prpw")    ;; one read-only and one writable
-(make-vtable "pwuwuw")  ;; one scheme and two uninterpreted
address@hidden example
-
-The optional @var{print} argument is a function called by
address@hidden and @code{write} (etc) to give a printed representation
-of a structure created from this vtable.  It's called
address@hidden(@var{print} struct port)} and should look at @var{struct} and
-write to @var{port}.  The default print merely gives a form like
address@hidden<struct ADDR:ADDR>} with a pair of machine addresses.
-
-The following print function for example shows the two fields of its
-structure.
-
address@hidden
-(make-vtable "prpw"
-             (lambda (struct port)
-               (format port "#<~a and ~a>"
-                       (struct-ref struct 0)
-                       (struct-ref struct 1))))
address@hidden example
address@hidden deffn
-
-
address@hidden Structure Basics
address@hidden Structure Basics
-
-This section describes the basic procedures for working with
-structures.  @code{make-struct} creates a structure, and
address@hidden and @code{struct-set!} access its fields.
-
address@hidden {Scheme Procedure} make-struct vtable tail-size init @dots{}
address@hidden {Scheme Procedure} make-struct/no-tail vtable init @dots{}
-Create a new structure, with layout per the given @var{vtable}
-(@pxref{Vtables}).
-
-The optional @address@hidden arguments are initial values for the
-fields of the structure.  This is the only way to
-put values in read-only fields.  If there are fewer @var{init}
-arguments than fields then the defaults are @code{#f} for a Scheme
-field (type @code{p}) or 0 for an uninterpreted field (type @code{u}).
-
-Structures also have the ability to allocate a variable number of
-additional cells at the end, at their tails.  However, this legacy
address@hidden array} facilty is confusing and inefficient, and so we do not
-recommend it.  @xref{Tail Arrays}, for more on the legacy tail array
-interface.
-
-Type @code{s} self-reference fields, permission @code{o} opaque
-fields, and the count field of a tail array are all ignored for the
address@hidden arguments, ie.@: an argument is not consumed by such a
-field.  An @code{s} is always set to the structure itself, an @code{o}
-is always set to @code{#f} or 0 (with the intention that C code will
-do something to it later), and the tail count is always the given
address@hidden
-
-For example,
-
address@hidden
-(define v (make-vtable "prpwpw"))
-(define s (make-struct v 0 123 "abc" 456))
-(struct-ref s 0) @result{} 123
-(struct-ref s 1) @result{} "abc"
address@hidden example
address@hidden deffn
-
address@hidden {C Function} SCM scm_make_struct (SCM vtable, SCM tail_size, SCM 
init_list)
address@hidden {C Function} SCM scm_c_make_struct (SCM vtable, SCM tail_size, 
SCM init, ...)
address@hidden {C Function} SCM scm_c_make_structv (SCM vtable, SCM tail_size, 
size_t n_inits, scm_t_bits init[])
-There are a few ways to make structures from C.  @code{scm_make_struct}
-takes a list, @code{scm_c_make_struct} takes variable arguments
-terminated with SCM_UNDEFINED, and @code{scm_c_make_structv} takes a
-packed array.
address@hidden deftypefn
-
address@hidden {Scheme Procedure} struct? obj
address@hidden {C Function} scm_struct_p (obj)
-Return @code{#t} if @var{obj} is a structure, or @code{#f} if not.
address@hidden deffn
-
address@hidden {Scheme Procedure} struct-ref struct n
address@hidden {C Function} scm_struct_ref (struct, n)
-Return the contents of field number @var{n} in @var{struct}.  The
-first field is number 0.
-
-An error is thrown if @var{n} is out of range, or if the field cannot
-be read because it's @code{o} opaque.
address@hidden deffn
-
address@hidden {Scheme Procedure} struct-set! struct n value
address@hidden {C Function} scm_struct_set_x (struct, n, value)
-Set field number @var{n} in @var{struct} to @var{value}.  The first
-field is number 0.
-
-An error is thrown if @var{n} is out of range, or if the field cannot
-be written because it's @code{r} read-only or @code{o} opaque.  
address@hidden deffn
-
address@hidden {Scheme Procedure} struct-vtable struct
address@hidden {C Function} scm_struct_vtable (struct)
-Return the vtable that describes @var{struct}.
-
-The vtable is effectively the type of the structure.  See @ref{Vtable
-Contents}, for more on vtables.
address@hidden deffn
-
-
address@hidden Vtable Contents
address@hidden Vtable Contents
-
-A vtable is itself a structure.  It has a specific set of fields
-describing various aspects of its @dfn{instances}: the structures
-created from a vtable.  Some of the fields are internal to Guile, some
-of them are part of the public interface, and there may be additional
-fields added on by the user.
-
-Every vtable has a field for the layout of their instances, a field for
-the procedure used to print its instances, and a field for the name of
-the vtable itself.  Access to the layout and printer is exposed directly
-via field indexes.  Access to the vtable name is exposed via accessor
-procedures.
-
address@hidden {Scheme Variable} vtable-index-layout
address@hidden {C Macro} scm_vtable_index_layout
-The field number of the layout specification in a vtable.  The layout
-specification is a symbol like @code{pwpw} formed from the fields
-string passed to @code{make-vtable}, or created by
address@hidden (@pxref{Meta-Vtables}).
-
address@hidden
-(define v (make-vtable "pwpw" 0))
-(struct-ref v vtable-index-layout) @result{} pwpw
address@hidden example
-
-This field is read-only, since the layout of structures using a vtable
-cannot be changed.
address@hidden defvr
-
address@hidden {Scheme Variable} vtable-index-printer
address@hidden {C Macro} scm_vtable_index_printer
-The field number of the printer function.  This field contains @code{#f}
-if the default print function should be used.
-
address@hidden
-(define (my-print-func struct port)
-  ...)
-(define v (make-vtable "pwpw" my-print-func))
-(struct-ref v vtable-index-printer) @result{} my-print-func
address@hidden example
-
-This field is writable, allowing the print function to be changed
-dynamically.
address@hidden defvr
-
address@hidden {Scheme Procedure} struct-vtable-name vtable
address@hidden {Scheme Procedure} set-struct-vtable-name! vtable name
address@hidden {C Function} scm_struct_vtable_name (vtable)
address@hidden {C Function} scm_set_struct_vtable_name_x (vtable, name)
-Get or set the name of @var{vtable}.  @var{name} is a symbol and is
-used in the default print function when printing structures created
-from @var{vtable}.
-
address@hidden
-(define v (make-vtable "pw"))
-(set-struct-vtable-name! v 'my-name)
-
-(define s (make-struct v 0))
-(display s) @print{} #<my-name b7ab3ae0:b7ab3730>
address@hidden example
address@hidden deffn
-
-
address@hidden Meta-Vtables
address@hidden Meta-Vtables
-
-As a structure, a vtable also has a vtable, which is also a structure.
-Structures, their vtables, the vtables of the vtables, and so on form a
-tree of structures.  Making a new structure adds a leaf to the tree, and
-if that structure is a vtable, it may be used to create other leaves.
-
-If you traverse up the tree of vtables, via calling
address@hidden, eventually you reach a root which is the vtable of
-itself:
-
address@hidden
-scheme@@(guile-user)> (current-module)
-$1 = #<directory (guile-user) 221b090>
-scheme@@(guile-user)> (struct-vtable $1)
-$2 = #<record-type module>
-scheme@@(guile-user)> (struct-vtable $2)
-$3 = #<<standard-vtable> 12c30a0>
-scheme@@(guile-user)> (struct-vtable $3)
-$4 = #<<standard-vtable> 12c3fa0>
-scheme@@(guile-user)> (struct-vtable $4)
-$5 = #<<standard-vtable> 12c3fa0>
-scheme@@(guile-user)> <standard-vtable>
-$6 = #<<standard-vtable> 12c3fa0>
address@hidden example
-
-In this example, we can say that @code{$1} is an instance of @code{$2},
address@hidden is an instance of @code{$3}, @code{$3} is an instance of
address@hidden, and @code{$4}, strangely enough, is an instance of itself.
-The value bound to @code{$4} in this console session also bound to
address@hidden<standard-vtable>} in the default environment.
-
address@hidden {Scheme Variable} <standard-vtable>
-A meta-vtable, useful for making new vtables.
address@hidden defvr
-
-All of these values are structures.  All but @code{$1} are vtables.  As
address@hidden is an instance of @code{$3}, and @code{$3} is a vtable, we can
-say that @code{$3} is a @dfn{meta-vtable}: a vtable that can create
-vtables.
-
-With this definition, we can specify more precisely what a vtable is: a
-vtable is a structure made from a meta-vtable.  Making a structure from
-a meta-vtable runs some special checks to ensure that the first field of
-the structure is a valid layout.  Additionally, if these checks see that
-the layout of the child vtable contains all the required fields of a
-vtable, in the correct order, then the child vtable will also be a
-meta-table, inheriting a magical bit from the parent.
-
address@hidden {Scheme Procedure} struct-vtable? obj
address@hidden {C Function} scm_struct_vtable_p (obj)
-Return @code{#t} if @var{obj} is a vtable structure: an instance of a
-meta-vtable.
address@hidden deffn
-
address@hidden<standard-vtable>} is a root of the vtable tree.  (Normally there
-is only one root in a given Guile process, but due to some legacy
-interfaces there may be more than one.)
-
-The set of required fields of a vtable is the set of fields in the
address@hidden<standard-vtable>}, and is bound to @code{standard-vtable-fields}
-in the default environment.  It is possible to create a meta-vtable that
-with additional fields in its layout, which can be used to create
-vtables with additional data:
-
address@hidden
-scheme@@(guile-user)> (struct-ref $3 vtable-index-layout)
-$6 = pruhsruhpwphuhuhprprpw
-scheme@@(guile-user)> (struct-ref $4 vtable-index-layout)
-$7 = pruhsruhpwphuhuh
-scheme@@(guile-user)> standard-vtable-fields 
-$8 = "pruhsruhpwphuhuh"
-scheme@@(guile-user)> (struct-ref $2 vtable-offset-user)
-$9 = module
address@hidden example
-
-In this continuation of our earlier example, @code{$2} is a vtable that
-has extra fields, because its vtable, @code{$3}, was made from a
-meta-vtable with an extended layout.  @code{vtable-offset-user} is a
-convenient definition that indicates the number of fields in
address@hidden
-
address@hidden {Scheme Variable} standard-vtable-fields
-A string containing the ordered set of fields that a vtable must have.
address@hidden defvr
-
address@hidden {Scheme Variable} vtable-offset-user
-The first index in a vtable that is available for a user.
address@hidden defvr
-
address@hidden {Scheme Procedure} make-struct-layout fields
address@hidden {C Function} scm_make_struct_layout (fields)
-Return a structure layout symbol, from a @var{fields} string.
address@hidden is as described under @code{make-vtable}
-(@pxref{Vtables}).  An invalid @var{fields} string is an error.
address@hidden deffn
-
-With these definitions, one can define @code{make-vtable} in this way:
-
address@hidden
-(define* (make-vtable fields #:optional printer)
-  (make-struct/no-tail <standard-vtable>
-    (make-struct-layout fields)
-    printer))
address@hidden example
-
-
address@hidden Vtable Example
address@hidden Vtable Example
-
-Let us bring these points together with an example.  Consider a simple
-object system with single inheritance.  Objects will be normal
-structures, and classes will be vtables with three extra class fields:
-the name of the class, the parent class, and the list of fields.
-
-So, first we need a meta-vtable that allocates instances with these
-extra class fields.
-
address@hidden
-(define <class>
-  (make-vtable
-   (string-append standard-vtable-fields "pwpwpw")
-   (lambda (x port)
-     (format port "<<class> ~a>" (class-name x)))))
-
-(define (class? x)
-  (and (struct? x)
-       (eq? (struct-vtable x) <class>)))
address@hidden example
-
-To make a structure with a specific meta-vtable, we will use
address@hidden/no-tail}, passing it the computed instance layout and
-printer, as with @code{make-vtable}, and additionally the extra three
-class fields.
-
address@hidden
-(define (make-class name parent fields)
-  (let* ((fields (compute-fields parent fields))
-         (layout (compute-layout fields)))
-    (make-struct/no-tail <class>
-      layout 
-      (lambda (x port)
-        (print-instance x port))
-      name
-      parent
-      fields)))
address@hidden example
-
-Instances will store their associated data in slots in the structure: as
-many slots as there are fields.  The @code{compute-layout} procedure
-below can compute a layout, and @code{field-index} returns the slot
-corresponding to a field.
-
address@hidden
-(define-syntax-rule (define-accessor name n)
-  (define (name obj)
-    (struct-ref obj n)))
-
-;; Accessors for classes
-(define-accessor class-name (+ vtable-offset-user 0))
-(define-accessor class-parent (+ vtable-offset-user 1))
-(define-accessor class-fields (+ vtable-offset-user 2))
-
-(define (compute-fields parent fields)
-  (if parent
-      (append (class-fields parent) fields)
-      fields))
-
-(define (compute-layout fields)
-  (make-struct-layout
-   (string-concatenate (make-list (length fields) "pw"))))
-
-(define (field-index class field)
-  (list-index (class-fields class) field))
-
-(define (print-instance x port)
-  (format port "<~a" (class-name (struct-vtable x)))
-  (for-each (lambda (field idx)
-              (format port " ~a: ~a" field (struct-ref x idx)))
-            (class-fields (struct-vtable x))
-            (iota (length (class-fields (struct-vtable x)))))
-  (format port ">"))
address@hidden example
-
-So, at this point we can actually make a few classes:
-
address@hidden
-(define-syntax-rule (define-class name parent field ...)
-  (define name (make-class 'name parent '(field ...))))
-
-(define-class <surface> #f
-  width height)
-
-(define-class <window> <surface>
-  x y)
address@hidden example
-
-And finally, make an instance:
-
address@hidden
-(make-struct/no-tail <window> 400 300 10 20)
address@hidden <<window> width: 400 height: 300 x: 10 y: 20>
address@hidden example
-
-And that's that.  Note that there are many possible optimizations and
-feature enhancements that can be made to this object system, and the
-included GOOPS system does make most of them.  For more simple use
-cases, the records facility is usually sufficient.  But sometimes you
-need to make new kinds of data abstractions, and for that purpose,
-structs are here.
-
address@hidden Tail Arrays
address@hidden Tail Arrays
-
-Guile's structures have a facility whereby each instance of a vtable can
-contain a variable-length tail array of values.  The length of the tail
-array is stored in the structure.  This facility was originally intended
-to allow C code to expose raw C structures with word-sized tail arrays
-to Scheme.
-
-However, the tail array facility is confusing and doesn't work very
-well.  It is very rarely used, but it insinuates itself into all
-invocations of @code{make-struct}.  For this reason the clumsily-named
address@hidden/no-tail} procedure can actually be more elegant in
-actual use, because it doesn't have a random @code{0} argument stuck in
-the middle.
-
-Tail arrays also inhibit optimization by allowing instances to affect
-their shapes.  In the absence of tail arrays, all instances of a given
-vtable have the same number and kinds of fields.  This uniformity can be
-exploited by the runtime and the optimizer.  The presence of tail arrays
-make some of these optimizations more difficult.
-
-Finally, the tail array facility is ad-hoc and does not compose with the
-rest of Guile.  If a Guile user wants an array with user-specified
-length, it's best to use a vector.  It is more clear in the code, and
-the standard optimization techniques will do a good job with it.
-
-That said, we should mention some details about the interface.  A vtable
-that has tail array has upper-case permission descriptors: @code{W},
address@hidden or @code{O}, correspoding to tail arrays of writable,
-read-only, or opaque elements.  A tail array permission descriptor may
-only appear in the last element of a vtable layout.
-
-For exampple, @samp{pW} indicates a tail of writable Scheme-valued
-fields.  The @samp{pW} field itself holds the tail size, and the tail
-fields come after it.
-
address@hidden
-(define v (make-vtable "prpW")) ;; one fixed then a tail array
-(define s (make-struct v 6 "fixed field" 'x 'y))
-(struct-ref s 0) @result{} "fixed field"
-(struct-ref s 1) @result{} 2    ;; tail size
-(struct-ref s 2) @result{} x    ;; tail array ...
-(struct-ref s 3) @result{} y
-(struct-ref s 4) @result{} #f
address@hidden example
-
-
address@hidden Dictionary Types
address@hidden Dictionary Types
-
-A @dfn{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.@: @code{(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 @dfn{association list} (or @dfn{alist} for short) is a list of
-key-value pairs.  Each pair represents a single quantity or
-object; the @code{car} of the pair is a key which is used to
-identify the object, and the @code{cdr} is the object's value.
-
-A @dfn{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, @dfn{car}, @dfn{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.
-
address@hidden Association Lists
address@hidden Association Lists
address@hidden Association Lists
address@hidden Alist
address@hidden association List
address@hidden alist
address@hidden database
-
-An association list is a conventional data structure that is often used
-to implement simple key-value databases.  It consists of a list of
-entries in which each entry is a pair.  The @dfn{key} of each entry is
-the @code{car} of the pair and the @dfn{value} of each entry is the
address@hidden
-
address@hidden
-ASSOCIATION LIST ::=  '( (KEY1 . VALUE1)
-                         (KEY2 . VALUE2)
-                         (KEY3 . VALUE3)
-                         @dots{}
-                       )
address@hidden example
-
address@hidden
-Association lists are also known, for short, as @dfn{alists}.
-
-The structure of an association list is just one example of the infinite
-number of possible structures that can be built using pairs and lists.
-As such, the keys and values in an association list can be manipulated
-using the general list structure procedures @code{cons}, @code{car},
address@hidden, @code{set-car!}, @code{set-cdr!} and so on.  However,
-because association lists are so useful, Guile also provides specific
-procedures for manipulating them.
-
address@hidden
-* Alist Key Equality::
-* Adding or Setting Alist Entries::
-* Retrieving Alist Entries::
-* Removing Alist Entries::
-* Sloppy Alist Functions::
-* Alist Example::
address@hidden menu
-
address@hidden Alist Key Equality
address@hidden Alist Key Equality
-
-All of Guile's dedicated association list procedures, apart from
address@hidden, come in three flavours, depending on the level of equality
-that is required to decide whether an existing key in the association
-list is the same as the key that the procedure call uses to identify the
-required entry.
-
address@hidden @bullet
address@hidden
-Procedures with @dfn{assq} in their name use @code{eq?} to determine key
-equality.
-
address@hidden
-Procedures with @dfn{assv} in their name use @code{eqv?} to determine
-key equality.
-
address@hidden
-Procedures with @dfn{assoc} in their name use @code{equal?} to
-determine key equality.
address@hidden itemize
-
address@hidden is an exception because it is used to build association
-lists which do not require their entries' keys to be unique.
-
address@hidden Adding or Setting Alist Entries
address@hidden Adding or Setting Alist Entries
-
address@hidden adds a new entry to an association list and returns the
-combined association list.  The combined alist is formed by consing the
-new entry onto the head of the alist specified in the @code{acons}
-procedure call.  So the specified alist is not modified, but its
-contents become shared with the tail of the combined alist that
address@hidden returns.
-
-In the most common usage of @code{acons}, a variable holding the
-original association list is updated with the combined alist:
-
address@hidden
-(set! address-list (acons name address address-list))
address@hidden example
-
-In such cases, it doesn't matter that the old and new values of
address@hidden share some of their contents, since the old value is
-usually no longer independently accessible.
-
-Note that @code{acons} adds the specified new entry regardless of
-whether the alist may already contain entries with keys that are, in
-some sense, the same as that of the new entry.  Thus @code{acons} is
-ideal for building alists where there is no concept of key uniqueness.
-
address@hidden
-(set! task-list (acons 3 "pay gas bill" '()))
-task-list
address@hidden
-((3 . "pay gas bill"))
-
-(set! task-list (acons 3 "tidy bedroom" task-list))
-task-list
address@hidden
-((3 . "tidy bedroom") (3 . "pay gas bill"))
address@hidden example
-
address@hidden, @code{assv-set!} and @code{assoc-set!} are used to add
-or replace an entry in an association list where there @emph{is} a
-concept of key uniqueness.  If the specified association list already
-contains an entry whose key is the same as that specified in the
-procedure call, the existing entry is replaced by the new one.
-Otherwise, the new entry is consed onto the head of the old association
-list to create the combined alist.  In all cases, these procedures
-return the combined alist.
-
address@hidden and friends @emph{may} destructively modify the
-structure of the old association list in such a way that an existing
-variable is correctly updated without having to @code{set!} it to the
-value returned:
-
address@hidden
-address-list
address@hidden
-(("mary" . "34 Elm Road") ("james" . "16 Bow Street"))
-
-(assoc-set! address-list "james" "1a London Road")
address@hidden
-(("mary" . "34 Elm Road") ("james" . "1a London Road"))
-
-address-list
address@hidden
-(("mary" . "34 Elm Road") ("james" . "1a London Road"))
address@hidden example
-
-Or they may not:
-
address@hidden
-(assoc-set! address-list "bob" "11 Newington Avenue")
address@hidden
-(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
- ("james" . "1a London Road"))
-
-address-list
address@hidden
-(("mary" . "34 Elm Road") ("james" . "1a London Road"))
address@hidden example
-
-The only safe way to update an association list variable when adding or
-replacing an entry like this is to @code{set!} the variable to the
-returned value:
-
address@hidden
-(set! address-list
-      (assoc-set! address-list "bob" "11 Newington Avenue"))
-address-list
address@hidden
-(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
- ("james" . "1a London Road"))
address@hidden example
-
-Because of this slight inconvenience, 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.
-
-If you need to keep the old value of an association list in a form
-independent from the list that results from modification by
address@hidden, @code{assq-set!}, @code{assv-set!} or @code{assoc-set!},
-use @code{list-copy} to copy the old association list before modifying
-it.
-
address@hidden {Scheme Procedure} acons key value alist
address@hidden {C Function} scm_acons (key, value, alist)
-Add a new key-value pair to @var{alist}.  A new pair is
-created whose car is @var{key} and whose cdr is @var{value}, and the
-pair is consed onto @var{alist}, and the new list is returned.  This
-function is @emph{not} destructive; @var{alist} is not modified.
address@hidden deffn
-
address@hidden {Scheme Procedure} assq-set! alist key val
address@hidden {Scheme Procedure} assv-set! alist key value
address@hidden {Scheme Procedure} assoc-set! alist key value
address@hidden {C Function} scm_assq_set_x (alist, key, val)
address@hidden {C Function} scm_assv_set_x (alist, key, val)
address@hidden {C Function} scm_assoc_set_x (alist, key, val)
-Reassociate @var{key} in @var{alist} with @var{value}: find any existing
address@hidden entry for @var{key} and associate it with the new
address@hidden  If @var{alist} does not contain an entry for @var{key},
-add a new one.  Return the (possibly new) alist.
-
-These functions do not attempt to verify the structure of @var{alist},
-and so may cause unusual results if passed an object that is not an
-association list.
address@hidden deffn
-
address@hidden Retrieving Alist Entries
address@hidden Retrieving Alist Entries
address@hidden assq
address@hidden assv
address@hidden assoc
-
address@hidden, @code{assv} and @code{assoc} find the entry in an alist
-for a given key, and return the @code{(@var{key} . @var{value})} pair.
address@hidden, @code{assv-ref} and @code{assoc-ref} do a similar
-lookup, but return just the @var{value}.
-
address@hidden {Scheme Procedure} assq key alist
address@hidden {Scheme Procedure} assv key alist
address@hidden {Scheme Procedure} assoc key alist
address@hidden {C Function} scm_assq (key, alist)
address@hidden {C Function} scm_assv (key, alist)
address@hidden {C Function} scm_assoc (key, alist)
-Return the first entry in @var{alist} with the given @var{key}.  The
-return is the pair @code{(KEY . VALUE)} from @var{alist}.  If there's
-no matching entry the return is @code{#f}.
-
address@hidden compares keys with @code{eq?}, @code{assv} uses
address@hidden and @code{assoc} uses @code{equal?}.  See also SRFI-1
-which has an extended @code{assoc} (@ref{SRFI-1 Association Lists}).
address@hidden deffn
-
address@hidden {Scheme Procedure} assq-ref alist key
address@hidden {Scheme Procedure} assv-ref alist key
address@hidden {Scheme Procedure} assoc-ref alist key
address@hidden {C Function} scm_assq_ref (alist, key)
address@hidden {C Function} scm_assv_ref (alist, key)
address@hidden {C Function} scm_assoc_ref (alist, key)
-Return the value from the first entry in @var{alist} with the given
address@hidden, or @code{#f} if there's no such entry.
-
address@hidden compares keys with @code{eq?}, @code{assv-ref} uses
address@hidden and @code{assoc-ref} uses @code{equal?}.
-
-Notice these functions have the @var{key} argument last, like other
address@hidden functions, but this is opposite to what @code{assq}
-etc above use.
-
-When the return is @code{#f} it can be either @var{key} not found, or
-an entry which happens to have value @code{#f} in the @code{cdr}.  Use
address@hidden etc above if you need to differentiate these cases.
address@hidden deffn
-
-
address@hidden Removing Alist Entries
address@hidden Removing Alist Entries
-
-To remove the element from an association list whose key matches a
-specified key, use @code{assq-remove!}, @code{assv-remove!} or
address@hidden (depending, as usual, on the level of equality
-required between the key that you specify and the keys in the
-association list).
-
-As with @code{assq-set!} and friends, the specified alist may or may not
-be modified destructively, and the only safe way to update a variable
-containing the alist is to @code{set!} it to the value that
address@hidden and friends return.
-
address@hidden
-address-list
address@hidden
-(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
- ("james" . "1a London Road"))
-
-(set! address-list (assoc-remove! address-list "mary"))
-address-list
address@hidden
-(("bob" . "11 Newington Avenue") ("james" . "1a London Road"))
address@hidden example
-
-Note that, when @code{assq/v/oc-remove!} is used to modify an
-association list that has been constructed only using the corresponding
address@hidden/v/oc-set!}, there can be at most one matching entry in the
-alist, so the question of multiple entries being removed in one go does
-not arise.  If @code{assq/v/oc-remove!} is applied to an association
-list that has been constructed using @code{acons}, or an
address@hidden/v/oc-set!} with a different level of equality, or any mixture
-of these, it removes only the first matching entry from the alist, even
-if the alist might contain further matching entries.  For example:
-
address@hidden
-(define address-list '())
-(set! address-list (assq-set! address-list "mary" "11 Elm Street"))
-(set! address-list (assq-set! address-list "mary" "57 Pine Drive"))
-address-list
address@hidden
-(("mary" . "57 Pine Drive") ("mary" . "11 Elm Street"))
-
-(set! address-list (assoc-remove! address-list "mary"))
-address-list
address@hidden
-(("mary" . "11 Elm Street"))
address@hidden example
-
-In this example, the two instances of the string "mary" are not the same
-when compared using @code{eq?}, so the two @code{assq-set!} calls add
-two distinct entries to @code{address-list}.  When compared using
address@hidden, both "mary"s in @code{address-list} are the same as the
-"mary" in the @code{assoc-remove!} call, but @code{assoc-remove!} stops
-after removing the first matching entry that it finds, and so one of the
-"mary" entries is left in place.
-
address@hidden {Scheme Procedure} assq-remove! alist key
address@hidden {Scheme Procedure} assv-remove! alist key
address@hidden {Scheme Procedure} assoc-remove! alist key
address@hidden {C Function} scm_assq_remove_x (alist, key)
address@hidden {C Function} scm_assv_remove_x (alist, key)
address@hidden {C Function} scm_assoc_remove_x (alist, key)
-Delete the first entry in @var{alist} associated with @var{key}, and return
-the resulting alist.
address@hidden deffn
-
address@hidden Sloppy Alist Functions
address@hidden Sloppy Alist Functions
-
address@hidden, @code{sloppy-assv} and @code{sloppy-assoc} behave
-like the corresponding address@hidden procedures, except that they
-return @code{#f} when the specified association list is not well-formed,
-where the address@hidden versions would signal an error.
-
-Specifically, there are two conditions for which the address@hidden
-procedures signal an error, which the @code{sloppy-} procedures handle
-instead by returning @code{#f}.  Firstly, if the specified alist as a
-whole is not a proper list:
-
address@hidden
-(assoc "mary" '((1 . 2) ("key" . "door") . "open sesame"))
address@hidden
-ERROR: In procedure assoc in expression (assoc "mary" (quote #)):
-ERROR: Wrong type argument in position 2 (expecting
-   association list): ((1 . 2) ("key" . "door") . "open sesame")
-
-(sloppy-assoc "mary" '((1 . 2) ("key" . "door") . "open sesame"))
address@hidden
-#f
address@hidden example
-
address@hidden
-Secondly, if one of the entries in the specified alist is not a pair:
-
address@hidden
-(assoc 2 '((1 . 1) 2 (3 . 9)))
address@hidden
-ERROR: In procedure assoc in expression (assoc 2 (quote #)):
-ERROR: Wrong type argument in position 2 (expecting
-   association list): ((1 . 1) 2 (3 . 9))
-
-(sloppy-assoc 2 '((1 . 1) 2 (3 . 9)))
address@hidden
-#f
address@hidden example
-
-Unless you are explicitly working with badly formed association lists,
-it is much safer to use the address@hidden procedures, because they
-help to highlight coding and data errors that the @code{sloppy-}
-versions would silently cover up.
-
address@hidden {Scheme Procedure} sloppy-assq key alist
address@hidden {C Function} scm_sloppy_assq (key, alist)
-Behaves like @code{assq} but does not do any error checking.
-Recommended only for use in Guile internals.
address@hidden deffn
-
address@hidden {Scheme Procedure} sloppy-assv key alist
address@hidden {C Function} scm_sloppy_assv (key, alist)
-Behaves like @code{assv} but does not do any error checking.
-Recommended only for use in Guile internals.
address@hidden deffn
-
address@hidden {Scheme Procedure} sloppy-assoc key alist
address@hidden {C Function} scm_sloppy_assoc (key, alist)
-Behaves like @code{assoc} but does not do any error checking.
-Recommended only for use in Guile internals.
address@hidden deffn
-
address@hidden Alist Example
address@hidden Alist Example
-
-Here is a longer example of how alists may be used in practice.
-
address@hidden
-(define capitals '(("New York" . "Albany")
-                   ("Oregon"   . "Salem")
-                   ("Florida"  . "Miami")))
-
-;; What's the capital of Oregon?
-(assoc "Oregon" capitals)       @result{} ("Oregon" . "Salem")
-(assoc-ref capitals "Oregon")   @result{} "Salem"
-
-;; We left out South Dakota.
-(set! capitals
-      (assoc-set! capitals "South Dakota" "Pierre"))
-capitals
address@hidden (("South Dakota" . "Pierre")
-    ("New York" . "Albany")
-    ("Oregon" . "Salem")
-    ("Florida" . "Miami"))
-
-;; And we got Florida wrong.
-(set! capitals
-      (assoc-set! capitals "Florida" "Tallahassee"))
-capitals
address@hidden (("South Dakota" . "Pierre")
-    ("New York" . "Albany")
-    ("Oregon" . "Salem")
-    ("Florida" . "Tallahassee"))
-
-;; After Oregon secedes, we can remove it.
-(set! capitals
-      (assoc-remove! capitals "Oregon"))
-capitals
address@hidden (("South Dakota" . "Pierre")
-    ("New York" . "Albany")
-    ("Florida" . "Tallahassee"))
address@hidden lisp
-
address@hidden VHashes
address@hidden VList-Based Hash Lists or ``VHashes''
-
address@hidden VList-based hash lists
address@hidden VHash
-
-The @code{(ice-9 vlist)} module provides an implementation of @dfn{VList-based
-hash lists} (@pxref{VLists}).  VList-based hash lists, or @dfn{vhashes}, are an
-immutable dictionary type similar to association lists that maps @dfn{keys} to
address@hidden  However, unlike association lists, accessing a value given its
-key is typically a constant-time operation.
-
-The VHash programming interface of @code{(ice-9 vlist)} is mostly the same as
-that of association lists found in SRFI-1, with procedure names prefixed by
address@hidden instead of @code{alist-} (@pxref{SRFI-1 Association Lists}).
-
-In addition, vhashes can be manipulated using VList operations:
-
address@hidden
-(vlist-head (vhash-consq 'a 1 vlist-null))
address@hidden (a . 1)
-
-(define vh1 (vhash-consq 'b 2 (vhash-consq 'a 1 vlist-null)))
-(define vh2 (vhash-consq 'c 3 (vlist-tail vh1)))
-
-(vhash-assq 'a vh2)
address@hidden (a . 1)
-(vhash-assq 'b vh2)
address@hidden #f
-(vhash-assq 'c vh2)
address@hidden (c . 3)
-(vlist->list vh2)
address@hidden ((c . 3) (a . 1))
address@hidden example
-
-However, keep in mind that procedures that construct new VLists
-(@code{vlist-map}, @code{vlist-filter}, etc.) return raw VLists, not vhashes:
-
address@hidden
-(define vh (alist->vhash '((a . 1) (b . 2) (c . 3)) hashq))
-(vhash-assq 'a vh)
address@hidden (a . 1)
-
-(define vl
-  ;; This will create a raw vlist.
-  (vlist-filter (lambda (key+value) (odd? (cdr key+value))) vh))
-(vhash-assq 'a vl)
address@hidden ERROR: Wrong type argument in position 2
-
-(vlist->list vl)
address@hidden ((a . 1) (c . 3))
address@hidden example
-
address@hidden {Scheme Procedure} vhash? obj
-Return true if @var{obj} is a vhash.
address@hidden deffn
-
address@hidden {Scheme Procedure} vhash-cons key value vhash [hash-proc]
address@hidden {Scheme Procedure} vhash-consq key value vhash
address@hidden {Scheme Procedure} vhash-consv key value vhash
-Return a new hash list based on @var{vhash} where @var{key} is associated with
address@hidden, using @var{hash-proc} to compute the hash of @var{key}.
address@hidden must be either @code{vlist-null} or a vhash returned by a 
previous
-call to @code{vhash-cons}.  @var{hash-proc} defaults to @code{hash} 
(@pxref{Hash
-Table Reference, @code{hash} procedure}).  With @code{vhash-consq}, the
address@hidden hash function is used; with @code{vhash-consv} the @code{hashv}
-hash function is used.
-
-All @code{vhash-cons} calls made to construct a vhash should use the same
address@hidden  Failing to do that, the result is undefined.
address@hidden deffn
-
address@hidden {Scheme Procedure} vhash-assoc key vhash [equal? [hash-proc]]
address@hidden {Scheme Procedure} vhash-assq key vhash
address@hidden {Scheme Procedure} vhash-assv key vhash
-Return the first key/value pair from @var{vhash} whose key is equal to 
@var{key}
-according to the @var{equal?} equality predicate (which defaults to
address@hidden), and using @var{hash-proc} (which defaults to @code{hash}) to
-compute the hash of @var{key}.  The second form uses @code{eq?} as the equality
-predicate and @code{hashq} as the hash function; the last form uses @code{eqv?}
-and @code{hashv}.
-
-Note that it is important to consistently use the same hash function for
address@hidden as was passed to @code{vhash-cons}.  Failing to do that, the
-result is unpredictable.
address@hidden deffn
-
address@hidden {Scheme Procedure} vhash-delete key vhash [equal? [hash-proc]]
address@hidden {Scheme Procedure} vhash-delq key vhash
address@hidden {Scheme Procedure} vhash-delv key vhash
-Remove all associations from @var{vhash} with @var{key}, comparing keys with
address@hidden (which defaults to @code{equal?}), and computing the hash of
address@hidden using @var{hash-proc} (which defaults to @code{hash}).  The 
second
-form uses @code{eq?} as the equality predicate and @code{hashq} as the hash
-function; the last one uses @code{eqv?} and @code{hashv}.
-
-Again the choice of @var{hash-proc} must be consistent with previous calls to
address@hidden
address@hidden deffn
-
address@hidden {Scheme Procedure} vhash-fold proc init vhash
address@hidden {Scheme Procedure} vhash-fold-right proc init vhash
-Fold over the key/value elements of @var{vhash} in the given direction,
-with each call to @var{proc} having the form @code{(@var{proc} key value
-result)}, where @var{result} is the result of the previous call to
address@hidden and @var{init} the value of @var{result} for the first call
-to @var{proc}.
address@hidden deffn
-
address@hidden {Scheme Procedure} vhash-fold* proc init key vhash [equal? 
[hash]]
address@hidden {Scheme Procedure} vhash-foldq* proc init key vhash
address@hidden {Scheme Procedure} vhash-foldv* proc init key vhash
-Fold over all the values associated with @var{key} in @var{vhash}, with each
-call to @var{proc} having the form @code{(proc value result)}, where
address@hidden is the result of the previous call to @var{proc} and @var{init} 
the
-value of @var{result} for the first call to @var{proc}.
-
-Keys in @var{vhash} are hashed using @var{hash} are compared using 
@var{equal?}.
-The second form uses @code{eq?} as the equality predicate and @code{hashq} as
-the hash function; the third one uses @code{eqv?} and @code{hashv}.
-
-Example:
-
address@hidden
-(define vh
-  (alist->vhash '((a . 1) (a . 2) (z . 0) (a . 3))))
-
-(vhash-fold* cons '() 'a vh)
address@hidden (3 2 1)
-
-(vhash-fold* cons '() 'z vh)
address@hidden (0)
address@hidden example
address@hidden deffn
-
address@hidden {Scheme Procedure} alist->vhash alist [hash-proc]
-Return the vhash corresponding to @var{alist}, an association list, using
address@hidden to compute key hashes.  When omitted, @var{hash-proc} defaults
-to @code{hash}.
address@hidden deffn
-
-
address@hidden Hash Tables
address@hidden Hash Tables
address@hidden Hash Tables
-
-Hash tables are dictionaries which offer similar functionality as
-association lists: They provide a mapping from keys to values.  The
-difference is that association lists need time linear in the size of
-elements when searching for entries, whereas hash tables can normally
-search in constant time.  The drawback is that hash tables require a
-little bit more memory, and that you can not use the normal list
-procedures (@pxref{Lists}) for working with them.
-
address@hidden
-* Hash Table Examples::         Demonstration of hash table usage.
-* Hash Table Reference::        Hash table procedure descriptions.
address@hidden menu
-
-
address@hidden Hash Table Examples
address@hidden Hash Table Examples
-
-For demonstration purposes, this section gives a few usage examples of
-some hash table procedures, together with some explanation what they do.
-
-First we start by creating a new hash table with 31 slots, and
-populate it with two key/value pairs.
-
address@hidden
-(define h (make-hash-table 31))
-
-;; This is an opaque object
-h
address@hidden
-#<hash-table 0/31>
-
-;; Inserting into a hash table can be done with hashq-set!
-(hashq-set! h 'foo "bar")
address@hidden
-"bar"
-
-(hashq-set! h 'braz "zonk")
address@hidden
-"zonk"
-
-;; Or with hash-create-handle!
-(hashq-create-handle! h 'frob #f)
address@hidden
-(frob . #f)
address@hidden lisp
-
-You can get the value for a given key with the procedure
address@hidden, but the problem with this procedure is that you
-cannot reliably determine whether a key does exists in the table.  The
-reason is that the procedure returns @code{#f} if the key is not in
-the table, but it will return the same value if the key is in the
-table and just happens to have the value @code{#f}, as you can see in
-the following examples.
-
address@hidden
-(hashq-ref h 'foo)
address@hidden
-"bar"
-
-(hashq-ref h 'frob)
address@hidden
-#f
-
-(hashq-ref h 'not-there)
address@hidden
-#f
address@hidden lisp
-
-It is often better is to use the procedure @code{hashq-get-handle},
-which makes a distinction between the two cases.  Just like @code{assq},
-this procedure returns a key/value-pair on success, and @code{#f} if the
-key is not found.
-
address@hidden
-(hashq-get-handle h 'foo)
address@hidden
-(foo . "bar")
-
-(hashq-get-handle h 'not-there)
address@hidden
-#f
address@hidden lisp
-
-Interesting results can be computed by using @code{hash-fold} to work
-through each element.  This example will count the total number of
-elements:
-
address@hidden
-(hash-fold (lambda (key value seed) (+ 1 seed)) 0 h)
address@hidden
-3
address@hidden lisp
-
-The same thing can be done with the procedure @code{hash-count}, which
-can also count the number of elements matching a particular predicate.
-For example, count the number of elements with string values:
-
address@hidden
-(hash-count (lambda (key value) (string? value)) h)
address@hidden
-2
address@hidden lisp
-
-Counting all the elements is a simple task using @code{const}:
-
address@hidden
-(hash-count (const #t) h)
address@hidden
-3
address@hidden lisp
-
address@hidden Hash Table Reference
address@hidden Hash Table Reference
-
address@hidden  FIXME: Describe in broad terms what happens for resizing, and 
what
address@hidden  the initial size means for this.
-
-Like the association list functions, the hash table functions come in
-several varieties, according to the equality test used for the keys.
-Plain @code{hash-} functions use @code{equal?}, @code{hashq-}
-functions use @code{eq?}, @code{hashv-} functions use @code{eqv?}, and
-the @code{hashx-} functions use an application supplied test.
-
-A single @code{make-hash-table} creates a hash table suitable for use
-with any set of functions, but it's imperative that just one set is
-then used consistently, or results will be unpredictable.
-
-Hash tables are implemented as a vector indexed by a hash value formed
-from the key, with an association list of key/value pairs for each
-bucket in case distinct keys hash together.  Direct access to the
-pairs in those lists is provided by the @code{-handle-} functions.
-
-When the number of entries in a hash table goes above a threshold, the
-vector is made larger and the entries are rehashed, to prevent the
-bucket lists from becoming too long and slowing down accesses.  When the
-number of entries goes below a threshold, the vector is shrunk to save
-space.
-
-For the @code{hashx-} ``extended'' routines, an application supplies a
address@hidden function producing an integer index like @code{hashq} etc
-below, and an @var{assoc} alist search function like @code{assq} etc
-(@pxref{Retrieving Alist Entries}).  Here's an example of such
-functions implementing case-insensitive hashing of string keys,
-
address@hidden
-(use-modules (srfi srfi-1)
-             (srfi srfi-13))
-
-(define (my-hash str size)
-  (remainder (string-hash-ci str) size))
-(define (my-assoc str alist)
-  (find (lambda (pair) (string-ci=? str (car pair))) alist))
-
-(define my-table (make-hash-table))
-(hashx-set! my-hash my-assoc my-table "foo" 123)
-
-(hashx-ref my-hash my-assoc my-table "FOO")
address@hidden 123
address@hidden example
-
-In a @code{hashx-} @var{hash} function the aim is to spread keys
-across the vector, so bucket lists don't become long.  But the actual
-values are arbitrary as long as they're in the range 0 to
address@hidden@var{size}-1}.  Helpful functions for forming a hash value, in
-addition to @code{hashq} etc below, include @code{symbol-hash}
-(@pxref{Symbol Keys}), @code{string-hash} and @code{string-hash-ci}
-(@pxref{String Comparison}), and @code{char-set-hash}
-(@pxref{Character Set Predicates/Comparison}).
-
address@hidden 1
address@hidden {Scheme Procedure} make-hash-table [size]
-Create a new hash table object, with an optional minimum
-vector @var{size}.
-
-When @var{size} is given, the table vector will still grow and shrink
-automatically, as described above, but with @var{size} as a minimum.
-If an application knows roughly how many entries the table will hold
-then it can use @var{size} to avoid rehashing when initial entries are
-added.
address@hidden deffn
-
address@hidden {Scheme Procedure} alist->hash-table alist
address@hidden {Scheme Procedure} alist->hashq-table alist
address@hidden {Scheme Procedure} alist->hashv-table alist
address@hidden {Scheme Procedure} alist->hashx-table hash assoc alist
-Convert @var{alist} into a hash table. When keys are repeated in
address@hidden, the leftmost association takes precedence.
-
address@hidden
-(use-modules (ice-9 hash-table))
-(alist->hash-table '((foo . 1) (bar . 2)))
address@hidden example
-
-When converting to an extended hash table, custom @var{hash} and
address@hidden procedures must be provided.
-
address@hidden
-(alist->hashx-table hash assoc '((foo . 1) (bar . 2)))
address@hidden example
-
address@hidden deffn
-
address@hidden {Scheme Procedure} hash-table? obj
address@hidden {C Function} scm_hash_table_p (obj)
-Return @code{#t} if @var{obj} is a abstract hash table object.
address@hidden deffn
-
address@hidden {Scheme Procedure} hash-clear! table
address@hidden {C Function} scm_hash_clear_x (table)
-Remove all items from @var{table} (without triggering a resize).
address@hidden deffn
-
address@hidden {Scheme Procedure} hash-ref table key [dflt]
address@hidden {Scheme Procedure} hashq-ref table key [dflt]
address@hidden {Scheme Procedure} hashv-ref table key [dflt]
address@hidden {Scheme Procedure} hashx-ref hash assoc table key [dflt]
address@hidden {C Function} scm_hash_ref (table, key, dflt)
address@hidden {C Function} scm_hashq_ref (table, key, dflt)
address@hidden {C Function} scm_hashv_ref (table, key, dflt)
address@hidden {C Function} scm_hashx_ref (hash, assoc, table, key, dflt)
-Lookup @var{key} in the given hash @var{table}, and return the
-associated value.  If @var{key} is not found, return @var{dflt}, or
address@hidden if @var{dflt} is not given.
address@hidden deffn
-
address@hidden {Scheme Procedure} hash-set! table key val
address@hidden {Scheme Procedure} hashq-set! table key val
address@hidden {Scheme Procedure} hashv-set! table key val
address@hidden {Scheme Procedure} hashx-set! hash assoc table key val
address@hidden {C Function} scm_hash_set_x (table, key, val)
address@hidden {C Function} scm_hashq_set_x (table, key, val)
address@hidden {C Function} scm_hashv_set_x (table, key, val)
address@hidden {C Function} scm_hashx_set_x (hash, assoc, table, key, val)
-Associate @var{val} with @var{key} in the given hash @var{table}.  If
address@hidden is already present then it's associated value is changed.
-If it's not present then a new entry is created.
address@hidden deffn
-
address@hidden {Scheme Procedure} hash-remove! table key
address@hidden {Scheme Procedure} hashq-remove! table key
address@hidden {Scheme Procedure} hashv-remove! table key
address@hidden {Scheme Procedure} hashx-remove! hash assoc table key
address@hidden {C Function} scm_hash_remove_x (table, key)
address@hidden {C Function} scm_hashq_remove_x (table, key)
address@hidden {C Function} scm_hashv_remove_x (table, key)
address@hidden {C Function} scm_hashx_remove_x (hash, assoc, table, key)
-Remove any association for @var{key} in the given hash @var{table}.
-If @var{key} is not in @var{table} then nothing is done.
address@hidden deffn
-
address@hidden {Scheme Procedure} hash key size
address@hidden {Scheme Procedure} hashq key size
address@hidden {Scheme Procedure} hashv key size
address@hidden {C Function} scm_hash (key, size)
address@hidden {C Function} scm_hashq (key, size)
address@hidden {C Function} scm_hashv (key, size)
-Return a hash value for @var{key}.  This is a number in the range
address@hidden to @address@hidden, which is suitable for use in a hash
-table of the given @var{size}.
-
-Note that @code{hashq} and @code{hashv} may use internal addresses of
-objects, so if an object is garbage collected and re-created it can
-have a different hash value, even when the two are notionally
address@hidden  For instance with symbols,
-
address@hidden
-(hashq 'something 123)   @result{} 19
-(gc)
-(hashq 'something 123)   @result{} 62
address@hidden example
-
-In normal use this is not a problem, since an object entered into a
-hash table won't be garbage collected until removed.  It's only if
-hashing calculations are somehow separated from normal references that
-its lifetime needs to be considered.
address@hidden deffn
-
address@hidden {Scheme Procedure} hash-get-handle table key
address@hidden {Scheme Procedure} hashq-get-handle table key
address@hidden {Scheme Procedure} hashv-get-handle table key
address@hidden {Scheme Procedure} hashx-get-handle hash assoc table key
address@hidden {C Function} scm_hash_get_handle (table, key)
address@hidden {C Function} scm_hashq_get_handle (table, key)
address@hidden {C Function} scm_hashv_get_handle (table, key)
address@hidden {C Function} scm_hashx_get_handle (hash, assoc, table, key)
-Return the @code{(@var{key} . @var{value})} pair for @var{key} in the
-given hash @var{table}, or @code{#f} if @var{key} is not in
address@hidden
address@hidden deffn
-
address@hidden {Scheme Procedure} hash-create-handle! table key init
address@hidden {Scheme Procedure} hashq-create-handle! table key init
address@hidden {Scheme Procedure} hashv-create-handle! table key init
address@hidden {Scheme Procedure} hashx-create-handle! hash assoc table key init
address@hidden {C Function} scm_hash_create_handle_x (table, key, init)
address@hidden {C Function} scm_hashq_create_handle_x (table, key, init)
address@hidden {C Function} scm_hashv_create_handle_x (table, key, init)
address@hidden {C Function} scm_hashx_create_handle_x (hash, assoc, table, key, 
init)
-Return the @code{(@var{key} . @var{value})} pair for @var{key} in the
-given hash @var{table}.  If @var{key} is not in @var{table} then
-create an entry for it with @var{init} as the value, and return that
-pair.
address@hidden deffn
-
address@hidden {Scheme Procedure} hash-map->list proc table
address@hidden {Scheme Procedure} hash-for-each proc table
address@hidden {C Function} scm_hash_map_to_list (proc, table)
address@hidden {C Function} scm_hash_for_each (proc, table)
-Apply @var{proc} to the entries in the given hash @var{table}.  Each
-call is @code{(@var{proc} @var{key} @var{value})}.  @code{hash-map->list}
-returns a list of the results from these calls, @code{hash-for-each}
-discards the results and returns an unspecified value.
-
-Calls are made over the table entries in an unspecified order, and for
address@hidden>list} the order of the values in the returned list is
-unspecified.  Results will be unpredictable if @var{table} is modified
-while iterating.
-
-For example the following returns a new alist comprising all the
-entries from @code{mytable}, in no particular order.
-
address@hidden
-(hash-map->list cons mytable)
address@hidden example
address@hidden deffn
-
address@hidden {Scheme Procedure} hash-for-each-handle proc table
address@hidden {C Function} scm_hash_for_each_handle (proc, table)
-Apply @var{proc} to the entries in the given hash @var{table}.  Each
-call is @code{(@var{proc} @var{handle})}, where @var{handle} is a
address@hidden(@var{key} . @var{value})} pair. Return an unspecified value.
-
address@hidden differs from @code{hash-for-each} only in
-the argument list of @var{proc}.
address@hidden deffn
-
address@hidden {Scheme Procedure} hash-fold proc init table
address@hidden {C Function} scm_hash_fold (proc, init, table)
-Accumulate a result by applying @var{proc} to the elements of the
-given hash @var{table}.  Each call is @code{(@var{proc} @var{key}
address@hidden @var{prior-result})}, where @var{key} and @var{value} are
-from the @var{table} and @var{prior-result} is the return from the
-previous @var{proc} call.  For the first call, @var{prior-result} is
-the given @var{init} value.
-
-Calls are made over the table entries in an unspecified order.
-Results will be unpredictable if @var{table} is modified while
address@hidden is running.
-
-For example, the following returns a count of how many keys in
address@hidden are strings.
-
address@hidden
-(hash-fold (lambda (key value prior)
-             (if (string? key) (1+ prior) prior))
-           0 mytable)
address@hidden example
address@hidden deffn
-
address@hidden {Scheme Procedure} hash-count pred table
address@hidden {C Function} scm_hash_count (pred, table)
-Return the number of elements in the given hash @var{table} that cause
address@hidden(@var{pred} @var{key} @var{value})} to return true.  To quickly
-determine the total number of elements, use @code{(const #t)} for
address@hidden
address@hidden deffn
-
address@hidden Local Variables:
address@hidden TeX-master: "guile.texi"
address@hidden End:
diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi
index 34e1ff6..6862ef3 100644
--- a/doc/ref/api-data.texi
+++ b/doc/ref/api-data.texi
@@ -4,39 +4,13 @@
 @c   Free Software Foundation, Inc.
 @c See the file guile.texi for copying conditions.
 
address@hidden Simple Data Types
address@hidden Simple Generic Data Types
-
-This chapter describes those of Guile's simple data types which are
-primarily used for their role as items of generic data.  By
address@hidden we mean data types that are not primarily used as
-containers to hold other data --- i.e.@: pairs, lists, vectors and so on.
-For the documentation of such @dfn{compound} data types, see
address@hidden Data Types}.
-
address@hidden One of the great strengths of Scheme is that there is no 
straightforward
address@hidden distinction between ``data'' and ``functionality''.  For example,
address@hidden Guile's support for dynamic linking could be described:
-
address@hidden @itemize @bullet
address@hidden @item
address@hidden either in a ``data-centric'' way, as the behaviour and 
properties of the
address@hidden ``dynamically linked object'' data type, and the operations that 
may be
address@hidden applied to instances of this type
-
address@hidden @item
address@hidden or in a ``functionality-centric'' way, as the set of procedures 
that
address@hidden constitute Guile's support for dynamic linking, in the context 
of the
address@hidden module system.
address@hidden @end itemize
-
address@hidden The contents of this chapter are, therefore, a matter of 
judgment.  By
address@hidden @dfn{generic}, we mean to select those data types whose typical 
use as
address@hidden @emph{data} in a wide variety of programming contexts is more 
important
address@hidden than their use in the implementation of a particular piece of
address@hidden @emph{functionality}.  The last section of this chapter provides
address@hidden references for all the data types that are documented not here 
but in a
address@hidden ``functionality-centric'' way elsewhere in the manual.
address@hidden Data Types
address@hidden Data Types
+
+Guile's data types form a powerful built-in library of representations
+and functionality that you can apply to your problem domain.  This
+chapter surveys the data types built-in to Guile, from the simple to the
+complex.
 
 @menu
 * Booleans::                    True/false values.
@@ -44,10 +18,24 @@ For the documentation of such @dfn{compound} data types, see
 * Characters::                  Single characters.
 * Character Sets::              Sets of characters.
 * Strings::                     Sequences of characters.
-* Bytevectors::                 Sequences of bytes.
 * Symbols::                     Symbols.
 * Keywords::                    Self-quoting, customizable display keywords.
-* Other Types::                 "Functionality-centric" data types.
+* Pairs::                       Scheme's basic building block.
+* Lists::                       Special list functions supported by Guile.
+* Vectors::                     One-dimensional arrays of Scheme objects.
+* Bit Vectors::                 Vectors of bits.
+* Bytevectors::                 Sequences of bytes.
+* Arrays::                      Multidimensional matrices.
+* VLists::                      Vector-like lists.
+* Record Overview::             Walking through the maze of record APIs.
+* SRFI-9 Records::              The standard, recommended record API.
+* Records::                     Guile's historical record API.
+* Structures::                  Low-level record representation.
+* Dictionary Types::            About dictionary types in general.
+* Association Lists::           List-based dictionaries.
+* VHashes::                     VList-based dictionaries.   
+* Hash Tables::                 Table-based dictionaries.
+* Other Types::                 Other sections describe data types too.
 @end menu
 
 
@@ -4579,1490 +4567,5470 @@ or @code{#f} if they are stored in an 8-bit buffer
 @end deffn
 
 
address@hidden Bytevectors
address@hidden Bytevectors
-
address@hidden bytevector
address@hidden R6RS
address@hidden Symbols
address@hidden Symbols
address@hidden Symbols
 
-A @dfn{bytevector} is a raw bit string.  The @code{(rnrs bytevectors)}
-module provides the programming interface specified by the
address@hidden://www.r6rs.org/, Revised^6 Report on the Algorithmic Language
-Scheme (R6RS)}.  It contains procedures to manipulate bytevectors and
-interpret their contents in a number of ways: bytevector contents can be
-accessed as signed or unsigned integer of various sizes and endianness,
-as IEEE-754 floating point numbers, or as strings.  It is a useful tool
-to encode and decode binary data.
+Symbols in Scheme are widely used in three ways: as items of discrete
+data, as lookup keys for alists and hash tables, and to denote variable
+references.
 
-The R6RS (Section 4.3.4) specifies an external representation for
-bytevectors, whereby the octets (integers in the range 0--255) contained
-in the bytevector are represented as a list prefixed by @code{#vu8}:
+A @dfn{symbol} is similar to a string in that it is defined by a
+sequence of characters.  The sequence of characters is known as the
+symbol's @dfn{name}.  In the usual case --- that is, where the symbol's
+name doesn't include any characters that could be confused with other
+elements of Scheme syntax --- a symbol is written in a Scheme program by
+writing the sequence of characters that make up the name, @emph{without}
+any quotation marks or other special syntax.  For example, the symbol
+whose name is ``multiply-by-2'' is written, simply:
 
 @lisp
-#vu8(1 53 204)
+multiply-by-2
 @end lisp
 
-denotes a 3-byte bytevector containing the octets 1, 53, and 204.  Like
-string literals, booleans, etc., bytevectors are ``self-quoting'', i.e.,
-they do not need to be quoted:
+Notice how this differs from a @emph{string} with contents
+``multiply-by-2'', which is written with double quotation marks, like
+this:
 
 @lisp
-#vu8(1 53 204)
address@hidden #vu8(1 53 204)
+"multiply-by-2"
 @end lisp
 
-Bytevectors can be used with the binary input/output primitives
-(@pxref{Binary I/O}).
-
address@hidden
-* Bytevector Endianness::       Dealing with byte order.
-* Bytevector Manipulation::     Creating, copying, manipulating bytevectors.
-* Bytevectors as Integers::     Interpreting bytes as integers.
-* Bytevectors and Integer Lists::  Converting to/from an integer list.
-* Bytevectors as Floats::       Interpreting bytes as real numbers.
-* Bytevectors as Strings::      Interpreting bytes as Unicode strings.
-* Bytevectors as Arrays::       Guile extension to the bytevector API.
-* Bytevectors as Uniform Vectors::  Bytevectors and SRFI-4.
address@hidden menu
+Looking beyond how they are written, symbols are different from strings
+in two important respects.
 
address@hidden Bytevector Endianness
address@hidden Endianness
+The first important difference is uniqueness.  If the same-looking
+string is read twice from two different places in a program, the result
+is two @emph{different} string objects whose contents just happen to be
+the same.  If, on the other hand, the same-looking symbol is read twice
+from two different places in a program, the result is the @emph{same}
+symbol object both times.
 
address@hidden endianness
address@hidden byte order
address@hidden word order
+Given two read symbols, you can use @code{eq?} to test whether they are
+the same (that is, have the same name).  @code{eq?} is the most
+efficient comparison operator in Scheme, and comparing two symbols like
+this is as fast as comparing, for example, two numbers.  Given two
+strings, on the other hand, you must use @code{equal?} or
address@hidden, which are much slower comparison operators, to
+determine whether the strings have the same contents.
 
-Some of the following procedures take an @var{endianness} parameter.
-The @dfn{endianness} is defined as the order of bytes in multi-byte
-numbers: numbers encoded in @dfn{big endian} have their most
-significant bytes written first, whereas numbers encoded in
address@hidden endian} have their least significant bytes
address@hidden and little-endian are the most common
-``endiannesses'', but others do exist. For instance, the GNU MP
-library allows @dfn{word order} to be specified independently of
address@hidden order} (@pxref{Integer Import and Export,,, gmp, The GNU
-Multiple Precision Arithmetic Library Manual}).}.
address@hidden
+(define sym1 (quote hello))
+(define sym2 (quote hello))
+(eq? sym1 sym2) @result{} #t
 
-Little-endian is the native endianness of the IA32 architecture and
-its derivatives, while big-endian is native to SPARC and PowerPC,
-among others. The @code{native-endianness} procedure returns the
-native endianness of the machine it runs on.
+(define str1 "hello")
+(define str2 "hello")
+(eq? str1 str2) @result{} #f
+(equal? str1 str2) @result{} #t
address@hidden lisp
 
address@hidden {Scheme Procedure} native-endianness
address@hidden {C Function} scm_native_endianness ()
-Return a value denoting the native endianness of the host machine.
address@hidden deffn
+The second important difference is that symbols, unlike strings, are not
+self-evaluating.  This is why we need the @code{(quote @dots{})}s in the
+example above: @code{(quote hello)} evaluates to the symbol named
+"hello" itself, whereas an unquoted @code{hello} is @emph{read} as the
+symbol named "hello" and evaluated as a variable reference @dots{} about
+which more below (@pxref{Symbol Variables}).
 
address@hidden {Scheme Macro} endianness symbol
-Return an object denoting the endianness specified by @var{symbol}.  If
address@hidden is neither @code{big} nor @code{little} then an error is
-raised at expand-time.
address@hidden deffn
address@hidden
+* Symbol Data::                 Symbols as discrete data.
+* Symbol Keys::                 Symbols as lookup keys.
+* Symbol Variables::            Symbols as denoting variables.
+* Symbol Primitives::           Operations related to symbols.
+* Symbol Props::                Function slots and property lists.
+* Symbol Read Syntax::          Extended read syntax for symbols.
+* Symbol Uninterned::           Uninterned symbols.
address@hidden menu
 
address@hidden {C Variable} scm_endianness_big
address@hidden {C Variable} scm_endianness_little
-The objects denoting big- and little-endianness, respectively.
address@hidden defvr
 
address@hidden Symbol Data
address@hidden Symbols as Discrete Data
 
address@hidden Bytevector Manipulation
address@hidden Manipulating Bytevectors
+Numbers and symbols are similar to the extent that they both lend
+themselves to @code{eq?} comparison.  But symbols are more descriptive
+than numbers, because a symbol's name can be used directly to describe
+the concept for which that symbol stands.
 
-Bytevectors can be created, copied, and analyzed with the following
-procedures and C functions.
+For example, imagine that you need to represent some colours in a
+computer program.  Using numbers, you would have to choose arbitrarily
+some mapping between numbers and colours, and then take care to use that
+mapping consistently:
 
address@hidden {Scheme Procedure} make-bytevector len [fill]
address@hidden {C Function} scm_make_bytevector (len, fill)
address@hidden {C Function} scm_c_make_bytevector (size_t len)
-Return a new bytevector of @var{len} bytes.  Optionally, if @var{fill}
-is given, fill it with @var{fill}; @var{fill} must be in the range
-[-128,255].
address@hidden deffn
address@hidden
+;; 1=red, 2=green, 3=purple
 
address@hidden {Scheme Procedure} bytevector? obj
address@hidden {C Function} scm_bytevector_p (obj)
-Return true if @var{obj} is a bytevector.
address@hidden deffn
+(if (eq? (colour-of vehicle) 1)
+    ...)
address@hidden lisp
 
address@hidden {C Function} int scm_is_bytevector (SCM obj)
-Equivalent to @code{scm_is_true (scm_bytevector_p (obj))}.
address@hidden deftypefn
address@hidden
+You can make the mapping more explicit and the code more readable by
+defining constants:
 
address@hidden {Scheme Procedure} bytevector-length bv
address@hidden {C Function} scm_bytevector_length (bv)
-Return the length in bytes of bytevector @var{bv}.
address@hidden deffn
address@hidden
+(define red 1)
+(define green 2)
+(define purple 3)
 
address@hidden {C Function} size_t scm_c_bytevector_length (SCM bv)
-Likewise, return the length in bytes of bytevector @var{bv}.
address@hidden deftypefn
+(if (eq? (colour-of vehicle) red)
+    ...)
address@hidden lisp
 
address@hidden {Scheme Procedure} bytevector=? bv1 bv2
address@hidden {C Function} scm_bytevector_eq_p (bv1, bv2)
-Return is @var{bv1} equals to @var{bv2}---i.e., if they have the same
-length and contents.
address@hidden deffn
address@hidden
+But the simplest and clearest approach is not to use numbers at all, but
+symbols whose names specify the colours that they refer to:
 
address@hidden {Scheme Procedure} bytevector-fill! bv fill
address@hidden {C Function} scm_bytevector_fill_x (bv, fill)
-Fill bytevector @var{bv} with @var{fill}, a byte.
address@hidden deffn
address@hidden
+(if (eq? (colour-of vehicle) 'red)
+    ...)
address@hidden lisp
 
address@hidden {Scheme Procedure} bytevector-copy! source source-start target 
target-start len
address@hidden {C Function} scm_bytevector_copy_x (source, source_start, 
target, target_start, len)
-Copy @var{len} bytes from @var{source} into @var{target}, starting
-reading from @var{source-start} (a positive index within @var{source})
-and start writing at @var{target-start}.  It is permitted for the
address@hidden and @var{target} regions to overlap.
address@hidden deffn
+The descriptive advantages of symbols over numbers increase as the set
+of concepts that you want to describe grows.  Suppose that a car object
+can have other properties as well, such as whether it has or uses:
 
address@hidden {Scheme Procedure} bytevector-copy bv
address@hidden {C Function} scm_bytevector_copy (bv)
-Return a newly allocated copy of @var{bv}.
address@hidden deffn
address@hidden @bullet
address@hidden
+automatic or manual transmission
address@hidden
+leaded or unleaded fuel
address@hidden
+power steering (or not).
address@hidden itemize
 
address@hidden {C Function} scm_t_uint8 scm_c_bytevector_ref (SCM bv, size_t 
index)
-Return the byte at @var{index} in bytevector @var{bv}.
address@hidden deftypefn
address@hidden
+Then a car's combined property set could be naturally represented and
+manipulated as a list of symbols:
 
address@hidden {C Function} void scm_c_bytevector_set_x (SCM bv, size_t index, 
scm_t_uint8 value)
-Set the byte at @var{index} in @var{bv} to @var{value}.
address@hidden deftypefn
address@hidden
+(properties-of vehicle1)
address@hidden
+(red manual unleaded power-steering)
 
-Low-level C macros are available.  They do not perform any
-type-checking; as such they should be used with care.
+(if (memq 'power-steering (properties-of vehicle1))
+    (display "Unfit people can drive this vehicle.\n")
+    (display "You'll need strong arms to drive this vehicle!\n"))
address@hidden
+Unfit people can drive this vehicle.
address@hidden lisp
 
address@hidden {C Macro} size_t SCM_BYTEVECTOR_LENGTH (bv)
-Return the length in bytes of bytevector @var{bv}.
address@hidden deftypefn
+Remember, the fundamental property of symbols that we are relying on
+here is that an occurrence of @code{'red} in one part of a program is an
address@hidden symbol from an occurrence of @code{'red} in
+another part of a program; this means that symbols can usefully be
+compared using @code{eq?}.  At the same time, symbols have naturally
+descriptive names.  This combination of efficiency and descriptive power
+makes them ideal for use as discrete data.
 
address@hidden {C Macro} {signed char *} SCM_BYTEVECTOR_CONTENTS (bv)
-Return a pointer to the contents of bytevector @var{bv}.
address@hidden deftypefn
 
address@hidden Symbol Keys
address@hidden Symbols as Lookup Keys
 
address@hidden Bytevectors as Integers
address@hidden Interpreting Bytevector Contents as Integers
+Given their efficiency and descriptive power, it is natural to use
+symbols as the keys in an association list or hash table.
+
+To illustrate this, consider a more structured representation of the car
+properties example from the preceding subsection.  Rather than
+mixing all the properties up together in a flat list, we could use an
+association list like this:
+
address@hidden
+(define car1-properties '((colour . red)
+                          (transmission . manual)
+                          (fuel . unleaded)
+                          (steering . power-assisted)))
address@hidden lisp
+
+Notice how this structure is more explicit and extensible than the flat
+list.  For example it makes clear that @code{manual} refers to the
+transmission rather than, say, the windows or the locking of the car.
+It also allows further properties to use the same symbols among their
+possible values without becoming ambiguous:
+
address@hidden
+(define car1-properties '((colour . red)
+                          (transmission . manual)
+                          (fuel . unleaded)
+                          (steering . power-assisted)
+                          (seat-colour . red)
+                          (locking . manual)))
address@hidden lisp
+
+With a representation like this, it is easy to use the efficient
address@hidden family of procedures (@pxref{Association Lists}) to
+extract or change individual pieces of information:
+
address@hidden
+(assq-ref car1-properties 'fuel) @result{} unleaded
+(assq-ref car1-properties 'transmission) @result{} manual
+
+(assq-set! car1-properties 'seat-colour 'black)
address@hidden
+((colour . red)
+ (transmission . manual)
+ (fuel . unleaded)
+ (steering . power-assisted)
+ (seat-colour . black)
+ (locking . manual)))
address@hidden lisp
+
+Hash tables also have keys, and exactly the same arguments apply to the
+use of symbols in hash tables as in association lists.  The hash value
+that Guile uses to decide where to add a symbol-keyed entry to a hash
+table can be obtained by calling the @code{symbol-hash} procedure:
+
address@hidden {Scheme Procedure} symbol-hash symbol
address@hidden {C Function} scm_symbol_hash (symbol)
+Return a hash value for @var{symbol}.
address@hidden deffn
+
+See @ref{Hash Tables} for information about hash tables in general, and
+for why you might choose to use a hash table rather than an association
+list.
+
+
address@hidden Symbol Variables
address@hidden Symbols as Denoting Variables
+
+When an unquoted symbol in a Scheme program is evaluated, it is
+interpreted as a variable reference, and the result of the evaluation is
+the appropriate variable's value.
+
+For example, when the expression @code{(string-length "abcd")} is read
+and evaluated, the sequence of characters @code{string-length} is read
+as the symbol whose name is "string-length".  This symbol is associated
+with a variable whose value is the procedure that implements string
+length calculation.  Therefore evaluation of the @code{string-length}
+symbol results in that procedure.
+
+The details of the connection between an unquoted symbol and the
+variable to which it refers are explained elsewhere.  See @ref{Binding
+Constructs}, for how associations between symbols and variables are
+created, and @ref{Modules}, for how those associations are affected by
+Guile's module system.
+
+
address@hidden Symbol Primitives
address@hidden Operations Related to Symbols
+
+Given any Scheme value, you can determine whether it is a symbol using
+the @code{symbol?} primitive:
+
address@hidden symbol?
address@hidden {Scheme Procedure} symbol? obj
address@hidden {C Function} scm_symbol_p (obj)
+Return @code{#t} if @var{obj} is a symbol, otherwise return
address@hidden
address@hidden deffn
+
address@hidden {C Function} int scm_is_symbol (SCM val)
+Equivalent to @code{scm_is_true (scm_symbol_p (val))}.
address@hidden deftypefn
+
+Once you know that you have a symbol, you can obtain its name as a
+string by calling @code{symbol->string}.  Note that Guile differs by
+default from R5RS on the details of @code{symbol->string} as regards
+case-sensitivity:
+
address@hidden symbol->string
address@hidden {Scheme Procedure} symbol->string s
address@hidden {C Function} scm_symbol_to_string (s)
+Return the name of symbol @var{s} as a string.  By default, Guile reads
+symbols case-sensitively, so the string returned will have the same case
+variation as the sequence of characters that caused @var{s} to be
+created.
+
+If Guile is set to read symbols case-insensitively (as specified by
+R5RS), and @var{s} comes into being as part of a literal expression
+(@pxref{Literal expressions,,,r5rs, The Revised^5 Report on Scheme}) or
+by a call to the @code{read} or @code{string-ci->symbol} procedures,
+Guile converts any alphabetic characters in the symbol's name to
+lower case before creating the symbol object, so the string returned
+here will be in lower case.
+
+If @var{s} was created by @code{string->symbol}, the case of characters
+in the string returned will be the same as that in the string that was
+passed to @code{string->symbol}, regardless of Guile's case-sensitivity
+setting at the time @var{s} was created.
+
+It is an error to apply mutation procedures like @code{string-set!} to
+strings returned by this procedure.
address@hidden deffn
+
+Most symbols are created by writing them literally in code.  However it
+is also possible to create symbols programmatically using the following
+procedures:
+
address@hidden {Scheme Procedure} symbol address@hidden
address@hidden symbol
+Return a newly allocated symbol made from the given character arguments.
+
address@hidden
+(symbol #\x #\y #\z) @result{} xyz
address@hidden example
address@hidden deffn
+
address@hidden {Scheme Procedure} list->symbol lst
address@hidden list->symbol
+Return a newly allocated symbol made from a list of characters.
+
address@hidden
+(list->symbol '(#\a #\b #\c)) @result{} abc
address@hidden example
address@hidden deffn
+
address@hidden symbol-append
address@hidden {Scheme Procedure} symbol-append arg @dots{}
+Return a newly allocated symbol whose characters form the
+concatenation of the given symbols, @var{arg} @enddots{}.
+
address@hidden
+(let ((h 'hello))
+  (symbol-append h 'world))
address@hidden helloworld
address@hidden example
address@hidden deffn
+
address@hidden string->symbol
address@hidden {Scheme Procedure} string->symbol string
address@hidden {C Function} scm_string_to_symbol (string)
+Return the symbol whose name is @var{string}.  This procedure can create
+symbols with names containing special characters or letters in the
+non-standard case, but it is usually a bad idea to create such symbols
+because in some implementations of Scheme they cannot be read as
+themselves.
address@hidden deffn
+
address@hidden {Scheme Procedure} string-ci->symbol str
address@hidden {C Function} scm_string_ci_to_symbol (str)
+Return the symbol whose name is @var{str}.  If Guile is currently
+reading symbols case-insensitively, @var{str} is converted to lowercase
+before the returned symbol is looked up or created.
address@hidden deffn
+
+The following examples illustrate Guile's detailed behaviour as regards
+the case-sensitivity of symbols:
+
address@hidden
+(read-enable 'case-insensitive)   ; R5RS compliant behaviour
+
+(symbol->string 'flying-fish)    @result{} "flying-fish"
+(symbol->string 'Martin)         @result{} "martin"
+(symbol->string
+   (string->symbol "Malvina"))   @result{} "Malvina"
+
+(eq? 'mISSISSIppi 'mississippi)  @result{} #t
+(string->symbol "mISSISSIppi")   @result{} mISSISSIppi
+(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #f
+(eq? 'LolliPop
+  (string->symbol (symbol->string 'LolliPop))) @result{} #t
+(string=? "K. Harper, M.D."
+  (symbol->string
+    (string->symbol "K. Harper, M.D."))) @result{} #t
+
+(read-disable 'case-insensitive)   ; Guile default behaviour
+
+(symbol->string 'flying-fish)    @result{} "flying-fish"
+(symbol->string 'Martin)         @result{} "Martin"
+(symbol->string
+   (string->symbol "Malvina"))   @result{} "Malvina"
+
+(eq? 'mISSISSIppi 'mississippi)  @result{} #f
+(string->symbol "mISSISSIppi")   @result{} mISSISSIppi
+(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #t
+(eq? 'LolliPop
+  (string->symbol (symbol->string 'LolliPop))) @result{} #t
+(string=? "K. Harper, M.D."
+  (symbol->string
+    (string->symbol "K. Harper, M.D."))) @result{} #t
address@hidden lisp
+
+From C, there are lower level functions that construct a Scheme symbol
+from a C string in the current locale encoding.
+
+When you want to do more from C, you should convert between symbols
+and strings using @code{scm_symbol_to_string} and
address@hidden and work with the strings.
+
address@hidden {C Function} SCM scm_from_latin1_symbol (const char *name)
address@hidden {C Function} SCM scm_from_utf8_symbol (const char *name)
+Construct and return a Scheme symbol whose name is specified by the
+null-terminated C string @var{name}.  These are appropriate when
+the C string is hard-coded in the source code.
address@hidden deftypefn
+
address@hidden {C Function} SCM scm_from_locale_symbol (const char *name)
address@hidden {C Function} SCM scm_from_locale_symboln (const char *name, 
size_t len)
+Construct and return a Scheme symbol whose name is specified by
address@hidden  For @code{scm_from_locale_symbol}, @var{name} must be null
+terminated; for @code{scm_from_locale_symboln} the length of @var{name} is
+specified explicitly by @var{len}.
+
+Note that these functions should @emph{not} be used when @var{name} is a
+C string constant, because there is no guarantee that the current locale
+will match that of the execution character set, used for string and
+character constants.  Most modern C compilers use UTF-8 by default, so
+in such cases we recommend @code{scm_from_utf8_symbol}.
address@hidden deftypefn
+
address@hidden  {C Function} SCM scm_take_locale_symbol (char *str)
address@hidden {C Function} SCM scm_take_locale_symboln (char *str, size_t len)
+Like @code{scm_from_locale_symbol} and @code{scm_from_locale_symboln},
+respectively, but also frees @var{str} with @code{free} eventually.
+Thus, you can use this function when you would free @var{str} anyway
+immediately after creating the Scheme string.  In certain cases, Guile
+can then use @var{str} directly as its internal representation.
address@hidden deftypefn
+
+The size of a symbol can also be obtained from C:
+
address@hidden {C Function} size_t scm_c_symbol_length (SCM sym)
+Return the number of characters in @var{sym}.
address@hidden deftypefn
+
+Finally, some applications, especially those that generate new Scheme
+code dynamically, need to generate symbols for use in the generated
+code.  The @code{gensym} primitive meets this need:
+
address@hidden {Scheme Procedure} gensym [prefix]
address@hidden {C Function} scm_gensym (prefix)
+Create a new symbol with a name constructed from a prefix and a counter
+value.  The string @var{prefix} can be specified as an optional
+argument.  Default prefix is @address@hidden g}}.  The counter is increased by 
1
+at each call.  There is no provision for resetting the counter.
address@hidden deffn
+
+The symbols generated by @code{gensym} are @emph{likely} to be unique,
+since their names begin with a space and it is only otherwise possible
+to generate such symbols if a programmer goes out of their way to do
+so.  Uniqueness can be guaranteed by instead using uninterned symbols
+(@pxref{Symbol Uninterned}), though they can't be usefully written out
+and read back in.
+
+
address@hidden Symbol Props
address@hidden Function Slots and Property Lists
+
+In traditional Lisp dialects, symbols are often understood as having
+three kinds of value at once:
+
address@hidden @bullet
address@hidden
+a @dfn{variable} value, which is used when the symbol appears in
+code in a variable reference context
+
address@hidden
+a @dfn{function} value, which is used when the symbol appears in
+code in a function name position (i.e.@: as the first element in an
+unquoted list)
+
address@hidden
+a @dfn{property list} value, which is used when the symbol is given as
+the first argument to Lisp's @code{put} or @code{get} functions.
address@hidden itemize
+
+Although Scheme (as one of its simplifications with respect to Lisp)
+does away with the distinction between variable and function namespaces,
+Guile currently retains some elements of the traditional structure in
+case they turn out to be useful when implementing translators for other
+languages, in particular Emacs Lisp.
+
+Specifically, Guile symbols have two extra slots, one for a symbol's
+property list, and one for its ``function value.''  The following procedures
+are provided to access these slots.
+
address@hidden {Scheme Procedure} symbol-fref symbol
address@hidden {C Function} scm_symbol_fref (symbol)
+Return the contents of @var{symbol}'s @dfn{function slot}.
address@hidden deffn
+
address@hidden {Scheme Procedure} symbol-fset! symbol value
address@hidden {C Function} scm_symbol_fset_x (symbol, value)
+Set the contents of @var{symbol}'s function slot to @var{value}.
address@hidden deffn
+
address@hidden {Scheme Procedure} symbol-pref symbol
address@hidden {C Function} scm_symbol_pref (symbol)
+Return the @dfn{property list} currently associated with @var{symbol}.
address@hidden deffn
+
address@hidden {Scheme Procedure} symbol-pset! symbol value
address@hidden {C Function} scm_symbol_pset_x (symbol, value)
+Set @var{symbol}'s property list to @var{value}.
address@hidden deffn
+
address@hidden {Scheme Procedure} symbol-property sym prop
+From @var{sym}'s property list, return the value for property
address@hidden  The assumption is that @var{sym}'s property list is an
+association list whose keys are distinguished from each other using
address@hidden; @var{prop} should be one of the keys in that list.  If
+the property list has no entry for @var{prop}, @code{symbol-property}
+returns @code{#f}.
address@hidden deffn
+
address@hidden {Scheme Procedure} set-symbol-property! sym prop val
+In @var{sym}'s property list, set the value for property @var{prop} to
address@hidden, or add a new entry for @var{prop}, with value @var{val}, if
+none already exists.  For the structure of the property list, see
address@hidden
address@hidden deffn
+
address@hidden {Scheme Procedure} symbol-property-remove! sym prop
+From @var{sym}'s property list, remove the entry for property
address@hidden, if there is one.  For the structure of the property list,
+see @code{symbol-property}.
address@hidden deffn
+
+Support for these extra slots may be removed in a future release, and it
+is probably better to avoid using them.  For a more modern and Schemely
+approach to properties, see @ref{Object Properties}.
+
+
address@hidden Symbol Read Syntax
address@hidden Extended Read Syntax for Symbols
+
address@hidden r7rs-symbols
+
+The read syntax for a symbol is a sequence of letters, digits, and
address@hidden alphabetic characters}, beginning with a character that
+cannot begin a number.  In addition, the special cases of @code{+},
address@hidden, and @code{...} are read as symbols even though numbers can
+begin with @code{+}, @code{-} or @code{.}.
+
+Extended alphabetic characters may be used within identifiers as if
+they were letters.  The set of extended alphabetic characters is:
+
address@hidden
+! $ % & * + - . / : < = > ? @@ ^ _ ~
address@hidden example
+
+In addition to the standard read syntax defined above (which is taken
+from R5RS (@pxref{Formal syntax,,,r5rs,The Revised^5 Report on
+Scheme})), Guile provides an extended symbol read syntax that allows the
+inclusion of unusual characters such as space characters, newlines and
+parentheses.  If (for whatever reason) you need to write a symbol
+containing characters not mentioned above, you can do so as follows.
+
address@hidden @bullet
address@hidden
+Begin the symbol with the characters @address@hidden,
+
address@hidden
+write the characters of the symbol and
+
address@hidden
+finish the symbol with the characters @address@hidden
address@hidden itemize
+
+Here are a few examples of this form of read syntax.  The first symbol
+needs to use extended syntax because it contains a space character, the
+second because it contains a line break, and the last because it looks
+like a number.
+
address@hidden
address@hidden address@hidden
+
address@hidden
address@hidden
+
address@hidden@}#
address@hidden lisp
+
+Although Guile provides this extended read syntax for symbols,
+widespread usage of it is discouraged because it is not portable and not
+very readable.
+
+Alternatively, if you enable the @code{r7rs-symbols} read option (see
address@hidden Read}), you can write arbitrary symbols using the same
+notation used for strings, except delimited by vertical bars instead of
+double quotes.
+
address@hidden
+|foo bar|
+|\x3BB; is a greek lambda|
+|\| is a vertical bar|
address@hidden example
+
+Note that there's also an @code{r7rs-symbols} print option
+(@pxref{Scheme Write}).  To enable the use of this notation, evaluate
+one or both of the following expressions:
+
address@hidden
+(read-enable  'r7rs-symbols)
+(print-enable 'r7rs-symbols)
address@hidden example
+
+
address@hidden Symbol Uninterned
address@hidden Uninterned Symbols
+
+What makes symbols useful is that they are automatically kept unique.
+There are no two symbols that are distinct objects but have the same
+name.  But of course, there is no rule without exception.  In addition
+to the normal symbols that have been discussed up to now, you can also
+create special @dfn{uninterned} symbols that behave slightly
+differently.
+
+To understand what is different about them and why they might be useful,
+we look at how normal symbols are actually kept unique.
+
+Whenever Guile wants to find the symbol with a specific name, for
+example during @code{read} or when executing @code{string->symbol}, it
+first looks into a table of all existing symbols to find out whether a
+symbol with the given name already exists.  When this is the case, Guile
+just returns that symbol.  When not, a new symbol with the name is
+created and entered into the table so that it can be found later.
+
+Sometimes you might want to create a symbol that is guaranteed `fresh',
+i.e.@: a symbol that did not exist previously.  You might also want to
+somehow guarantee that no one else will ever unintentionally stumble
+across your symbol in the future.  These properties of a symbol are
+often needed when generating code during macro expansion.  When
+introducing new temporary variables, you want to guarantee that they
+don't conflict with variables in other people's code.
+
+The simplest way to arrange for this is to create a new symbol but
+not enter it into the global table of all symbols.  That way, no one
+will ever get access to your symbol by chance.  Symbols that are not in
+the table are called @dfn{uninterned}.  Of course, symbols that
address@hidden in the table are called @dfn{interned}.
+
+You create new uninterned symbols with the function @code{make-symbol}.
+You can test whether a symbol is interned or not with
address@hidden
+
+Uninterned symbols break the rule that the name of a symbol uniquely
+identifies the symbol object.  Because of this, they can not be written
+out and read back in like interned symbols.  Currently, Guile has no
+support for reading uninterned symbols.  Note that the function
address@hidden does not return uninterned symbols for this reason.
+
address@hidden {Scheme Procedure} make-symbol name
address@hidden {C Function} scm_make_symbol (name)
+Return a new uninterned symbol with the name @var{name}.  The returned
+symbol is guaranteed to be unique and future calls to
address@hidden>symbol} will not return it.
address@hidden deffn
+
address@hidden {Scheme Procedure} symbol-interned? symbol
address@hidden {C Function} scm_symbol_interned_p (symbol)
+Return @code{#t} if @var{symbol} is interned, otherwise return
address@hidden
address@hidden deffn
+
+For example:
+
address@hidden
+(define foo-1 (string->symbol "foo"))
+(define foo-2 (string->symbol "foo"))
+(define foo-3 (make-symbol "foo"))
+(define foo-4 (make-symbol "foo"))
+
+(eq? foo-1 foo-2)
address@hidden #t
+; Two interned symbols with the same name are the same object,
+
+(eq? foo-1 foo-3)
address@hidden #f
+; but a call to make-symbol with the same name returns a
+; distinct object.
+
+(eq? foo-3 foo-4)
address@hidden #f
+; A call to make-symbol always returns a new object, even for
+; the same name.
+
+foo-3
address@hidden #<uninterned-symbol foo 8085290>
+; Uninterned symbols print differently from interned symbols,
+
+(symbol? foo-3)
address@hidden #t
+; but they are still symbols,
+
+(symbol-interned? foo-3)
address@hidden #f
+; just not interned.
address@hidden lisp
+
+
address@hidden Keywords
address@hidden Keywords
address@hidden Keywords
+
+Keywords are self-evaluating objects with a convenient read syntax that
+makes them easy to type.
+
+Guile's keyword support conforms to R5RS, and adds a (switchable) read
+syntax extension to permit keywords to begin with @code{:} as well as
address@hidden:}, or to end with @code{:}.
+
address@hidden
+* Why Use Keywords?::           Motivation for keyword usage.
+* Coding With Keywords::        How to use keywords.
+* Keyword Read Syntax::         Read syntax for keywords.
+* Keyword Procedures::          Procedures for dealing with keywords.
address@hidden menu
+
address@hidden Why Use Keywords?
address@hidden Why Use Keywords?
+
+Keywords are useful in contexts where a program or procedure wants to be
+able to accept a large number of optional arguments without making its
+interface unmanageable.
+
+To illustrate this, consider a hypothetical @code{make-window}
+procedure, which creates a new window on the screen for drawing into
+using some graphical toolkit.  There are many parameters that the caller
+might like to specify, but which could also be sensibly defaulted, for
+example:
+
address@hidden @bullet
address@hidden
+color depth -- Default: the color depth for the screen
+
address@hidden
+background color -- Default: white
+
address@hidden
+width -- Default: 600
+
address@hidden
+height -- Default: 400
address@hidden itemize
+
+If @code{make-window} did not use keywords, the caller would have to
+pass in a value for each possible argument, remembering the correct
+argument order and using a special value to indicate the default value
+for that argument:
+
address@hidden
+(make-window 'default              ;; Color depth
+             'default              ;; Background color
+             800                   ;; Width
+             100                   ;; Height
+             @dots{})                  ;; More make-window arguments
address@hidden lisp
+
+With keywords, on the other hand, defaulted arguments are omitted, and
+non-default arguments are clearly tagged by the appropriate keyword.  As
+a result, the invocation becomes much clearer:
+
address@hidden
+(make-window #:width 800 #:height 100)
address@hidden lisp
+
+On the other hand, for a simpler procedure with few arguments, the use
+of keywords would be a hindrance rather than a help.  The primitive
+procedure @code{cons}, for example, would not be improved if it had to
+be invoked as
+
address@hidden
+(cons #:car x #:cdr y)
address@hidden lisp
+
+So the decision whether to use keywords or not is purely pragmatic: use
+them if they will clarify the procedure invocation at point of call.
+
address@hidden Coding With Keywords
address@hidden Coding With Keywords
+
+If a procedure wants to support keywords, it should take a rest argument
+and then use whatever means is convenient to extract keywords and their
+corresponding arguments from the contents of that rest argument.
+
+The following example illustrates the principle: the code for
address@hidden uses a helper procedure called
address@hidden to extract individual keyword arguments from
+the rest argument.
+
address@hidden
+(define (get-keyword-value args keyword default)
+  (let ((kv (memq keyword args)))
+    (if (and kv (>= (length kv) 2))
+        (cadr kv)
+        default)))
+
+(define (make-window . args)
+  (let ((depth  (get-keyword-value args #:depth  screen-depth))
+        (bg     (get-keyword-value args #:bg     "white"))
+        (width  (get-keyword-value args #:width  800))
+        (height (get-keyword-value args #:height 100))
+        @dots{})
+    @dots{}))
address@hidden lisp
+
+But you don't need to write @code{get-keyword-value}.  The @code{(ice-9
+optargs)} module provides a set of powerful macros that you can use to
+implement keyword-supporting procedures like this:
+
address@hidden
+(use-modules (ice-9 optargs))
+
+(define (make-window . args)
+  (let-keywords args #f ((depth  screen-depth)
+                         (bg     "white")
+                         (width  800)
+                         (height 100))
+    ...))
address@hidden lisp
+
address@hidden
+Or, even more economically, like this:
+
address@hidden
+(use-modules (ice-9 optargs))
+
+(define* (make-window #:key (depth  screen-depth)
+                            (bg     "white")
+                            (width  800)
+                            (height 100))
+  ...)
address@hidden lisp
+
+For further details on @code{let-keywords}, @code{define*} and other
+facilities provided by the @code{(ice-9 optargs)} module, see
address@hidden Arguments}.
+
+To handle keyword arguments from procedures implemented in C,
+use @code{scm_c_bind_keyword_arguments} (@pxref{Keyword Procedures}).
+
address@hidden Keyword Read Syntax
address@hidden Keyword Read Syntax
+
+Guile, by default, only recognizes a keyword syntax that is compatible
+with R5RS.  A token of the form @code{#:NAME}, where @code{NAME} has the
+same syntax as a Scheme symbol (@pxref{Symbol Read Syntax}), is the
+external representation of the keyword named @code{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.
+
+If the @code{keywords} read option is set to @code{'prefix}, Guile also
+recognizes the alternative read syntax @code{:NAME}.  Otherwise, tokens
+of the form @code{:NAME} are read as symbols, as required by R5RS.
+
address@hidden SRFI-88 keyword syntax
+
+If the @code{keyword} read option is set to @code{'postfix}, Guile
+recognizes the SRFI-88 read syntax @code{NAME:} (@pxref{SRFI-88}).
+Otherwise, tokens of this form are read as symbols.
+
+To enable and disable the alternative non-R5RS keyword syntax, you use
+the @code{read-set!} procedure documented @ref{Scheme Read}.  Note that
+the @code{prefix} and @code{postfix} syntax are mutually exclusive.
+
address@hidden
+(read-set! keywords 'prefix)
+
+#:type
address@hidden
+#:type
+
+:type
address@hidden
+#:type
+
+(read-set! keywords 'postfix)
+
+type:
address@hidden
+#:type
+
+:type
address@hidden
+:type
+
+(read-set! keywords #f)
+
+#:type
address@hidden
+#:type
+
+:type
address@hidden
+ERROR: In expression :type:
+ERROR: Unbound variable: :type
+ABORT: (unbound-variable)
address@hidden lisp
+
address@hidden Keyword Procedures
address@hidden Keyword Procedures
+
address@hidden {Scheme Procedure} keyword? obj
address@hidden {C Function} scm_keyword_p (obj)
+Return @code{#t} if the argument @var{obj} is a keyword, else
address@hidden
address@hidden deffn
+
address@hidden {Scheme Procedure} keyword->symbol keyword
address@hidden {C Function} scm_keyword_to_symbol (keyword)
+Return the symbol with the same name as @var{keyword}.
address@hidden deffn
+
address@hidden {Scheme Procedure} symbol->keyword symbol
address@hidden {C Function} scm_symbol_to_keyword (symbol)
+Return the keyword with the same name as @var{symbol}.
address@hidden deffn
+
address@hidden {C Function} int scm_is_keyword (SCM obj)
+Equivalent to @code{scm_is_true (scm_keyword_p (@var{obj}))}.
address@hidden deftypefn
+
address@hidden {C Function} SCM scm_from_locale_keyword (const char *name)
address@hidden {C Function} SCM scm_from_locale_keywordn (const char *name, 
size_t len)
+Equivalent to @code{scm_symbol_to_keyword (scm_from_locale_symbol
+(@var{name}))} and @code{scm_symbol_to_keyword (scm_from_locale_symboln
+(@var{name}, @var{len}))}, respectively.
+
+Note that these functions should @emph{not} be used when @var{name} is a
+C string constant, because there is no guarantee that the current locale
+will match that of the execution character set, used for string and
+character constants.  Most modern C compilers use UTF-8 by default, so
+in such cases we recommend @code{scm_from_utf8_keyword}.
address@hidden deftypefn
+
address@hidden {C Function} SCM scm_from_latin1_keyword (const char *name)
address@hidden {C Function} SCM scm_from_utf8_keyword (const char *name)
+Equivalent to @code{scm_symbol_to_keyword (scm_from_latin1_symbol
+(@var{name}))} and @code{scm_symbol_to_keyword (scm_from_utf8_symbol
+(@var{name}))}, respectively.
address@hidden deftypefn
+
address@hidden {C Function} void scm_c_bind_keyword_arguments (const char 
*subr, @
+                             SCM rest, scm_t_keyword_arguments_flags flags, @
+                             SCM keyword1, SCM *argp1, @
+                             @dots{}, @
+                             SCM keywordN, SCM *argpN, @
+                             @nicode{SCM_UNDEFINED})
+
+Extract the specified keyword arguments from @var{rest}, which is not
+modified.  If the keyword argument @var{keyword1} is present in
address@hidden with an associated value, that value is stored in the
+variable pointed to by @var{argp1}, otherwise the variable is left
+unchanged.  Similarly for the other keywords and argument pointers up to
address@hidden and @var{argpN}.  The argument list to
address@hidden must be terminated by
address@hidden
+
+Note that since the variables pointed to by @var{argp1} through
address@hidden are left unchanged if the associated keyword argument is not
+present, they should be initialized to their default values before
+calling @code{scm_c_bind_keyword_arguments}.  Alternatively, you can
+initialize them to @code{SCM_UNDEFINED} before the call, and then use
address@hidden after the call to see which ones were provided.
+
+If an unrecognized keyword argument is present in @var{rest} and
address@hidden does not contain @code{SCM_ALLOW_OTHER_KEYS}, or if
+non-keyword arguments are present and @var{flags} does not contain
address@hidden, an exception is raised.
address@hidden should be the name of the procedure receiving the keyword
+arguments, for purposes of error reporting.
+
+For example:
+
address@hidden
+SCM k_delimiter;
+SCM k_grammar;
+SCM sym_infix;
+
+SCM my_string_join (SCM strings, SCM rest)
address@hidden
+  SCM delimiter = SCM_UNDEFINED;
+  SCM grammar   = sym_infix;
+
+  scm_c_bind_keyword_arguments ("my-string-join", rest, 0,
+                                k_delimiter, &delimiter,
+                                k_grammar, &grammar,
+                                SCM_UNDEFINED);
+
+  if (SCM_UNBNDP (delimiter))
+    delimiter = scm_from_utf8_string (" ");
+
+  return scm_string_join (strings, delimiter, grammar);
address@hidden
+
+void my_init ()
address@hidden
+  k_delimiter = scm_from_utf8_keyword ("delimiter");
+  k_grammar   = scm_from_utf8_keyword ("grammar");
+  sym_infix   = scm_from_utf8_symbol  ("infix");
+  scm_c_define_gsubr ("my-string-join", 1, 0, 1, my_string_join);
address@hidden
address@hidden example
address@hidden deftypefn
+
+
address@hidden Pairs
address@hidden Pairs
address@hidden Pairs
+
+Pairs are used to combine two Scheme objects into one compound object.
+Hence the name: A pair stores a pair of objects.
+
+The data type @dfn{pair} is extremely important in Scheme, just like in
+any other Lisp dialect.  The reason is that pairs are not only used to
+make two values available as one object, but that pairs are used for
+constructing lists of values.  Because lists are so important in Scheme,
+they are described in a section of their own (@pxref{Lists}).
+
+Pairs can literally get entered in source code or at the REPL, in the
+so-called @dfn{dotted list} syntax.  This syntax consists of an opening
+parentheses, the first element of the pair, a dot, the second element
+and a closing parentheses.  The following example shows how a pair
+consisting of the two numbers 1 and 2, and a pair containing the symbols
address@hidden and @code{bar} can be entered.  It is very important to write
+the whitespace before and after the dot, because otherwise the Scheme
+parser would not be able to figure out where to split the tokens.
+
address@hidden
+(1 . 2)
+(foo . bar)
address@hidden lisp
+
+But beware, if you want to try out these examples, you have to
address@hidden the expressions.  More information about quotation is
+available in the section @ref{Expression Syntax}.  The correct way
+to try these examples is as follows.
+
address@hidden
+'(1 . 2)
address@hidden
+(1 . 2)
+'(foo . bar)
address@hidden
+(foo . bar)
address@hidden lisp
+
+A new pair is made by calling the procedure @code{cons} with two
+arguments.  Then the argument values are stored into a newly allocated
+pair, and the pair is returned.  The name @code{cons} stands for
+"construct".  Use the procedure @code{pair?} to test whether a
+given Scheme object is a pair or not.
+
address@hidden cons
address@hidden {Scheme Procedure} cons x y
address@hidden {C Function} scm_cons (x, y)
+Return a newly allocated pair whose car is @var{x} and whose
+cdr is @var{y}.  The pair is guaranteed to be different (in the
+sense of @code{eq?}) from every previously existing object.
address@hidden deffn
+
address@hidden pair?
address@hidden {Scheme Procedure} pair? x
address@hidden {C Function} scm_pair_p (x)
+Return @code{#t} if @var{x} is a pair; otherwise return
address@hidden
address@hidden deffn
+
address@hidden {C Function} int scm_is_pair (SCM x)
+Return 1 when @var{x} is a pair; otherwise return 0.
address@hidden deftypefn
+
+The two parts of a pair are traditionally called @dfn{car} and
address@hidden  They can be retrieved with procedures of the same name
+(@code{car} and @code{cdr}), and can be modified with the procedures
address@hidden and @code{set-cdr!}.
+
+Since a very common operation in Scheme programs is to access the car of
+a car of a pair, or the car of the cdr of a pair, etc., the procedures
+called @code{caar}, @code{cadr} and so on are also predefined.  However,
+using these procedures is often detrimental to readability, and
+error-prone.  Thus, accessing the contents of a list is usually better
+achieved using pattern matching techniques (@pxref{Pattern Matching}).
+
address@hidden car
address@hidden cdr
address@hidden {Scheme Procedure} car pair
address@hidden {Scheme Procedure} cdr pair
address@hidden {C Function} scm_car (pair)
address@hidden {C Function} scm_cdr (pair)
+Return the car or the cdr of @var{pair}, respectively.
address@hidden deffn
+
address@hidden  {C Macro} SCM SCM_CAR (SCM pair)
address@hidden {C Macro} SCM SCM_CDR (SCM pair)
+These two macros are the fastest way to access the car or cdr of a
+pair; they can be thought of as compiling into a single memory
+reference.
+
+These macros do no checking at all.  The argument @var{pair} must be a
+valid pair.
address@hidden deftypefn
+
address@hidden  {Scheme Procedure} cddr pair
address@hidden {Scheme Procedure} cdar pair
address@hidden {Scheme Procedure} cadr pair
address@hidden {Scheme Procedure} caar pair
address@hidden {Scheme Procedure} cdddr pair
address@hidden {Scheme Procedure} cddar pair
address@hidden {Scheme Procedure} cdadr pair
address@hidden {Scheme Procedure} cdaar pair
address@hidden {Scheme Procedure} caddr pair
address@hidden {Scheme Procedure} cadar pair
address@hidden {Scheme Procedure} caadr pair
address@hidden {Scheme Procedure} caaar pair
address@hidden {Scheme Procedure} cddddr pair
address@hidden {Scheme Procedure} cdddar pair
address@hidden {Scheme Procedure} cddadr pair
address@hidden {Scheme Procedure} cddaar pair
address@hidden {Scheme Procedure} cdaddr pair
address@hidden {Scheme Procedure} cdadar pair
address@hidden {Scheme Procedure} cdaadr pair
address@hidden {Scheme Procedure} cdaaar pair
address@hidden {Scheme Procedure} cadddr pair
address@hidden {Scheme Procedure} caddar pair
address@hidden {Scheme Procedure} cadadr pair
address@hidden {Scheme Procedure} cadaar pair
address@hidden {Scheme Procedure} caaddr pair
address@hidden {Scheme Procedure} caadar pair
address@hidden {Scheme Procedure} caaadr pair
address@hidden {Scheme Procedure} caaaar pair
address@hidden {C Function} scm_cddr (pair)
address@hidden {C Function} scm_cdar (pair)
address@hidden {C Function} scm_cadr (pair)
address@hidden {C Function} scm_caar (pair)
address@hidden {C Function} scm_cdddr (pair)
address@hidden {C Function} scm_cddar (pair)
address@hidden {C Function} scm_cdadr (pair)
address@hidden {C Function} scm_cdaar (pair)
address@hidden {C Function} scm_caddr (pair)
address@hidden {C Function} scm_cadar (pair)
address@hidden {C Function} scm_caadr (pair)
address@hidden {C Function} scm_caaar (pair)
address@hidden {C Function} scm_cddddr (pair)
address@hidden {C Function} scm_cdddar (pair)
address@hidden {C Function} scm_cddadr (pair)
address@hidden {C Function} scm_cddaar (pair)
address@hidden {C Function} scm_cdaddr (pair)
address@hidden {C Function} scm_cdadar (pair)
address@hidden {C Function} scm_cdaadr (pair)
address@hidden {C Function} scm_cdaaar (pair)
address@hidden {C Function} scm_cadddr (pair)
address@hidden {C Function} scm_caddar (pair)
address@hidden {C Function} scm_cadadr (pair)
address@hidden {C Function} scm_cadaar (pair)
address@hidden {C Function} scm_caaddr (pair)
address@hidden {C Function} scm_caadar (pair)
address@hidden {C Function} scm_caaadr (pair)
address@hidden {C Function} scm_caaaar (pair)
+These procedures are compositions of @code{car} and @code{cdr}, where
+for example @code{caddr} could be defined by
+
address@hidden
+(define caddr (lambda (x) (car (cdr (cdr x)))))
address@hidden lisp
+
address@hidden, @code{caddr} and @code{cadddr} pick out the second, third
+or fourth elements of a list, respectively.  SRFI-1 provides the same
+under the names @code{second}, @code{third} and @code{fourth}
+(@pxref{SRFI-1 Selectors}).
address@hidden deffn
+
address@hidden set-car!
address@hidden {Scheme Procedure} set-car! pair value
address@hidden {C Function} scm_set_car_x (pair, value)
+Stores @var{value} in the car field of @var{pair}.  The value returned
+by @code{set-car!} is unspecified.
address@hidden deffn
+
address@hidden set-cdr!
address@hidden {Scheme Procedure} set-cdr! pair value
address@hidden {C Function} scm_set_cdr_x (pair, value)
+Stores @var{value} in the cdr field of @var{pair}.  The value returned
+by @code{set-cdr!} is unspecified.
address@hidden deffn
+
+
address@hidden Lists
address@hidden Lists
address@hidden Lists
+
+A very important data type in Scheme---as well as in all other Lisp
+dialects---is the data type @address@hidden speaking,
+Scheme does not have a real datatype @dfn{list}.  Lists are made up of
address@hidden pairs}, and only exist by definition---a list is a chain
+of pairs which looks like a list.}
+
+This is the short definition of what a list is:
+
address@hidden @bullet
address@hidden
+Either the empty list @code{()},
+
address@hidden
+or a pair which has a list in its cdr.
address@hidden itemize
+
address@hidden FIXME::martin: Describe the pair chaining in more detail.
+
address@hidden FIXME::martin: What is a proper, what an improper list?
address@hidden What is a circular list?
+
address@hidden FIXME::martin: Maybe steal some graphics from the Elisp 
reference 
address@hidden manual?
+
address@hidden
+* List Syntax::                 Writing literal lists.
+* List Predicates::             Testing lists.
+* List Constructors::           Creating new lists.
+* List Selection::              Selecting from lists, getting their length.
+* Append/Reverse::              Appending and reversing lists.
+* List Modification::           Modifying existing lists.
+* List Searching::              Searching for list elements
+* List Mapping::                Applying procedures to lists.
address@hidden menu
+
address@hidden List Syntax
address@hidden List Read Syntax
+
+The syntax for lists is an opening parentheses, then all the elements of
+the list (separated by whitespace) and finally a closing
address@hidden that there is no separation character between
+the list elements, like a comma or a semicolon.}.
+
address@hidden
+(1 2 3)            ; @r{a list of the numbers 1, 2 and 3}
+("foo" bar 3.1415) ; @r{a string, a symbol and a real number}
+()                 ; @r{the empty list}
address@hidden lisp
+
+The last example needs a bit more explanation.  A list with no elements,
+called the @dfn{empty list}, is special in some ways.  It is used for
+terminating lists by storing it into the cdr of the last pair that makes
+up a list.  An example will clear that up:
+
address@hidden
+(car '(1))
address@hidden
+1
+(cdr '(1))
address@hidden
+()
address@hidden lisp
+
+This example also shows that lists have to be quoted when written
+(@pxref{Expression Syntax}), because they would otherwise be
+mistakingly taken as procedure applications (@pxref{Simple
+Invocation}).
+
+
address@hidden List Predicates
address@hidden List Predicates
+
+Often it is useful to test whether a given Scheme object is a list or
+not.  List-processing procedures could use this information to test
+whether their input is valid, or they could do different things
+depending on the datatype of their arguments.
+
address@hidden list?
address@hidden {Scheme Procedure} list? x
address@hidden {C Function} scm_list_p (x)
+Return @code{#t} if @var{x} is a proper list, else @code{#f}.
address@hidden deffn
+
+The predicate @code{null?} is often used in list-processing code to
+tell whether a given list has run out of elements.  That is, a loop
+somehow deals with the elements of a list until the list satisfies
address@hidden  Then, the algorithm terminates.
+
address@hidden null?
address@hidden {Scheme Procedure} null? x
address@hidden {C Function} scm_null_p (x)
+Return @code{#t} if @var{x} is the empty list, else @code{#f}.
address@hidden deffn
+
address@hidden {C Function} int scm_is_null (SCM x)
+Return 1 when @var{x} is the empty list; otherwise return 0.
address@hidden deftypefn
+
+
address@hidden List Constructors
address@hidden List Constructors
+
+This section describes the procedures for constructing new lists.
address@hidden simply returns a list where the elements are the arguments,
address@hidden is similar, but the last argument is stored in the cdr of
+the last pair of the list.
+
address@hidden  C Function scm_list(rest) used to be documented here, but it's a
address@hidden  no-op since it does nothing but return the list the caller must
address@hidden  have already created.
address@hidden
address@hidden {Scheme Procedure} list elem @dots{}
address@hidden {C Function} scm_list_1 (elem1)
address@hidden {C Function} scm_list_2 (elem1, elem2)
address@hidden {C Function} scm_list_3 (elem1, elem2, elem3)
address@hidden {C Function} scm_list_4 (elem1, elem2, elem3, elem4)
address@hidden {C Function} scm_list_5 (elem1, elem2, elem3, elem4, elem5)
address@hidden {C Function} scm_list_n (elem1, @dots{}, elemN, 
@nicode{SCM_UNDEFINED})
address@hidden list
+Return a new list containing elements @var{elem} @enddots{}.
+
address@hidden takes a variable number of arguments, terminated by
+the special @code{SCM_UNDEFINED}.  That final @code{SCM_UNDEFINED} is
+not included in the list.  None of @var{elem} @dots{} can
+themselves be @code{SCM_UNDEFINED}, or @code{scm_list_n} will
+terminate at that point.
address@hidden deffn
+
address@hidden  C Function scm_cons_star(arg1,rest) used to be documented here,
address@hidden  but it's not really a useful interface, since it expects the
address@hidden  caller to have already consed up all but the first argument
address@hidden  already.
address@hidden
address@hidden {Scheme Procedure} cons* arg1 arg2 @dots{}
+Like @code{list}, but the last arg provides the tail of the
+constructed list, returning @code{(cons @var{arg1} (cons
address@hidden (cons @dots{} @var{argn})))}.  Requires at least one
+argument.  If given one argument, that argument is returned as
+result.  This function is called @code{list*} in some other
+Schemes and in Common LISP.
address@hidden deffn
+
address@hidden {Scheme Procedure} list-copy lst
address@hidden {C Function} scm_list_copy (lst)
+Return a (newly-created) copy of @var{lst}.
address@hidden deffn
+
address@hidden {Scheme Procedure} make-list n [init]
+Create a list containing of @var{n} elements, where each element is
+initialized to @var{init}.  @var{init} defaults to the empty list
address@hidden()} if not given.
address@hidden deffn
+
+Note that @code{list-copy} only makes a copy of the pairs which make up
+the spine of the lists.  The list elements are not copied, which means
+that modifying the elements of the new list also modifies the elements
+of the old list.  On the other hand, applying procedures like
address@hidden or @code{delv!} to the new list will not alter the old
+list.  If you also need to copy the list elements (making a deep copy),
+use the procedure @code{copy-tree} (@pxref{Copying}).
+
address@hidden List Selection
address@hidden List Selection
+
+These procedures are used to get some information about a list, or to
+retrieve one or more elements of a list.
+
address@hidden length
address@hidden {Scheme Procedure} length lst
address@hidden {C Function} scm_length (lst)
+Return the number of elements in list @var{lst}.
address@hidden deffn
+
address@hidden {Scheme Procedure} last-pair lst
address@hidden {C Function} scm_last_pair (lst)
+Return the last pair in @var{lst}, signalling an error if
address@hidden is circular.
address@hidden deffn
+
address@hidden list-ref
address@hidden {Scheme Procedure} list-ref list k
address@hidden {C Function} scm_list_ref (list, k)
+Return the @var{k}th element from @var{list}.
address@hidden deffn
+
address@hidden list-tail
address@hidden {Scheme Procedure} list-tail lst k
address@hidden {Scheme Procedure} list-cdr-ref lst k
address@hidden {C Function} scm_list_tail (lst, k)
+Return the "tail" of @var{lst} beginning with its @var{k}th element.
+The first element of the list is considered to be element 0.
+
address@hidden and @code{list-cdr-ref} are identical.  It may help to
+think of @code{list-cdr-ref} as accessing the @var{k}th cdr of the list,
+or returning the results of cdring @var{k} times down @var{lst}.
address@hidden deffn
+
address@hidden {Scheme Procedure} list-head lst k
address@hidden {C Function} scm_list_head (lst, k)
+Copy the first @var{k} elements from @var{lst} into a new list, and
+return it.
address@hidden deffn
+
address@hidden Append/Reverse
address@hidden Append and Reverse
+
address@hidden and @code{append!} are used to concatenate two or more
+lists in order to form a new list.  @code{reverse} and @code{reverse!}
+return lists with the same elements as their arguments, but in reverse
+order.  The procedure variants with an @code{!} directly modify the
+pairs which form the list, whereas the other procedures create new
+pairs.  This is why you should be careful when using the side-effecting
+variants.
+
address@hidden append
address@hidden {Scheme Procedure} append lst @dots{} obj
address@hidden {Scheme Procedure} append
address@hidden {Scheme Procedure} append! lst @dots{} obj
address@hidden {Scheme Procedure} append!
address@hidden {C Function} scm_append (lstlst)
address@hidden {C Function} scm_append_x (lstlst)
+Return a list comprising all the elements of lists @var{lst} @dots{}
address@hidden  If called with no arguments, return the empty list.
+
address@hidden
+(append '(x) '(y))          @result{}  (x y)
+(append '(a) '(b c d))      @result{}  (a b c d)
+(append '(a (b)) '((c)))    @result{}  (a (b) (c))
address@hidden lisp
+
+The last argument @var{obj} may actually be any object; an improper
+list results if the last argument is not a proper list.
+
address@hidden
+(append '(a b) '(c . d))    @result{}  (a b c . d)
+(append '() 'a)             @result{}  a
address@hidden lisp
+
address@hidden doesn't modify the given lists, but the return may share
+structure with the final @var{obj}.  @code{append!} is permitted, but
+not required, to modify the given lists to form its return.
+
+For @code{scm_append} and @code{scm_append_x}, @var{lstlst} is a list
+of the list operands @var{lst} @dots{} @var{obj}.  That @var{lstlst}
+itself is not modified or used in the return.
address@hidden deffn
+
address@hidden reverse
address@hidden {Scheme Procedure} reverse lst
address@hidden {Scheme Procedure} reverse! lst [newtail]
address@hidden {C Function} scm_reverse (lst)
address@hidden {C Function} scm_reverse_x (lst, newtail)
+Return a list comprising the elements of @var{lst}, in reverse order.
+
address@hidden constructs a new list.  @code{reverse!} is permitted, but
+not required, to modify @var{lst} in constructing its return.
+
+For @code{reverse!}, the optional @var{newtail} is appended to the
+result.  @var{newtail} isn't reversed, it simply becomes the list
+tail.  For @code{scm_reverse_x}, the @var{newtail} parameter is
+mandatory, but can be @code{SCM_EOL} if no further tail is required.
address@hidden deffn
+
address@hidden List Modification
address@hidden List Modification
+
+The following procedures modify an existing list, either by changing
+elements of the list, or by changing the list structure itself.
+
address@hidden {Scheme Procedure} list-set! list k val
address@hidden {C Function} scm_list_set_x (list, k, val)
+Set the @var{k}th element of @var{list} to @var{val}.
address@hidden deffn
+
address@hidden {Scheme Procedure} list-cdr-set! list k val
address@hidden {C Function} scm_list_cdr_set_x (list, k, val)
+Set the @var{k}th cdr of @var{list} to @var{val}.
address@hidden deffn
+
address@hidden {Scheme Procedure} delq item lst
address@hidden {C Function} scm_delq (item, lst)
+Return a newly-created copy of @var{lst} with elements
address@hidden to @var{item} removed.  This procedure mirrors
address@hidden: @code{delq} compares elements of @var{lst} against
address@hidden with @code{eq?}.
address@hidden deffn
+
address@hidden {Scheme Procedure} delv item lst
address@hidden {C Function} scm_delv (item, lst)
+Return a newly-created copy of @var{lst} with elements
address@hidden to @var{item} removed.  This procedure mirrors
address@hidden: @code{delv} compares elements of @var{lst} against
address@hidden with @code{eqv?}.
address@hidden deffn
+
address@hidden {Scheme Procedure} delete item lst
address@hidden {C Function} scm_delete (item, lst)
+Return a newly-created copy of @var{lst} with elements
address@hidden to @var{item} removed.  This procedure mirrors
address@hidden: @code{delete} compares elements of @var{lst}
+against @var{item} with @code{equal?}.
+
+See also SRFI-1 which has an extended @code{delete} (@ref{SRFI-1
+Deleting}), and also an @code{lset-difference} which can delete
+multiple @var{item}s in one call (@ref{SRFI-1 Set Operations}).
address@hidden deffn
+
address@hidden {Scheme Procedure} delq! item lst
address@hidden {Scheme Procedure} delv! item lst
address@hidden {Scheme Procedure} delete! item lst
address@hidden {C Function} scm_delq_x (item, lst)
address@hidden {C Function} scm_delv_x (item, lst)
address@hidden {C Function} scm_delete_x (item, lst)
+These procedures are destructive versions of @code{delq}, @code{delv}
+and @code{delete}: they modify the pointers in the existing @var{lst}
+rather than creating a new list.  Caveat evaluator: Like other
+destructive list functions, these functions cannot modify the binding of
address@hidden, and so cannot be used to delete the first element of
address@hidden destructively.
address@hidden deffn
+
address@hidden {Scheme Procedure} delq1! item lst
address@hidden {C Function} scm_delq1_x (item, lst)
+Like @code{delq!}, but only deletes the first occurrence of
address@hidden from @var{lst}.  Tests for equality using
address@hidden  See also @code{delv1!} and @code{delete1!}.
address@hidden deffn
+
address@hidden {Scheme Procedure} delv1! item lst
address@hidden {C Function} scm_delv1_x (item, lst)
+Like @code{delv!}, but only deletes the first occurrence of
address@hidden from @var{lst}.  Tests for equality using
address@hidden  See also @code{delq1!} and @code{delete1!}.
address@hidden deffn
+
address@hidden {Scheme Procedure} delete1! item lst
address@hidden {C Function} scm_delete1_x (item, lst)
+Like @code{delete!}, but only deletes the first occurrence of
address@hidden from @var{lst}.  Tests for equality using
address@hidden  See also @code{delq1!} and @code{delv1!}.
address@hidden deffn
+
address@hidden {Scheme Procedure} filter pred lst
address@hidden {Scheme Procedure} filter! pred lst
+Return a list containing all elements from @var{lst} which satisfy the
+predicate @var{pred}.  The elements in the result list have the same
+order as in @var{lst}.  The order in which @var{pred} is applied to
+the list elements is not specified.
+
address@hidden does not change @var{lst}, but the result may share a
+tail with it.  @code{filter!} may modify @var{lst} to construct its
+return.
address@hidden deffn
+
address@hidden List Searching
address@hidden List Searching
+
+The following procedures search lists for particular elements.  They use
+different comparison predicates for comparing list elements with the
+object to be searched.  When they fail, they return @code{#f}, otherwise
+they return the sublist whose car is equal to the search object, where
+equality depends on the equality predicate used.
+
address@hidden memq
address@hidden {Scheme Procedure} memq x lst
address@hidden {C Function} scm_memq (x, lst)
+Return the first sublist of @var{lst} whose car is @code{eq?}
+to @var{x} where the sublists of @var{lst} are the non-empty
+lists returned by @code{(list-tail @var{lst} @var{k})} for
address@hidden less than the length of @var{lst}.  If @var{x} does not
+occur in @var{lst}, then @code{#f} (not the empty list) is
+returned.
address@hidden deffn
+
address@hidden memv
address@hidden {Scheme Procedure} memv x lst
address@hidden {C Function} scm_memv (x, lst)
+Return the first sublist of @var{lst} whose car is @code{eqv?}
+to @var{x} where the sublists of @var{lst} are the non-empty
+lists returned by @code{(list-tail @var{lst} @var{k})} for
address@hidden less than the length of @var{lst}.  If @var{x} does not
+occur in @var{lst}, then @code{#f} (not the empty list) is
+returned.
address@hidden deffn
+
address@hidden member
address@hidden {Scheme Procedure} member x lst
address@hidden {C Function} scm_member (x, lst)
+Return the first sublist of @var{lst} whose car is
address@hidden to @var{x} where the sublists of @var{lst} are
+the non-empty lists returned by @code{(list-tail @var{lst}
address@hidden)} for @var{k} less than the length of @var{lst}.  If
address@hidden does not occur in @var{lst}, then @code{#f} (not the
+empty list) is returned.
+
+See also SRFI-1 which has an extended @code{member} function
+(@ref{SRFI-1 Searching}).
address@hidden deffn
+
+
address@hidden List Mapping
address@hidden List Mapping
+
+List processing is very convenient in Scheme because the process of
+iterating over the elements of a list can be highly abstracted.  The
+procedures in this section are the most basic iterating procedures for
+lists.  They take a procedure and one or more lists as arguments, and
+apply the procedure to each element of the list.  They differ in their
+return value.
+
address@hidden map
address@hidden begin (texi-doc-string "guile" "map")
address@hidden {Scheme Procedure} map proc arg1 arg2 @dots{}
address@hidden {Scheme Procedure} map-in-order proc arg1 arg2 @dots{}
address@hidden {C Function} scm_map (proc, arg1, args)
+Apply @var{proc} to each element of the list @var{arg1} (if only two
+arguments are given), or to the corresponding elements of the argument
+lists (if more than two arguments are given).  The result(s) of the
+procedure applications are saved and returned in a list.  For
address@hidden, the order of procedure applications is not specified,
address@hidden applies the procedure from left to right to the list
+elements.
address@hidden deffn
+
address@hidden for-each
address@hidden begin (texi-doc-string "guile" "for-each")
address@hidden {Scheme Procedure} for-each proc arg1 arg2 @dots{}
+Like @code{map}, but the procedure is always applied from left to right,
+and the result(s) of the procedure applications are thrown away.  The
+return value is not specified.
address@hidden deffn
+
+See also SRFI-1 which extends these functions to take lists of unequal
+lengths (@ref{SRFI-1 Fold and Map}).
+
address@hidden Vectors
address@hidden Vectors
address@hidden Vectors
+
+Vectors are sequences of Scheme objects.  Unlike lists, the length of a
+vector, once the vector is created, cannot be changed.  The advantage of
+vectors over lists is that the time required to access one element of a vector
+given its @dfn{position} (synonymous with @dfn{index}), a zero-origin number,
+is constant, whereas lists have an access time linear to the position of the
+accessed element in the list.
+
+Vectors can contain any kind of Scheme object; it is even possible to
+have different types of objects in the same vector.  For vectors
+containing vectors, you may wish to use arrays, instead.  Note, too,
+that vectors are the special case of one dimensional non-uniform arrays
+and that most array procedures operate happily on vectors
+(@pxref{Arrays}).
+
+Also see @ref{SRFI-43}, for a comprehensive vector library.
+
address@hidden
+* Vector Syntax::               Read syntax for vectors.
+* Vector Creation::             Dynamic vector creation and validation.
+* Vector Accessors::            Accessing and modifying vector contents.
+* Vector Accessing from C::     Ways to work with vectors from C.
+* Uniform Numeric Vectors::     Vectors of unboxed numeric values.
address@hidden menu
+
+
address@hidden Vector Syntax
address@hidden Read Syntax for Vectors
+
+Vectors can literally be entered in source code, just like strings,
+characters or some of the other data types.  The read syntax for vectors
+is as follows: A sharp sign (@code{#}), followed by an opening
+parentheses, all elements of the vector in their respective read syntax,
+and finally a closing parentheses.  Like strings, vectors do not have to
+be quoted.
+
+The following are examples of the read syntax for vectors; where the
+first vector only contains numbers and the second three different object
+types: a string, a symbol and a number in hexadecimal notation.
+
address@hidden
+#(1 2 3)
+#("Hello" foo #xdeadbeef)
address@hidden lisp
+
address@hidden Vector Creation
address@hidden Dynamic Vector Creation and Validation
+
+Instead of creating a vector implicitly by using the read syntax just
+described, you can create a vector dynamically by calling one of the
address@hidden and @code{list->vector} primitives with the list of Scheme
+values that you want to place into a vector.  The size of the vector
+thus created is determined implicitly by the number of arguments given.
+
address@hidden vector
address@hidden list->vector
address@hidden {Scheme Procedure} vector arg @dots{}
address@hidden {Scheme Procedure} list->vector l
address@hidden {C Function} scm_vector (l)
+Return a newly allocated vector composed of the
+given arguments.  Analogous to @code{list}.
+
address@hidden
+(vector 'a 'b 'c) @result{} #(a b c)
address@hidden lisp
address@hidden deffn
+
+The inverse operation is @code{vector->list}:
+
address@hidden vector->list
address@hidden {Scheme Procedure} vector->list v
address@hidden {C Function} scm_vector_to_list (v)
+Return a newly allocated list composed of the elements of @var{v}.
+
address@hidden
+(vector->list #(dah dah didah)) @result{}  (dah dah didah)
+(list->vector '(dididit dah)) @result{}  #(dididit dah)
address@hidden lisp
address@hidden deffn
+
+To allocate a vector with an explicitly specified size, use
address@hidden  With this primitive you can also specify an initial
+value for the vector elements (the same value for all elements, that
+is):
+
address@hidden make-vector
address@hidden {Scheme Procedure} make-vector len [fill]
address@hidden {C Function} scm_make_vector (len, fill)
+Return a newly allocated vector of @var{len} elements.  If a
+second argument is given, then each position is initialized to
address@hidden  Otherwise the initial contents of each position is
+unspecified.
address@hidden deffn
+
address@hidden {C Function} SCM scm_c_make_vector (size_t k, SCM fill)
+Like @code{scm_make_vector}, but the length is given as a @code{size_t}.
address@hidden deftypefn
+
+To check whether an arbitrary Scheme value @emph{is} a vector, use the
address@hidden primitive:
+
address@hidden vector?
address@hidden {Scheme Procedure} vector? obj
address@hidden {C Function} scm_vector_p (obj)
+Return @code{#t} if @var{obj} is a vector, otherwise return
address@hidden
address@hidden deffn
+
address@hidden {C Function} int scm_is_vector (SCM obj)
+Return non-zero when @var{obj} is a vector, otherwise return
address@hidden
address@hidden deftypefn
+
address@hidden Vector Accessors
address@hidden Accessing and Modifying Vector Contents
+
address@hidden and @code{vector-ref} return information about a
+given vector, respectively its size and the elements that are contained
+in the vector.
+
address@hidden vector-length
address@hidden {Scheme Procedure} vector-length vector
address@hidden {C Function} scm_vector_length (vector)
+Return the number of elements in @var{vector} as an exact integer.
address@hidden deffn
+
address@hidden {C Function} size_t scm_c_vector_length (SCM vec)
+Return the number of elements in @var{vec} as a @code{size_t}.
address@hidden deftypefn
+
address@hidden vector-ref
address@hidden {Scheme Procedure} vector-ref vec k
address@hidden {C Function} scm_vector_ref (vec, k)
+Return the contents of position @var{k} of @var{vec}.
address@hidden must be a valid index of @var{vec}.
address@hidden
+(vector-ref #(1 1 2 3 5 8 13 21) 5) @result{} 8
+(vector-ref #(1 1 2 3 5 8 13 21)
+    (let ((i (round (* 2 (acos -1)))))
+      (if (inexact? i)
+        (inexact->exact i)
+           i))) @result{} 13
address@hidden lisp
address@hidden deffn
+
address@hidden {C Function} SCM scm_c_vector_ref (SCM vec, size_t k)
+Return the contents of position @var{k} (a @code{size_t}) of
address@hidden
address@hidden deftypefn
+
+A vector created by one of the dynamic vector constructor procedures
+(@pxref{Vector Creation}) can be modified using the following
+procedures.
+
address@hidden:} According to R5RS, it is an error to use any of these
+procedures on a literally read vector, because such vectors should be
+considered as constants.  Currently, however, Guile does not detect this
+error.
+
address@hidden vector-set!
address@hidden {Scheme Procedure} vector-set! vec k obj
address@hidden {C Function} scm_vector_set_x (vec, k, obj)
+Store @var{obj} in position @var{k} of @var{vec}.
address@hidden must be a valid index of @var{vec}.
+The value returned by @samp{vector-set!} is unspecified.
address@hidden
+(let ((vec (vector 0 '(2 2 2 2) "Anna")))
+  (vector-set! vec 1 '("Sue" "Sue"))
+  vec) @result{}  #(0 ("Sue" "Sue") "Anna")
address@hidden lisp
address@hidden deffn
+
address@hidden {C Function} void scm_c_vector_set_x (SCM vec, size_t k, SCM obj)
+Store @var{obj} in position @var{k} (a @code{size_t}) of @var{vec}.
address@hidden deftypefn
+
address@hidden vector-fill!
address@hidden {Scheme Procedure} vector-fill! vec fill
address@hidden {C Function} scm_vector_fill_x (vec, fill)
+Store @var{fill} in every position of @var{vec}.  The value
+returned by @code{vector-fill!} is unspecified.
address@hidden deffn
+
address@hidden {Scheme Procedure} vector-copy vec
address@hidden {C Function} scm_vector_copy (vec)
+Return a copy of @var{vec}.
address@hidden deffn
+
address@hidden {Scheme Procedure} vector-move-left! vec1 start1 end1 vec2 start2
address@hidden {C Function} scm_vector_move_left_x (vec1, start1, end1, vec2, 
start2)
+Copy elements from @var{vec1}, positions @var{start1} to @var{end1},
+to @var{vec2} starting at position @var{start2}.  @var{start1} and
address@hidden are inclusive indices; @var{end1} is exclusive.
+
address@hidden copies elements in leftmost order.
+Therefore, in the case where @var{vec1} and @var{vec2} refer to the
+same vector, @code{vector-move-left!} is usually appropriate when
address@hidden is greater than @var{start2}.
address@hidden deffn
+
address@hidden {Scheme Procedure} vector-move-right! vec1 start1 end1 vec2 
start2
address@hidden {C Function} scm_vector_move_right_x (vec1, start1, end1, vec2, 
start2)
+Copy elements from @var{vec1}, positions @var{start1} to @var{end1},
+to @var{vec2} starting at position @var{start2}.  @var{start1} and
address@hidden are inclusive indices; @var{end1} is exclusive.
+
address@hidden copies elements in rightmost order.
+Therefore, in the case where @var{vec1} and @var{vec2} refer to the
+same vector, @code{vector-move-right!} is usually appropriate when
address@hidden is less than @var{start2}.
address@hidden deffn
+
address@hidden Vector Accessing from C
address@hidden Vector Accessing from C
+
+A vector can be read and modified from C with the functions
address@hidden and @code{scm_c_vector_set_x}, for example.  In
+addition to these functions, there are two more ways to access vectors
+from C that might be more efficient in certain situations: you can
+restrict yourself to @dfn{simple vectors} and then use the very fast
address@hidden vector macros}; or you can use the very general framework
+for accessing all kinds of arrays (@pxref{Accessing Arrays from C}),
+which is more verbose, but can deal efficiently with all kinds of
+vectors (and arrays).  For vectors, you can use the
address@hidden and @code{scm_vector_writable_elements}
+functions as shortcuts.
+
address@hidden {C Function} int scm_is_simple_vector (SCM obj)
+Return non-zero if @var{obj} is a simple vector, else return zero.  A
+simple vector is a vector that can be used with the @code{SCM_SIMPLE_*}
+macros below.
+
+The following functions are guaranteed to return simple vectors:
address@hidden, @code{scm_c_make_vector}, @code{scm_vector},
address@hidden
address@hidden deftypefn
+
address@hidden {C Macro} size_t SCM_SIMPLE_VECTOR_LENGTH (SCM vec)
+Evaluates to the length of the simple vector @var{vec}.  No type
+checking is done.
address@hidden deftypefn
+
address@hidden {C Macro} SCM SCM_SIMPLE_VECTOR_REF (SCM vec, size_t idx)
+Evaluates to the element at position @var{idx} in the simple vector
address@hidden  No type or range checking is done.
address@hidden deftypefn
+
address@hidden {C Macro} void SCM_SIMPLE_VECTOR_SET (SCM vec, size_t idx, SCM 
val)
+Sets the element at position @var{idx} in the simple vector
address@hidden to @var{val}.  No type or range checking is done.
address@hidden deftypefn
+
address@hidden {C Function} {const SCM *} scm_vector_elements (SCM vec, 
scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+Acquire a handle for the vector @var{vec} and return a pointer to the
+elements of it.  This pointer can only be used to read the elements of
address@hidden  When @var{vec} is not a vector, an error is signaled.  The
+handle must eventually be released with
address@hidden
+
+The variables pointed to by @var{lenp} and @var{incp} are filled with
+the number of elements of the vector and the increment (number of
+elements) between successive elements, respectively.  Successive
+elements of @var{vec} need not be contiguous in their underlying
+``root vector'' returned here; hence the increment is not necessarily
+equal to 1 and may well be negative too (@pxref{Shared Arrays}).
+
+The following example shows the typical way to use this function.  It
+creates a list of all elements of @var{vec} (in reverse order).
+
address@hidden
+scm_t_array_handle handle;
+size_t i, len;
+ssize_t inc;
+const SCM *elt;
+SCM list;
+
+elt = scm_vector_elements (vec, &handle, &len, &inc);
+list = SCM_EOL;
+for (i = 0; i < len; i++, elt += inc)
+  list = scm_cons (*elt, list);
+scm_array_handle_release (&handle);
address@hidden example
+
address@hidden deftypefn
+
address@hidden {C Function} {SCM *} scm_vector_writable_elements (SCM vec, 
scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+Like @code{scm_vector_elements} but the pointer can be used to modify
+the vector.
+
+The following example shows the typical way to use this function.  It
+fills a vector with @code{#t}.
+
address@hidden
+scm_t_array_handle handle;
+size_t i, len;
+ssize_t inc;
+SCM *elt;
+
+elt = scm_vector_writable_elements (vec, &handle, &len, &inc);
+for (i = 0; i < len; i++, elt += inc)
+  *elt = SCM_BOOL_T;
+scm_array_handle_release (&handle);
address@hidden example
+
address@hidden deftypefn
+
address@hidden Uniform Numeric Vectors
address@hidden Uniform Numeric Vectors
+
+A uniform numeric vector is a vector whose elements are all of a single
+numeric type.  Guile offers uniform numeric vectors for signed and
+unsigned 8-bit, 16-bit, 32-bit, and 64-bit integers, two sizes of
+floating point values, and complex floating-point numbers of these two
+sizes. @xref{SRFI-4}, for more information.
+
+For many purposes, bytevectors work just as well as uniform vectors, and have
+the advantage that they integrate well with binary input and output.
address@hidden, for more information on bytevectors.
+
address@hidden Bit Vectors
address@hidden Bit Vectors
+
address@hidden
+Bit vectors are zero-origin, one-dimensional arrays of booleans.  They
+are displayed as a sequence of @code{0}s and @code{1}s prefixed by
address@hidden, e.g.,
+
address@hidden
+(make-bitvector 8 #f) @result{}
+#*00000000
address@hidden example
+
+Bit vectors are the special case of one dimensional bit arrays, and can
+thus be used with the array procedures, @xref{Arrays}.
+
address@hidden {Scheme Procedure} bitvector? obj
address@hidden {C Function} scm_bitvector_p (obj)
+Return @code{#t} when @var{obj} is a bitvector, else
+return @code{#f}.
address@hidden deffn
+
address@hidden {C Function} int scm_is_bitvector (SCM obj)
+Return @code{1} when @var{obj} is a bitvector, else return @code{0}.
address@hidden deftypefn
+
address@hidden {Scheme Procedure} make-bitvector len [fill]
address@hidden {C Function} scm_make_bitvector (len, fill)
+Create a new bitvector of length @var{len} and
+optionally initialize all elements to @var{fill}.
address@hidden deffn
+
address@hidden {C Function} SCM scm_c_make_bitvector (size_t len, SCM fill)
+Like @code{scm_make_bitvector}, but the length is given as a
address@hidden
address@hidden deftypefn
+
address@hidden {Scheme Procedure} bitvector bit @dots{}
address@hidden {C Function} scm_bitvector (bits)
+Create a new bitvector with the arguments as elements.
address@hidden deffn
+
address@hidden {Scheme Procedure} bitvector-length vec
address@hidden {C Function} scm_bitvector_length (vec)
+Return the length of the bitvector @var{vec}.
address@hidden deffn
+
address@hidden {C Function} size_t scm_c_bitvector_length (SCM vec)
+Like @code{scm_bitvector_length}, but the length is returned as a
address@hidden
address@hidden deftypefn
+
address@hidden {Scheme Procedure} bitvector-ref vec idx
address@hidden {C Function} scm_bitvector_ref (vec, idx)
+Return the element at index @var{idx} of the bitvector
address@hidden
address@hidden deffn
+
address@hidden {C Function} SCM scm_c_bitvector_ref (SCM vec, size_t idx)
+Return the element at index @var{idx} of the bitvector
address@hidden
address@hidden deftypefn
+
address@hidden {Scheme Procedure} bitvector-set! vec idx val
address@hidden {C Function} scm_bitvector_set_x (vec, idx, val)
+Set the element at index @var{idx} of the bitvector
address@hidden when @var{val} is true, else clear it.
address@hidden deffn
+
address@hidden {C Function} SCM scm_c_bitvector_set_x (SCM vec, size_t idx, SCM 
val)
+Set the element at index @var{idx} of the bitvector
address@hidden when @var{val} is true, else clear it.
address@hidden deftypefn
+
address@hidden {Scheme Procedure} bitvector-fill! vec val
address@hidden {C Function} scm_bitvector_fill_x (vec, val)
+Set all elements of the bitvector
address@hidden when @var{val} is true, else clear them.
address@hidden deffn
+
address@hidden {Scheme Procedure} list->bitvector list
address@hidden {C Function} scm_list_to_bitvector (list)
+Return a new bitvector initialized with the elements
+of @var{list}.
address@hidden deffn
+
address@hidden {Scheme Procedure} bitvector->list vec
address@hidden {C Function} scm_bitvector_to_list (vec)
+Return a new list initialized with the elements
+of the bitvector @var{vec}.
address@hidden deffn
+
address@hidden {Scheme Procedure} bit-count bool bitvector
address@hidden {C Function} scm_bit_count (bool, bitvector)
+Return a count of how many entries in @var{bitvector} are equal to
address@hidden  For example,
+
address@hidden
+(bit-count #f #*000111000)  @result{} 6
address@hidden example
address@hidden deffn
+
address@hidden {Scheme Procedure} bit-position bool bitvector start
address@hidden {C Function} scm_bit_position (bool, bitvector, start)
+Return the index of the first occurrence of @var{bool} in
address@hidden, starting from @var{start}.  If there is no @var{bool}
+entry between @var{start} and the end of @var{bitvector}, then return
address@hidden  For example,
+
address@hidden
+(bit-position #t #*000101 0)  @result{} 3
+(bit-position #f #*0001111 3) @result{} #f
address@hidden example
address@hidden deffn
+
address@hidden {Scheme Procedure} bit-invert! bitvector
address@hidden {C Function} scm_bit_invert_x (bitvector)
+Modify @var{bitvector} by replacing each element with its negation.
address@hidden deffn
+
address@hidden {Scheme Procedure} bit-set*! bitvector uvec bool
address@hidden {C Function} scm_bit_set_star_x (bitvector, uvec, bool)
+Set entries of @var{bitvector} to @var{bool}, with @var{uvec}
+selecting the entries to change.  The return value is unspecified.
+
+If @var{uvec} is a bit vector, then those entries where it has
address@hidden are the ones in @var{bitvector} which are set to @var{bool}.
address@hidden and @var{bitvector} must be the same length.  When
address@hidden is @code{#t} it's like @var{uvec} is OR'ed into
address@hidden  Or when @var{bool} is @code{#f} it can be seen as an
+ANDNOT.
+
address@hidden
+(define bv #*01000010)
+(bit-set*! bv #*10010001 #t)
+bv
address@hidden #*11010011
address@hidden example
+
+If @var{uvec} is a uniform vector of unsigned long integers, then
+they're indexes into @var{bitvector} which are set to @var{bool}.  
+
address@hidden
+(define bv #*01000010)
+(bit-set*! bv #u(5 2 7) #t)
+bv
address@hidden #*01100111
address@hidden example
address@hidden deffn
+
address@hidden {Scheme Procedure} bit-count* bitvector uvec bool
address@hidden {C Function} scm_bit_count_star (bitvector, uvec, bool)
+Return a count of how many entries in @var{bitvector} are equal to
address@hidden, with @var{uvec} selecting the entries to consider.
+
address@hidden is interpreted in the same way as for @code{bit-set*!}
+above.  Namely, if @var{uvec} is a bit vector then entries which have
address@hidden there are considered in @var{bitvector}.  Or if @var{uvec}
+is a uniform vector of unsigned long integers then it's the indexes in
address@hidden to consider.
+
+For example,
+
address@hidden
+(bit-count* #*01110111 #*11001101 #t) @result{} 3
+(bit-count* #*01110111 #u32(7 0 4) #f)  @result{} 2
address@hidden example
address@hidden deffn
+
address@hidden {C Function} {const scm_t_uint32 *} scm_bitvector_elements (SCM 
vec, scm_t_array_handle *handle, size_t *offp, size_t *lenp, ssize_t *incp)
+Like @code{scm_vector_elements} (@pxref{Vector Accessing from C}), but
+for bitvectors.  The variable pointed to by @var{offp} is set to the
+value returned by @code{scm_array_handle_bit_elements_offset}.  See
address@hidden for how to use the returned
+pointer and the offset.
address@hidden deftypefn
+
address@hidden {C Function} {scm_t_uint32 *} scm_bitvector_writable_elements 
(SCM vec, scm_t_array_handle *handle, size_t *offp, size_t *lenp, ssize_t *incp)
+Like @code{scm_bitvector_elements}, but the pointer is good for reading
+and writing.
address@hidden deftypefn
+
address@hidden Bytevectors
address@hidden Bytevectors
+
address@hidden bytevector
address@hidden R6RS
+
+A @dfn{bytevector} is a raw bit string.  The @code{(rnrs bytevectors)}
+module provides the programming interface specified by the
address@hidden://www.r6rs.org/, Revised^6 Report on the Algorithmic Language
+Scheme (R6RS)}.  It contains procedures to manipulate bytevectors and
+interpret their contents in a number of ways: bytevector contents can be
+accessed as signed or unsigned integer of various sizes and endianness,
+as IEEE-754 floating point numbers, or as strings.  It is a useful tool
+to encode and decode binary data.
+
+The R6RS (Section 4.3.4) specifies an external representation for
+bytevectors, whereby the octets (integers in the range 0--255) contained
+in the bytevector are represented as a list prefixed by @code{#vu8}:
+
address@hidden
+#vu8(1 53 204)
address@hidden lisp
+
+denotes a 3-byte bytevector containing the octets 1, 53, and 204.  Like
+string literals, booleans, etc., bytevectors are ``self-quoting'', i.e.,
+they do not need to be quoted:
+
address@hidden
+#vu8(1 53 204)
address@hidden #vu8(1 53 204)
address@hidden lisp
+
+Bytevectors can be used with the binary input/output primitives
+(@pxref{Binary I/O}).
+
address@hidden
+* Bytevector Endianness::       Dealing with byte order.
+* Bytevector Manipulation::     Creating, copying, manipulating bytevectors.
+* Bytevectors as Integers::     Interpreting bytes as integers.
+* Bytevectors and Integer Lists::  Converting to/from an integer list.
+* Bytevectors as Floats::       Interpreting bytes as real numbers.
+* Bytevectors as Strings::      Interpreting bytes as Unicode strings.
+* Bytevectors as Arrays::       Guile extension to the bytevector API.
+* Bytevectors as Uniform Vectors::  Bytevectors and SRFI-4.
address@hidden menu
+
address@hidden Bytevector Endianness
address@hidden Endianness
+
address@hidden endianness
address@hidden byte order
address@hidden word order
+
+Some of the following procedures take an @var{endianness} parameter.
+The @dfn{endianness} is defined as the order of bytes in multi-byte
+numbers: numbers encoded in @dfn{big endian} have their most
+significant bytes written first, whereas numbers encoded in
address@hidden endian} have their least significant bytes
address@hidden and little-endian are the most common
+``endiannesses'', but others do exist. For instance, the GNU MP
+library allows @dfn{word order} to be specified independently of
address@hidden order} (@pxref{Integer Import and Export,,, gmp, The GNU
+Multiple Precision Arithmetic Library Manual}).}.
+
+Little-endian is the native endianness of the IA32 architecture and
+its derivatives, while big-endian is native to SPARC and PowerPC,
+among others. The @code{native-endianness} procedure returns the
+native endianness of the machine it runs on.
+
address@hidden {Scheme Procedure} native-endianness
address@hidden {C Function} scm_native_endianness ()
+Return a value denoting the native endianness of the host machine.
address@hidden deffn
+
address@hidden {Scheme Macro} endianness symbol
+Return an object denoting the endianness specified by @var{symbol}.  If
address@hidden is neither @code{big} nor @code{little} then an error is
+raised at expand-time.
address@hidden deffn
+
address@hidden {C Variable} scm_endianness_big
address@hidden {C Variable} scm_endianness_little
+The objects denoting big- and little-endianness, respectively.
address@hidden defvr
+
+
address@hidden Bytevector Manipulation
address@hidden Manipulating Bytevectors
+
+Bytevectors can be created, copied, and analyzed with the following
+procedures and C functions.
+
address@hidden {Scheme Procedure} make-bytevector len [fill]
address@hidden {C Function} scm_make_bytevector (len, fill)
address@hidden {C Function} scm_c_make_bytevector (size_t len)
+Return a new bytevector of @var{len} bytes.  Optionally, if @var{fill}
+is given, fill it with @var{fill}; @var{fill} must be in the range
+[-128,255].
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector? obj
address@hidden {C Function} scm_bytevector_p (obj)
+Return true if @var{obj} is a bytevector.
address@hidden deffn
+
address@hidden {C Function} int scm_is_bytevector (SCM obj)
+Equivalent to @code{scm_is_true (scm_bytevector_p (obj))}.
address@hidden deftypefn
+
address@hidden {Scheme Procedure} bytevector-length bv
address@hidden {C Function} scm_bytevector_length (bv)
+Return the length in bytes of bytevector @var{bv}.
address@hidden deffn
+
address@hidden {C Function} size_t scm_c_bytevector_length (SCM bv)
+Likewise, return the length in bytes of bytevector @var{bv}.
address@hidden deftypefn
+
address@hidden {Scheme Procedure} bytevector=? bv1 bv2
address@hidden {C Function} scm_bytevector_eq_p (bv1, bv2)
+Return is @var{bv1} equals to @var{bv2}---i.e., if they have the same
+length and contents.
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector-fill! bv fill
address@hidden {C Function} scm_bytevector_fill_x (bv, fill)
+Fill bytevector @var{bv} with @var{fill}, a byte.
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector-copy! source source-start target 
target-start len
address@hidden {C Function} scm_bytevector_copy_x (source, source_start, 
target, target_start, len)
+Copy @var{len} bytes from @var{source} into @var{target}, starting
+reading from @var{source-start} (a positive index within @var{source})
+and start writing at @var{target-start}.  It is permitted for the
address@hidden and @var{target} regions to overlap.
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector-copy bv
address@hidden {C Function} scm_bytevector_copy (bv)
+Return a newly allocated copy of @var{bv}.
address@hidden deffn
+
address@hidden {C Function} scm_t_uint8 scm_c_bytevector_ref (SCM bv, size_t 
index)
+Return the byte at @var{index} in bytevector @var{bv}.
address@hidden deftypefn
+
address@hidden {C Function} void scm_c_bytevector_set_x (SCM bv, size_t index, 
scm_t_uint8 value)
+Set the byte at @var{index} in @var{bv} to @var{value}.
address@hidden deftypefn
+
+Low-level C macros are available.  They do not perform any
+type-checking; as such they should be used with care.
+
address@hidden {C Macro} size_t SCM_BYTEVECTOR_LENGTH (bv)
+Return the length in bytes of bytevector @var{bv}.
address@hidden deftypefn
+
address@hidden {C Macro} {signed char *} SCM_BYTEVECTOR_CONTENTS (bv)
+Return a pointer to the contents of bytevector @var{bv}.
address@hidden deftypefn
+
+
address@hidden Bytevectors as Integers
address@hidden Interpreting Bytevector Contents as Integers
 
 The contents of a bytevector can be interpreted as a sequence of
 integers of any given size, sign, and endianness.
 
 @lisp
-(let ((bv (make-bytevector 4)))
-  (bytevector-u8-set! bv 0 #x12)
-  (bytevector-u8-set! bv 1 #x34)
-  (bytevector-u8-set! bv 2 #x56)
-  (bytevector-u8-set! bv 3 #x78)
+(let ((bv (make-bytevector 4)))
+  (bytevector-u8-set! bv 0 #x12)
+  (bytevector-u8-set! bv 1 #x34)
+  (bytevector-u8-set! bv 2 #x56)
+  (bytevector-u8-set! bv 3 #x78)
+
+  (map (lambda (number)
+         (number->string number 16))
+       (list (bytevector-u8-ref bv 0)
+             (bytevector-u16-ref bv 0 (endianness big))
+             (bytevector-u32-ref bv 0 (endianness little)))))
+
address@hidden ("12" "1234" "78563412")
address@hidden lisp
+
+The most generic procedures to interpret bytevector contents as integers
+are described below.
+
address@hidden {Scheme Procedure} bytevector-uint-ref bv index endianness size
address@hidden {C Function} scm_bytevector_uint_ref (bv, index, endianness, 
size)
+Return the @var{size}-byte long unsigned integer at index @var{index} in
address@hidden, decoded according to @var{endianness}.
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector-sint-ref bv index endianness size
address@hidden {C Function} scm_bytevector_sint_ref (bv, index, endianness, 
size)
+Return the @var{size}-byte long signed integer at index @var{index} in
address@hidden, decoded according to @var{endianness}.
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector-uint-set! bv index value 
endianness size
address@hidden {C Function} scm_bytevector_uint_set_x (bv, index, value, 
endianness, size)
+Set the @var{size}-byte long unsigned integer at @var{index} to
address@hidden, encoded according to @var{endianness}.
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector-sint-set! bv index value 
endianness size
address@hidden {C Function} scm_bytevector_sint_set_x (bv, index, value, 
endianness, size)
+Set the @var{size}-byte long signed integer at @var{index} to
address@hidden, encoded according to @var{endianness}.
address@hidden deffn
+
+The following procedures are similar to the ones above, but specialized
+to a given integer size:
+
address@hidden {Scheme Procedure} bytevector-u8-ref bv index
address@hidden {Scheme Procedure} bytevector-s8-ref bv index
address@hidden {Scheme Procedure} bytevector-u16-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-s16-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-u32-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-s32-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-u64-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-s64-ref bv index endianness
address@hidden {C Function} scm_bytevector_u8_ref (bv, index)
address@hidden {C Function} scm_bytevector_s8_ref (bv, index)
address@hidden {C Function} scm_bytevector_u16_ref (bv, index, endianness)
address@hidden {C Function} scm_bytevector_s16_ref (bv, index, endianness)
address@hidden {C Function} scm_bytevector_u32_ref (bv, index, endianness)
address@hidden {C Function} scm_bytevector_s32_ref (bv, index, endianness)
address@hidden {C Function} scm_bytevector_u64_ref (bv, index, endianness)
address@hidden {C Function} scm_bytevector_s64_ref (bv, index, endianness)
+Return the unsigned @var{n}-bit (signed) integer (where @var{n} is 8,
+16, 32 or 64) from @var{bv} at @var{index}, decoded according to
address@hidden
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector-u8-set! bv index value
address@hidden {Scheme Procedure} bytevector-s8-set! bv index value
address@hidden {Scheme Procedure} bytevector-u16-set! bv index value endianness
address@hidden {Scheme Procedure} bytevector-s16-set! bv index value endianness
address@hidden {Scheme Procedure} bytevector-u32-set! bv index value endianness
address@hidden {Scheme Procedure} bytevector-s32-set! bv index value endianness
address@hidden {Scheme Procedure} bytevector-u64-set! bv index value endianness
address@hidden {Scheme Procedure} bytevector-s64-set! bv index value endianness
address@hidden {C Function} scm_bytevector_u8_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_s8_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_u16_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_s16_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_u32_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_s32_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_u64_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_s64_set_x (bv, index, value, 
endianness)
+Store @var{value} as an @var{n}-bit (signed) integer (where @var{n} is
+8, 16, 32 or 64) in @var{bv} at @var{index}, encoded according to
address@hidden
address@hidden deffn
+
+Finally, a variant specialized for the host's endianness is available
+for each of these functions (with the exception of the @code{u8}
+accessors, for obvious reasons):
+
address@hidden {Scheme Procedure} bytevector-u16-native-ref bv index
address@hidden {Scheme Procedure} bytevector-s16-native-ref bv index
address@hidden {Scheme Procedure} bytevector-u32-native-ref bv index
address@hidden {Scheme Procedure} bytevector-s32-native-ref bv index
address@hidden {Scheme Procedure} bytevector-u64-native-ref bv index
address@hidden {Scheme Procedure} bytevector-s64-native-ref bv index
address@hidden {C Function} scm_bytevector_u16_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_s16_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_u32_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_s32_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_u64_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_s64_native_ref (bv, index)
+Return the unsigned @var{n}-bit (signed) integer (where @var{n} is 8,
+16, 32 or 64) from @var{bv} at @var{index}, decoded according to the
+host's native endianness.
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector-u16-native-set! bv index value
address@hidden {Scheme Procedure} bytevector-s16-native-set! bv index value
address@hidden {Scheme Procedure} bytevector-u32-native-set! bv index value
address@hidden {Scheme Procedure} bytevector-s32-native-set! bv index value
address@hidden {Scheme Procedure} bytevector-u64-native-set! bv index value
address@hidden {Scheme Procedure} bytevector-s64-native-set! bv index value
address@hidden {C Function} scm_bytevector_u16_native_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_s16_native_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_u32_native_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_s32_native_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_u64_native_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_s64_native_set_x (bv, index, value)
+Store @var{value} as an @var{n}-bit (signed) integer (where @var{n} is
+8, 16, 32 or 64) in @var{bv} at @var{index}, encoded according to the
+host's native endianness.
address@hidden deffn
+
+
address@hidden Bytevectors and Integer Lists
address@hidden Converting Bytevectors to/from Integer Lists
+
+Bytevector contents can readily be converted to/from lists of signed or
+unsigned integers:
+
address@hidden
+(bytevector->sint-list (u8-list->bytevector (make-list 4 255))
+                       (endianness little) 2)
address@hidden (-1 -1)
address@hidden lisp
+
address@hidden {Scheme Procedure} bytevector->u8-list bv
address@hidden {C Function} scm_bytevector_to_u8_list (bv)
+Return a newly allocated list of unsigned 8-bit integers from the
+contents of @var{bv}.
address@hidden deffn
+
address@hidden {Scheme Procedure} u8-list->bytevector lst
address@hidden {C Function} scm_u8_list_to_bytevector (lst)
+Return a newly allocated bytevector consisting of the unsigned 8-bit
+integers listed in @var{lst}.
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector->uint-list bv endianness size
address@hidden {C Function} scm_bytevector_to_uint_list (bv, endianness, size)
+Return a list of unsigned integers of @var{size} bytes representing the
+contents of @var{bv}, decoded according to @var{endianness}.
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector->sint-list bv endianness size
address@hidden {C Function} scm_bytevector_to_sint_list (bv, endianness, size)
+Return a list of signed integers of @var{size} bytes representing the
+contents of @var{bv}, decoded according to @var{endianness}.
address@hidden deffn
+
address@hidden {Scheme Procedure} uint-list->bytevector lst endianness size
address@hidden {C Function} scm_uint_list_to_bytevector (lst, endianness, size)
+Return a new bytevector containing the unsigned integers listed in
address@hidden and encoded on @var{size} bytes according to @var{endianness}.
address@hidden deffn
+
address@hidden {Scheme Procedure} sint-list->bytevector lst endianness size
address@hidden {C Function} scm_sint_list_to_bytevector (lst, endianness, size)
+Return a new bytevector containing the signed integers listed in
address@hidden and encoded on @var{size} bytes according to @var{endianness}.
address@hidden deffn
+
address@hidden Bytevectors as Floats
address@hidden Interpreting Bytevector Contents as Floating Point Numbers
+
address@hidden IEEE-754 floating point numbers
+
+Bytevector contents can also be accessed as IEEE-754 single- or
+double-precision floating point numbers (respectively 32 and 64-bit
+long) using the procedures described here.
+
address@hidden {Scheme Procedure} bytevector-ieee-single-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-ieee-double-ref bv index endianness
address@hidden {C Function} scm_bytevector_ieee_single_ref (bv, index, 
endianness)
address@hidden {C Function} scm_bytevector_ieee_double_ref (bv, index, 
endianness)
+Return the IEEE-754 single-precision floating point number from @var{bv}
+at @var{index} according to @var{endianness}.
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector-ieee-single-set! bv index value 
endianness
address@hidden {Scheme Procedure} bytevector-ieee-double-set! bv index value 
endianness
address@hidden {C Function} scm_bytevector_ieee_single_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_ieee_double_set_x (bv, index, value, 
endianness)
+Store real number @var{value} in @var{bv} at @var{index} according to
address@hidden
address@hidden deffn
+
+Specialized procedures are also available:
+
address@hidden {Scheme Procedure} bytevector-ieee-single-native-ref bv index
address@hidden {Scheme Procedure} bytevector-ieee-double-native-ref bv index
address@hidden {C Function} scm_bytevector_ieee_single_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_ieee_double_native_ref (bv, index)
+Return the IEEE-754 single-precision floating point number from @var{bv}
+at @var{index} according to the host's native endianness.
address@hidden deffn
+
address@hidden {Scheme Procedure} bytevector-ieee-single-native-set! bv index 
value
address@hidden {Scheme Procedure} bytevector-ieee-double-native-set! bv index 
value
address@hidden {C Function} scm_bytevector_ieee_single_native_set_x (bv, index, 
value)
address@hidden {C Function} scm_bytevector_ieee_double_native_set_x (bv, index, 
value)
+Store real number @var{value} in @var{bv} at @var{index} according to
+the host's native endianness.
address@hidden deffn
+
+
address@hidden Bytevectors as Strings
address@hidden Interpreting Bytevector Contents as Unicode Strings
+
address@hidden Unicode string encoding
+
+Bytevector contents can also be interpreted as Unicode strings encoded
+in one of the most commonly available encoding formats.
address@hidden Strings as Bytes}, for a more generic interface.
+
address@hidden
+(utf8->string (u8-list->bytevector '(99 97 102 101)))
address@hidden "cafe"
 
-  (map (lambda (number)
-         (number->string number 16))
-       (list (bytevector-u8-ref bv 0)
-             (bytevector-u16-ref bv 0 (endianness big))
-             (bytevector-u32-ref bv 0 (endianness little)))))
+(string->utf8 "caf@'e") ;; SMALL LATIN LETTER E WITH ACUTE ACCENT
address@hidden #vu8(99 97 102 195 169)
address@hidden lisp
+
address@hidden {Scheme Procedure} {} string-utf8-length str
address@hidden {C function} SCM scm_string_utf8_length (str)
address@hidden {C function} size_t scm_c_string_utf8_length (str)
+Return the number of bytes in the UTF-8 representation of @var{str}.
address@hidden deftypefn
+
address@hidden {Scheme Procedure} string->utf8 str
address@hidden {Scheme Procedure} string->utf16 str [endianness]
address@hidden {Scheme Procedure} string->utf32 str [endianness]
address@hidden {C Function} scm_string_to_utf8 (str)
address@hidden {C Function} scm_string_to_utf16 (str, endianness)
address@hidden {C Function} scm_string_to_utf32 (str, endianness)
+Return a newly allocated bytevector that contains the UTF-8, UTF-16, or
+UTF-32 (aka. UCS-4) encoding of @var{str}.  For UTF-16 and UTF-32,
address@hidden should be the symbol @code{big} or @code{little}; when omitted,
+it defaults to big endian.
address@hidden deffn
+
address@hidden {Scheme Procedure} utf8->string utf
address@hidden {Scheme Procedure} utf16->string utf [endianness]
address@hidden {Scheme Procedure} utf32->string utf [endianness]
address@hidden {C Function} scm_utf8_to_string (utf)
address@hidden {C Function} scm_utf16_to_string (utf, endianness)
address@hidden {C Function} scm_utf32_to_string (utf, endianness)
+Return a newly allocated string that contains from the UTF-8-, UTF-16-,
+or UTF-32-decoded contents of bytevector @var{utf}.  For UTF-16 and UTF-32,
address@hidden should be the symbol @code{big} or @code{little}; when omitted,
+it defaults to big endian.
address@hidden deffn
+
address@hidden Bytevectors as Arrays
address@hidden Accessing Bytevectors with the Array API
+
+As an extension to the R6RS, Guile allows bytevectors to be manipulated
+with the @dfn{array} procedures (@pxref{Arrays}).  When using these
+APIs, bytes are accessed one at a time as 8-bit unsigned integers:
+
address@hidden
+(define bv #vu8(0 1 2 3))
+
+(array? bv)
address@hidden #t
+
+(array-rank bv)
address@hidden 1
+
+(array-ref bv 2)
address@hidden 2
+
+;; Note the different argument order on array-set!.
+(array-set! bv 77 2)
+(array-ref bv 2)
address@hidden 77
+
+(array-type bv)
address@hidden vu8
address@hidden example
+
+
address@hidden Bytevectors as Uniform Vectors
address@hidden Accessing Bytevectors with the SRFI-4 API
+
+Bytevectors may also be accessed with the SRFI-4 API. @xref{SRFI-4 and
+Bytevectors}, for more information.
+
+
address@hidden Arrays
address@hidden Arrays
address@hidden Arrays
+
address@hidden are a collection of cells organized into an arbitrary
+number of dimensions.  Each cell can be accessed in constant time by
+supplying an index for each dimension.
+
+In the current implementation, an array uses a vector of some kind for
+the actual storage of its elements.  Any kind of vector will do, so you
+can have arrays of uniform numeric values, arrays of characters, arrays
+of bits, and of course, arrays of arbitrary Scheme values.  For example,
+arrays with an underlying @code{c64vector} might be nice for digital
+signal processing, while arrays made from a @code{u8vector} might be
+used to hold gray-scale images.
+
+The number of dimensions of an array is called its @dfn{rank}.  Thus,
+a matrix is an array of rank 2, while a vector has rank 1.  When
+accessing an array element, you have to specify one exact integer for
+each dimension.  These integers are called the @dfn{indices} of the
+element.  An array specifies the allowed range of indices for each
+dimension via an inclusive lower and upper bound.  These bounds can
+well be negative, but the upper bound must be greater than or equal to
+the lower bound minus one.  When all lower bounds of an array are
+zero, it is called a @dfn{zero-origin} array.
+
+Arrays can be of rank 0, which could be interpreted as a scalar.
+Thus, a zero-rank array can store exactly one object and the list of
+indices of this element is the empty list.
+
+Arrays contain zero elements when one of their dimensions has a zero
+length.  These empty arrays maintain information about their shape: a
+matrix with zero columns and 3 rows is different from a matrix with 3
+columns and zero rows, which again is different from a vector of
+length zero.
+
+The array procedures are all polymorphic, treating strings, uniform
+numeric vectors, bytevectors, bit vectors and ordinary vectors as one
+dimensional arrays.
+
address@hidden
+* Array Syntax::                
+* Array Procedures::            
+* Shared Arrays::               
+* Accessing Arrays from C::     
address@hidden menu
+
address@hidden Array Syntax
address@hidden Array Syntax
+
+An array is displayed as @code{#} followed by its rank, followed by a
+tag that describes the underlying vector, optionally followed by
+information about its shape, and finally followed by the cells,
+organized into dimensions using parentheses.
+
+In more words, the array tag is of the form
+
address@hidden
+  #<rank><vectag><@@lower><:len><@@lower><:len>...
address@hidden example
+
+where @code{<rank>} is a positive integer in decimal giving the rank of
+the array.  It is omitted when the rank is 1 and the array is non-shared
+and has zero-origin (see below).  For shared arrays and for a non-zero
+origin, the rank is always printed even when it is 1 to distinguish
+them from ordinary vectors.
+
+The @code{<vectag>} part is the tag for a uniform numeric vector, like
address@hidden, @code{s16}, etc, @code{b} for bitvectors, or @code{a} for
+strings.  It is empty for ordinary vectors.
+
+The @code{<@@lower>} part is a @samp{@@} character followed by a signed
+integer in decimal giving the lower bound of a dimension.  There is one
address@hidden<@@lower>} for each dimension.  When all lower bounds are zero,
+all @code{<@@lower>} parts are omitted.
+
+The @code{<:len>} part is a @samp{:} character followed by an unsigned
+integer in decimal giving the length of a dimension.  Like for the lower
+bounds, there is one @code{<:len>} for each dimension, and the
address@hidden<:len>} part always follows the @code{<@@lower>} part for a
+dimension.  Lengths are only then printed when they can't be deduced
+from the nested lists of elements of the array literal, which can happen
+when at least one length is zero.
+
+As a special case, an array of rank 0 is printed as
address@hidden<vectag>(<scalar>)}, where @code{<scalar>} is the result of
+printing the single element of the array.
+
+Thus, 
+
address@hidden @code
address@hidden #(1 2 3)
+is an ordinary array of rank 1 with lower bound 0 in dimension 0.
+(I.e., a regular vector.)
+
address@hidden #@@2(1 2 3)
+is an ordinary array of rank 1 with lower bound 2 in dimension 0.
+
address@hidden #2((1 2 3) (4 5 6))
+is a non-uniform array of rank 2; a address@hidden matrix with index ranges 
0..1
+and 0..2.
+
address@hidden #u32(0 1 2)
+is a uniform u8 array of rank 1.
+
address@hidden #2u32@@2@@3((1 2) (2 3))
+is a uniform u32 array of rank 2 with index ranges 2..3 and 3..4.
+
address@hidden #2()
+is a two-dimensional array with index ranges 0..-1 and 0..-1, i.e.@:
+both dimensions have length zero.
+
address@hidden #2:0:2()
+is a two-dimensional array with index ranges 0..-1 and 0..1, i.e.@: the
+first dimension has length zero, but the second has length 2.
+
address@hidden #0(12)
+is a rank-zero array with contents 12.
+
address@hidden table
+
+In addition, bytevectors are also arrays, but use a different syntax
+(@pxref{Bytevectors}):
+
address@hidden @code
+
address@hidden #vu8(1 2 3)
+is a 3-byte long bytevector, with contents 1, 2, 3.
+
address@hidden table
+
address@hidden Array Procedures
address@hidden Array Procedures
+
+When an array is created, the range of each dimension must be
+specified, e.g., to create a address@hidden array with a zero-based index:
+
address@hidden
+(make-array 'ho 2 3) @result{} #2((ho ho ho) (ho ho ho))
address@hidden example
+
+The range of each dimension can also be given explicitly, e.g., another
+way to create the same array:
+
address@hidden
+(make-array 'ho '(0 1) '(0 2)) @result{} #2((ho ho ho) (ho ho ho))
address@hidden example
+
+The following procedures can be used with arrays (or vectors).  An
+argument shown as @address@hidden means one parameter for each
+dimension in the array.  A @var{idxlist} argument means a list of such
+values, one for each dimension.
+
+
address@hidden {Scheme Procedure} array? obj
address@hidden {C Function} scm_array_p (obj, unused)
+Return @code{#t} if the @var{obj} is an array, and @code{#f} if
+not.
+
+The second argument to scm_array_p is there for historical reasons,
+but it is not used.  You should always pass @code{SCM_UNDEFINED} as
+its value.
address@hidden deffn
+
address@hidden {Scheme Procedure} typed-array? obj type
address@hidden {C Function} scm_typed_array_p (obj, type)
+Return @code{#t} if the @var{obj} is an array of type @var{type}, and
address@hidden if not.
address@hidden deffn
+
address@hidden {C Function} int scm_is_array (SCM obj)
+Return @code{1} if the @var{obj} is an array and @code{0} if not.
address@hidden deftypefn
+
address@hidden {C Function} int scm_is_typed_array (SCM obj, SCM type)
+Return @code{0} if the @var{obj} is an array of type @var{type}, and
address@hidden if not.
address@hidden deftypefn
+
address@hidden {Scheme Procedure} make-array fill bound @dots{}
address@hidden {C Function} scm_make_array (fill, bounds)
+Equivalent to @code{(make-typed-array #t @var{fill} @var{bound} ...)}.
address@hidden deffn
+
address@hidden {Scheme Procedure} make-typed-array type fill bound @dots{}
address@hidden {C Function} scm_make_typed_array (type, fill, bounds)
+Create and return an array that has as many dimensions as there are
address@hidden and (maybe) fill it with @var{fill}.
+
+The underlying storage vector is created according to @var{type},
+which must be a symbol whose name is the `vectag' of the array as
+explained above, or @code{#t} for ordinary, non-specialized arrays.
+
+For example, using the symbol @code{f64} for @var{type} will create an
+array that uses a @code{f64vector} for storing its elements, and
address@hidden will use a string.
+
+When @var{fill} is not the special @emph{unspecified} value, the new
+array is filled with @var{fill}.  Otherwise, the initial contents of
+the array is unspecified.  The special @emph{unspecified} value is
+stored in the variable @code{*unspecified*} so that for example
address@hidden(make-typed-array 'u32 *unspecified* 4)} creates a uninitialized
address@hidden vector of length 4.
+
+Each @var{bound} may be a positive non-zero integer @var{n}, in which
+case the index for that dimension can range from 0 through @var{n}-1; or
+an explicit index range specifier in the form @code{(LOWER UPPER)},
+where both @var{lower} and @var{upper} are integers, possibly less than
+zero, and possibly the same number (however, @var{lower} cannot be
+greater than @var{upper}).
address@hidden deffn
+
address@hidden {Scheme Procedure} list->array dimspec list
+Equivalent to @code{(list->typed-array #t @var{dimspec}
address@hidden)}.
address@hidden deffn
+
address@hidden {Scheme Procedure} list->typed-array type dimspec list
address@hidden {C Function} scm_list_to_typed_array (type, dimspec, list)
+Return an array of the type indicated by @var{type} with elements the
+same as those of @var{list}.
+
+The argument @var{dimspec} determines the number of dimensions of the
+array and their lower bounds.  When @var{dimspec} is an exact integer,
+it gives the number of dimensions directly and all lower bounds are
+zero.  When it is a list of exact integers, then each element is the
+lower index bound of a dimension, and there will be as many dimensions
+as elements in the list.
address@hidden deffn
+
address@hidden {Scheme Procedure} array-type array
address@hidden {C Function} scm_array_type (array)
+Return the type of @var{array}.  This is the `vectag' used for
+printing @var{array} (or @code{#t} for ordinary arrays) and can be
+used with @code{make-typed-array} to create an array of the same kind
+as @var{array}.
address@hidden deffn
+
address@hidden {Scheme Procedure} array-ref array idx @dots{}
address@hidden {C Function} scm_array_ref (array, idxlist)
+Return the element at @code{(idx @dots{})} in @var{array}.
+
address@hidden
+(define a (make-array 999 '(1 2) '(3 4)))
+(array-ref a 2 4) @result{} 999
address@hidden example
address@hidden deffn
+
address@hidden {Scheme Procedure} array-in-bounds? array idx @dots{}
address@hidden {C Function} scm_array_in_bounds_p (array, idxlist)
+Return @code{#t} if the given indices would be acceptable to
address@hidden
+
address@hidden
+(define a (make-array #f '(1 2) '(3 4)))
+(array-in-bounds? a 2 3) @result{} #t
+(array-in-bounds? a 0 0) @result{} #f
address@hidden example
address@hidden deffn
+
address@hidden {Scheme Procedure} array-set! array obj idx @dots{}
address@hidden {C Function} scm_array_set_x (array, obj, idxlist)
+Set the element at @code{(idx @dots{})} in @var{array} to @var{obj}.
+The return value is unspecified.
+
address@hidden
+(define a (make-array #f '(0 1) '(0 1)))
+(array-set! a #t 1 1)
+a @result{} #2((#f #f) (#f #t))
address@hidden example
address@hidden deffn
+
address@hidden {Scheme Procedure} array-shape array
address@hidden {Scheme Procedure} array-dimensions array
address@hidden {C Function} scm_array_dimensions (array)
+Return a list of the bounds for each dimension of @var{array}.
+
address@hidden gives @code{(@var{lower} @var{upper})} for each
+dimension.  @code{array-dimensions} instead returns just
address@hidden@var{upper}+1} for dimensions with a 0 lower bound.  Both are
+suitable as input to @code{make-array}.
+
+For example,
+
address@hidden
+(define a (make-array 'foo '(-1 3) 5))
+(array-shape a)      @result{} ((-1 3) (0 4))
+(array-dimensions a) @result{} ((-1 3) 5)
address@hidden example
address@hidden deffn
+
address@hidden {Scheme Procedure} array-length array
address@hidden {C Function} scm_array_length (array)
address@hidden {C Function} size_t scm_c_array_length (array)
+Return the length of an array: its first dimension. It is an error to
+ask for the length of an array of rank 0.
address@hidden deffn
+
address@hidden {Scheme Procedure} array-rank array
address@hidden {C Function} scm_array_rank (array)
+Return the rank of @var{array}.
address@hidden deffn
+
address@hidden {C Function} size_t scm_c_array_rank (SCM array)
+Return the rank of @var{array} as a @code{size_t}.
address@hidden deftypefn
+
address@hidden {Scheme Procedure} array->list array
address@hidden {C Function} scm_array_to_list (array)
+Return a list consisting of all the elements, in order, of
address@hidden
address@hidden deffn
+
address@hidden  FIXME: Describe how the order affects the copying (it matters 
for
address@hidden  shared arrays with the same underlying root vector, presumably).
address@hidden
address@hidden {Scheme Procedure} array-copy! src dst
address@hidden {Scheme Procedure} array-copy-in-order! src dst
address@hidden {C Function} scm_array_copy_x (src, dst)
+Copy every element from vector or array @var{src} to the corresponding
+element of @var{dst}.  @var{dst} must have the same rank as @var{src},
+and be at least as large in each dimension.  The return value is
+unspecified.
address@hidden deffn
+
address@hidden {Scheme Procedure} array-fill! array fill
address@hidden {C Function} scm_array_fill_x (array, fill)
+Store @var{fill} in every element of @var{array}.  The value returned
+is unspecified.
address@hidden deffn
+
address@hidden begin (texi-doc-string "guile" "array-equal?")
address@hidden {Scheme Procedure} array-equal? array @dots{}
+Return @code{#t} if all arguments are arrays with the same shape, the
+same type, and have corresponding elements which are either
address@hidden or @code{array-equal?}.  This function differs from
address@hidden (@pxref{Equality}) in that all arguments must be arrays.
address@hidden deffn
+
address@hidden  FIXME: array-map! accepts no source arrays at all, and in that
address@hidden  case makes calls "(proc)".  Is that meant to be a documented
address@hidden  feature?
address@hidden
address@hidden  FIXME: array-for-each doesn't say what happens if the sources 
have
address@hidden  different index ranges.  The code currently iterates over the
address@hidden  indices of the first and expects the others to cover those.  
That
address@hidden  at least vaguely matches array-map!, but is it meant to be a
address@hidden  documented feature?
+
address@hidden {Scheme Procedure} array-map! dst proc src @dots{}
address@hidden {Scheme Procedure} array-map-in-order! dst proc src1 @dots{} srcN
address@hidden {C Function} scm_array_map_x (dst, proc, srclist)
+Set each element of the @var{dst} array to values obtained from calls
+to @var{proc}.  The value returned is unspecified.
+
+Each call is @code{(@var{proc} @var{elem1} @dots{} @var{elemN})},
+where each @var{elem} is from the corresponding @var{src} array, at
+the @var{dst} index.  @code{array-map-in-order!} makes the calls in
+row-major order, @code{array-map!} makes them in an unspecified order.
+
+The @var{src} arrays must have the same number of dimensions as
address@hidden, and must have a range for each dimension which covers the
+range in @var{dst}.  This ensures all @var{dst} indices are valid in
+each @var{src}.
address@hidden deffn
+
address@hidden {Scheme Procedure} array-for-each proc src1 src2 @dots{}
address@hidden {C Function} scm_array_for_each (proc, src1, srclist)
+Apply @var{proc} to each tuple of elements of @var{src1} @var{src2}
address@hidden, in row-major order.  The value returned is unspecified.
address@hidden deffn
+
address@hidden {Scheme Procedure} array-index-map! dst proc
address@hidden {C Function} scm_array_index_map_x (dst, proc)
+Set each element of the @var{dst} array to values returned by calls to
address@hidden  The value returned is unspecified.
+
+Each call is @code{(@var{proc} @var{i1} @dots{} @var{iN})}, where
address@hidden@address@hidden is the destination index, one parameter for
+each dimension.  The order in which the calls are made is unspecified.
+
+For example, to create a @m{4\times4, 4x4} matrix representing a
+cyclic group,
+
address@hidden
+\advance\leftskip by 2\lispnarrowing {
+$\left(\matrix{%
+0 & 1 & 2 & 3 \cr
+1 & 2 & 3 & 0 \cr
+2 & 3 & 0 & 1 \cr
+3 & 0 & 1 & 2 \cr
+}\right)$} \par
address@hidden tex
address@hidden
address@hidden
+    / 0 1 2 3 \
+    | 1 2 3 0 |
+    | 2 3 0 1 |
+    \ 3 0 1 2 /
address@hidden example
address@hidden ifnottex
+
address@hidden
+(define a (make-array #f 4 4))
+(array-index-map! a (lambda (i j)
+                      (modulo (+ i j) 4)))
address@hidden example
address@hidden deffn
+
address@hidden {Scheme Procedure} uniform-array-read! ra [port_or_fd [start 
[end]]]
address@hidden {C Function} scm_uniform_array_read_x (ra, port_or_fd, start, 
end)
+Attempt to read all elements of array @var{ra}, in lexicographic order, as
+binary objects from @var{port_or_fd}.
+If an end of file is encountered,
+the objects up to that point are put into @var{ra}
+(starting at the beginning) and the remainder of the array is
+unchanged.
+
+The optional arguments @var{start} and @var{end} allow
+a specified region of a vector (or linearized array) to be read,
+leaving the remainder of the vector unchanged.
+
address@hidden returns the number of objects read.
address@hidden may be omitted, in which case it defaults to the value
+returned by @code{(current-input-port)}.
address@hidden deffn
+
address@hidden {Scheme Procedure} uniform-array-write ra [port_or_fd [start 
[end]]]
address@hidden {C Function} scm_uniform_array_write (ra, port_or_fd, start, end)
+Writes all elements of @var{ra} as binary objects to
address@hidden
+
+The optional arguments @var{start}
+and @var{end} allow
+a specified region of a vector (or linearized array) to be written.
+
+The number of objects actually written is returned.
address@hidden may be
+omitted, in which case it defaults to the value returned by
address@hidden(current-output-port)}.
address@hidden deffn
+
address@hidden Shared Arrays
address@hidden Shared Arrays
+
address@hidden {Scheme Procedure} make-shared-array oldarray mapfunc bound 
@dots{}
address@hidden {C Function} scm_make_shared_array (oldarray, mapfunc, boundlist)
+Return a new array which shares the storage of @var{oldarray}.
+Changes made through either affect the same underlying storage.  The
address@hidden @dots{} arguments are the shape of the new array, the same
+as @code{make-array} (@pxref{Array Procedures}).
+
address@hidden translates coordinates from the new array to the
address@hidden  It's called as @code{(@var{mapfunc} newidx1 @dots{})}
+with one parameter for each dimension of the new array, and should
+return a list of indices for @var{oldarray}, one for each dimension of
address@hidden
+
address@hidden must be affine linear, meaning that each @var{oldarray}
+index must be formed by adding integer multiples (possibly negative)
+of some or all of @var{newidx1} etc, plus a possible integer offset.
+The multiples and offset must be the same in each call.
+
address@hidden 1
+One good use for a shared array is to restrict the range of some
+dimensions, so as to apply say @code{array-for-each} or
address@hidden to only part of an array.  The plain @code{list}
+function can be used for @var{mapfunc} in this case, making no changes
+to the index values.  For example,
+
address@hidden
+(make-shared-array #2((a b c) (d e f) (g h i)) list 3 2)
address@hidden #2((a b) (d e) (g h))
address@hidden example
+
+The new array can have fewer dimensions than @var{oldarray}, for
+example to take a column from an array.
+
address@hidden
+(make-shared-array #2((a b c) (d e f) (g h i))
+                   (lambda (i) (list i 2))
+                   '(0 2))
address@hidden #1(c f i)
address@hidden example
+
+A diagonal can be taken by using the single new array index for both
+row and column in the old array.  For example,
+
address@hidden
+(make-shared-array #2((a b c) (d e f) (g h i))
+                   (lambda (i) (list i i))
+                   '(0 2))
address@hidden #1(a e i)
address@hidden example
+
+Dimensions can be increased by for instance considering portions of a
+one dimensional array as rows in a two dimensional array.
+(@code{array-contents} below can do the opposite, flattening an
+array.)
+
address@hidden
+(make-shared-array #1(a b c d e f g h i j k l)
+                   (lambda (i j) (list (+ (* i 3) j)))
+                   4 3)
address@hidden #2((a b c) (d e f) (g h i) (j k l))
address@hidden example
+
+By negating an index the order that elements appear can be reversed.
+The following just reverses the column order,
+
address@hidden
+(make-shared-array #2((a b c) (d e f) (g h i))
+                   (lambda (i j) (list i (- 2 j)))
+                   3 3)
address@hidden #2((c b a) (f e d) (i h g))
address@hidden example
+
+A fixed offset on indexes allows for instance a change from a 0 based
+to a 1 based array,
+
address@hidden
+(define x #2((a b c) (d e f) (g h i)))
+(define y (make-shared-array x
+                             (lambda (i j) (list (1- i) (1- j)))
+                             '(1 3) '(1 3)))
+(array-ref x 0 0) @result{} a
+(array-ref y 1 1) @result{} a
address@hidden example
+
+A multiple on an index allows every Nth element of an array to be
+taken.  The following is every third element,
+
address@hidden
+(make-shared-array #1(a b c d e f g h i j k l)
+                   (lambda (i) (list (* i 3)))
+                   4)
address@hidden #1(a d g j)
address@hidden example
 
address@hidden ("12" "1234" "78563412")
address@hidden lisp
+The above examples can be combined to make weird and wonderful
+selections from an array, but it's important to note that because
address@hidden must be affine linear, arbitrary permutations are not
+possible.
 
-The most generic procedures to interpret bytevector contents as integers
-are described below.
+In the current implementation, @var{mapfunc} is not called for every
+access to the new array but only on some sample points to establish a
+base and stride for new array indices in @var{oldarray} data.  A few
+sample points are enough because @var{mapfunc} is linear.
address@hidden deffn
 
address@hidden {Scheme Procedure} bytevector-uint-ref bv index endianness size
address@hidden {C Function} scm_bytevector_uint_ref (bv, index, endianness, 
size)
-Return the @var{size}-byte long unsigned integer at index @var{index} in
address@hidden, decoded according to @var{endianness}.
address@hidden {Scheme Procedure} shared-array-increments array
address@hidden {C Function} scm_shared_array_increments (array)
+For each dimension, return the distance between elements in the root vector.
 @end deffn
 
address@hidden {Scheme Procedure} bytevector-sint-ref bv index endianness size
address@hidden {C Function} scm_bytevector_sint_ref (bv, index, endianness, 
size)
-Return the @var{size}-byte long signed integer at index @var{index} in
address@hidden, decoded according to @var{endianness}.
address@hidden {Scheme Procedure} shared-array-offset array
address@hidden {C Function} scm_shared_array_offset (array)
+Return the root vector index of the first element in the array.
 @end deffn
 
address@hidden {Scheme Procedure} bytevector-uint-set! bv index value 
endianness size
address@hidden {C Function} scm_bytevector_uint_set_x (bv, index, value, 
endianness, size)
-Set the @var{size}-byte long unsigned integer at @var{index} to
address@hidden, encoded according to @var{endianness}.
address@hidden {Scheme Procedure} shared-array-root array
address@hidden {C Function} scm_shared_array_root (array)
+Return the root vector of a shared array.
 @end deffn
 
address@hidden {Scheme Procedure} bytevector-sint-set! bv index value 
endianness size
address@hidden {C Function} scm_bytevector_sint_set_x (bv, index, value, 
endianness, size)
-Set the @var{size}-byte long signed integer at @var{index} to
address@hidden, encoded according to @var{endianness}.
address@hidden {Scheme Procedure} array-contents array [strict]
address@hidden {C Function} scm_array_contents (array, strict)
+If @var{array} may be @dfn{unrolled} into a one dimensional shared array
+without changing their order (last subscript changing fastest), then
address@hidden returns that shared array, otherwise it returns
address@hidden  All arrays made by @code{make-array} and
address@hidden may be unrolled, some arrays made by
address@hidden may not be.
+
+If the optional argument @var{strict} is provided, a shared array will
+be returned only if its elements are stored internally contiguous in
+memory.
 @end deffn
 
-The following procedures are similar to the ones above, but specialized
-to a given integer size:
address@hidden {Scheme Procedure} transpose-array array dim1 dim2 @dots{}
address@hidden {C Function} scm_transpose_array (array, dimlist)
+Return an array sharing contents with @var{array}, but with
+dimensions arranged in a different order.  There must be one
address@hidden argument for each dimension of @var{array}.
address@hidden, @var{dim2}, @dots{} 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.
 
address@hidden {Scheme Procedure} bytevector-u8-ref bv index
address@hidden {Scheme Procedure} bytevector-s8-ref bv index
address@hidden {Scheme Procedure} bytevector-u16-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-s16-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-u32-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-s32-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-u64-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-s64-ref bv index endianness
address@hidden {C Function} scm_bytevector_u8_ref (bv, index)
address@hidden {C Function} scm_bytevector_s8_ref (bv, index)
address@hidden {C Function} scm_bytevector_u16_ref (bv, index, endianness)
address@hidden {C Function} scm_bytevector_s16_ref (bv, index, endianness)
address@hidden {C Function} scm_bytevector_u32_ref (bv, index, endianness)
address@hidden {C Function} scm_bytevector_s32_ref (bv, index, endianness)
address@hidden {C Function} scm_bytevector_u64_ref (bv, index, endianness)
address@hidden {C Function} scm_bytevector_s64_ref (bv, index, endianness)
-Return the unsigned @var{n}-bit (signed) integer (where @var{n} is 8,
-16, 32 or 64) from @var{bv} at @var{index}, decoded according to
address@hidden
+The values of @var{dim1}, @var{dim2}, @dots{} correspond to
+dimensions in the array to be returned, and their positions in the
+argument list to dimensions of @var{array}.  Several @var{dim}s
+may have the same value, in which case the returned array will
+have smaller rank than @var{array}.
+
address@hidden
+(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d))
+(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d)
+(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{}
+                #2((a 4) (b 5) (c 6))
address@hidden lisp
 @end deffn
 
address@hidden {Scheme Procedure} bytevector-u8-set! bv index value
address@hidden {Scheme Procedure} bytevector-s8-set! bv index value
address@hidden {Scheme Procedure} bytevector-u16-set! bv index value endianness
address@hidden {Scheme Procedure} bytevector-s16-set! bv index value endianness
address@hidden {Scheme Procedure} bytevector-u32-set! bv index value endianness
address@hidden {Scheme Procedure} bytevector-s32-set! bv index value endianness
address@hidden {Scheme Procedure} bytevector-u64-set! bv index value endianness
address@hidden {Scheme Procedure} bytevector-s64-set! bv index value endianness
address@hidden {C Function} scm_bytevector_u8_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_s8_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_u16_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_s16_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_u32_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_s32_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_u64_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_s64_set_x (bv, index, value, 
endianness)
-Store @var{value} as an @var{n}-bit (signed) integer (where @var{n} is
-8, 16, 32 or 64) in @var{bv} at @var{index}, encoded according to
address@hidden
address@hidden Accessing Arrays from C
address@hidden Accessing Arrays from C
+
+For interworking with external C code, Guile provides an API to allow C
+code to access the elements of a Scheme array.  In particular, for
+uniform numeric arrays, the API exposes the underlying uniform data as a
+C array of numbers of the relevant type.
+
+While pointers to the elements of an array are in use, the array itself
+must be protected so that the pointer remains valid.  Such a protected
+array is said to be @dfn{reserved}.  A reserved array can be read but
+modifications to it that would cause the pointer to its elements to
+become invalid are prevented.  When you attempt such a modification, an
+error is signalled.
+
+(This is similar to locking the array while it is in use, but without
+the danger of a deadlock.  In a multi-threaded program, you will need
+additional synchronization to avoid modifying reserved arrays.)
+
+You must take care to always unreserve an array after reserving it,
+even in the presence of non-local exits.  If a non-local exit can
+happen between these two calls, you should install a dynwind context
+that releases the array when it is left (@pxref{Dynamic Wind}).
+
+In addition, array reserving and unreserving must be properly
+paired.  For instance, when reserving two or more arrays in a certain
+order, you need to unreserve them in the opposite order.
+
+Once you have reserved an array and have retrieved the pointer to its
+elements, you must figure out the layout of the elements in memory.
+Guile allows slices to be taken out of arrays without actually making a
+copy, such as making an alias for the diagonal of a matrix that can be
+treated as a vector.  Arrays that result from such an operation are not
+stored contiguously in memory and when working with their elements
+directly, you need to take this into account.
+
+The layout of array elements in memory can be defined via a
address@hidden function} that computes a scalar position from a vector of
+indices.  The scalar position then is the offset of the element with the
+given indices from the start of the storage block of the array.
+
+In Guile, this mapping function is restricted to be @dfn{affine}: all
+mapping functions of Guile arrays can be written as @code{p = b +
+c[0]*i[0] + c[1]*i[1] + ... + c[n-1]*i[n-1]} where @code{i[k]} is the
address@hidden index and @code{n} is the rank of the array.  For
+example, a matrix of size 3x3 would have @code{b == 0}, @code{c[0] ==
+3} and @code{c[1] == 1}.  When you transpose this matrix (with
address@hidden, say), you will get an array whose mapping
+function has @code{b == 0}, @code{c[0] == 1} and @code{c[1] == 3}.
+
+The function @code{scm_array_handle_dims} gives you (indirect) access to
+the coefficients @code{c[k]}.
+
address@hidden XXX
+Note that there are no functions for accessing the elements of a
+character array yet.  Once the string implementation of Guile has been
+changed to use Unicode, we will provide them.
+
address@hidden {C Type} scm_t_array_handle
+This is a structure type that holds all information necessary to manage
+the reservation of arrays as explained above.  Structures of this type
+must be allocated on the stack and must only be accessed by the
+functions listed below.
address@hidden deftp
+
address@hidden {C Function} void scm_array_get_handle (SCM array, 
scm_t_array_handle *handle)
+Reserve @var{array}, which must be an array, and prepare @var{handle} to
+be used with the functions below.  You must eventually call
address@hidden on @var{handle}, and do this in a
+properly nested fashion, as explained above.  The structure pointed to
+by @var{handle} does not need to be initialized before calling this
+function.
address@hidden deftypefn
+
address@hidden {C Function} void scm_array_handle_release (scm_t_array_handle 
*handle)
+End the array reservation represented by @var{handle}.  After a call to
+this function, @var{handle} might be used for another reservation.
address@hidden deftypefn
+
address@hidden {C Function} size_t scm_array_handle_rank (scm_t_array_handle 
*handle)
+Return the rank of the array represented by @var{handle}.
address@hidden deftypefn
+
address@hidden {C Type} scm_t_array_dim
+This structure type holds information about the layout of one dimension
+of an array.  It includes the following fields:
+
address@hidden @code
address@hidden  ssize_t lbnd
address@hidden ssize_t ubnd
+The lower and upper bounds (both inclusive) of the permissible index
+range for the given dimension.  Both values can be negative, but
address@hidden is always less than or equal to @var{ubnd}.
+
address@hidden ssize_t inc
+The distance from one element of this dimension to the next.  Note, too,
+that this can be negative.
address@hidden table
address@hidden deftp
+
address@hidden {C Function} {const scm_t_array_dim *} scm_array_handle_dims 
(scm_t_array_handle *handle)
+Return a pointer to a C vector of information about the dimensions of
+the array represented by @var{handle}.  This pointer is valid as long as
+the array remains reserved.  As explained above, the
address@hidden structures returned by this function can be used
+calculate the position of an element in the storage block of the array
+from its indices.
+
+This position can then be used as an index into the C array pointer
+returned by the various @code{scm_array_handle_<foo>_elements}
+functions, or with @code{scm_array_handle_ref} and
address@hidden
+
+Here is how one can compute the position @var{pos} of an element given
+its indices in the vector @var{indices}:
+
address@hidden
+ssize_t indices[RANK];
+scm_t_array_dim *dims;
+ssize_t pos;
+size_t i;
+
+pos = 0;
+for (i = 0; i < RANK; i++)
+  @{
+    if (indices[i] < dims[i].lbnd || indices[i] > dims[i].ubnd)
+      out_of_range ();
+    pos += (indices[i] - dims[i].lbnd) * dims[i].inc;
+  @}
address@hidden example
address@hidden deftypefn
+
address@hidden {C Function} ssize_t scm_array_handle_pos (scm_t_array_handle 
*handle, SCM indices)
+Compute the position corresponding to @var{indices}, a list of
+indices.  The position is computed as described above for
address@hidden  The number of the indices and their
+range is checked and an appropriate error is signalled for invalid
+indices.
address@hidden deftypefn
+
address@hidden {C Function} SCM scm_array_handle_ref (scm_t_array_handle 
*handle, ssize_t pos)
+Return the element at position @var{pos} in the storage block of the
+array represented by @var{handle}.  Any kind of array is acceptable.  No
+range checking is done on @var{pos}.
address@hidden deftypefn
+
address@hidden {C Function} void scm_array_handle_set (scm_t_array_handle 
*handle, ssize_t pos, SCM val)
+Set the element at position @var{pos} in the storage block of the array
+represented by @var{handle} to @var{val}.  Any kind of array is
+acceptable.  No range checking is done on @var{pos}.  An error is
+signalled when the array can not store @var{val}.
address@hidden deftypefn
+
address@hidden {C Function} {const SCM *} scm_array_handle_elements 
(scm_t_array_handle *handle)
+Return a pointer to the elements of a ordinary array of general Scheme
+values (i.e., a non-uniform array) for reading.  This pointer is valid
+as long as the array remains reserved.
address@hidden deftypefn
+
address@hidden {C Function} {SCM *} scm_array_handle_writable_elements 
(scm_t_array_handle *handle)
+Like @code{scm_array_handle_elements}, but the pointer is good for
+reading and writing.
address@hidden deftypefn
+
address@hidden {C Function} {const void *} scm_array_handle_uniform_elements 
(scm_t_array_handle *handle)
+Return a pointer to the elements of a uniform numeric array for reading.
+This pointer is valid as long as the array remains reserved.  The size
+of each element is given by @code{scm_array_handle_uniform_element_size}.
address@hidden deftypefn
+
address@hidden {C Function} {void *} scm_array_handle_uniform_writable_elements 
(scm_t_array_handle *handle)
+Like @code{scm_array_handle_uniform_elements}, but the pointer is good
+reading and writing.
address@hidden deftypefn
+
address@hidden {C Function} size_t scm_array_handle_uniform_element_size 
(scm_t_array_handle *handle)
+Return the size of one element of the uniform numeric array represented
+by @var{handle}.
address@hidden deftypefn
+
address@hidden  {C Function} {const scm_t_uint8 *} scm_array_handle_u8_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_int8 *} scm_array_handle_s8_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_uint16 *} 
scm_array_handle_u16_elements (scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_int16 *} scm_array_handle_s16_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_uint32 *} 
scm_array_handle_u32_elements (scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_int32 *} scm_array_handle_s32_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_uint64 *} 
scm_array_handle_u64_elements (scm_t_array_handle *handle)
address@hidden {C Function} {const scm_t_int64 *} scm_array_handle_s64_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const float *} scm_array_handle_f32_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const double *} scm_array_handle_f64_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const float *} scm_array_handle_c32_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {const double *} scm_array_handle_c64_elements 
(scm_t_array_handle *handle)
+Return a pointer to the elements of a uniform numeric array of the
+indicated kind for reading.  This pointer is valid as long as the array
+remains reserved.
+
+The pointers for @code{c32} and @code{c64} uniform numeric arrays point
+to pairs of floating point numbers.  The even index holds the real part,
+the odd index the imaginary part of the complex number.
address@hidden deftypefn
+
address@hidden {C Function} {scm_t_uint8 *} 
scm_array_handle_u8_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_int8 *} 
scm_array_handle_s8_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_uint16 *} 
scm_array_handle_u16_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_int16 *} 
scm_array_handle_s16_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_uint32 *} 
scm_array_handle_u32_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_int32 *} 
scm_array_handle_s32_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_uint64 *} 
scm_array_handle_u64_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {scm_t_int64 *} 
scm_array_handle_s64_writable_elements (scm_t_array_handle *handle)
address@hidden {C Function} {float *} scm_array_handle_f32_writable_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {double *} scm_array_handle_f64_writable_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {float *} scm_array_handle_c32_writable_elements 
(scm_t_array_handle *handle)
address@hidden {C Function} {double *} scm_array_handle_c64_writable_elements 
(scm_t_array_handle *handle)
+Like @code{scm_array_handle_<kind>_elements}, but the pointer is good
+for reading and writing.
address@hidden deftypefn
+
address@hidden {C Function} {const scm_t_uint32 *} 
scm_array_handle_bit_elements (scm_t_array_handle *handle)
+Return a pointer to the words that store the bits of the represented
+array, which must be a bit array.
+
+Unlike other arrays, bit arrays have an additional offset that must be
+figured into index calculations.  That offset is returned by
address@hidden
+
+To find a certain bit you first need to calculate its position as
+explained above for @code{scm_array_handle_dims} and then add the
+offset.  This gives the absolute position of the bit, which is always a
+non-negative integer.
+
+Each word of the bit array storage block contains exactly 32 bits, with
+the least significant bit in that word having the lowest absolute
+position number.  The next word contains the next 32 bits.
+
+Thus, the following code can be used to access a bit whose position
+according to @code{scm_array_handle_dims} is given in @var{pos}:
+
address@hidden
+SCM bit_array;
+scm_t_array_handle handle;
+scm_t_uint32 *bits;
+ssize_t pos;
+size_t abs_pos;
+size_t word_pos, mask;
+
+scm_array_get_handle (&bit_array, &handle);
+bits = scm_array_handle_bit_elements (&handle);
+
+pos = ...
+abs_pos = pos + scm_array_handle_bit_elements_offset (&handle);
+word_pos = abs_pos / 32;
+mask = 1L << (abs_pos % 32);
+
+if (bits[word_pos] & mask)
+  /* bit is set. */
+
+scm_array_handle_release (&handle);
address@hidden example
+
address@hidden deftypefn
+
address@hidden {C Function} {scm_t_uint32 *} 
scm_array_handle_bit_writable_elements (scm_t_array_handle *handle)
+Like @code{scm_array_handle_bit_elements} but the pointer is good for
+reading and writing.  You must take care not to modify bits outside of
+the allowed index range of the array, even for contiguous arrays.
address@hidden deftypefn
+
address@hidden VLists
address@hidden VLists
+
address@hidden vlist
+
+The @code{(ice-9 vlist)} module provides an implementation of the @dfn{VList}
+data structure designed by Phil Bagwell in 2002.  VLists are immutable lists,
+which can contain any Scheme object.  They improve on standard Scheme linked
+lists in several areas:
+
address@hidden
address@hidden
+Random access has typically constant-time complexity.
+
address@hidden
+Computing the length of a VList has time complexity logarithmic in the number 
of
+elements.
+
address@hidden
+VLists use less storage space than standard lists.
+
address@hidden
+VList elements are stored in contiguous regions, which improves memory locality
+and leads to more efficient use of hardware caches.
address@hidden itemize
+
+The idea behind VLists is to store vlist elements in increasingly large
+contiguous blocks (implemented as vectors here).  These blocks are linked to 
one
+another using a pointer to the next block and an offset within that block.  The
+size of these blocks form a geometric series with ratio
address@hidden (2 by default).
+
+The VList structure also serves as the basis for the @dfn{VList-based hash
+lists} or ``vhashes'', an immutable dictionary type (@pxref{VHashes}).
+
+However, the current implementation in @code{(ice-9 vlist)} has several
+noteworthy shortcomings:
+
address@hidden
+
address@hidden
+It is @emph{not} thread-safe.  Although operations on vlists are all
address@hidden transparent} (i.e., purely functional), adding elements to a
+vlist with @code{vlist-cons} mutates part of its internal structure, which 
makes
+it non-thread-safe.  This could be fixed, but it would slow down
address@hidden
+
address@hidden
address@hidden always allocates at least as much memory as @code{cons}.
+Again, Phil Bagwell describes how to fix it, but that would require tuning the
+garbage collector in a way that may not be generally beneficial.
+
address@hidden
address@hidden is a Scheme procedure compiled to bytecode, and it does not
+compete with the straightforward C implementation of @code{cons}, and with the
+fact that the VM has a special @code{cons} instruction.
+
address@hidden itemize
+
+We hope to address these in the future.
+
+The programming interface exported by @code{(ice-9 vlist)} is defined below.
+Most of it is the same as SRFI-1 with an added @code{vlist-} prefix to function
+names.
+
address@hidden {Scheme Procedure} vlist? obj
+Return true if @var{obj} is a VList.
 @end deffn
 
-Finally, a variant specialized for the host's endianness is available
-for each of these functions (with the exception of the @code{u8}
-accessors, for obvious reasons):
address@hidden {Scheme Variable} vlist-null
+The empty VList.  Note that it's possible to create an empty VList not
address@hidden to @code{vlist-null}; thus, callers should always use
address@hidden when testing whether a VList is empty.
address@hidden defvr
 
address@hidden {Scheme Procedure} bytevector-u16-native-ref bv index
address@hidden {Scheme Procedure} bytevector-s16-native-ref bv index
address@hidden {Scheme Procedure} bytevector-u32-native-ref bv index
address@hidden {Scheme Procedure} bytevector-s32-native-ref bv index
address@hidden {Scheme Procedure} bytevector-u64-native-ref bv index
address@hidden {Scheme Procedure} bytevector-s64-native-ref bv index
address@hidden {C Function} scm_bytevector_u16_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_s16_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_u32_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_s32_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_u64_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_s64_native_ref (bv, index)
-Return the unsigned @var{n}-bit (signed) integer (where @var{n} is 8,
-16, 32 or 64) from @var{bv} at @var{index}, decoded according to the
-host's native endianness.
address@hidden {Scheme Procedure} vlist-null? vlist
+Return true if @var{vlist} is empty.
 @end deffn
 
address@hidden {Scheme Procedure} bytevector-u16-native-set! bv index value
address@hidden {Scheme Procedure} bytevector-s16-native-set! bv index value
address@hidden {Scheme Procedure} bytevector-u32-native-set! bv index value
address@hidden {Scheme Procedure} bytevector-s32-native-set! bv index value
address@hidden {Scheme Procedure} bytevector-u64-native-set! bv index value
address@hidden {Scheme Procedure} bytevector-s64-native-set! bv index value
address@hidden {C Function} scm_bytevector_u16_native_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_s16_native_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_u32_native_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_s32_native_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_u64_native_set_x (bv, index, value)
address@hidden {C Function} scm_bytevector_s64_native_set_x (bv, index, value)
-Store @var{value} as an @var{n}-bit (signed) integer (where @var{n} is
-8, 16, 32 or 64) in @var{bv} at @var{index}, encoded according to the
-host's native endianness.
address@hidden {Scheme Procedure} vlist-cons item vlist
+Return a new vlist with @var{item} as its head and @var{vlist} as its tail.
 @end deffn
 
address@hidden {Scheme Procedure} vlist-head vlist
+Return the head of @var{vlist}.
address@hidden deffn
 
address@hidden Bytevectors and Integer Lists
address@hidden Converting Bytevectors to/from Integer Lists
address@hidden {Scheme Procedure} vlist-tail vlist
+Return the tail of @var{vlist}.
address@hidden deffn
 
-Bytevector contents can readily be converted to/from lists of signed or
-unsigned integers:
address@hidden {Scheme Variable} block-growth-factor
+A fluid that defines the growth factor of VList blocks, 2 by default.
address@hidden defvr
 
address@hidden
-(bytevector->sint-list (u8-list->bytevector (make-list 4 255))
-                       (endianness little) 2)
address@hidden (-1 -1)
address@hidden lisp
+The functions below provide the usual set of higher-level list operations.
 
address@hidden {Scheme Procedure} bytevector->u8-list bv
address@hidden {C Function} scm_bytevector_to_u8_list (bv)
-Return a newly allocated list of unsigned 8-bit integers from the
-contents of @var{bv}.
address@hidden {Scheme Procedure} vlist-fold proc init vlist
address@hidden {Scheme Procedure} vlist-fold-right proc init vlist
+Fold over @var{vlist}, calling @var{proc} for each element, as for SRFI-1
address@hidden and @code{fold-right} (@pxref{SRFI-1, @code{fold}}).
 @end deffn
 
address@hidden {Scheme Procedure} u8-list->bytevector lst
address@hidden {C Function} scm_u8_list_to_bytevector (lst)
-Return a newly allocated bytevector consisting of the unsigned 8-bit
-integers listed in @var{lst}.
address@hidden {Scheme Procedure} vlist-ref vlist index
+Return the element at index @var{index} in @var{vlist}.  This is typically a
+constant-time operation.
 @end deffn
 
address@hidden {Scheme Procedure} bytevector->uint-list bv endianness size
address@hidden {C Function} scm_bytevector_to_uint_list (bv, endianness, size)
-Return a list of unsigned integers of @var{size} bytes representing the
-contents of @var{bv}, decoded according to @var{endianness}.
address@hidden {Scheme Procedure} vlist-length vlist
+Return the length of @var{vlist}.  This is typically logarithmic in the number
+of elements in @var{vlist}.
 @end deffn
 
address@hidden {Scheme Procedure} bytevector->sint-list bv endianness size
address@hidden {C Function} scm_bytevector_to_sint_list (bv, endianness, size)
-Return a list of signed integers of @var{size} bytes representing the
-contents of @var{bv}, decoded according to @var{endianness}.
address@hidden {Scheme Procedure} vlist-reverse vlist
+Return a new @var{vlist} whose content are those of @var{vlist} in reverse
+order.
 @end deffn
 
address@hidden {Scheme Procedure} uint-list->bytevector lst endianness size
address@hidden {C Function} scm_uint_list_to_bytevector (lst, endianness, size)
-Return a new bytevector containing the unsigned integers listed in
address@hidden and encoded on @var{size} bytes according to @var{endianness}.
address@hidden {Scheme Procedure} vlist-map proc vlist
+Map @var{proc} over the elements of @var{vlist} and return a new vlist.
 @end deffn
 
address@hidden {Scheme Procedure} sint-list->bytevector lst endianness size
address@hidden {C Function} scm_sint_list_to_bytevector (lst, endianness, size)
-Return a new bytevector containing the signed integers listed in
address@hidden and encoded on @var{size} bytes according to @var{endianness}.
address@hidden {Scheme Procedure} vlist-for-each proc vlist
+Call @var{proc} on each element of @var{vlist}.  The result is unspecified.
 @end deffn
 
address@hidden Bytevectors as Floats
address@hidden Interpreting Bytevector Contents as Floating Point Numbers
address@hidden {Scheme Procedure} vlist-drop vlist count
+Return a new vlist that does not contain the @var{count} first elements of
address@hidden  This is typically a constant-time operation.
address@hidden deffn
 
address@hidden IEEE-754 floating point numbers
address@hidden {Scheme Procedure} vlist-take vlist count
+Return a new vlist that contains only the @var{count} first elements of
address@hidden
address@hidden deffn
 
-Bytevector contents can also be accessed as IEEE-754 single- or
-double-precision floating point numbers (respectively 32 and 64-bit
-long) using the procedures described here.
address@hidden {Scheme Procedure} vlist-filter pred vlist
+Return a new vlist containing all the elements from @var{vlist} that satisfy
address@hidden
address@hidden deffn
 
address@hidden {Scheme Procedure} bytevector-ieee-single-ref bv index endianness
address@hidden {Scheme Procedure} bytevector-ieee-double-ref bv index endianness
address@hidden {C Function} scm_bytevector_ieee_single_ref (bv, index, 
endianness)
address@hidden {C Function} scm_bytevector_ieee_double_ref (bv, index, 
endianness)
-Return the IEEE-754 single-precision floating point number from @var{bv}
-at @var{index} according to @var{endianness}.
address@hidden {Scheme Procedure} vlist-delete x vlist [equal?]
+Return a new vlist corresponding to @var{vlist} without the elements
address@hidden to @var{x}.
 @end deffn
 
address@hidden {Scheme Procedure} bytevector-ieee-single-set! bv index value 
endianness
address@hidden {Scheme Procedure} bytevector-ieee-double-set! bv index value 
endianness
address@hidden {C Function} scm_bytevector_ieee_single_set_x (bv, index, value, 
endianness)
address@hidden {C Function} scm_bytevector_ieee_double_set_x (bv, index, value, 
endianness)
-Store real number @var{value} in @var{bv} at @var{index} according to
address@hidden
address@hidden {Scheme Procedure} vlist-unfold p f g seed [tail-gen]
address@hidden {Scheme Procedure} vlist-unfold-right p f g seed [tail]
+Return a new vlist, as for SRFI-1 @code{unfold} and @code{unfold-right}
+(@pxref{SRFI-1, @code{unfold}}).
 @end deffn
 
-Specialized procedures are also available:
address@hidden {Scheme Procedure} vlist-append vlist @dots{}
+Append the given vlists and return the resulting vlist.
address@hidden deffn
 
address@hidden {Scheme Procedure} bytevector-ieee-single-native-ref bv index
address@hidden {Scheme Procedure} bytevector-ieee-double-native-ref bv index
address@hidden {C Function} scm_bytevector_ieee_single_native_ref (bv, index)
address@hidden {C Function} scm_bytevector_ieee_double_native_ref (bv, index)
-Return the IEEE-754 single-precision floating point number from @var{bv}
-at @var{index} according to the host's native endianness.
address@hidden {Scheme Procedure} list->vlist lst
+Return a new vlist whose contents correspond to @var{lst}.
 @end deffn
 
address@hidden {Scheme Procedure} bytevector-ieee-single-native-set! bv index 
value
address@hidden {Scheme Procedure} bytevector-ieee-double-native-set! bv index 
value
address@hidden {C Function} scm_bytevector_ieee_single_native_set_x (bv, index, 
value)
address@hidden {C Function} scm_bytevector_ieee_double_native_set_x (bv, index, 
value)
-Store real number @var{value} in @var{bv} at @var{index} according to
-the host's native endianness.
address@hidden {Scheme Procedure} vlist->list vlist
+Return a new list whose contents match those of @var{vlist}.
 @end deffn
 
address@hidden Record Overview
address@hidden Record Overview
+
address@hidden record
address@hidden structure
 
address@hidden Bytevectors as Strings
address@hidden Interpreting Bytevector Contents as Unicode Strings
address@hidden, also called @dfn{structures}, are Scheme's primary
+mechanism to define new disjoint types.  A @dfn{record type} defines a
+list of @dfn{fields} that instances of the type consist of.  This is like
+C's @code{struct}.
 
address@hidden Unicode string encoding
+Historically, Guile has offered several different ways to define record
+types and to create records, offering different features, and making
+different trade-offs.  Over the years, each ``standard'' has also come
+with its own new record interface, leading to a maze of record APIs.
 
-Bytevector contents can also be interpreted as Unicode strings encoded
-in one of the most commonly available encoding formats.
address@hidden Strings as Bytes}, for a more generic interface.
+At the highest level is SRFI-9, a high-level record interface
+implemented by most Scheme implementations (@pxref{SRFI-9 Records}).  It
+defines a simple and efficient syntactic abstraction of record types and
+their associated type predicate, fields, and field accessors.  SRFI-9 is
+suitable for most uses, and this is the recommended way to create record
+types in Guile.  Similar high-level record APIs include SRFI-35
+(@pxref{SRFI-35}) and R6RS records (@pxref{rnrs records syntactic}).
 
address@hidden
-(utf8->string (u8-list->bytevector '(99 97 102 101)))
address@hidden "cafe"
+Then comes Guile's historical ``records'' API (@pxref{Records}).  Record
+types defined this way are first-class objects.  Introspection
+facilities are available, allowing users to query the list of fields or
+the value of a specific field at run-time, without prior knowledge of
+the type.
 
-(string->utf8 "caf@'e") ;; SMALL LATIN LETTER E WITH ACUTE ACCENT
address@hidden #vu8(99 97 102 195 169)
address@hidden lisp
+Finally, the common denominator of these interfaces is Guile's
address@hidden API (@pxref{Structures}).  Guile's structures are the
+low-level building block for all other record APIs.  Application writers
+will normally not need to use it.
 
address@hidden {Scheme Procedure} {} string-utf8-length str
address@hidden {C function} SCM scm_string_utf8_length (str)
address@hidden {C function} size_t scm_c_string_utf8_length (str)
-Return the number of bytes in the UTF-8 representation of @var{str}.
address@hidden deftypefn
+Records created with these APIs may all be pattern-matched using Guile's
+standard pattern matcher (@pxref{Pattern Matching}).
 
address@hidden {Scheme Procedure} string->utf8 str
address@hidden {Scheme Procedure} string->utf16 str [endianness]
address@hidden {Scheme Procedure} string->utf32 str [endianness]
address@hidden {C Function} scm_string_to_utf8 (str)
address@hidden {C Function} scm_string_to_utf16 (str, endianness)
address@hidden {C Function} scm_string_to_utf32 (str, endianness)
-Return a newly allocated bytevector that contains the UTF-8, UTF-16, or
-UTF-32 (aka. UCS-4) encoding of @var{str}.  For UTF-16 and UTF-32,
address@hidden should be the symbol @code{big} or @code{little}; when omitted,
-it defaults to big endian.
address@hidden deffn
 
address@hidden {Scheme Procedure} utf8->string utf
address@hidden {Scheme Procedure} utf16->string utf [endianness]
address@hidden {Scheme Procedure} utf32->string utf [endianness]
address@hidden {C Function} scm_utf8_to_string (utf)
address@hidden {C Function} scm_utf16_to_string (utf, endianness)
address@hidden {C Function} scm_utf32_to_string (utf, endianness)
-Return a newly allocated string that contains from the UTF-8-, UTF-16-,
-or UTF-32-decoded contents of bytevector @var{utf}.  For UTF-16 and UTF-32,
address@hidden should be the symbol @code{big} or @code{little}; when omitted,
-it defaults to big endian.
address@hidden deffn
address@hidden SRFI-9 Records
address@hidden SRFI-9 Records
 
address@hidden Bytevectors as Arrays
address@hidden Accessing Bytevectors with the Array API
address@hidden SRFI-9
address@hidden record
 
-As an extension to the R6RS, Guile allows bytevectors to be manipulated
-with the @dfn{array} procedures (@pxref{Arrays}).  When using these
-APIs, bytes are accessed one at a time as 8-bit unsigned integers:
+SRFI-9 standardizes a syntax for defining new record types and creating
+predicate, constructor, and field getter and setter functions.  In Guile
+this is the recommended option to create new record types (@pxref{Record
+Overview}).  It can be used with:
 
 @example
-(define bv #vu8(0 1 2 3))
+(use-modules (srfi srfi-9))
address@hidden example
 
-(array? bv)
address@hidden #t
address@hidden {Scheme Syntax} define-record-type type @* (constructor 
fieldname @dots{}) @* predicate @* (fieldname accessor [modifier]) @dots{}
address@hidden 1
+Create a new record type, and make various @code{define}s for using
+it.  This syntax can only occur at the top-level, not nested within
+some other form.
 
-(array-rank bv)
address@hidden 1
address@hidden is bound to the record type, which is as per the return
+from the core @code{make-record-type}.  @var{type} also provides the
+name for the record, as per @code{record-type-name}.
 
-(array-ref bv 2)
address@hidden 2
address@hidden is bound to a function to be called as
address@hidden(@var{constructor} fieldval @dots{})} to create a new record of
+this type.  The arguments are initial values for the fields, one
+argument for each field, in the order they appear in the
address@hidden form.
 
-;; Note the different argument order on array-set!.
-(array-set! bv 77 2)
-(array-ref bv 2)
address@hidden 77
+The @var{fieldname}s provide the names for the record fields, as per
+the core @code{record-type-fields} etc, and are referred to in the
+subsequent accessor/modifier forms.
 
-(array-type bv)
address@hidden vu8
address@hidden is bound to a function to be called as
address@hidden(@var{predicate} obj)}.  It returns @code{#t} or @code{#f}
+according to whether @var{obj} is a record of this type.
+
+Each @var{accessor} is bound to a function to be called
address@hidden(@var{accessor} record)} to retrieve the respective field from a
address@hidden  Similarly each @var{modifier} is bound to a function to
+be called @code{(@var{modifier} record val)} to set the respective
+field in a @var{record}.
address@hidden deffn
+
address@hidden
+An example will illustrate typical usage,
+
address@hidden
+(define-record-type <employee>
+  (make-employee name age salary)
+  employee?
+  (name    employee-name)
+  (age     employee-age    set-employee-age!)
+  (salary  employee-salary set-employee-salary!))
 @end example
 
+This creates a new employee data type, with name, age and salary
+fields.  Accessor functions are created for each field, but no
+modifier function for the name (the intention in this example being
+that it's established only when an employee object is created).  These
+can all then be used as for example,
 
address@hidden Bytevectors as Uniform Vectors
address@hidden Accessing Bytevectors with the SRFI-4 API
address@hidden
+<employee> @result{} #<record-type <employee>>
 
-Bytevectors may also be accessed with the SRFI-4 API. @xref{SRFI-4 and
-Bytevectors}, for more information.
+(define fred (make-employee "Fred" 45 20000.00))
 
+(employee? fred)        @result{} #t
+(employee-age fred)     @result{} 45
+(set-employee-salary! fred 25000.00)  ;; pay rise
address@hidden example
 
address@hidden Symbols
address@hidden Symbols
address@hidden Symbols
+The functions created by @code{define-record-type} are ordinary
+top-level @code{define}s.  They can be redefined or @code{set!} as
+desired, exported from a module, etc.
 
-Symbols in Scheme are widely used in three ways: as items of discrete
-data, as lookup keys for alists and hash tables, and to denote variable
-references.
address@hidden Non-toplevel Record Definitions
 
-A @dfn{symbol} is similar to a string in that it is defined by a
-sequence of characters.  The sequence of characters is known as the
-symbol's @dfn{name}.  In the usual case --- that is, where the symbol's
-name doesn't include any characters that could be confused with other
-elements of Scheme syntax --- a symbol is written in a Scheme program by
-writing the sequence of characters that make up the name, @emph{without}
-any quotation marks or other special syntax.  For example, the symbol
-whose name is ``multiply-by-2'' is written, simply:
+The SRFI-9 specification explicitly disallows record definitions in a
+non-toplevel context, such as inside @code{lambda} body or inside a
address@hidden block.  However, Guile's implementation does not enforce that
+restriction.
 
address@hidden
-multiply-by-2
address@hidden lisp
address@hidden Custom Printers
 
-Notice how this differs from a @emph{string} with contents
-``multiply-by-2'', which is written with double quotation marks, like
-this:
+You may use @code{set-record-type-printer!} to customize the default printing
+behavior of records.  This is a Guile extension and is not part of SRFI-9.  It
+is located in the @nicode{(srfi srfi-9 gnu)} module.
 
address@hidden
-"multiply-by-2"
address@hidden lisp
address@hidden {Scheme Syntax} set-record-type-printer! type proc
+Where @var{type} corresponds to the first argument of 
@code{define-record-type},
+and @var{proc} is a procedure accepting two arguments, the record to print, and
+an output port.
address@hidden deffn
 
-Looking beyond how they are written, symbols are different from strings
-in two important respects.
address@hidden
+This example prints the employee's name in brackets, for instance 
@code{[Fred]}.
 
-The first important difference is uniqueness.  If the same-looking
-string is read twice from two different places in a program, the result
-is two @emph{different} string objects whose contents just happen to be
-the same.  If, on the other hand, the same-looking symbol is read twice
-from two different places in a program, the result is the @emph{same}
-symbol object both times.
address@hidden
+(set-record-type-printer! <employee>
+  (lambda (record port)
+    (write-char #\[ port)
+    (display (employee-name record) port)
+    (write-char #\] port)))
address@hidden example
 
-Given two read symbols, you can use @code{eq?} to test whether they are
-the same (that is, have the same name).  @code{eq?} is the most
-efficient comparison operator in Scheme, and comparing two symbols like
-this is as fast as comparing, for example, two numbers.  Given two
-strings, on the other hand, you must use @code{equal?} or
address@hidden, which are much slower comparison operators, to
-determine whether the strings have the same contents.
address@hidden Functional ``Setters''
 
address@hidden
-(define sym1 (quote hello))
-(define sym2 (quote hello))
-(eq? sym1 sym2) @result{} #t
address@hidden functional setters
 
-(define str1 "hello")
-(define str2 "hello")
-(eq? str1 str2) @result{} #f
-(equal? str1 str2) @result{} #t
address@hidden lisp
+When writing code in a functional style, it is desirable to never alter
+the contents of records.  For such code, a simple way to return new
+record instances based on existing ones is highly desirable.
 
-The second important difference is that symbols, unlike strings, are not
-self-evaluating.  This is why we need the @code{(quote @dots{})}s in the
-example above: @code{(quote hello)} evaluates to the symbol named
-"hello" itself, whereas an unquoted @code{hello} is @emph{read} as the
-symbol named "hello" and evaluated as a variable reference @dots{} about
-which more below (@pxref{Symbol Variables}).
+The @code{(srfi srfi-9 gnu)} module extends SRFI-9 with facilities to
+return new record instances based on existing ones, only with one or
+more field values address@hidden setters}.  First, the
address@hidden works like
address@hidden, except that fields are immutable and setters
+are defined as functional setters.
 
address@hidden
-* Symbol Data::                 Symbols as discrete data.
-* Symbol Keys::                 Symbols as lookup keys.
-* Symbol Variables::            Symbols as denoting variables.
-* Symbol Primitives::           Operations related to symbols.
-* Symbol Props::                Function slots and property lists.
-* Symbol Read Syntax::          Extended read syntax for symbols.
-* Symbol Uninterned::           Uninterned symbols.
address@hidden menu
address@hidden {Scheme Syntax} define-immutable-record-type type @* 
(constructor fieldname @dots{}) @* predicate @* (fieldname accessor [modifier]) 
@dots{}
+Define @var{type} as a new record type, like @code{define-record-type}.
+However, the record type is made @emph{immutable} (records may not be
+mutated, even with @code{struct-set!}), and any @var{modifier} is
+defined to be a functional setter---a procedure that returns a new
+record instance with the specified field changed, and leaves the
+original unchanged (see example below.)
address@hidden deffn
 
address@hidden
+In addition, the generic @code{set-field} and @code{set-fields} macros
+may be applied to any SRFI-9 record.
 
address@hidden Symbol Data
address@hidden Symbols as Discrete Data
address@hidden {Scheme Syntax} set-field record (field sub-fields ...) value
+Return a new record of @var{record}'s type whose fields are equal to
+the corresponding fields of @var{record} except for the one specified by
address@hidden
 
-Numbers and symbols are similar to the extent that they both lend
-themselves to @code{eq?} comparison.  But symbols are more descriptive
-than numbers, because a symbol's name can be used directly to describe
-the concept for which that symbol stands.
address@hidden must be the name of the getter corresponding to the field of
address@hidden being ``set''.  Subsequent @var{sub-fields} must be record
+getters designating sub-fields within that field value to be set (see
+example below.)
address@hidden deffn
 
-For example, imagine that you need to represent some colours in a
-computer program.  Using numbers, you would have to choose arbitrarily
-some mapping between numbers and colours, and then take care to use that
-mapping consistently:
address@hidden {Scheme Syntax} set-fields record ((field sub-fields ...) value) 
...
+Like @code{set-field}, but can be used to set more than one field at a
+time.  This expands to code that is more efficient than a series of
+single @code{set-field} calls.
address@hidden deffn
 
address@hidden
-;; 1=red, 2=green, 3=purple
+To illustrate the use of functional setters, let's assume these two
+record type definitions:
 
-(if (eq? (colour-of vehicle) 1)
-    ...)
address@hidden lisp
address@hidden
+(define-record-type <address>
+  (address street city country)
+  address?
+  (street  address-street)
+  (city    address-city)
+  (country address-country))
+
+(define-immutable-record-type <person>
+  (person age email address)
+  person?
+  (age     person-age set-person-age)
+  (email   person-email set-person-email)
+  (address person-address set-person-address))
address@hidden example
 
 @noindent
-You can make the mapping more explicit and the code more readable by
-defining constants:
+First, note that the @code{<person>} record type definition introduces
+named functional setters.  These may be used like this:
 
address@hidden
-(define red 1)
-(define green 2)
-(define purple 3)
address@hidden
+(define fsf-address
+  (address "Franklin Street" "Boston" "USA"))
 
-(if (eq? (colour-of vehicle) red)
-    ...)
address@hidden lisp
+(define rms
+  (person 30 "rms@@gnu.org" fsf-address))
 
address@hidden
-But the simplest and clearest approach is not to use numbers at all, but
-symbols whose names specify the colours that they refer to:
+(and (equal? (set-person-age rms 60)
+             (person 60 "rms@@gnu.org" fsf-address))
+     (= (person-age rms) 30))
address@hidden #t
address@hidden example
 
address@hidden
-(if (eq? (colour-of vehicle) 'red)
-    ...)
address@hidden lisp
address@hidden
+Here, the original @code{<person>} record, to which @var{rms} is bound,
+is left unchanged.
 
-The descriptive advantages of symbols over numbers increase as the set
-of concepts that you want to describe grows.  Suppose that a car object
-can have other properties as well, such as whether it has or uses:
+Now, suppose we want to change both the street and age of @var{rms}.
+This can be achieved using @code{set-fields}:
 
address@hidden @bullet
address@hidden
-automatic or manual transmission
address@hidden
-leaded or unleaded fuel
address@hidden
-power steering (or not).
address@hidden itemize
address@hidden
+(set-fields rms
+  ((person-age) 60)
+  ((person-address address-street) "Temple Place"))
address@hidden #<<person> age: 60 email: "rms@@gnu.org"
+  address: #<<address> street: "Temple Place" city: "Boston" country: "USA">>
address@hidden example
 
 @noindent
-Then a car's combined property set could be naturally represented and
-manipulated as a list of symbols:
+Notice how the above changed two fields of @var{rms}, including the
address@hidden field of its @code{address} field, in a concise way.  Also
+note that @code{set-fields} works equally well for types defined with
+just @code{define-record-type}.
 
address@hidden
-(properties-of vehicle1)
address@hidden
-(red manual unleaded power-steering)
address@hidden Records
address@hidden Records
 
-(if (memq 'power-steering (properties-of vehicle1))
-    (display "Unfit people can drive this vehicle.\n")
-    (display "You'll need strong arms to drive this vehicle!\n"))
address@hidden
-Unfit people can drive this vehicle.
address@hidden lisp
+A @dfn{record type} is a first class object representing a user-defined
+data type.  A @dfn{record} is an instance of a record type.
 
-Remember, the fundamental property of symbols that we are relying on
-here is that an occurrence of @code{'red} in one part of a program is an
address@hidden symbol from an occurrence of @code{'red} in
-another part of a program; this means that symbols can usefully be
-compared using @code{eq?}.  At the same time, symbols have naturally
-descriptive names.  This combination of efficiency and descriptive power
-makes them ideal for use as discrete data.
+Note that in many ways, this interface is too low-level for every-day
+use.  Most uses of records are better served by SRFI-9 records.
address@hidden Records}.
 
address@hidden {Scheme Procedure} record? obj
+Return @code{#t} if @var{obj} is a record of any type and @code{#f}
+otherwise.
 
address@hidden Symbol Keys
address@hidden Symbols as Lookup Keys
+Note that @code{record?} may be true of any Scheme value; there is no
+promise that records are disjoint with other Scheme types.
address@hidden deffn
 
-Given their efficiency and descriptive power, it is natural to use
-symbols as the keys in an association list or hash table.
address@hidden {Scheme Procedure} make-record-type type-name field-names [print]
+Create and return a new @dfn{record-type descriptor}.
 
-To illustrate this, consider a more structured representation of the car
-properties example from the preceding subsection.  Rather than
-mixing all the properties up together in a flat list, we could use an
-association list like this:
address@hidden is a string naming the type.  Currently it's only used
+in the printed representation of records, and in diagnostics.
address@hidden is a list of symbols naming the fields of a record
+of the type.  Duplicates are not allowed among these symbols.
 
address@hidden
-(define car1-properties '((colour . red)
-                          (transmission . manual)
-                          (fuel . unleaded)
-                          (steering . power-assisted)))
address@hidden lisp
address@hidden
+(make-record-type "employee" '(name age salary))
address@hidden example
 
-Notice how this structure is more explicit and extensible than the flat
-list.  For example it makes clear that @code{manual} refers to the
-transmission rather than, say, the windows or the locking of the car.
-It also allows further properties to use the same symbols among their
-possible values without becoming ambiguous:
+The optional @var{print} argument is a function used by
address@hidden, @code{write}, etc, for printing a record of the new
+type.  It's called as @code{(@var{print} record port)} and should look
+at @var{record} and write to @var{port}.
address@hidden deffn
+
address@hidden {Scheme Procedure} record-constructor rtd [field-names]
+Return a procedure for constructing new members of the type represented
+by @var{rtd}.  The returned procedure accepts exactly as many arguments
+as there are symbols in the given list, @var{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 @var{field-names}
+argument defaults to the list of field names in the call to
address@hidden that created the type represented by @var{rtd};
+if the @var{field-names} argument is provided, it is an error if it
+contains any duplicates or any symbols not in the default list.
address@hidden deffn
+
address@hidden {Scheme Procedure} record-predicate rtd
+Return a procedure for testing membership in the type represented by
address@hidden  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.
address@hidden deffn
+
address@hidden {Scheme Procedure} record-accessor rtd field-name
+Return a procedure for reading the value of a particular field of a
+member of the type represented by @var{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
address@hidden in that record.  The symbol @var{field-name} must be a
+member of the list of field-names in the call to @code{make-record-type}
+that created the type represented by @var{rtd}.
address@hidden deffn
+
address@hidden {Scheme Procedure} record-modifier rtd field-name
+Return a procedure for writing the value of a particular field of a
+member of the type represented by @var{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 @var{field-name} in that record to contain the given value.
+The returned value of the modifier procedure is unspecified.  The symbol
address@hidden must be a member of the list of field-names in the call
+to @code{make-record-type} that created the type represented by
address@hidden
address@hidden deffn
+
address@hidden {Scheme Procedure} record-type-descriptor record
+Return a record-type descriptor representing the type of the given
+record.  That is, for example, if the returned descriptor were passed to
address@hidden, 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
address@hidden in the call that created the constructor
+procedure that created the given record.
address@hidden deffn
+
address@hidden {Scheme Procedure} record-type-name rtd
+Return the type-name associated with the type represented by rtd.  The
+returned value is @code{eqv?} to the @var{type-name} argument given in
+the call to @code{make-record-type} that created the type represented by
address@hidden
address@hidden deffn
+
address@hidden {Scheme Procedure} record-type-fields rtd
+Return a list of the symbols naming the fields in members of the type
+represented by @var{rtd}.  The returned value is @code{equal?} to the
+field-names argument given in the call to @code{make-record-type} that
+created the type represented by @var{rtd}.
address@hidden deffn
+
+
address@hidden Structures
address@hidden Structures
address@hidden Structures
+
+A @dfn{structure} is a first class data type which holds Scheme values
+or C words in fields numbered 0 upwards.  A @dfn{vtable} is a structure
+that represents a structure type, giving field types and permissions,
+and an optional print function for @code{write} etc.
+
+Structures are lower level than records (@pxref{Records}).  Usually,
+when you need to represent structured data, you just want to use
+records.  But sometimes you need to implement new kinds of structured
+data abstractions, and for that purpose structures are useful.  Indeed,
+records in Guile are implemented with structures.
 
address@hidden
-(define car1-properties '((colour . red)
-                          (transmission . manual)
-                          (fuel . unleaded)
-                          (steering . power-assisted)
-                          (seat-colour . red)
-                          (locking . manual)))
address@hidden lisp
address@hidden
+* Vtables::
+* Structure Basics::
+* Vtable Contents::
+* Meta-Vtables::
+* Vtable Example::
+* Tail Arrays::
address@hidden menu
+
address@hidden Vtables
address@hidden Vtables
+
+A vtable is a structure type, specifying its layout, and other
+information.  A vtable is actually itself a structure, but there's no
+need to worry about that initially (@pxref{Vtable Contents}.)
+
address@hidden {Scheme Procedure} make-vtable fields [print]
+Create a new vtable.
+
address@hidden is a string describing the fields in the structures to be
+created.  Each field is represented by two characters, a type letter
+and a permissions letter, for example @code{"pw"}.  The types are as
+follows.
+
address@hidden @bullet{}
address@hidden
address@hidden -- a Scheme value.  ``p'' stands for ``protected'' meaning
+it's protected against garbage collection.
+
address@hidden
address@hidden -- an arbitrary word of data (an @code{scm_t_bits}).  At the
+Scheme level it's read and written as an unsigned integer.  ``u''
+stands for ``uninterpreted'' (it's not treated as a Scheme value), or
+``unprotected'' (it's not marked during GC), or ``unsigned long'' (its
+size), or all of these things.
+
address@hidden
address@hidden -- a self-reference.  Such a field holds the @code{SCM} value
+of the structure itself (a circular reference).  This can be useful in
+C code where you might have a pointer to the data array, and want to
+get the Scheme @code{SCM} handle for the structure.  In Scheme code it
+has no use.
address@hidden itemize
+
+The second letter for each field is a permission code,
+
address@hidden @bullet{}
address@hidden
address@hidden -- writable, the field can be read and written.
address@hidden
address@hidden -- read-only, the field can be read but not written.
address@hidden
address@hidden -- opaque, the field can be neither read nor written at the
+Scheme level.  This can be used for fields which should only be used
+from C code.
address@hidden itemize
 
-With a representation like this, it is easy to use the efficient
address@hidden family of procedures (@pxref{Association Lists}) to
-extract or change individual pieces of information:
+Here are some examples.  @xref{Tail Arrays}, for information on the
+legacy tail array facility.
 
address@hidden
-(assq-ref car1-properties 'fuel) @result{} unleaded
-(assq-ref car1-properties 'transmission) @result{} manual
address@hidden
+(make-vtable "pw")      ;; one writable field
+(make-vtable "prpw")    ;; one read-only and one writable
+(make-vtable "pwuwuw")  ;; one scheme and two uninterpreted
address@hidden example
 
-(assq-set! car1-properties 'seat-colour 'black)
address@hidden
-((colour . red)
- (transmission . manual)
- (fuel . unleaded)
- (steering . power-assisted)
- (seat-colour . black)
- (locking . manual)))
address@hidden lisp
+The optional @var{print} argument is a function called by
address@hidden and @code{write} (etc) to give a printed representation
+of a structure created from this vtable.  It's called
address@hidden(@var{print} struct port)} and should look at @var{struct} and
+write to @var{port}.  The default print merely gives a form like
address@hidden<struct ADDR:ADDR>} with a pair of machine addresses.
 
-Hash tables also have keys, and exactly the same arguments apply to the
-use of symbols in hash tables as in association lists.  The hash value
-that Guile uses to decide where to add a symbol-keyed entry to a hash
-table can be obtained by calling the @code{symbol-hash} procedure:
+The following print function for example shows the two fields of its
+structure.
 
address@hidden {Scheme Procedure} symbol-hash symbol
address@hidden {C Function} scm_symbol_hash (symbol)
-Return a hash value for @var{symbol}.
address@hidden
+(make-vtable "prpw"
+             (lambda (struct port)
+               (format port "#<~a and ~a>"
+                       (struct-ref struct 0)
+                       (struct-ref struct 1))))
address@hidden example
 @end deffn
 
-See @ref{Hash Tables} for information about hash tables in general, and
-for why you might choose to use a hash table rather than an association
-list.
-
 
address@hidden Symbol Variables
address@hidden Symbols as Denoting Variables
address@hidden Structure Basics
address@hidden Structure Basics
 
-When an unquoted symbol in a Scheme program is evaluated, it is
-interpreted as a variable reference, and the result of the evaluation is
-the appropriate variable's value.
+This section describes the basic procedures for working with
+structures.  @code{make-struct} creates a structure, and
address@hidden and @code{struct-set!} access its fields.
 
-For example, when the expression @code{(string-length "abcd")} is read
-and evaluated, the sequence of characters @code{string-length} is read
-as the symbol whose name is "string-length".  This symbol is associated
-with a variable whose value is the procedure that implements string
-length calculation.  Therefore evaluation of the @code{string-length}
-symbol results in that procedure.
address@hidden {Scheme Procedure} make-struct vtable tail-size init @dots{}
address@hidden {Scheme Procedure} make-struct/no-tail vtable init @dots{}
+Create a new structure, with layout per the given @var{vtable}
+(@pxref{Vtables}).
 
-The details of the connection between an unquoted symbol and the
-variable to which it refers are explained elsewhere.  See @ref{Binding
-Constructs}, for how associations between symbols and variables are
-created, and @ref{Modules}, for how those associations are affected by
-Guile's module system.
+The optional @address@hidden arguments are initial values for the
+fields of the structure.  This is the only way to
+put values in read-only fields.  If there are fewer @var{init}
+arguments than fields then the defaults are @code{#f} for a Scheme
+field (type @code{p}) or 0 for an uninterpreted field (type @code{u}).
 
+Structures also have the ability to allocate a variable number of
+additional cells at the end, at their tails.  However, this legacy
address@hidden array} facilty is confusing and inefficient, and so we do not
+recommend it.  @xref{Tail Arrays}, for more on the legacy tail array
+interface.
 
address@hidden Symbol Primitives
address@hidden Operations Related to Symbols
+Type @code{s} self-reference fields, permission @code{o} opaque
+fields, and the count field of a tail array are all ignored for the
address@hidden arguments, ie.@: an argument is not consumed by such a
+field.  An @code{s} is always set to the structure itself, an @code{o}
+is always set to @code{#f} or 0 (with the intention that C code will
+do something to it later), and the tail count is always the given
address@hidden
 
-Given any Scheme value, you can determine whether it is a symbol using
-the @code{symbol?} primitive:
+For example,
 
address@hidden symbol?
address@hidden {Scheme Procedure} symbol? obj
address@hidden {C Function} scm_symbol_p (obj)
-Return @code{#t} if @var{obj} is a symbol, otherwise return
address@hidden
address@hidden
+(define v (make-vtable "prpwpw"))
+(define s (make-struct v 0 123 "abc" 456))
+(struct-ref s 0) @result{} 123
+(struct-ref s 1) @result{} "abc"
address@hidden example
 @end deffn
 
address@hidden {C Function} int scm_is_symbol (SCM val)
-Equivalent to @code{scm_is_true (scm_symbol_p (val))}.
address@hidden {C Function} SCM scm_make_struct (SCM vtable, SCM tail_size, SCM 
init_list)
address@hidden {C Function} SCM scm_c_make_struct (SCM vtable, SCM tail_size, 
SCM init, ...)
address@hidden {C Function} SCM scm_c_make_structv (SCM vtable, SCM tail_size, 
size_t n_inits, scm_t_bits init[])
+There are a few ways to make structures from C.  @code{scm_make_struct}
+takes a list, @code{scm_c_make_struct} takes variable arguments
+terminated with SCM_UNDEFINED, and @code{scm_c_make_structv} takes a
+packed array.
 @end deftypefn
 
-Once you know that you have a symbol, you can obtain its name as a
-string by calling @code{symbol->string}.  Note that Guile differs by
-default from R5RS on the details of @code{symbol->string} as regards
-case-sensitivity:
address@hidden {Scheme Procedure} struct? obj
address@hidden {C Function} scm_struct_p (obj)
+Return @code{#t} if @var{obj} is a structure, or @code{#f} if not.
address@hidden deffn
 
address@hidden symbol->string
address@hidden {Scheme Procedure} symbol->string s
address@hidden {C Function} scm_symbol_to_string (s)
-Return the name of symbol @var{s} as a string.  By default, Guile reads
-symbols case-sensitively, so the string returned will have the same case
-variation as the sequence of characters that caused @var{s} to be
-created.
address@hidden {Scheme Procedure} struct-ref struct n
address@hidden {C Function} scm_struct_ref (struct, n)
+Return the contents of field number @var{n} in @var{struct}.  The
+first field is number 0.
 
-If Guile is set to read symbols case-insensitively (as specified by
-R5RS), and @var{s} comes into being as part of a literal expression
-(@pxref{Literal expressions,,,r5rs, The Revised^5 Report on Scheme}) or
-by a call to the @code{read} or @code{string-ci->symbol} procedures,
-Guile converts any alphabetic characters in the symbol's name to
-lower case before creating the symbol object, so the string returned
-here will be in lower case.
+An error is thrown if @var{n} is out of range, or if the field cannot
+be read because it's @code{o} opaque.
address@hidden deffn
 
-If @var{s} was created by @code{string->symbol}, the case of characters
-in the string returned will be the same as that in the string that was
-passed to @code{string->symbol}, regardless of Guile's case-sensitivity
-setting at the time @var{s} was created.
address@hidden {Scheme Procedure} struct-set! struct n value
address@hidden {C Function} scm_struct_set_x (struct, n, value)
+Set field number @var{n} in @var{struct} to @var{value}.  The first
+field is number 0.
 
-It is an error to apply mutation procedures like @code{string-set!} to
-strings returned by this procedure.
+An error is thrown if @var{n} is out of range, or if the field cannot
+be written because it's @code{r} read-only or @code{o} opaque.  
 @end deffn
 
-Most symbols are created by writing them literally in code.  However it
-is also possible to create symbols programmatically using the following
-procedures:
-
address@hidden {Scheme Procedure} symbol address@hidden
address@hidden symbol
-Return a newly allocated symbol made from the given character arguments.
address@hidden {Scheme Procedure} struct-vtable struct
address@hidden {C Function} scm_struct_vtable (struct)
+Return the vtable that describes @var{struct}.
 
address@hidden
-(symbol #\x #\y #\z) @result{} xyz
address@hidden example
+The vtable is effectively the type of the structure.  See @ref{Vtable
+Contents}, for more on vtables.
 @end deffn
 
address@hidden {Scheme Procedure} list->symbol lst
address@hidden list->symbol
-Return a newly allocated symbol made from a list of characters.
+
address@hidden Vtable Contents
address@hidden Vtable Contents
+
+A vtable is itself a structure.  It has a specific set of fields
+describing various aspects of its @dfn{instances}: the structures
+created from a vtable.  Some of the fields are internal to Guile, some
+of them are part of the public interface, and there may be additional
+fields added on by the user.
+
+Every vtable has a field for the layout of their instances, a field for
+the procedure used to print its instances, and a field for the name of
+the vtable itself.  Access to the layout and printer is exposed directly
+via field indexes.  Access to the vtable name is exposed via accessor
+procedures.
+
address@hidden {Scheme Variable} vtable-index-layout
address@hidden {C Macro} scm_vtable_index_layout
+The field number of the layout specification in a vtable.  The layout
+specification is a symbol like @code{pwpw} formed from the fields
+string passed to @code{make-vtable}, or created by
address@hidden (@pxref{Meta-Vtables}).
 
 @example
-(list->symbol '(#\a #\b #\c)) @result{} abc
+(define v (make-vtable "pwpw" 0))
+(struct-ref v vtable-index-layout) @result{} pwpw
 @end example
address@hidden deffn
 
address@hidden symbol-append
address@hidden {Scheme Procedure} symbol-append arg @dots{}
-Return a newly allocated symbol whose characters form the
-concatenation of the given symbols, @var{arg} @enddots{}.
+This field is read-only, since the layout of structures using a vtable
+cannot be changed.
address@hidden defvr
+
address@hidden {Scheme Variable} vtable-index-printer
address@hidden {C Macro} scm_vtable_index_printer
+The field number of the printer function.  This field contains @code{#f}
+if the default print function should be used.
 
 @example
-(let ((h 'hello))
-  (symbol-append h 'world))
address@hidden helloworld
+(define (my-print-func struct port)
+  ...)
+(define v (make-vtable "pwpw" my-print-func))
+(struct-ref v vtable-index-printer) @result{} my-print-func
 @end example
address@hidden deffn
 
address@hidden string->symbol
address@hidden {Scheme Procedure} string->symbol string
address@hidden {C Function} scm_string_to_symbol (string)
-Return the symbol whose name is @var{string}.  This procedure can create
-symbols with names containing special characters or letters in the
-non-standard case, but it is usually a bad idea to create such symbols
-because in some implementations of Scheme they cannot be read as
-themselves.
address@hidden deffn
+This field is writable, allowing the print function to be changed
+dynamically.
address@hidden defvr
 
address@hidden {Scheme Procedure} string-ci->symbol str
address@hidden {C Function} scm_string_ci_to_symbol (str)
-Return the symbol whose name is @var{str}.  If Guile is currently
-reading symbols case-insensitively, @var{str} is converted to lowercase
-before the returned symbol is looked up or created.
address@hidden deffn
address@hidden {Scheme Procedure} struct-vtable-name vtable
address@hidden {Scheme Procedure} set-struct-vtable-name! vtable name
address@hidden {C Function} scm_struct_vtable_name (vtable)
address@hidden {C Function} scm_set_struct_vtable_name_x (vtable, name)
+Get or set the name of @var{vtable}.  @var{name} is a symbol and is
+used in the default print function when printing structures created
+from @var{vtable}.
 
-The following examples illustrate Guile's detailed behaviour as regards
-the case-sensitivity of symbols:
address@hidden
+(define v (make-vtable "pw"))
+(set-struct-vtable-name! v 'my-name)
 
address@hidden
-(read-enable 'case-insensitive)   ; R5RS compliant behaviour
+(define s (make-struct v 0))
+(display s) @print{} #<my-name b7ab3ae0:b7ab3730>
address@hidden example
address@hidden deffn
 
-(symbol->string 'flying-fish)    @result{} "flying-fish"
-(symbol->string 'Martin)         @result{} "martin"
-(symbol->string
-   (string->symbol "Malvina"))   @result{} "Malvina"
 
-(eq? 'mISSISSIppi 'mississippi)  @result{} #t
-(string->symbol "mISSISSIppi")   @result{} mISSISSIppi
-(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #f
-(eq? 'LolliPop
-  (string->symbol (symbol->string 'LolliPop))) @result{} #t
-(string=? "K. Harper, M.D."
-  (symbol->string
-    (string->symbol "K. Harper, M.D."))) @result{} #t
address@hidden Meta-Vtables
address@hidden Meta-Vtables
 
-(read-disable 'case-insensitive)   ; Guile default behaviour
+As a structure, a vtable also has a vtable, which is also a structure.
+Structures, their vtables, the vtables of the vtables, and so on form a
+tree of structures.  Making a new structure adds a leaf to the tree, and
+if that structure is a vtable, it may be used to create other leaves.
 
-(symbol->string 'flying-fish)    @result{} "flying-fish"
-(symbol->string 'Martin)         @result{} "Martin"
-(symbol->string
-   (string->symbol "Malvina"))   @result{} "Malvina"
+If you traverse up the tree of vtables, via calling
address@hidden, eventually you reach a root which is the vtable of
+itself:
 
-(eq? 'mISSISSIppi 'mississippi)  @result{} #f
-(string->symbol "mISSISSIppi")   @result{} mISSISSIppi
-(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #t
-(eq? 'LolliPop
-  (string->symbol (symbol->string 'LolliPop))) @result{} #t
-(string=? "K. Harper, M.D."
-  (symbol->string
-    (string->symbol "K. Harper, M.D."))) @result{} #t
address@hidden lisp
address@hidden
+scheme@@(guile-user)> (current-module)
+$1 = #<directory (guile-user) 221b090>
+scheme@@(guile-user)> (struct-vtable $1)
+$2 = #<record-type module>
+scheme@@(guile-user)> (struct-vtable $2)
+$3 = #<<standard-vtable> 12c30a0>
+scheme@@(guile-user)> (struct-vtable $3)
+$4 = #<<standard-vtable> 12c3fa0>
+scheme@@(guile-user)> (struct-vtable $4)
+$5 = #<<standard-vtable> 12c3fa0>
+scheme@@(guile-user)> <standard-vtable>
+$6 = #<<standard-vtable> 12c3fa0>
address@hidden example
 
-From C, there are lower level functions that construct a Scheme symbol
-from a C string in the current locale encoding.
+In this example, we can say that @code{$1} is an instance of @code{$2},
address@hidden is an instance of @code{$3}, @code{$3} is an instance of
address@hidden, and @code{$4}, strangely enough, is an instance of itself.
+The value bound to @code{$4} in this console session also bound to
address@hidden<standard-vtable>} in the default environment.
 
-When you want to do more from C, you should convert between symbols
-and strings using @code{scm_symbol_to_string} and
address@hidden and work with the strings.
address@hidden {Scheme Variable} <standard-vtable>
+A meta-vtable, useful for making new vtables.
address@hidden defvr
 
address@hidden {C Function} SCM scm_from_latin1_symbol (const char *name)
address@hidden {C Function} SCM scm_from_utf8_symbol (const char *name)
-Construct and return a Scheme symbol whose name is specified by the
-null-terminated C string @var{name}.  These are appropriate when
-the C string is hard-coded in the source code.
address@hidden deftypefn
+All of these values are structures.  All but @code{$1} are vtables.  As
address@hidden is an instance of @code{$3}, and @code{$3} is a vtable, we can
+say that @code{$3} is a @dfn{meta-vtable}: a vtable that can create
+vtables.
 
address@hidden {C Function} SCM scm_from_locale_symbol (const char *name)
address@hidden {C Function} SCM scm_from_locale_symboln (const char *name, 
size_t len)
-Construct and return a Scheme symbol whose name is specified by
address@hidden  For @code{scm_from_locale_symbol}, @var{name} must be null
-terminated; for @code{scm_from_locale_symboln} the length of @var{name} is
-specified explicitly by @var{len}.
+With this definition, we can specify more precisely what a vtable is: a
+vtable is a structure made from a meta-vtable.  Making a structure from
+a meta-vtable runs some special checks to ensure that the first field of
+the structure is a valid layout.  Additionally, if these checks see that
+the layout of the child vtable contains all the required fields of a
+vtable, in the correct order, then the child vtable will also be a
+meta-table, inheriting a magical bit from the parent.
 
-Note that these functions should @emph{not} be used when @var{name} is a
-C string constant, because there is no guarantee that the current locale
-will match that of the execution character set, used for string and
-character constants.  Most modern C compilers use UTF-8 by default, so
-in such cases we recommend @code{scm_from_utf8_symbol}.
address@hidden deftypefn
address@hidden {Scheme Procedure} struct-vtable? obj
address@hidden {C Function} scm_struct_vtable_p (obj)
+Return @code{#t} if @var{obj} is a vtable structure: an instance of a
+meta-vtable.
address@hidden deffn
 
address@hidden  {C Function} SCM scm_take_locale_symbol (char *str)
address@hidden {C Function} SCM scm_take_locale_symboln (char *str, size_t len)
-Like @code{scm_from_locale_symbol} and @code{scm_from_locale_symboln},
-respectively, but also frees @var{str} with @code{free} eventually.
-Thus, you can use this function when you would free @var{str} anyway
-immediately after creating the Scheme string.  In certain cases, Guile
-can then use @var{str} directly as its internal representation.
address@hidden deftypefn
address@hidden<standard-vtable>} is a root of the vtable tree.  (Normally there
+is only one root in a given Guile process, but due to some legacy
+interfaces there may be more than one.)
 
-The size of a symbol can also be obtained from C:
+The set of required fields of a vtable is the set of fields in the
address@hidden<standard-vtable>}, and is bound to @code{standard-vtable-fields}
+in the default environment.  It is possible to create a meta-vtable that
+with additional fields in its layout, which can be used to create
+vtables with additional data:
 
address@hidden {C Function} size_t scm_c_symbol_length (SCM sym)
-Return the number of characters in @var{sym}.
address@hidden deftypefn
address@hidden
+scheme@@(guile-user)> (struct-ref $3 vtable-index-layout)
+$6 = pruhsruhpwphuhuhprprpw
+scheme@@(guile-user)> (struct-ref $4 vtable-index-layout)
+$7 = pruhsruhpwphuhuh
+scheme@@(guile-user)> standard-vtable-fields 
+$8 = "pruhsruhpwphuhuh"
+scheme@@(guile-user)> (struct-ref $2 vtable-offset-user)
+$9 = module
address@hidden example
 
-Finally, some applications, especially those that generate new Scheme
-code dynamically, need to generate symbols for use in the generated
-code.  The @code{gensym} primitive meets this need:
+In this continuation of our earlier example, @code{$2} is a vtable that
+has extra fields, because its vtable, @code{$3}, was made from a
+meta-vtable with an extended layout.  @code{vtable-offset-user} is a
+convenient definition that indicates the number of fields in
address@hidden
 
address@hidden {Scheme Procedure} gensym [prefix]
address@hidden {C Function} scm_gensym (prefix)
-Create a new symbol with a name constructed from a prefix and a counter
-value.  The string @var{prefix} can be specified as an optional
-argument.  Default prefix is @address@hidden g}}.  The counter is increased by 
1
-at each call.  There is no provision for resetting the counter.
address@hidden deffn
address@hidden {Scheme Variable} standard-vtable-fields
+A string containing the ordered set of fields that a vtable must have.
address@hidden defvr
 
-The symbols generated by @code{gensym} are @emph{likely} to be unique,
-since their names begin with a space and it is only otherwise possible
-to generate such symbols if a programmer goes out of their way to do
-so.  Uniqueness can be guaranteed by instead using uninterned symbols
-(@pxref{Symbol Uninterned}), though they can't be usefully written out
-and read back in.
address@hidden {Scheme Variable} vtable-offset-user
+The first index in a vtable that is available for a user.
address@hidden defvr
 
address@hidden {Scheme Procedure} make-struct-layout fields
address@hidden {C Function} scm_make_struct_layout (fields)
+Return a structure layout symbol, from a @var{fields} string.
address@hidden is as described under @code{make-vtable}
+(@pxref{Vtables}).  An invalid @var{fields} string is an error.
address@hidden deffn
 
address@hidden Symbol Props
address@hidden Function Slots and Property Lists
+With these definitions, one can define @code{make-vtable} in this way:
 
-In traditional Lisp dialects, symbols are often understood as having
-three kinds of value at once:
address@hidden
+(define* (make-vtable fields #:optional printer)
+  (make-struct/no-tail <standard-vtable>
+    (make-struct-layout fields)
+    printer))
address@hidden example
 
address@hidden @bullet
address@hidden
-a @dfn{variable} value, which is used when the symbol appears in
-code in a variable reference context
 
address@hidden
-a @dfn{function} value, which is used when the symbol appears in
-code in a function name position (i.e.@: as the first element in an
-unquoted list)
address@hidden Vtable Example
address@hidden Vtable Example
 
address@hidden
-a @dfn{property list} value, which is used when the symbol is given as
-the first argument to Lisp's @code{put} or @code{get} functions.
address@hidden itemize
+Let us bring these points together with an example.  Consider a simple
+object system with single inheritance.  Objects will be normal
+structures, and classes will be vtables with three extra class fields:
+the name of the class, the parent class, and the list of fields.
 
-Although Scheme (as one of its simplifications with respect to Lisp)
-does away with the distinction between variable and function namespaces,
-Guile currently retains some elements of the traditional structure in
-case they turn out to be useful when implementing translators for other
-languages, in particular Emacs Lisp.
+So, first we need a meta-vtable that allocates instances with these
+extra class fields.
 
-Specifically, Guile symbols have two extra slots, one for a symbol's
-property list, and one for its ``function value.''  The following procedures
-are provided to access these slots.
address@hidden
+(define <class>
+  (make-vtable
+   (string-append standard-vtable-fields "pwpwpw")
+   (lambda (x port)
+     (format port "<<class> ~a>" (class-name x)))))
+
+(define (class? x)
+  (and (struct? x)
+       (eq? (struct-vtable x) <class>)))
address@hidden example
 
address@hidden {Scheme Procedure} symbol-fref symbol
address@hidden {C Function} scm_symbol_fref (symbol)
-Return the contents of @var{symbol}'s @dfn{function slot}.
address@hidden deffn
+To make a structure with a specific meta-vtable, we will use
address@hidden/no-tail}, passing it the computed instance layout and
+printer, as with @code{make-vtable}, and additionally the extra three
+class fields.
 
address@hidden {Scheme Procedure} symbol-fset! symbol value
address@hidden {C Function} scm_symbol_fset_x (symbol, value)
-Set the contents of @var{symbol}'s function slot to @var{value}.
address@hidden deffn
address@hidden
+(define (make-class name parent fields)
+  (let* ((fields (compute-fields parent fields))
+         (layout (compute-layout fields)))
+    (make-struct/no-tail <class>
+      layout 
+      (lambda (x port)
+        (print-instance x port))
+      name
+      parent
+      fields)))
address@hidden example
 
address@hidden {Scheme Procedure} symbol-pref symbol
address@hidden {C Function} scm_symbol_pref (symbol)
-Return the @dfn{property list} currently associated with @var{symbol}.
address@hidden deffn
+Instances will store their associated data in slots in the structure: as
+many slots as there are fields.  The @code{compute-layout} procedure
+below can compute a layout, and @code{field-index} returns the slot
+corresponding to a field.
 
address@hidden {Scheme Procedure} symbol-pset! symbol value
address@hidden {C Function} scm_symbol_pset_x (symbol, value)
-Set @var{symbol}'s property list to @var{value}.
address@hidden deffn
address@hidden
+(define-syntax-rule (define-accessor name n)
+  (define (name obj)
+    (struct-ref obj n)))
+
+;; Accessors for classes
+(define-accessor class-name (+ vtable-offset-user 0))
+(define-accessor class-parent (+ vtable-offset-user 1))
+(define-accessor class-fields (+ vtable-offset-user 2))
+
+(define (compute-fields parent fields)
+  (if parent
+      (append (class-fields parent) fields)
+      fields))
+
+(define (compute-layout fields)
+  (make-struct-layout
+   (string-concatenate (make-list (length fields) "pw"))))
+
+(define (field-index class field)
+  (list-index (class-fields class) field))
+
+(define (print-instance x port)
+  (format port "<~a" (class-name (struct-vtable x)))
+  (for-each (lambda (field idx)
+              (format port " ~a: ~a" field (struct-ref x idx)))
+            (class-fields (struct-vtable x))
+            (iota (length (class-fields (struct-vtable x)))))
+  (format port ">"))
address@hidden example
 
address@hidden {Scheme Procedure} symbol-property sym prop
-From @var{sym}'s property list, return the value for property
address@hidden  The assumption is that @var{sym}'s property list is an
-association list whose keys are distinguished from each other using
address@hidden; @var{prop} should be one of the keys in that list.  If
-the property list has no entry for @var{prop}, @code{symbol-property}
-returns @code{#f}.
address@hidden deffn
+So, at this point we can actually make a few classes:
 
address@hidden {Scheme Procedure} set-symbol-property! sym prop val
-In @var{sym}'s property list, set the value for property @var{prop} to
address@hidden, or add a new entry for @var{prop}, with value @var{val}, if
-none already exists.  For the structure of the property list, see
address@hidden
address@hidden deffn
address@hidden
+(define-syntax-rule (define-class name parent field ...)
+  (define name (make-class 'name parent '(field ...))))
 
address@hidden {Scheme Procedure} symbol-property-remove! sym prop
-From @var{sym}'s property list, remove the entry for property
address@hidden, if there is one.  For the structure of the property list,
-see @code{symbol-property}.
address@hidden deffn
+(define-class <surface> #f
+  width height)
 
-Support for these extra slots may be removed in a future release, and it
-is probably better to avoid using them.  For a more modern and Schemely
-approach to properties, see @ref{Object Properties}.
+(define-class <window> <surface>
+  x y)
address@hidden example
 
+And finally, make an instance:
 
address@hidden Symbol Read Syntax
address@hidden Extended Read Syntax for Symbols
address@hidden
+(make-struct/no-tail <window> 400 300 10 20)
address@hidden <<window> width: 400 height: 300 x: 10 y: 20>
address@hidden example
 
address@hidden r7rs-symbols
+And that's that.  Note that there are many possible optimizations and
+feature enhancements that can be made to this object system, and the
+included GOOPS system does make most of them.  For more simple use
+cases, the records facility is usually sufficient.  But sometimes you
+need to make new kinds of data abstractions, and for that purpose,
+structs are here.
+
address@hidden Tail Arrays
address@hidden Tail Arrays
+
+Guile's structures have a facility whereby each instance of a vtable can
+contain a variable-length tail array of values.  The length of the tail
+array is stored in the structure.  This facility was originally intended
+to allow C code to expose raw C structures with word-sized tail arrays
+to Scheme.
+
+However, the tail array facility is confusing and doesn't work very
+well.  It is very rarely used, but it insinuates itself into all
+invocations of @code{make-struct}.  For this reason the clumsily-named
address@hidden/no-tail} procedure can actually be more elegant in
+actual use, because it doesn't have a random @code{0} argument stuck in
+the middle.
+
+Tail arrays also inhibit optimization by allowing instances to affect
+their shapes.  In the absence of tail arrays, all instances of a given
+vtable have the same number and kinds of fields.  This uniformity can be
+exploited by the runtime and the optimizer.  The presence of tail arrays
+make some of these optimizations more difficult.
+
+Finally, the tail array facility is ad-hoc and does not compose with the
+rest of Guile.  If a Guile user wants an array with user-specified
+length, it's best to use a vector.  It is more clear in the code, and
+the standard optimization techniques will do a good job with it.
+
+That said, we should mention some details about the interface.  A vtable
+that has tail array has upper-case permission descriptors: @code{W},
address@hidden or @code{O}, correspoding to tail arrays of writable,
+read-only, or opaque elements.  A tail array permission descriptor may
+only appear in the last element of a vtable layout.
+
+For exampple, @samp{pW} indicates a tail of writable Scheme-valued
+fields.  The @samp{pW} field itself holds the tail size, and the tail
+fields come after it.
 
-The read syntax for a symbol is a sequence of letters, digits, and
address@hidden alphabetic characters}, beginning with a character that
-cannot begin a number.  In addition, the special cases of @code{+},
address@hidden, and @code{...} are read as symbols even though numbers can
-begin with @code{+}, @code{-} or @code{.}.
address@hidden
+(define v (make-vtable "prpW")) ;; one fixed then a tail array
+(define s (make-struct v 6 "fixed field" 'x 'y))
+(struct-ref s 0) @result{} "fixed field"
+(struct-ref s 1) @result{} 2    ;; tail size
+(struct-ref s 2) @result{} x    ;; tail array ...
+(struct-ref s 3) @result{} y
+(struct-ref s 4) @result{} #f
address@hidden example
 
-Extended alphabetic characters may be used within identifiers as if
-they were letters.  The set of extended alphabetic characters is:
+
address@hidden Dictionary Types
address@hidden Dictionary Types
+
+A @dfn{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.@: @code{(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 @dfn{association list} (or @dfn{alist} for short) is a list of
+key-value pairs.  Each pair represents a single quantity or
+object; the @code{car} of the pair is a key which is used to
+identify the object, and the @code{cdr} is the object's value.
+
+A @dfn{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, @dfn{car}, @dfn{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.
+
address@hidden Association Lists
address@hidden Association Lists
address@hidden Association Lists
address@hidden Alist
address@hidden association List
address@hidden alist
address@hidden database
+
+An association list is a conventional data structure that is often used
+to implement simple key-value databases.  It consists of a list of
+entries in which each entry is a pair.  The @dfn{key} of each entry is
+the @code{car} of the pair and the @dfn{value} of each entry is the
address@hidden
 
 @example
-! $ % & * + - . / : < = > ? @@ ^ _ ~
+ASSOCIATION LIST ::=  '( (KEY1 . VALUE1)
+                         (KEY2 . VALUE2)
+                         (KEY3 . VALUE3)
+                         @dots{}
+                       )
 @end example
 
-In addition to the standard read syntax defined above (which is taken
-from R5RS (@pxref{Formal syntax,,,r5rs,The Revised^5 Report on
-Scheme})), Guile provides an extended symbol read syntax that allows the
-inclusion of unusual characters such as space characters, newlines and
-parentheses.  If (for whatever reason) you need to write a symbol
-containing characters not mentioned above, you can do so as follows.
address@hidden
+Association lists are also known, for short, as @dfn{alists}.
+
+The structure of an association list is just one example of the infinite
+number of possible structures that can be built using pairs and lists.
+As such, the keys and values in an association list can be manipulated
+using the general list structure procedures @code{cons}, @code{car},
address@hidden, @code{set-car!}, @code{set-cdr!} and so on.  However,
+because association lists are so useful, Guile also provides specific
+procedures for manipulating them.
+
address@hidden
+* Alist Key Equality::
+* Adding or Setting Alist Entries::
+* Retrieving Alist Entries::
+* Removing Alist Entries::
+* Sloppy Alist Functions::
+* Alist Example::
address@hidden menu
+
address@hidden Alist Key Equality
address@hidden Alist Key Equality
+
+All of Guile's dedicated association list procedures, apart from
address@hidden, come in three flavours, depending on the level of equality
+that is required to decide whether an existing key in the association
+list is the same as the key that the procedure call uses to identify the
+required entry.
 
 @itemize @bullet
 @item
-Begin the symbol with the characters @address@hidden,
+Procedures with @dfn{assq} in their name use @code{eq?} to determine key
+equality.
 
 @item
-write the characters of the symbol and
+Procedures with @dfn{assv} in their name use @code{eqv?} to determine
+key equality.
 
 @item
-finish the symbol with the characters @address@hidden
+Procedures with @dfn{assoc} in their name use @code{equal?} to
+determine key equality.
 @end itemize
 
-Here are a few examples of this form of read syntax.  The first symbol
-needs to use extended syntax because it contains a space character, the
-second because it contains a line break, and the last because it looks
-like a number.
address@hidden is an exception because it is used to build association
+lists which do not require their entries' keys to be unique.
 
address@hidden
address@hidden address@hidden
address@hidden Adding or Setting Alist Entries
address@hidden Adding or Setting Alist Entries
 
address@hidden
address@hidden
address@hidden adds a new entry to an association list and returns the
+combined association list.  The combined alist is formed by consing the
+new entry onto the head of the alist specified in the @code{acons}
+procedure call.  So the specified alist is not modified, but its
+contents become shared with the tail of the combined alist that
address@hidden returns.
 
address@hidden@}#
address@hidden lisp
+In the most common usage of @code{acons}, a variable holding the
+original association list is updated with the combined alist:
 
-Although Guile provides this extended read syntax for symbols,
-widespread usage of it is discouraged because it is not portable and not
-very readable.
address@hidden
+(set! address-list (acons name address address-list))
address@hidden example
 
-Alternatively, if you enable the @code{r7rs-symbols} read option (see
address@hidden Read}), you can write arbitrary symbols using the same
-notation used for strings, except delimited by vertical bars instead of
-double quotes.
+In such cases, it doesn't matter that the old and new values of
address@hidden share some of their contents, since the old value is
+usually no longer independently accessible.
+
+Note that @code{acons} adds the specified new entry regardless of
+whether the alist may already contain entries with keys that are, in
+some sense, the same as that of the new entry.  Thus @code{acons} is
+ideal for building alists where there is no concept of key uniqueness.
 
 @example
-|foo bar|
-|\x3BB; is a greek lambda|
-|\| is a vertical bar|
+(set! task-list (acons 3 "pay gas bill" '()))
+task-list
address@hidden
+((3 . "pay gas bill"))
+
+(set! task-list (acons 3 "tidy bedroom" task-list))
+task-list
address@hidden
+((3 . "tidy bedroom") (3 . "pay gas bill"))
 @end example
 
-Note that there's also an @code{r7rs-symbols} print option
-(@pxref{Scheme Write}).  To enable the use of this notation, evaluate
-one or both of the following expressions:
address@hidden, @code{assv-set!} and @code{assoc-set!} are used to add
+or replace an entry in an association list where there @emph{is} a
+concept of key uniqueness.  If the specified association list already
+contains an entry whose key is the same as that specified in the
+procedure call, the existing entry is replaced by the new one.
+Otherwise, the new entry is consed onto the head of the old association
+list to create the combined alist.  In all cases, these procedures
+return the combined alist.
+
address@hidden and friends @emph{may} destructively modify the
+structure of the old association list in such a way that an existing
+variable is correctly updated without having to @code{set!} it to the
+value returned:
 
 @example
-(read-enable  'r7rs-symbols)
-(print-enable 'r7rs-symbols)
+address-list
address@hidden
+(("mary" . "34 Elm Road") ("james" . "16 Bow Street"))
+
+(assoc-set! address-list "james" "1a London Road")
address@hidden
+(("mary" . "34 Elm Road") ("james" . "1a London Road"))
+
+address-list
address@hidden
+(("mary" . "34 Elm Road") ("james" . "1a London Road"))
 @end example
 
+Or they may not:
 
address@hidden Symbol Uninterned
address@hidden Uninterned Symbols
address@hidden
+(assoc-set! address-list "bob" "11 Newington Avenue")
address@hidden
+(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
+ ("james" . "1a London Road"))
 
-What makes symbols useful is that they are automatically kept unique.
-There are no two symbols that are distinct objects but have the same
-name.  But of course, there is no rule without exception.  In addition
-to the normal symbols that have been discussed up to now, you can also
-create special @dfn{uninterned} symbols that behave slightly
-differently.
+address-list
address@hidden
+(("mary" . "34 Elm Road") ("james" . "1a London Road"))
address@hidden example
 
-To understand what is different about them and why they might be useful,
-we look at how normal symbols are actually kept unique.
+The only safe way to update an association list variable when adding or
+replacing an entry like this is to @code{set!} the variable to the
+returned value:
 
-Whenever Guile wants to find the symbol with a specific name, for
-example during @code{read} or when executing @code{string->symbol}, it
-first looks into a table of all existing symbols to find out whether a
-symbol with the given name already exists.  When this is the case, Guile
-just returns that symbol.  When not, a new symbol with the name is
-created and entered into the table so that it can be found later.
address@hidden
+(set! address-list
+      (assoc-set! address-list "bob" "11 Newington Avenue"))
+address-list
address@hidden
+(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
+ ("james" . "1a London Road"))
address@hidden example
 
-Sometimes you might want to create a symbol that is guaranteed `fresh',
-i.e.@: a symbol that did not exist previously.  You might also want to
-somehow guarantee that no one else will ever unintentionally stumble
-across your symbol in the future.  These properties of a symbol are
-often needed when generating code during macro expansion.  When
-introducing new temporary variables, you want to guarantee that they
-don't conflict with variables in other people's code.
+Because of this slight inconvenience, 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.
+
+If you need to keep the old value of an association list in a form
+independent from the list that results from modification by
address@hidden, @code{assq-set!}, @code{assv-set!} or @code{assoc-set!},
+use @code{list-copy} to copy the old association list before modifying
+it.
+
address@hidden {Scheme Procedure} acons key value alist
address@hidden {C Function} scm_acons (key, value, alist)
+Add a new key-value pair to @var{alist}.  A new pair is
+created whose car is @var{key} and whose cdr is @var{value}, and the
+pair is consed onto @var{alist}, and the new list is returned.  This
+function is @emph{not} destructive; @var{alist} is not modified.
address@hidden deffn
+
address@hidden {Scheme Procedure} assq-set! alist key val
address@hidden {Scheme Procedure} assv-set! alist key value
address@hidden {Scheme Procedure} assoc-set! alist key value
address@hidden {C Function} scm_assq_set_x (alist, key, val)
address@hidden {C Function} scm_assv_set_x (alist, key, val)
address@hidden {C Function} scm_assoc_set_x (alist, key, val)
+Reassociate @var{key} in @var{alist} with @var{value}: find any existing
address@hidden entry for @var{key} and associate it with the new
address@hidden  If @var{alist} does not contain an entry for @var{key},
+add a new one.  Return the (possibly new) alist.
+
+These functions do not attempt to verify the structure of @var{alist},
+and so may cause unusual results if passed an object that is not an
+association list.
address@hidden deffn
+
address@hidden Retrieving Alist Entries
address@hidden Retrieving Alist Entries
address@hidden assq
address@hidden assv
address@hidden assoc
+
address@hidden, @code{assv} and @code{assoc} find the entry in an alist
+for a given key, and return the @code{(@var{key} . @var{value})} pair.
address@hidden, @code{assv-ref} and @code{assoc-ref} do a similar
+lookup, but return just the @var{value}.
+
address@hidden {Scheme Procedure} assq key alist
address@hidden {Scheme Procedure} assv key alist
address@hidden {Scheme Procedure} assoc key alist
address@hidden {C Function} scm_assq (key, alist)
address@hidden {C Function} scm_assv (key, alist)
address@hidden {C Function} scm_assoc (key, alist)
+Return the first entry in @var{alist} with the given @var{key}.  The
+return is the pair @code{(KEY . VALUE)} from @var{alist}.  If there's
+no matching entry the return is @code{#f}.
+
address@hidden compares keys with @code{eq?}, @code{assv} uses
address@hidden and @code{assoc} uses @code{equal?}.  See also SRFI-1
+which has an extended @code{assoc} (@ref{SRFI-1 Association Lists}).
address@hidden deffn
+
address@hidden {Scheme Procedure} assq-ref alist key
address@hidden {Scheme Procedure} assv-ref alist key
address@hidden {Scheme Procedure} assoc-ref alist key
address@hidden {C Function} scm_assq_ref (alist, key)
address@hidden {C Function} scm_assv_ref (alist, key)
address@hidden {C Function} scm_assoc_ref (alist, key)
+Return the value from the first entry in @var{alist} with the given
address@hidden, or @code{#f} if there's no such entry.
+
address@hidden compares keys with @code{eq?}, @code{assv-ref} uses
address@hidden and @code{assoc-ref} uses @code{equal?}.
+
+Notice these functions have the @var{key} argument last, like other
address@hidden functions, but this is opposite to what @code{assq}
+etc above use.
+
+When the return is @code{#f} it can be either @var{key} not found, or
+an entry which happens to have value @code{#f} in the @code{cdr}.  Use
address@hidden etc above if you need to differentiate these cases.
address@hidden deffn
+
+
address@hidden Removing Alist Entries
address@hidden Removing Alist Entries
+
+To remove the element from an association list whose key matches a
+specified key, use @code{assq-remove!}, @code{assv-remove!} or
address@hidden (depending, as usual, on the level of equality
+required between the key that you specify and the keys in the
+association list).
+
+As with @code{assq-set!} and friends, the specified alist may or may not
+be modified destructively, and the only safe way to update a variable
+containing the alist is to @code{set!} it to the value that
address@hidden and friends return.
 
-The simplest way to arrange for this is to create a new symbol but
-not enter it into the global table of all symbols.  That way, no one
-will ever get access to your symbol by chance.  Symbols that are not in
-the table are called @dfn{uninterned}.  Of course, symbols that
address@hidden in the table are called @dfn{interned}.
address@hidden
+address-list
address@hidden
+(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
+ ("james" . "1a London Road"))
 
-You create new uninterned symbols with the function @code{make-symbol}.
-You can test whether a symbol is interned or not with
address@hidden
+(set! address-list (assoc-remove! address-list "mary"))
+address-list
address@hidden
+(("bob" . "11 Newington Avenue") ("james" . "1a London Road"))
address@hidden example
 
-Uninterned symbols break the rule that the name of a symbol uniquely
-identifies the symbol object.  Because of this, they can not be written
-out and read back in like interned symbols.  Currently, Guile has no
-support for reading uninterned symbols.  Note that the function
address@hidden does not return uninterned symbols for this reason.
+Note that, when @code{assq/v/oc-remove!} is used to modify an
+association list that has been constructed only using the corresponding
address@hidden/v/oc-set!}, there can be at most one matching entry in the
+alist, so the question of multiple entries being removed in one go does
+not arise.  If @code{assq/v/oc-remove!} is applied to an association
+list that has been constructed using @code{acons}, or an
address@hidden/v/oc-set!} with a different level of equality, or any mixture
+of these, it removes only the first matching entry from the alist, even
+if the alist might contain further matching entries.  For example:
 
address@hidden {Scheme Procedure} make-symbol name
address@hidden {C Function} scm_make_symbol (name)
-Return a new uninterned symbol with the name @var{name}.  The returned
-symbol is guaranteed to be unique and future calls to
address@hidden>symbol} will not return it.
address@hidden
+(define address-list '())
+(set! address-list (assq-set! address-list "mary" "11 Elm Street"))
+(set! address-list (assq-set! address-list "mary" "57 Pine Drive"))
+address-list
address@hidden
+(("mary" . "57 Pine Drive") ("mary" . "11 Elm Street"))
+
+(set! address-list (assoc-remove! address-list "mary"))
+address-list
address@hidden
+(("mary" . "11 Elm Street"))
address@hidden example
+
+In this example, the two instances of the string "mary" are not the same
+when compared using @code{eq?}, so the two @code{assq-set!} calls add
+two distinct entries to @code{address-list}.  When compared using
address@hidden, both "mary"s in @code{address-list} are the same as the
+"mary" in the @code{assoc-remove!} call, but @code{assoc-remove!} stops
+after removing the first matching entry that it finds, and so one of the
+"mary" entries is left in place.
+
address@hidden {Scheme Procedure} assq-remove! alist key
address@hidden {Scheme Procedure} assv-remove! alist key
address@hidden {Scheme Procedure} assoc-remove! alist key
address@hidden {C Function} scm_assq_remove_x (alist, key)
address@hidden {C Function} scm_assv_remove_x (alist, key)
address@hidden {C Function} scm_assoc_remove_x (alist, key)
+Delete the first entry in @var{alist} associated with @var{key}, and return
+the resulting alist.
address@hidden deffn
+
address@hidden Sloppy Alist Functions
address@hidden Sloppy Alist Functions
+
address@hidden, @code{sloppy-assv} and @code{sloppy-assoc} behave
+like the corresponding address@hidden procedures, except that they
+return @code{#f} when the specified association list is not well-formed,
+where the address@hidden versions would signal an error.
+
+Specifically, there are two conditions for which the address@hidden
+procedures signal an error, which the @code{sloppy-} procedures handle
+instead by returning @code{#f}.  Firstly, if the specified alist as a
+whole is not a proper list:
+
address@hidden
+(assoc "mary" '((1 . 2) ("key" . "door") . "open sesame"))
address@hidden
+ERROR: In procedure assoc in expression (assoc "mary" (quote #)):
+ERROR: Wrong type argument in position 2 (expecting
+   association list): ((1 . 2) ("key" . "door") . "open sesame")
+
+(sloppy-assoc "mary" '((1 . 2) ("key" . "door") . "open sesame"))
address@hidden
+#f
address@hidden example
+
address@hidden
+Secondly, if one of the entries in the specified alist is not a pair:
+
address@hidden
+(assoc 2 '((1 . 1) 2 (3 . 9)))
address@hidden
+ERROR: In procedure assoc in expression (assoc 2 (quote #)):
+ERROR: Wrong type argument in position 2 (expecting
+   association list): ((1 . 1) 2 (3 . 9))
+
+(sloppy-assoc 2 '((1 . 1) 2 (3 . 9)))
address@hidden
+#f
address@hidden example
+
+Unless you are explicitly working with badly formed association lists,
+it is much safer to use the address@hidden procedures, because they
+help to highlight coding and data errors that the @code{sloppy-}
+versions would silently cover up.
+
address@hidden {Scheme Procedure} sloppy-assq key alist
address@hidden {C Function} scm_sloppy_assq (key, alist)
+Behaves like @code{assq} but does not do any error checking.
+Recommended only for use in Guile internals.
 @end deffn
 
address@hidden {Scheme Procedure} symbol-interned? symbol
address@hidden {C Function} scm_symbol_interned_p (symbol)
-Return @code{#t} if @var{symbol} is interned, otherwise return
address@hidden
address@hidden {Scheme Procedure} sloppy-assv key alist
address@hidden {C Function} scm_sloppy_assv (key, alist)
+Behaves like @code{assv} but does not do any error checking.
+Recommended only for use in Guile internals.
 @end deffn
 
-For example:
address@hidden {Scheme Procedure} sloppy-assoc key alist
address@hidden {C Function} scm_sloppy_assoc (key, alist)
+Behaves like @code{assoc} but does not do any error checking.
+Recommended only for use in Guile internals.
address@hidden deffn
 
address@hidden
-(define foo-1 (string->symbol "foo"))
-(define foo-2 (string->symbol "foo"))
-(define foo-3 (make-symbol "foo"))
-(define foo-4 (make-symbol "foo"))
address@hidden Alist Example
address@hidden Alist Example
 
-(eq? foo-1 foo-2)
address@hidden #t
-; Two interned symbols with the same name are the same object,
+Here is a longer example of how alists may be used in practice.
 
-(eq? foo-1 foo-3)
address@hidden #f
-; but a call to make-symbol with the same name returns a
-; distinct object.
address@hidden
+(define capitals '(("New York" . "Albany")
+                   ("Oregon"   . "Salem")
+                   ("Florida"  . "Miami")))
+
+;; What's the capital of Oregon?
+(assoc "Oregon" capitals)       @result{} ("Oregon" . "Salem")
+(assoc-ref capitals "Oregon")   @result{} "Salem"
+
+;; We left out South Dakota.
+(set! capitals
+      (assoc-set! capitals "South Dakota" "Pierre"))
+capitals
address@hidden (("South Dakota" . "Pierre")
+    ("New York" . "Albany")
+    ("Oregon" . "Salem")
+    ("Florida" . "Miami"))
+
+;; And we got Florida wrong.
+(set! capitals
+      (assoc-set! capitals "Florida" "Tallahassee"))
+capitals
address@hidden (("South Dakota" . "Pierre")
+    ("New York" . "Albany")
+    ("Oregon" . "Salem")
+    ("Florida" . "Tallahassee"))
+
+;; After Oregon secedes, we can remove it.
+(set! capitals
+      (assoc-remove! capitals "Oregon"))
+capitals
address@hidden (("South Dakota" . "Pierre")
+    ("New York" . "Albany")
+    ("Florida" . "Tallahassee"))
address@hidden lisp
 
-(eq? foo-3 foo-4)
address@hidden #f
-; A call to make-symbol always returns a new object, even for
-; the same name.
address@hidden VHashes
address@hidden VList-Based Hash Lists or ``VHashes''
 
-foo-3
address@hidden #<uninterned-symbol foo 8085290>
-; Uninterned symbols print differently from interned symbols,
address@hidden VList-based hash lists
address@hidden VHash
 
-(symbol? foo-3)
address@hidden #t
-; but they are still symbols,
+The @code{(ice-9 vlist)} module provides an implementation of @dfn{VList-based
+hash lists} (@pxref{VLists}).  VList-based hash lists, or @dfn{vhashes}, are an
+immutable dictionary type similar to association lists that maps @dfn{keys} to
address@hidden  However, unlike association lists, accessing a value given its
+key is typically a constant-time operation.
 
-(symbol-interned? foo-3)
address@hidden #f
-; just not interned.
address@hidden lisp
+The VHash programming interface of @code{(ice-9 vlist)} is mostly the same as
+that of association lists found in SRFI-1, with procedure names prefixed by
address@hidden instead of @code{alist-} (@pxref{SRFI-1 Association Lists}).
 
+In addition, vhashes can be manipulated using VList operations:
 
address@hidden Keywords
address@hidden Keywords
address@hidden Keywords
address@hidden
+(vlist-head (vhash-consq 'a 1 vlist-null))
address@hidden (a . 1)
 
-Keywords are self-evaluating objects with a convenient read syntax that
-makes them easy to type.
+(define vh1 (vhash-consq 'b 2 (vhash-consq 'a 1 vlist-null)))
+(define vh2 (vhash-consq 'c 3 (vlist-tail vh1)))
 
-Guile's keyword support conforms to R5RS, and adds a (switchable) read
-syntax extension to permit keywords to begin with @code{:} as well as
address@hidden:}, or to end with @code{:}.
+(vhash-assq 'a vh2)
address@hidden (a . 1)
+(vhash-assq 'b vh2)
address@hidden #f
+(vhash-assq 'c vh2)
address@hidden (c . 3)
+(vlist->list vh2)
address@hidden ((c . 3) (a . 1))
address@hidden example
 
address@hidden
-* Why Use Keywords?::           Motivation for keyword usage.
-* Coding With Keywords::        How to use keywords.
-* Keyword Read Syntax::         Read syntax for keywords.
-* Keyword Procedures::          Procedures for dealing with keywords.
address@hidden menu
+However, keep in mind that procedures that construct new VLists
+(@code{vlist-map}, @code{vlist-filter}, etc.) return raw VLists, not vhashes:
 
address@hidden Why Use Keywords?
address@hidden Why Use Keywords?
address@hidden
+(define vh (alist->vhash '((a . 1) (b . 2) (c . 3)) hashq))
+(vhash-assq 'a vh)
address@hidden (a . 1)
+
+(define vl
+  ;; This will create a raw vlist.
+  (vlist-filter (lambda (key+value) (odd? (cdr key+value))) vh))
+(vhash-assq 'a vl)
address@hidden ERROR: Wrong type argument in position 2
+
+(vlist->list vl)
address@hidden ((a . 1) (c . 3))
address@hidden example
 
-Keywords are useful in contexts where a program or procedure wants to be
-able to accept a large number of optional arguments without making its
-interface unmanageable.
address@hidden {Scheme Procedure} vhash? obj
+Return true if @var{obj} is a vhash.
address@hidden deffn
 
-To illustrate this, consider a hypothetical @code{make-window}
-procedure, which creates a new window on the screen for drawing into
-using some graphical toolkit.  There are many parameters that the caller
-might like to specify, but which could also be sensibly defaulted, for
-example:
address@hidden {Scheme Procedure} vhash-cons key value vhash [hash-proc]
address@hidden {Scheme Procedure} vhash-consq key value vhash
address@hidden {Scheme Procedure} vhash-consv key value vhash
+Return a new hash list based on @var{vhash} where @var{key} is associated with
address@hidden, using @var{hash-proc} to compute the hash of @var{key}.
address@hidden must be either @code{vlist-null} or a vhash returned by a 
previous
+call to @code{vhash-cons}.  @var{hash-proc} defaults to @code{hash} 
(@pxref{Hash
+Table Reference, @code{hash} procedure}).  With @code{vhash-consq}, the
address@hidden hash function is used; with @code{vhash-consv} the @code{hashv}
+hash function is used.
 
address@hidden @bullet
address@hidden
-color depth -- Default: the color depth for the screen
+All @code{vhash-cons} calls made to construct a vhash should use the same
address@hidden  Failing to do that, the result is undefined.
address@hidden deffn
+
address@hidden {Scheme Procedure} vhash-assoc key vhash [equal? [hash-proc]]
address@hidden {Scheme Procedure} vhash-assq key vhash
address@hidden {Scheme Procedure} vhash-assv key vhash
+Return the first key/value pair from @var{vhash} whose key is equal to 
@var{key}
+according to the @var{equal?} equality predicate (which defaults to
address@hidden), and using @var{hash-proc} (which defaults to @code{hash}) to
+compute the hash of @var{key}.  The second form uses @code{eq?} as the equality
+predicate and @code{hashq} as the hash function; the last form uses @code{eqv?}
+and @code{hashv}.
 
address@hidden
-background color -- Default: white
+Note that it is important to consistently use the same hash function for
address@hidden as was passed to @code{vhash-cons}.  Failing to do that, the
+result is unpredictable.
address@hidden deffn
 
address@hidden
-width -- Default: 600
address@hidden {Scheme Procedure} vhash-delete key vhash [equal? [hash-proc]]
address@hidden {Scheme Procedure} vhash-delq key vhash
address@hidden {Scheme Procedure} vhash-delv key vhash
+Remove all associations from @var{vhash} with @var{key}, comparing keys with
address@hidden (which defaults to @code{equal?}), and computing the hash of
address@hidden using @var{hash-proc} (which defaults to @code{hash}).  The 
second
+form uses @code{eq?} as the equality predicate and @code{hashq} as the hash
+function; the last one uses @code{eqv?} and @code{hashv}.
 
address@hidden
-height -- Default: 400
address@hidden itemize
+Again the choice of @var{hash-proc} must be consistent with previous calls to
address@hidden
address@hidden deffn
 
-If @code{make-window} did not use keywords, the caller would have to
-pass in a value for each possible argument, remembering the correct
-argument order and using a special value to indicate the default value
-for that argument:
address@hidden {Scheme Procedure} vhash-fold proc init vhash
address@hidden {Scheme Procedure} vhash-fold-right proc init vhash
+Fold over the key/value elements of @var{vhash} in the given direction,
+with each call to @var{proc} having the form @code{(@var{proc} key value
+result)}, where @var{result} is the result of the previous call to
address@hidden and @var{init} the value of @var{result} for the first call
+to @var{proc}.
address@hidden deffn
 
address@hidden
-(make-window 'default              ;; Color depth
-             'default              ;; Background color
-             800                   ;; Width
-             100                   ;; Height
-             @dots{})                  ;; More make-window arguments
address@hidden lisp
address@hidden {Scheme Procedure} vhash-fold* proc init key vhash [equal? 
[hash]]
address@hidden {Scheme Procedure} vhash-foldq* proc init key vhash
address@hidden {Scheme Procedure} vhash-foldv* proc init key vhash
+Fold over all the values associated with @var{key} in @var{vhash}, with each
+call to @var{proc} having the form @code{(proc value result)}, where
address@hidden is the result of the previous call to @var{proc} and @var{init} 
the
+value of @var{result} for the first call to @var{proc}.
 
-With keywords, on the other hand, defaulted arguments are omitted, and
-non-default arguments are clearly tagged by the appropriate keyword.  As
-a result, the invocation becomes much clearer:
+Keys in @var{vhash} are hashed using @var{hash} are compared using 
@var{equal?}.
+The second form uses @code{eq?} as the equality predicate and @code{hashq} as
+the hash function; the third one uses @code{eqv?} and @code{hashv}.
 
address@hidden
-(make-window #:width 800 #:height 100)
address@hidden lisp
+Example:
 
-On the other hand, for a simpler procedure with few arguments, the use
-of keywords would be a hindrance rather than a help.  The primitive
-procedure @code{cons}, for example, would not be improved if it had to
-be invoked as
address@hidden
+(define vh
+  (alist->vhash '((a . 1) (a . 2) (z . 0) (a . 3))))
 
address@hidden
-(cons #:car x #:cdr y)
address@hidden lisp
+(vhash-fold* cons '() 'a vh)
address@hidden (3 2 1)
 
-So the decision whether to use keywords or not is purely pragmatic: use
-them if they will clarify the procedure invocation at point of call.
+(vhash-fold* cons '() 'z vh)
address@hidden (0)
address@hidden example
address@hidden deffn
 
address@hidden Coding With Keywords
address@hidden Coding With Keywords
address@hidden {Scheme Procedure} alist->vhash alist [hash-proc]
+Return the vhash corresponding to @var{alist}, an association list, using
address@hidden to compute key hashes.  When omitted, @var{hash-proc} defaults
+to @code{hash}.
address@hidden deffn
 
-If a procedure wants to support keywords, it should take a rest argument
-and then use whatever means is convenient to extract keywords and their
-corresponding arguments from the contents of that rest argument.
 
-The following example illustrates the principle: the code for
address@hidden uses a helper procedure called
address@hidden to extract individual keyword arguments from
-the rest argument.
address@hidden Hash Tables
address@hidden Hash Tables
address@hidden Hash Tables
 
address@hidden
-(define (get-keyword-value args keyword default)
-  (let ((kv (memq keyword args)))
-    (if (and kv (>= (length kv) 2))
-        (cadr kv)
-        default)))
+Hash tables are dictionaries which offer similar functionality as
+association lists: They provide a mapping from keys to values.  The
+difference is that association lists need time linear in the size of
+elements when searching for entries, whereas hash tables can normally
+search in constant time.  The drawback is that hash tables require a
+little bit more memory, and that you can not use the normal list
+procedures (@pxref{Lists}) for working with them.
 
-(define (make-window . args)
-  (let ((depth  (get-keyword-value args #:depth  screen-depth))
-        (bg     (get-keyword-value args #:bg     "white"))
-        (width  (get-keyword-value args #:width  800))
-        (height (get-keyword-value args #:height 100))
-        @dots{})
-    @dots{}))
address@hidden lisp
address@hidden
+* Hash Table Examples::         Demonstration of hash table usage.
+* Hash Table Reference::        Hash table procedure descriptions.
address@hidden menu
 
-But you don't need to write @code{get-keyword-value}.  The @code{(ice-9
-optargs)} module provides a set of powerful macros that you can use to
-implement keyword-supporting procedures like this:
 
address@hidden
-(use-modules (ice-9 optargs))
address@hidden Hash Table Examples
address@hidden Hash Table Examples
 
-(define (make-window . args)
-  (let-keywords args #f ((depth  screen-depth)
-                         (bg     "white")
-                         (width  800)
-                         (height 100))
-    ...))
address@hidden lisp
+For demonstration purposes, this section gives a few usage examples of
+some hash table procedures, together with some explanation what they do.
 
address@hidden
-Or, even more economically, like this:
+First we start by creating a new hash table with 31 slots, and
+populate it with two key/value pairs.
 
 @lisp
-(use-modules (ice-9 optargs))
+(define h (make-hash-table 31))
 
-(define* (make-window #:key (depth  screen-depth)
-                            (bg     "white")
-                            (width  800)
-                            (height 100))
-  ...)
address@hidden lisp
+;; This is an opaque object
+h
address@hidden
+#<hash-table 0/31>
 
-For further details on @code{let-keywords}, @code{define*} and other
-facilities provided by the @code{(ice-9 optargs)} module, see
address@hidden Arguments}.
+;; Inserting into a hash table can be done with hashq-set!
+(hashq-set! h 'foo "bar")
address@hidden
+"bar"
 
-To handle keyword arguments from procedures implemented in C,
-use @code{scm_c_bind_keyword_arguments} (@pxref{Keyword Procedures}).
+(hashq-set! h 'braz "zonk")
address@hidden
+"zonk"
 
address@hidden Keyword Read Syntax
address@hidden Keyword Read Syntax
+;; Or with hash-create-handle!
+(hashq-create-handle! h 'frob #f)
address@hidden
+(frob . #f)
address@hidden lisp
 
-Guile, by default, only recognizes a keyword syntax that is compatible
-with R5RS.  A token of the form @code{#:NAME}, where @code{NAME} has the
-same syntax as a Scheme symbol (@pxref{Symbol Read Syntax}), is the
-external representation of the keyword named @code{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.
+You can get the value for a given key with the procedure
address@hidden, but the problem with this procedure is that you
+cannot reliably determine whether a key does exists in the table.  The
+reason is that the procedure returns @code{#f} if the key is not in
+the table, but it will return the same value if the key is in the
+table and just happens to have the value @code{#f}, as you can see in
+the following examples.
 
-If the @code{keywords} read option is set to @code{'prefix}, Guile also
-recognizes the alternative read syntax @code{:NAME}.  Otherwise, tokens
-of the form @code{:NAME} are read as symbols, as required by R5RS.
address@hidden
+(hashq-ref h 'foo)
address@hidden
+"bar"
 
address@hidden SRFI-88 keyword syntax
+(hashq-ref h 'frob)
address@hidden
+#f
 
-If the @code{keyword} read option is set to @code{'postfix}, Guile
-recognizes the SRFI-88 read syntax @code{NAME:} (@pxref{SRFI-88}).
-Otherwise, tokens of this form are read as symbols.
+(hashq-ref h 'not-there)
address@hidden
+#f
address@hidden lisp
 
-To enable and disable the alternative non-R5RS keyword syntax, you use
-the @code{read-set!} procedure documented @ref{Scheme Read}.  Note that
-the @code{prefix} and @code{postfix} syntax are mutually exclusive.
+It is often better is to use the procedure @code{hashq-get-handle},
+which makes a distinction between the two cases.  Just like @code{assq},
+this procedure returns a key/value-pair on success, and @code{#f} if the
+key is not found.
 
 @lisp
-(read-set! keywords 'prefix)
-
-#:type
+(hashq-get-handle h 'foo)
 @result{}
-#:type
+(foo . "bar")
 
-:type
+(hashq-get-handle h 'not-there)
 @result{}
-#:type
+#f
address@hidden lisp
 
-(read-set! keywords 'postfix)
+Interesting results can be computed by using @code{hash-fold} to work
+through each element.  This example will count the total number of
+elements:
 
-type:
address@hidden
+(hash-fold (lambda (key value seed) (+ 1 seed)) 0 h)
 @result{}
-#:type
+3
address@hidden lisp
 
-:type
+The same thing can be done with the procedure @code{hash-count}, which
+can also count the number of elements matching a particular predicate.
+For example, count the number of elements with string values:
+
address@hidden
+(hash-count (lambda (key value) (string? value)) h)
 @result{}
-:type
+2
address@hidden lisp
 
-(read-set! keywords #f)
+Counting all the elements is a simple task using @code{const}:
 
-#:type
address@hidden
+(hash-count (const #t) h)
 @result{}
-#:type
-
-:type
address@hidden
-ERROR: In expression :type:
-ERROR: Unbound variable: :type
-ABORT: (unbound-variable)
+3
 @end lisp
 
address@hidden Keyword Procedures
address@hidden Keyword Procedures
address@hidden Hash Table Reference
address@hidden Hash Table Reference
 
address@hidden {Scheme Procedure} keyword? obj
address@hidden {C Function} scm_keyword_p (obj)
-Return @code{#t} if the argument @var{obj} is a keyword, else
address@hidden
address@hidden deffn
address@hidden  FIXME: Describe in broad terms what happens for resizing, and 
what
address@hidden  the initial size means for this.
 
address@hidden {Scheme Procedure} keyword->symbol keyword
address@hidden {C Function} scm_keyword_to_symbol (keyword)
-Return the symbol with the same name as @var{keyword}.
address@hidden deffn
+Like the association list functions, the hash table functions come in
+several varieties, according to the equality test used for the keys.
+Plain @code{hash-} functions use @code{equal?}, @code{hashq-}
+functions use @code{eq?}, @code{hashv-} functions use @code{eqv?}, and
+the @code{hashx-} functions use an application supplied test.
 
address@hidden {Scheme Procedure} symbol->keyword symbol
address@hidden {C Function} scm_symbol_to_keyword (symbol)
-Return the keyword with the same name as @var{symbol}.
address@hidden deffn
+A single @code{make-hash-table} creates a hash table suitable for use
+with any set of functions, but it's imperative that just one set is
+then used consistently, or results will be unpredictable.
 
address@hidden {C Function} int scm_is_keyword (SCM obj)
-Equivalent to @code{scm_is_true (scm_keyword_p (@var{obj}))}.
address@hidden deftypefn
+Hash tables are implemented as a vector indexed by a hash value formed
+from the key, with an association list of key/value pairs for each
+bucket in case distinct keys hash together.  Direct access to the
+pairs in those lists is provided by the @code{-handle-} functions.
 
address@hidden {C Function} SCM scm_from_locale_keyword (const char *name)
address@hidden {C Function} SCM scm_from_locale_keywordn (const char *name, 
size_t len)
-Equivalent to @code{scm_symbol_to_keyword (scm_from_locale_symbol
-(@var{name}))} and @code{scm_symbol_to_keyword (scm_from_locale_symboln
-(@var{name}, @var{len}))}, respectively.
+When the number of entries in a hash table goes above a threshold, the
+vector is made larger and the entries are rehashed, to prevent the
+bucket lists from becoming too long and slowing down accesses.  When the
+number of entries goes below a threshold, the vector is shrunk to save
+space.
 
-Note that these functions should @emph{not} be used when @var{name} is a
-C string constant, because there is no guarantee that the current locale
-will match that of the execution character set, used for string and
-character constants.  Most modern C compilers use UTF-8 by default, so
-in such cases we recommend @code{scm_from_utf8_keyword}.
address@hidden deftypefn
+For the @code{hashx-} ``extended'' routines, an application supplies a
address@hidden function producing an integer index like @code{hashq} etc
+below, and an @var{assoc} alist search function like @code{assq} etc
+(@pxref{Retrieving Alist Entries}).  Here's an example of such
+functions implementing case-insensitive hashing of string keys,
 
address@hidden {C Function} SCM scm_from_latin1_keyword (const char *name)
address@hidden {C Function} SCM scm_from_utf8_keyword (const char *name)
-Equivalent to @code{scm_symbol_to_keyword (scm_from_latin1_symbol
-(@var{name}))} and @code{scm_symbol_to_keyword (scm_from_utf8_symbol
-(@var{name}))}, respectively.
address@hidden deftypefn
address@hidden
+(use-modules (srfi srfi-1)
+             (srfi srfi-13))
 
address@hidden {C Function} void scm_c_bind_keyword_arguments (const char 
*subr, @
-                             SCM rest, scm_t_keyword_arguments_flags flags, @
-                             SCM keyword1, SCM *argp1, @
-                             @dots{}, @
-                             SCM keywordN, SCM *argpN, @
-                             @nicode{SCM_UNDEFINED})
+(define (my-hash str size)
+  (remainder (string-hash-ci str) size))
+(define (my-assoc str alist)
+  (find (lambda (pair) (string-ci=? str (car pair))) alist))
 
-Extract the specified keyword arguments from @var{rest}, which is not
-modified.  If the keyword argument @var{keyword1} is present in
address@hidden with an associated value, that value is stored in the
-variable pointed to by @var{argp1}, otherwise the variable is left
-unchanged.  Similarly for the other keywords and argument pointers up to
address@hidden and @var{argpN}.  The argument list to
address@hidden must be terminated by
address@hidden
+(define my-table (make-hash-table))
+(hashx-set! my-hash my-assoc my-table "foo" 123)
 
-Note that since the variables pointed to by @var{argp1} through
address@hidden are left unchanged if the associated keyword argument is not
-present, they should be initialized to their default values before
-calling @code{scm_c_bind_keyword_arguments}.  Alternatively, you can
-initialize them to @code{SCM_UNDEFINED} before the call, and then use
address@hidden after the call to see which ones were provided.
+(hashx-ref my-hash my-assoc my-table "FOO")
address@hidden 123
address@hidden example
 
-If an unrecognized keyword argument is present in @var{rest} and
address@hidden does not contain @code{SCM_ALLOW_OTHER_KEYS}, or if
-non-keyword arguments are present and @var{flags} does not contain
address@hidden, an exception is raised.
address@hidden should be the name of the procedure receiving the keyword
-arguments, for purposes of error reporting.
+In a @code{hashx-} @var{hash} function the aim is to spread keys
+across the vector, so bucket lists don't become long.  But the actual
+values are arbitrary as long as they're in the range 0 to
address@hidden@var{size}-1}.  Helpful functions for forming a hash value, in
+addition to @code{hashq} etc below, include @code{symbol-hash}
+(@pxref{Symbol Keys}), @code{string-hash} and @code{string-hash-ci}
+(@pxref{String Comparison}), and @code{char-set-hash}
+(@pxref{Character Set Predicates/Comparison}).
+
address@hidden 1
address@hidden {Scheme Procedure} make-hash-table [size]
+Create a new hash table object, with an optional minimum
+vector @var{size}.
+
+When @var{size} is given, the table vector will still grow and shrink
+automatically, as described above, but with @var{size} as a minimum.
+If an application knows roughly how many entries the table will hold
+then it can use @var{size} to avoid rehashing when initial entries are
+added.
address@hidden deffn
+
address@hidden {Scheme Procedure} alist->hash-table alist
address@hidden {Scheme Procedure} alist->hashq-table alist
address@hidden {Scheme Procedure} alist->hashv-table alist
address@hidden {Scheme Procedure} alist->hashx-table hash assoc alist
+Convert @var{alist} into a hash table. When keys are repeated in
address@hidden, the leftmost association takes precedence.
 
-For example:
address@hidden
+(use-modules (ice-9 hash-table))
+(alist->hash-table '((foo . 1) (bar . 2)))
address@hidden example
+
+When converting to an extended hash table, custom @var{hash} and
address@hidden procedures must be provided.
 
 @example
-SCM k_delimiter;
-SCM k_grammar;
-SCM sym_infix;
+(alist->hashx-table hash assoc '((foo . 1) (bar . 2)))
address@hidden example
 
-SCM my_string_join (SCM strings, SCM rest)
address@hidden
-  SCM delimiter = SCM_UNDEFINED;
-  SCM grammar   = sym_infix;
address@hidden deffn
 
-  scm_c_bind_keyword_arguments ("my-string-join", rest, 0,
-                                k_delimiter, &delimiter,
-                                k_grammar, &grammar,
-                                SCM_UNDEFINED);
address@hidden {Scheme Procedure} hash-table? obj
address@hidden {C Function} scm_hash_table_p (obj)
+Return @code{#t} if @var{obj} is a abstract hash table object.
address@hidden deffn
+
address@hidden {Scheme Procedure} hash-clear! table
address@hidden {C Function} scm_hash_clear_x (table)
+Remove all items from @var{table} (without triggering a resize).
address@hidden deffn
+
address@hidden {Scheme Procedure} hash-ref table key [dflt]
address@hidden {Scheme Procedure} hashq-ref table key [dflt]
address@hidden {Scheme Procedure} hashv-ref table key [dflt]
address@hidden {Scheme Procedure} hashx-ref hash assoc table key [dflt]
address@hidden {C Function} scm_hash_ref (table, key, dflt)
address@hidden {C Function} scm_hashq_ref (table, key, dflt)
address@hidden {C Function} scm_hashv_ref (table, key, dflt)
address@hidden {C Function} scm_hashx_ref (hash, assoc, table, key, dflt)
+Lookup @var{key} in the given hash @var{table}, and return the
+associated value.  If @var{key} is not found, return @var{dflt}, or
address@hidden if @var{dflt} is not given.
address@hidden deffn
+
address@hidden {Scheme Procedure} hash-set! table key val
address@hidden {Scheme Procedure} hashq-set! table key val
address@hidden {Scheme Procedure} hashv-set! table key val
address@hidden {Scheme Procedure} hashx-set! hash assoc table key val
address@hidden {C Function} scm_hash_set_x (table, key, val)
address@hidden {C Function} scm_hashq_set_x (table, key, val)
address@hidden {C Function} scm_hashv_set_x (table, key, val)
address@hidden {C Function} scm_hashx_set_x (hash, assoc, table, key, val)
+Associate @var{val} with @var{key} in the given hash @var{table}.  If
address@hidden is already present then it's associated value is changed.
+If it's not present then a new entry is created.
address@hidden deffn
+
address@hidden {Scheme Procedure} hash-remove! table key
address@hidden {Scheme Procedure} hashq-remove! table key
address@hidden {Scheme Procedure} hashv-remove! table key
address@hidden {Scheme Procedure} hashx-remove! hash assoc table key
address@hidden {C Function} scm_hash_remove_x (table, key)
address@hidden {C Function} scm_hashq_remove_x (table, key)
address@hidden {C Function} scm_hashv_remove_x (table, key)
address@hidden {C Function} scm_hashx_remove_x (hash, assoc, table, key)
+Remove any association for @var{key} in the given hash @var{table}.
+If @var{key} is not in @var{table} then nothing is done.
address@hidden deffn
+
address@hidden {Scheme Procedure} hash key size
address@hidden {Scheme Procedure} hashq key size
address@hidden {Scheme Procedure} hashv key size
address@hidden {C Function} scm_hash (key, size)
address@hidden {C Function} scm_hashq (key, size)
address@hidden {C Function} scm_hashv (key, size)
+Return a hash value for @var{key}.  This is a number in the range
address@hidden to @address@hidden, which is suitable for use in a hash
+table of the given @var{size}.
+
+Note that @code{hashq} and @code{hashv} may use internal addresses of
+objects, so if an object is garbage collected and re-created it can
+have a different hash value, even when the two are notionally
address@hidden  For instance with symbols,
 
-  if (SCM_UNBNDP (delimiter))
-    delimiter = scm_from_utf8_string (" ");
address@hidden
+(hashq 'something 123)   @result{} 19
+(gc)
+(hashq 'something 123)   @result{} 62
address@hidden example
 
-  return scm_string_join (strings, delimiter, grammar);
address@hidden
+In normal use this is not a problem, since an object entered into a
+hash table won't be garbage collected until removed.  It's only if
+hashing calculations are somehow separated from normal references that
+its lifetime needs to be considered.
address@hidden deffn
+
address@hidden {Scheme Procedure} hash-get-handle table key
address@hidden {Scheme Procedure} hashq-get-handle table key
address@hidden {Scheme Procedure} hashv-get-handle table key
address@hidden {Scheme Procedure} hashx-get-handle hash assoc table key
address@hidden {C Function} scm_hash_get_handle (table, key)
address@hidden {C Function} scm_hashq_get_handle (table, key)
address@hidden {C Function} scm_hashv_get_handle (table, key)
address@hidden {C Function} scm_hashx_get_handle (hash, assoc, table, key)
+Return the @code{(@var{key} . @var{value})} pair for @var{key} in the
+given hash @var{table}, or @code{#f} if @var{key} is not in
address@hidden
address@hidden deffn
+
address@hidden {Scheme Procedure} hash-create-handle! table key init
address@hidden {Scheme Procedure} hashq-create-handle! table key init
address@hidden {Scheme Procedure} hashv-create-handle! table key init
address@hidden {Scheme Procedure} hashx-create-handle! hash assoc table key init
address@hidden {C Function} scm_hash_create_handle_x (table, key, init)
address@hidden {C Function} scm_hashq_create_handle_x (table, key, init)
address@hidden {C Function} scm_hashv_create_handle_x (table, key, init)
address@hidden {C Function} scm_hashx_create_handle_x (hash, assoc, table, key, 
init)
+Return the @code{(@var{key} . @var{value})} pair for @var{key} in the
+given hash @var{table}.  If @var{key} is not in @var{table} then
+create an entry for it with @var{init} as the value, and return that
+pair.
address@hidden deffn
+
address@hidden {Scheme Procedure} hash-map->list proc table
address@hidden {Scheme Procedure} hash-for-each proc table
address@hidden {C Function} scm_hash_map_to_list (proc, table)
address@hidden {C Function} scm_hash_for_each (proc, table)
+Apply @var{proc} to the entries in the given hash @var{table}.  Each
+call is @code{(@var{proc} @var{key} @var{value})}.  @code{hash-map->list}
+returns a list of the results from these calls, @code{hash-for-each}
+discards the results and returns an unspecified value.
+
+Calls are made over the table entries in an unspecified order, and for
address@hidden>list} the order of the values in the returned list is
+unspecified.  Results will be unpredictable if @var{table} is modified
+while iterating.
+
+For example the following returns a new alist comprising all the
+entries from @code{mytable}, in no particular order.
 
-void my_init ()
address@hidden
-  k_delimiter = scm_from_utf8_keyword ("delimiter");
-  k_grammar   = scm_from_utf8_keyword ("grammar");
-  sym_infix   = scm_from_utf8_symbol  ("infix");
-  scm_c_define_gsubr ("my-string-join", 1, 0, 1, my_string_join);
address@hidden
address@hidden
+(hash-map->list cons mytable)
 @end example
address@hidden deftypefn
address@hidden deffn
+
address@hidden {Scheme Procedure} hash-for-each-handle proc table
address@hidden {C Function} scm_hash_for_each_handle (proc, table)
+Apply @var{proc} to the entries in the given hash @var{table}.  Each
+call is @code{(@var{proc} @var{handle})}, where @var{handle} is a
address@hidden(@var{key} . @var{value})} pair. Return an unspecified value.
+
address@hidden differs from @code{hash-for-each} only in
+the argument list of @var{proc}.
address@hidden deffn
+
address@hidden {Scheme Procedure} hash-fold proc init table
address@hidden {C Function} scm_hash_fold (proc, init, table)
+Accumulate a result by applying @var{proc} to the elements of the
+given hash @var{table}.  Each call is @code{(@var{proc} @var{key}
address@hidden @var{prior-result})}, where @var{key} and @var{value} are
+from the @var{table} and @var{prior-result} is the return from the
+previous @var{proc} call.  For the first call, @var{prior-result} is
+the given @var{init} value.
+
+Calls are made over the table entries in an unspecified order.
+Results will be unpredictable if @var{table} is modified while
address@hidden is running.
 
+For example, the following returns a count of how many keys in
address@hidden are strings.
+
address@hidden
+(hash-fold (lambda (key value prior)
+             (if (string? key) (1+ prior) prior))
+           0 mytable)
address@hidden example
address@hidden deffn
+
address@hidden {Scheme Procedure} hash-count pred table
address@hidden {C Function} scm_hash_count (pred, table)
+Return the number of elements in the given hash @var{table} that cause
address@hidden(@var{pred} @var{key} @var{value})} to return true.  To quickly
+determine the total number of elements, use @code{(const #t)} for
address@hidden
address@hidden deffn
 
 @node Other Types
address@hidden ``Functionality-Centric'' Data Types
address@hidden Other Types
 
-Procedures and macros are documented in their own sections: see
address@hidden and @ref{Macros}.
+Procedures are documented in their own section.  @xref{Procedures}.
 
 Variable objects are documented as part of the description of Guile's
 module system: see @ref{Variables}.
 
-Asyncs, dynamic roots and fluids are described in the section on
-scheduling: see @ref{Scheduling}.
-
-Hooks are documented in the section on general utility functions: see
address@hidden
address@hidden, for discussion of threads, mutexes, and so on.
 
 Ports are described in the section on I/O: see @ref{Input and Output}.
 
 Regular expressions are described in their own section: see @ref{Regular
 Expressions}.
 
+There are quite a number of additional data types documented in this
+manual; if you feel a link is missing here, please file a bug.
+
 @c Local Variables:
 @c TeX-master: "guile.texi"
 @c End:
diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi
index 0ab536b..4bc3b74 100644
--- a/doc/ref/guile.texi
+++ b/doc/ref/guile.texi
@@ -297,8 +297,7 @@ available through both Scheme and C interfaces.
 * The SCM Type::                The fundamental data type for C code.
 * Initialization::              Initializing Guile.
 * Snarfing Macros::             Macros for snarfing initialization actions.
-* Simple Data Types::           Numbers, strings, booleans and so on.
-* Compound Data Types::         Data types for holding other data.
+* Data Types::                  Representing values in Guile.
 * Foreign Objects::             Defining new data types in C.
 * Smobs::                       Use foreign objects instead.
 * Procedures::                  Procedures.
@@ -328,7 +327,6 @@ available through both Scheme and C interfaces.
 @include api-init.texi
 @include api-snarf.texi
 @include api-data.texi
address@hidden api-compound.texi
 @include api-foreign-objects.texi
 @include api-smobs.texi
 @include api-procedures.texi
diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi
index 1cada27..f712944 100644
--- a/doc/ref/srfi-modules.texi
+++ b/doc/ref/srfi-modules.texi
@@ -1823,8 +1823,8 @@ procedures easier.  It is documented in @xref{Multiple 
Values}.
 
 This SRFI is a syntax for defining new record types and creating
 predicate, constructor, and field getter and setter functions.  It is
-documented in the ``Compound Data Types'' section of the manual
-(@pxref{SRFI-9 Records}).
+documented in the ``Data Types'' section of the manual (@pxref{SRFI-9
+Records}).
 
 
 @node SRFI-10



reply via email to

[Prev in Thread] Current Thread [Next in Thread]