@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
-@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004
+@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008
@c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
* SRFI-19:: Time/Date library.
* SRFI-26:: Specializing parameters
* SRFI-31:: A special form `rec' for recursive evaluation
+* SRFI-34:: Exception handling.
+* SRFI-35:: Conditions.
+* SRFI-37:: args-fold program argument processor
* SRFI-39:: Parameter objects
+* SRFI-55:: Requiring Features.
+* SRFI-60:: Integers as bits.
+* SRFI-61:: A more general `cond' clause
+* SRFI-69:: Basic hash tables.
+* SRFI-88:: Keyword objects.
@end menu
@end example
@end deffn
-The Guile core provides features @code{guile}, @code{r5rs},
-@code{srfi-0} and @code{srfi-6} initially. Other SRFI feature symbols
-are defined once their code has been loaded with @code{use-modules},
-since only then are their bindings available.
+@noindent
+The Guile core has the following features,
+
+@example
+guile
+r5rs
+srfi-0
+srfi-4
+srfi-6
+srfi-13
+srfi-14
+@end example
+
+Other SRFI feature symbols are defined once their code has been loaded
+with @code{use-modules}, since only then are their bindings available.
The @samp{--use-srfi} command line option (@pxref{Invoking Guile}) is
a good way to load SRFIs to satisfy @code{cond-expand} when running a
The procedures in this section test specific properties of lists.
@deffn {Scheme Procedure} proper-list? obj
-Return @code{#t} if @var{obj} is a proper list, that is a finite list,
-terminated with the empty list. Otherwise, return @code{#f}.
+Return @code{#t} if @var{obj} is a proper list, or @code{#f}
+otherwise. This is the same as the core @code{list?} (@pxref{List
+Predicates}).
+
+A proper list is a list which ends with the empty list @code{()} in
+the usual way. The empty list @code{()} itself is a proper list too.
+
+@example
+(proper-list? '(1 2 3)) @result{} #t
+(proper-list? '()) @result{} #t
+@end example
@end deffn
@deffn {Scheme Procedure} circular-list? obj
-Return @code{#t} if @var{obj} is a circular list, otherwise return
-@code{#f}.
+Return @code{#t} if @var{obj} is a circular list, or @code{#f}
+otherwise.
+
+A circular list is a list where at some point the @code{cdr} refers
+back to a previous pair in the list (either the start or some later
+point), so that following the @code{cdr}s takes you around in a
+circle, with no end.
+
+@example
+(define x (list 1 2 3 4))
+(set-cdr! (last-pair x) (cddr x))
+x @result{} (1 2 3 4 3 4 3 4 ...)
+(circular-list? x) @result{} #t
+@end example
@end deffn
@deffn {Scheme Procedure} dotted-list? obj
-Return @code{#t} if @var{obj} is a dotted list, return @code{#f}
-otherwise. A dotted list is a finite list which is not terminated by
-the empty list, but some other value.
+Return @code{#t} if @var{obj} is a dotted list, or @code{#f}
+otherwise.
+
+A dotted list is a list where the @code{cdr} of the last pair is not
+the empty list @code{()}. Any non-pair @var{obj} is also considered a
+dotted list, with length zero.
+
+@example
+(dotted-list? '(1 2 . 3)) @result{} #t
+(dotted-list? 99) @result{} #t
+@end example
@end deffn
+It will be noted that any Scheme object passes exactly one of the
+above three tests @code{proper-list?}, @code{circular-list?} and
+@code{dotted-list?}. Non-lists are @code{dotted-list?}, finite lists
+are either @code{proper-list?} or @code{dotted-list?}, and infinite
+lists are @code{circular-list?}.
+
+@sp 1
@deffn {Scheme Procedure} null-list? lst
Return @code{#t} if @var{lst} is the empty list @code{()}, @code{#f}
otherwise. If something else than a proper or circular list is passed
@deffn {Scheme Procedure} take-right lst i
Return the a list containing the @var{i} last elements of @var{lst}.
+The return shares a common tail with @var{lst}.
@end deffn
@deffn {Scheme Procedure} drop-right lst i
Return the a list containing all but the @var{i} last elements of
@var{lst}.
-@code{drop-right!} may modify the structure of the argument list
-@var{lst} in order to produce the result.
+@code{drop-right} always returns a new list, even when @var{i} is
+zero. @code{drop-right!} may modify the structure of the argument
+list @var{lst} in order to produce the result.
@end deffn
@deffn {Scheme Procedure} split-at lst i
@deffn {Scheme Procedure} append-reverse rev-head tail
@deffnx {Scheme Procedure} append-reverse! rev-head tail
-Reverse @var{rev-head}, append @var{tail} and return the result. This
-is equivalent to @code{(append (reverse @var{rev-head}) @var{tail})},
-but more efficient.
+Reverse @var{rev-head}, append @var{tail} to it, and return the
+result. This is equivalent to @code{(append (reverse @var{rev-head})
+@var{tail})}, but its implementation is more efficient.
+
+@example
+(append-reverse '(1 2 3) '(4 5 6)) @result{} (3 2 1 4 5 6)
+@end example
@code{append-reverse!} may modify @var{rev-head} in order to produce
the result.
@c FIXME::martin: Review me!
-@deffn {Scheme Procedure} fold kons knil lst1 lst2 @dots{}
-Fold the procedure @var{kons} across all elements of @var{lst1},
-@var{lst2}, @dots{}. Produce the result of
+@deffn {Scheme Procedure} fold proc init lst1 @dots{} lstN
+@deffnx {Scheme Procedure} fold-right proc init lst1 @dots{} lstN
+Apply @var{proc} to the elements of @var{lst1} @dots{} @var{lstN} to
+build a result, and return that result.
-@code{(@var{kons} @var{en1} @var{en2} @dots{} (@var{kons} @var{e21}
-@var{e22} (@var{kons} @var{e11} @var{e12} @var{knil})))},
+Each @var{proc} call is @code{(@var{proc} @var{elem1} @dots{}
+@var{elemN} @var{previous})}, where @var{elem1} is from @var{lst1},
+through @var{elemN} from @var{lstN}. @var{previous} is the return
+from the previous call to @var{proc}, or the given @var{init} for the
+first call. If any list is empty, just @var{init} is returned.
-if @var{enm} are the elements of the lists @var{lst1}, @var{lst2},
-@dots{}.
-@end deffn
+@code{fold} works through the list elements from first to last. The
+following shows a list reversal and the calls it makes,
-@deffn {Scheme Procedure} fold-right kons knil lst1 lst2 @dots{}
-Similar to @code{fold}, but applies @var{kons} in right-to-left order
-to the list elements, that is:
+@example
+(fold cons '() '(1 2 3))
-@code{(@var{kons} @var{e11} @var{e12}(@var{kons} @var{e21}
-@var{e22} @dots{} (@var{kons} @var{en1} @var{en2} @var{knil})))},
-@end deffn
+(cons 1 '())
+(cons 2 '(1))
+(cons 3 '(2 1)
+@result{} (3 2 1)
+@end example
-@deffn {Scheme Procedure} pair-fold kons knil lst1 lst2 @dots{}
-Like @code{fold}, but apply @var{kons} to the pairs of the list
-instead of the list elements.
-@end deffn
+@code{fold-right} works through the list elements from last to first,
+ie.@: from the right. So for example the following finds the longest
+string, and the last among equal longest,
+
+@example
+(fold-right (lambda (str prev)
+ (if (> (string-length str) (string-length prev))
+ str
+ prev))
+ ""
+ '("x" "abc" "xyz" "jk"))
+@result{} "xyz"
+@end example
+
+If @var{lst1} through @var{lstN} have different lengths, @code{fold}
+stops when the end of the shortest is reached; @code{fold-right}
+commences at the last element of the shortest. Ie.@: elements past
+the length of the shortest are ignored in the other @var{lst}s. At
+least one @var{lst} must be non-circular.
+
+@code{fold} should be preferred over @code{fold-right} if the order of
+processing doesn't matter, or can be arranged either way, since
+@code{fold} is a little more efficient.
+
+The way @code{fold} builds a result from iterating is quite general,
+it can do more than other iterations like say @code{map} or
+@code{filter}. The following for example removes adjacent duplicate
+elements from a list,
-@deffn {Scheme Procedure} pair-fold-right kons knil lst1 lst2 @dots{}
-Like @code{fold-right}, but apply @var{kons} to the pairs of the list
-instead of the list elements.
+@example
+(define (delete-adjacent-duplicates lst)
+ (fold-right (lambda (elem ret)
+ (if (equal? elem (first ret))
+ ret
+ (cons elem ret)))
+ (list (last lst))
+ lst))
+(delete-adjacent-duplicates '(1 2 3 3 4 4 4 5))
+@result{} (1 2 3 4 5)
+@end example
+
+Clearly the same sort of thing can be done with a @code{for-each} and
+a variable in which to build the result, but a self-contained
+@var{proc} can be re-used in multiple contexts, where a
+@code{for-each} would have to be written out each time.
@end deffn
-@deffn {Scheme Procedure} reduce f ridentity lst
-@code{reduce} is a variant of @code{fold}. If @var{lst} is
-@code{()}, @var{ridentity} is returned. Otherwise, @code{(fold f (car
-@var{lst}) (cdr @var{lst}))} is returned.
+@deffn {Scheme Procedure} pair-fold proc init lst1 @dots{} lstN
+@deffnx {Scheme Procedure} pair-fold-right proc init lst1 @dots{} lstN
+The same as @code{fold} and @code{fold-right}, but apply @var{proc} to
+the pairs of the lists instead of the list elements.
@end deffn
-@deffn {Scheme Procedure} reduce-right f ridentity lst
-This is the @code{fold-right} variant of @code{reduce}.
+@deffn {Scheme Procedure} reduce proc default lst
+@deffnx {Scheme Procedure} reduce-right proc default lst
+@code{reduce} is a variant of @code{fold}, where the first call to
+@var{proc} is on two elements from @var{lst}, rather than one element
+and a given initial value.
+
+If @var{lst} is empty, @code{reduce} returns @var{default} (this is
+the only use for @var{default}). If @var{lst} has just one element
+then that's the return value. Otherwise @var{proc} is called on the
+elements of @var{lst}.
+
+Each @var{proc} call is @code{(@var{proc} @var{elem} @var{previous})},
+where @var{elem} is from @var{lst} (the second and subsequent elements
+of @var{lst}), and @var{previous} is the return from the previous call
+to @var{proc}. The first element of @var{lst} is the @var{previous}
+for the first call to @var{proc}.
+
+For example, the following adds a list of numbers, the calls made to
+@code{+} are shown. (Of course @code{+} accepts multiple arguments
+and can add a list directly, with @code{apply}.)
+
+@example
+(reduce + 0 '(5 6 7)) @result{} 18
+
+(+ 6 5) @result{} 11
+(+ 7 11) @result{} 18
+@end example
+
+@code{reduce} can be used instead of @code{fold} where the @var{init}
+value is an ``identity'', meaning a value which under @var{proc}
+doesn't change the result, in this case 0 is an identity since
+@code{(+ 5 0)} is just 5. @code{reduce} avoids that unnecessary call.
+
+@code{reduce-right} is a similar variation on @code{fold-right},
+working from the end (ie.@: the right) of @var{lst}. The last element
+of @var{lst} is the @var{previous} for the first call to @var{proc},
+and the @var{elem} values go from the second last.
+
+@code{reduce} should be preferred over @code{reduce-right} if the
+order of processing doesn't matter, or can be arranged either way,
+since @code{reduce} is a little more efficient.
@end deffn
@deffn {Scheme Procedure} unfold p f g seed [tail-gen]
@end deffn
@deffn {Scheme Procedure} list-index pred lst1 @dots{} lstN
-Call @var{pred} on sets of elements from the @var{lst}s, one from each
-list, starting from the first, as @code{(@var{pred} elem1 @dots{}
-elemN)}. Return the index of the first set for which @var{pred}
-returns true.
+Return the index of the first set of elements, one from each of
+@var{lst1}@dots{}@var{lstN}, which satisfies @var{pred}.
-The index starts from 0 for the first first set of elements.
-Searching stops when the end of the shortest @var{lst} is reached. If
-no set of elements pass then the return is @code{#f}.
+@var{pred} is called as @code{(@var{pred} elem1 @dots{} elemN)}.
+Searching stops when the end of the shortest @var{lst} is reached.
+The return index starts from 0 for the first set of elements. If no
+set of elements pass then the return is @code{#f}.
@example
(list-index odd? '(2 4 6 9)) @result{} 3
@subsubsection Deleting
@cindex list delete
-@c FIXME::martin: Review me!
-
@deffn {Scheme Procedure} delete x lst [=]
@deffnx {Scheme Procedure} delete! x lst [=]
Return a list containing the elements of @var{lst} but with those
common tail with @var{lst}. @code{delete!} may modify the structure
of @var{lst} to construct its return.
-These functions extend the core @code{delete} and @code{delete!} in
-accepting an equality predicate. (@pxref{List Modification})
+These functions extend the core @code{delete} and @code{delete!}
+(@pxref{List Modification}) in accepting an equality predicate. See
+also @code{lset-difference} (@pxref{SRFI-1 Set Operations}) for
+deleting multiple elements from a list.
@end deffn
@deffn {Scheme Procedure} delete-duplicates lst [=]
for dealing with association lists defined by SRFI-1.
@deffn {Scheme Procedure} assoc key alist [=]
-Return the pair from @var{alist} which matches @var{key}. Equality is
-determined by @var{=}, which defaults to @code{equal?} if not given.
-@var{alist} must be an association lists---a list of pairs.
+Return the pair from @var{alist} which matches @var{key}. This
+extends the core @code{assoc} (@pxref{Retrieving Alist Entries}) by
+taking an optional @var{=} comparison procedure.
+
+The default comparison is @code{equal?}. If an @var{=} parameter is
+given it's called @code{(@var{=} @var{key} @var{alistcar})}, ie. the
+given target @var{key} is the first argument, and a @code{car} from
+@var{alist} is second.
+
+For example a case-insensitive string lookup,
-This function extends the core @code{assoc} by accepting an equality
-predicate. (@pxref{Association Lists})
+@example
+(assoc "yy" '(("XX" . 1) ("YY" . 2)) string-ci=?)
+@result{} ("YY" . 2)
+@end example
@end deffn
@deffn {Scheme Procedure} alist-cons key datum alist
-Equivalent to
+Cons a new association @var{key} and @var{datum} onto @var{alist} and
+return the result. This is equivalent to
@lisp
(cons (cons @var{key} @var{datum}) @var{alist})
@end lisp
-This procedure is used to coons a new pair onto an existing
-association list.
+@code{acons} (@pxref{Adding or Setting Alist Entries}) in the Guile
+core does the same thing.
@end deffn
@deffn {Scheme Procedure} alist-copy alist
@subsubsection Set Operations on Lists
@cindex list set operation
-@c FIXME::martin: Review me!
+Lists can be used to represent sets of objects. The procedures in
+this section operate on such lists as sets.
+
+Note that lists are not an efficient way to implement large sets. The
+procedures here typically take time @math{@var{m}@cross{}@var{n}} when
+operating on @var{m} and @var{n} element lists. Other data structures
+like trees, bitsets (@pxref{Bit Vectors}) or hash tables (@pxref{Hash
+Tables}) are faster.
-Lists can be used for representing sets of objects. The procedures
-documented in this section can be used for such set representations.
-Man combining several sets or adding elements, they make sure that no
-object is contained more than once in a given list. Please note that
-lists are not a too efficient implementation method for sets, so if
-you need high performance, you should think about implementing a
-custom data structure for representing sets, such as trees, bitsets,
-hash tables or something similar.
+All these procedures take an equality predicate as the first argument.
+This predicate is used for testing the objects in the list sets for
+sameness. This predicate must be consistent with @code{eq?}
+(@pxref{Equality}) in the sense that if two list elements are
+@code{eq?} then they must also be equal under the predicate. This
+simply means a given object must be equal to itself.
-All these procedures accept an equality predicate as the first
-argument. This predicate is used for testing the objects in the list
-sets for sameness.
+@deffn {Scheme Procedure} lset<= = list1 list2 @dots{}
+Return @code{#t} if each list is a subset of the one following it.
+Ie.@: @var{list1} a subset of @var{list2}, @var{list2} a subset of
+@var{list3}, etc, for as many lists as given. If only one list or no
+lists are given then the return is @code{#t}.
-@deffn {Scheme Procedure} lset<= = list1 @dots{}
-Return @code{#t} if every @var{listi} is a subset of @var{listi+1},
-otherwise return @code{#f}. Returns @code{#t} if called with less
-than two arguments. @var{=} is used for testing element equality.
+A list @var{x} is a subset of @var{y} if each element of @var{x} is
+equal to some element in @var{y}. Elements are compared using the
+given @var{=} procedure, called as @code{(@var{=} xelem yelem)}.
+
+@example
+(lset<= eq?) @result{} #t
+(lset<= eqv? '(1 2 3) '(1)) @result{} #f
+(lset<= eqv? '(1 3 2) '(4 3 1 2)) @result{} #t
+@end example
@end deffn
@deffn {Scheme Procedure} lset= = list1 list2 @dots{}
-Return @code{#t} if all argument lists are equal. @var{=} is used for
-testing element equality.
+Return @code{#t} if all argument lists are set-equal. @var{list1} is
+compared to @var{list2}, @var{list2} to @var{list3}, etc, for as many
+lists as given. If only one list or no lists are given then the
+return is @code{#t}.
+
+Two lists @var{x} and @var{y} are set-equal if each element of @var{x}
+is equal to some element of @var{y} and conversely each element of
+@var{y} is equal to some element of @var{x}. The order of the
+elements in the lists doesn't matter. Element equality is determined
+with the given @var{=} procedure, called as @code{(@var{=} xelem
+yelem)}, but exactly which calls are made is unspecified.
+
+@example
+(lset= eq?) @result{} #t
+(lset= eqv? '(1 2 3) '(3 2 1)) @result{} #t
+(lset= string-ci=? '("a" "A" "b") '("B" "b" "a")) @result{} #t
+@end example
@end deffn
-@deffn {Scheme Procedure} lset-adjoin = list elt1 @dots{}
-@deffnx {Scheme Procedure} lset-adjoin! = list elt1 @dots{}
-Add all @var{elts} to the list @var{list}, suppressing duplicates and
-return the resulting list. @code{lset-adjoin!} is allowed, but not
-required to modify its first argument. @var{=} is used for testing
-element equality.
+@deffn {Scheme Procedure} lset-adjoin = list elem1 @dots{}
+Add to @var{list} any of the given @var{elem}s not already in the
+list. @var{elem}s are @code{cons}ed onto the start of @var{list} (so
+the return shares a common tail with @var{list}), but the order
+they're added is unspecified.
+
+The given @var{=} procedure is used for comparing elements, called as
+@code{(@var{=} listelem elem)}, ie.@: the second argument is one of
+the given @var{elem} parameters.
+
+@example
+(lset-adjoin eqv? '(1 2 3) 4 1 5) @result{} (5 4 1 2 3)
+@end example
@end deffn
-@deffn {Scheme Procedure} lset-union = list1 @dots{}
-@deffnx {Scheme Procedure} lset-union! = list1 @dots{}
-Return the union of all argument list sets. The union is the set of
-all elements which appear in any of the argument sets.
-@code{lset-union!} is allowed, but not required to modify its first
-argument. @var{=} is used for testing element equality.
+@deffn {Scheme Procedure} lset-union = list1 list2 @dots{}
+@deffnx {Scheme Procedure} lset-union! = list1 list2 @dots{}
+Return the union of the argument list sets. The result is built by
+taking the union of @var{list1} and @var{list2}, then the union of
+that with @var{list3}, etc, for as many lists as given. For one list
+argument that list itself is the result, for no list arguments the
+result is the empty list.
+
+The union of two lists @var{x} and @var{y} is formed as follows. If
+@var{x} is empty then the result is @var{y}. Otherwise start with
+@var{x} as the result and consider each @var{y} element (from first to
+last). A @var{y} element not equal to something already in the result
+is @code{cons}ed onto the result.
+
+The given @var{=} procedure is used for comparing elements, called as
+@code{(@var{=} relem yelem)}. The first argument is from the result
+accumulated so far, and the second is from the list being union-ed in.
+But exactly which calls are made is otherwise unspecified.
+
+Notice that duplicate elements in @var{list1} (or the first non-empty
+list) are preserved, but that repeated elements in subsequent lists
+are only added once.
+
+@example
+(lset-union eqv?) @result{} ()
+(lset-union eqv? '(1 2 3)) @result{} (1 2 3)
+(lset-union eqv? '(1 2 1 3) '(2 4 5) '(5)) @result{} (5 4 1 2 1 3)
+@end example
+
+@code{lset-union} doesn't change the given lists but the result may
+share a tail with the first non-empty list. @code{lset-union!} can
+modify all of the given lists to form the result.
@end deffn
@deffn {Scheme Procedure} lset-intersection = list1 list2 @dots{}
@deffnx {Scheme Procedure} lset-intersection! = list1 list2 @dots{}
-Return the intersection of all argument list sets. The intersection
-is the set containing all elements which appear in all argument sets.
-@code{lset-intersection!} is allowed, but not required to modify its
-first argument. @var{=} is used for testing element equality.
+Return the intersection of @var{list1} with the other argument lists,
+meaning those elements of @var{list1} which are also in all of
+@var{list2} etc. For one list argument, just that list is returned.
+
+The test for an element of @var{list1} to be in the return is simply
+that it's equal to some element in each of @var{list2} etc. Notice
+this means an element appearing twice in @var{list1} but only once in
+each of @var{list2} etc will go into the return twice. The return has
+its elements in the same order as they were in @var{list1}.
+
+The given @var{=} procedure is used for comparing elements, called as
+@code{(@var{=} elem1 elemN)}. The first argument is from @var{list1}
+and the second is from one of the subsequent lists. But exactly which
+calls are made and in what order is unspecified.
+
+@example
+(lset-intersection eqv? '(x y)) @result{} (x y)
+(lset-intersection eqv? '(1 2 3) '(4 3 2)) @result{} (2 3)
+(lset-intersection eqv? '(1 1 2 2) '(1 2) '(2 1) '(2)) @result{} (2 2)
+@end example
+
+The return from @code{lset-intersection} may share a tail with
+@var{list1}. @code{lset-intersection!} may modify @var{list1} to form
+its result.
@end deffn
@deffn {Scheme Procedure} lset-difference = list1 list2 @dots{}
@deffnx {Scheme Procedure} lset-difference! = list1 list2 @dots{}
-Return the difference of all argument list sets. The difference is
-the the set containing all elements of the first list which do not
-appear in the other lists. @code{lset-difference!} is allowed, but
-not required to modify its first argument. @var{=} is used for testing
-element equality.
-@end deffn
+Return @var{list1} with any elements in @var{list2}, @var{list3} etc
+removed (ie.@: subtracted). For one list argument, just that list is
+returned.
+
+The given @var{=} procedure is used for comparing elements, called as
+@code{(@var{=} elem1 elemN)}. The first argument is from @var{list1}
+and the second from one of the subsequent lists. But exactly which
+calls are made and in what order is unspecified.
+
+@example
+(lset-difference eqv? '(x y)) @result{} (x y)
+(lset-difference eqv? '(1 2 3) '(3 1)) @result{} (2)
+(lset-difference eqv? '(1 2 3) '(3) '(2)) @result{} (1)
+@end example
-@deffn {Scheme Procedure} lset-xor = list1 @dots{}
-@deffnx {Scheme Procedure} lset-xor! = list1 @dots{}
-Return the set containing all elements which appear in the first
-argument list set, but not in the second; or, more generally: which
-appear in an odd number of sets. @code{lset-xor!} is allowed, but
-not required to modify its first argument. @var{=} is used for testing
-element equality.
+The return from @code{lset-difference} may share a tail with
+@var{list1}. @code{lset-difference!} may modify @var{list1} to form
+its result.
@end deffn
@deffn {Scheme Procedure} lset-diff+intersection = list1 list2 @dots{}
@deffnx {Scheme Procedure} lset-diff+intersection! = list1 list2 @dots{}
-Return two values, the difference and the intersection of the argument
-list sets. This works like a combination of @code{lset-difference} and
-@code{lset-intersection}, but is more efficient.
-@code{lset-diff+intersection!} is allowed, but not required to modify
-its first argument. @var{=} is used for testing element equality. You
-have to use some means to deal with the multiple values these
-procedures return (@pxref{Multiple Values}).
+Return two values (@pxref{Multiple Values}), the difference and
+intersection of the argument lists as per @code{lset-difference} and
+@code{lset-intersection} above.
+
+For two list arguments this partitions @var{list1} into those elements
+of @var{list1} which are in @var{list2} and not in @var{list2}. (But
+for more than two arguments there can be elements of @var{list1} which
+are neither part of the difference nor the intersection.)
+
+One of the return values from @code{lset-diff+intersection} may share
+a tail with @var{list1}. @code{lset-diff+intersection!} may modify
+@var{list1} to form its results.
+@end deffn
+
+@deffn {Scheme Procedure} lset-xor = list1 list2 @dots{}
+@deffnx {Scheme Procedure} lset-xor! = list1 list2 @dots{}
+Return an XOR of the argument lists. For two lists this means those
+elements which are in exactly one of the lists. For more than two
+lists it means those elements which appear in an odd number of the
+lists.
+
+To be precise, the XOR of two lists @var{x} and @var{y} is formed by
+taking those elements of @var{x} not equal to any element of @var{y},
+plus those elements of @var{y} not equal to any element of @var{x}.
+Equality is determined with the given @var{=} procedure, called as
+@code{(@var{=} e1 e2)}. One argument is from @var{x} and the other
+from @var{y}, but which way around is unspecified. Exactly which
+calls are made is also unspecified, as is the order of the elements in
+the result.
+
+@example
+(lset-xor eqv? '(x y)) @result{} (x y)
+(lset-xor eqv? '(1 2 3) '(4 3 2)) @result{} (4 1)
+@end example
+
+The return from @code{lset-xor} may share a tail with one of the list
+arguments. @code{lset-xor!} may modify @var{list1} to form its
+result.
@end deffn
(lambda elems
(let ((table (make-hash-table)))
(for-each (lambda (elem)
- (apply hash-set! table elem))
- elems)
+ (apply hash-set! table elem))
+ elems)
table)))
(define (animal->family animal)
@subsection SRFI-17 - Generalized set!
@cindex SRFI-17
-This is an implementation of SRFI-17: Generalized set!
+This SRFI implements a generalized @code{set!}, allowing some
+``referencing'' functions to be used as the target location of a
+@code{set!}. This feature is available from
+
+@example
+(use-modules (srfi srfi-17))
+@end example
+
+@noindent
+For example @code{vector-ref} is extended so that
-@findex getter-with-setter
-It exports the Guile procedure @code{make-procedure-with-setter} under
-the SRFI name @code{getter-with-setter} and exports the standard
-procedures @code{car}, @code{cdr}, @dots{}, @code{cdddr},
-@code{string-ref} and @code{vector-ref} as procedures with setters, as
-required by the SRFI.
+@example
+(set! (vector-ref vec idx) new-value)
+@end example
-SRFI-17 was heavily criticized during its discussion period but it was
-finalized anyway. One issue was its concept of globally associating
-setter @dfn{properties} with (procedure) values, which is non-Schemy.
-For this reason, this implementation chooses not to provide a way to set
-the setter of a procedure. In fact, @code{(set! (setter @var{proc})
-@var{setter})} signals an error. The only way to attach a setter to a
-procedure is to create a new object (a @dfn{procedure with setter}) via
-the @code{getter-with-setter} procedure. This procedure is also
-specified in the SRFI. Using it avoids the described problems.
+@noindent
+is equivalent to
+
+@example
+(vector-set! vec idx new-value)
+@end example
+
+The idea is that a @code{vector-ref} expression identifies a location,
+which may be either fetched or stored. The same form is used for the
+location in both cases, encouraging visual clarity. This is similar
+to the idea of an ``lvalue'' in C.
+
+The mechanism for this kind of @code{set!} is in the Guile core
+(@pxref{Procedures with Setters}). This module adds definitions of
+the following functions as procedures with setters, allowing them to
+be targets of a @code{set!},
+
+@quotation
+@nicode{car}, @nicode{cdr}, @nicode{caar}, @nicode{cadr},
+@nicode{cdar}, @nicode{cddr}, @nicode{caaar}, @nicode{caadr},
+@nicode{cadar}, @nicode{caddr}, @nicode{cdaar}, @nicode{cdadr},
+@nicode{cddar}, @nicode{cdddr}, @nicode{caaaar}, @nicode{caaadr},
+@nicode{caadar}, @nicode{caaddr}, @nicode{cadaar}, @nicode{cadadr},
+@nicode{caddar}, @nicode{cadddr}, @nicode{cdaaar}, @nicode{cdaadr},
+@nicode{cdadar}, @nicode{cdaddr}, @nicode{cddaar}, @nicode{cddadr},
+@nicode{cdddar}, @nicode{cddddr}
+
+@nicode{string-ref}, @nicode{vector-ref}
+@end quotation
+
+The SRFI specifies @code{setter} (@pxref{Procedures with Setters}) as
+a procedure with setter, allowing the setter for a procedure to be
+changed, eg.@: @code{(set! (setter foo) my-new-setter-handler)}.
+Currently Guile does not implement this, a setter can only be
+specified on creation (@code{getter-with-setter} below).
+
+@defun getter-with-setter
+The same as the Guile core @code{make-procedure-with-setter}
+(@pxref{Procedures with Setters}).
+@end defun
@node SRFI-19
(use-modules (srfi srfi-19))
@end example
+@strong{Caution}: The current code in this module incorrectly extends
+the Gregorian calendar leap year rule back prior to the introduction
+of those reforms in 1582 (or the appropriate year in various
+countries). The Julian calendar was used prior to 1582, and there
+were 10 days skipped for the reform, but the code doesn't implement
+that.
+
+This will be fixed some time. Until then calculations for 1583
+onwards are correct, but prior to that any day/month/year and day of
+the week calculations are wrong.
+
@menu
* SRFI-19 Introduction::
* SRFI-19 Time::
instance @code{time-tai->time-utc} accepts a @var{time} object of type
@code{time-tai} and returns an object of type @code{time-utc}.
-For conversions to dates, @var{tz-offset} is seconds east of
-Greenwich. The default is the local timezone, at the given time, as
-provided by the system.
-
The @code{!} variants may modify their @var{time} argument to form
their return. The plain functions create a new object.
+
+For conversions to dates, @var{tz-offset} is seconds east of
+Greenwich. The default is the local timezone, at the given time, as
+provided by the system, using @code{localtime} (@pxref{Time}).
+
+On 32-bit systems, @code{localtime} is limited to a 32-bit
+@code{time_t}, so a default @var{tz-offset} is only available for
+times between Dec 1901 and Jan 2038. For prior dates an application
+might like to use the value in 1902, though some locations have zone
+changes prior to that. For future dates an application might like to
+assume today's rules extend indefinitely. But for correct daylight
+savings transitions it will be necessary to take an offset for the
+same day and time but a year in range and which has the same starting
+weekday and same leap/non-leap (to support rules like last Sunday in
+October).
@end defun
@node SRFI-19 Date to string
described here, since the specification and reference implementation
differ.
-Currently Guile doesn't implement any localizations for the above, all
-outputs are in English, and the @samp{~c} conversion is POSIX
-@code{ctime} style @samp{~a ~b ~d ~H:~M:~S~z ~Y}. This may change in
-the future.
+Conversion is locale-dependent on systems that support it
+(@pxref{Accessing Locale Information}). @xref{Locales,
+@code{setlocale}}, for information on how to change the current
+locale.
@node SRFI-19 String to date
returned, instead the weekday will be derived from the day, month and
year.
-Currently Guile doesn't implement any localizations for the above,
-month and weekday names are always expected in English. This may
-change in the future.
+Conversion is locale-dependent on systems that support it
+(@pxref{Accessing Locale Information}). @xref{Locales,
+@code{setlocale}}, for information on how to change the current
+locale.
@end defun
@end lisp
+@node SRFI-34
+@subsection SRFI-34 - Exception handling for programs
+
+@cindex SRFI-34
+Guile provides an implementation of
+@uref{http://srfi.schemers.org/srfi-34/srfi-34.html, SRFI-34's exception
+handling mechanisms} as an alternative to its own built-in mechanisms
+(@pxref{Exceptions}). It can be made available as follows:
+
+@lisp
+(use-modules (srfi srfi-34))
+@end lisp
+
+@c FIXME: Document it.
+
+
+@node SRFI-35
+@subsection SRFI-35 - Conditions
+
+@cindex SRFI-35
+@cindex conditions
+@cindex exceptions
+
+@uref{http://srfi.schemers.org/srfi-35/srfi-35.html, SRFI-35} implements
+@dfn{conditions}, a data structure akin to records designed to convey
+information about exceptional conditions between parts of a program. It
+is normally used in conjunction with SRFI-34's @code{raise}:
+
+@lisp
+(raise (condition (&message
+ (message "An error occurred"))))
+@end lisp
+
+Users can define @dfn{condition types} containing arbitrary information.
+Condition types may inherit from one another. This allows the part of
+the program that handles (or ``catches'') conditions to get accurate
+information about the exceptional condition that arose.
+
+SRFI-35 conditions are made available using:
+
+@lisp
+(use-modules (srfi srfi-35))
+@end lisp
+
+The procedures available to manipulate condition types are the
+following:
+
+@deffn {Scheme Procedure} make-condition-type id parent field-names
+Return a new condition type named @var{id}, inheriting from
+@var{parent}, and with the fields whose names are listed in
+@var{field-names}. @var{field-names} must be a list of symbols and must
+not contain names already used by @var{parent} or one of its supertypes.
+@end deffn
+
+@deffn {Scheme Procedure} condition-type? obj
+Return true if @var{obj} is a condition type.
+@end deffn
+
+Conditions can be created and accessed with the following procedures:
+
+@deffn {Scheme Procedure} make-condition type . field+value
+Return a new condition of type @var{type} with fields initialized as
+specified by @var{field+value}, a sequence of field names (symbols) and
+values as in the following example:
+
+@lisp
+(let ((&ct (make-condition-type 'foo &condition '(a b c))))
+ (make-condition &ct 'a 1 'b 2 'c 3))
+@end lisp
+
+Note that all fields of @var{type} and its supertypes must be specified.
+@end deffn
+
+@deffn {Scheme Procedure} make-compound-condition . conditions
+Return a new compound condition composed of @var{conditions}. The
+returned condition has the type of each condition of @var{conditions}
+(per @code{condition-has-type?}).
+@end deffn
+
+@deffn {Scheme Procedure} condition-has-type? c type
+Return true if condition @var{c} has type @var{type}.
+@end deffn
+
+@deffn {Scheme Procedure} condition-ref c field-name
+Return the value of the field named @var{field-name} from condition @var{c}.
+
+If @var{c} is a compound condition and several underlying condition
+types contain a field named @var{field-name}, then the value of the
+first such field is returned, using the order in which conditions were
+passed to @var{make-compound-condition}.
+@end deffn
+
+@deffn {Scheme Procedure} extract-condition c type
+Return a condition of condition type @var{type} with the field values
+specified by @var{c}.
+
+If @var{c} is a compound condition, extract the field values from the
+subcondition belonging to @var{type} that appeared first in the call to
+@code{make-compound-condition} that created the the condition.
+@end deffn
+
+Convenience macros are also available to create condition types and
+conditions.
+
+@deffn {library syntax} define-condition-type type supertype predicate field-spec...
+Define a new condition type named @var{type} that inherits from
+@var{supertype}. In addition, bind @var{predicate} to a type predicate
+that returns true when passed a condition of type @var{type} or any of
+its subtypes. @var{field-spec} must have the form @code{(field
+accessor)} where @var{field} is the name of field of @var{type} and
+@var{accessor} is the name of a procedure to access field @var{field} in
+conditions of type @var{type}.
+
+The example below defines condition type @code{&foo}, inheriting from
+@code{&condition} with fields @code{a}, @code{b} and @code{c}:
+
+@lisp
+(define-condition-type &foo &condition
+ foo-condition?
+ (a foo-a)
+ (b foo-b)
+ (c foo-c))
+@end lisp
+@end deffn
+
+@deffn {library syntax} condition type-field-bindings...
+Return a new condition, or compound condition, initialized according to
+@var{type-field-bindings}. Each @var{type-field-binding} must have the
+form @code{(type field-specs...)}, where @var{type} is the name of a
+variable bound to condition type; each @var{field-spec} must have the
+form @code{(field-name value)} where @var{field-name} is a symbol
+denoting the field being initialized to @var{value}. As for
+@code{make-condition}, all fields must be specified.
+
+The following example returns a simple condition:
+
+@lisp
+(condition (&message (message "An error occurred")))
+@end lisp
+
+The one below returns a compound condition:
+
+@lisp
+(condition (&message (message "An error occurred"))
+ (&serious))
+@end lisp
+@end deffn
+
+Finally, SRFI-35 defines a several standard condition types.
+
+@defvar &condition
+This condition type is the root of all condition types. It has no
+fields.
+@end defvar
+
+@defvar &message
+A condition type that carries a message describing the nature of the
+condition to humans.
+@end defvar
+
+@deffn {Scheme Procedure} message-condition? c
+Return true if @var{c} is of type @code{&message} or one of its
+subtypes.
+@end deffn
+
+@deffn {Scheme Procedure} condition-message c
+Return the message associated with message condition @var{c}.
+@end deffn
+
+@defvar &serious
+This type describes conditions serious enough that they cannot safely be
+ignored. It has no fields.
+@end defvar
+
+@deffn {Scheme Procedure} serious-condition? c
+Return true if @var{c} is of type @code{&serious} or one of its
+subtypes.
+@end deffn
+
+@defvar &error
+This condition describes errors, typically caused by something that has
+gone wrong in the interaction of the program with the external world or
+the user.
+@end defvar
+
+@deffn {Scheme Procedure} error? c
+Return true if @var{c} is of type @code{&error} or one of its subtypes.
+@end deffn
+
+
+@node SRFI-37
+@subsection SRFI-37 - args-fold
+@cindex SRFI-37
+
+This is a processor for GNU @code{getopt_long}-style program
+arguments. It provides an alternative, less declarative interface
+than @code{getopt-long} in @code{(ice-9 getopt-long)}
+(@pxref{getopt-long,,The (ice-9 getopt-long) Module}). Unlike
+@code{getopt-long}, it supports repeated options and any number of
+short and long names per option. Access it with:
+
+@lisp
+(use-modules (srfi srfi-37))
+@end lisp
+
+@acronym{SRFI}-37 principally provides an @code{option} type and the
+@code{args-fold} function. To use the library, create a set of
+options with @code{option} and use it as a specification for invoking
+@code{args-fold}.
+
+Here is an example of a simple argument processor for the typical
+@samp{--version} and @samp{--help} options, which returns a backwards
+list of files given on the command line:
+
+@lisp
+(args-fold (cdr (program-arguments))
+ (let ((display-and-exit-proc
+ (lambda (msg)
+ (lambda (opt name arg loads)
+ (display msg) (quit)))))
+ (list (option '(#\v "version") #f #f
+ (display-and-exit-proc "Foo version 42.0\n"))
+ (option '(#\h "help") #f #f
+ (display-and-exit-proc
+ "Usage: foo scheme-file ..."))))
+ (lambda (opt name arg loads)
+ (error "Unrecognized option `~A'" name))
+ (lambda (op loads) (cons op loads))
+ '())
+@end lisp
+
+@deffn {Scheme Procedure} option names required-arg? optional-arg? processor
+Return an object that specifies a single kind of program option.
+
+@var{names} is a list of command-line option names, and should consist of
+characters for traditional @code{getopt} short options and strings for
+@code{getopt_long}-style long options.
+
+@var{required-arg?} and @var{optional-arg?} are mutually exclusive;
+one or both must be @code{#f}. If @var{required-arg?}, the option
+must be followed by an argument on the command line, such as
+@samp{--opt=value} for long options, or an error will be signalled.
+If @var{optional-arg?}, an argument will be taken if available.
+
+@var{processor} is a procedure that takes at least 3 arguments, called
+when @code{args-fold} encounters the option: the containing option
+object, the name used on the command line, and the argument given for
+the option (or @code{#f} if none). The rest of the arguments are
+@code{args-fold} ``seeds'', and the @var{processor} should return
+seeds as well.
+@end deffn
+
+@deffn {Scheme Procedure} option-names opt
+@deffnx {Scheme Procedure} option-required-arg? opt
+@deffnx {Scheme Procedure} option-optional-arg? opt
+@deffnx {Scheme Procedure} option-processor opt
+Return the specified field of @var{opt}, an option object, as
+described above for @code{option}.
+@end deffn
+
+@deffn {Scheme Procedure} args-fold args options unrecognized-option-proc operand-proc seeds @dots{}
+Process @var{args}, a list of program arguments such as that returned
+by @code{(cdr (program-arguments))}, in order against @var{options}, a
+list of option objects as described above. All functions called take
+the ``seeds'', or the last multiple-values as multiple arguments,
+starting with @var{seeds}, and must return the new seeds. Return the
+final seeds.
+
+Call @code{unrecognized-option-proc}, which is like an option object's
+processor, for any options not found in @var{options}.
+
+Call @code{operand-proc} with any items on the command line that are
+not named options. This includes arguments after @samp{--}. It is
+called with the argument in question, as well as the seeds.
+@end deffn
+
+
@node SRFI-39
@subsection SRFI-39 - Parameters
@cindex SRFI-39
@code{with-parameters*}.
This function is a Guile-specific addition to the SRFI, it's similar
-to the core @code{with-fluids*} (@pxref{Fluids}).
+to the core @code{with-fluids*} (@pxref{Fluids and Dynamic States}).
@end defun
@sp 1
-Parameter objects are implemented using fluids (@pxref{Fluids}), so
-each dynamic root has it's own parameter locations. That includes the
-separate locations when outside any @code{parameterize} form. When a
-parameter is created it gets a separate initial location in each
-dynamic root, all initialized to the given @var{init} value.
-
-As alluded to above, because each thread is a separate dynamic root,
-each thread has it's own locations behind parameter objects, and
-changes in one thread are not visible to any other. When a new
-dynamic root or thread is created, the values of parameters in the
-originating context are copied, into new locations.
+Parameter objects are implemented using fluids (@pxref{Fluids and
+Dynamic States}), so each dynamic state has it's own parameter
+locations. That includes the separate locations when outside any
+@code{parameterize} form. When a parameter is created it gets a
+separate initial location in each dynamic state, all initialized to
+the given @var{init} value.
+
+As alluded to above, because each thread usually has a separate
+dynamic state, each thread has it's own locations behind parameter
+objects, and changes in one thread are not visible to any other. When
+a new dynamic state or thread is created, the values of parameters in
+the originating context are copied, into new locations.
SRFI-39 doesn't specify the interaction between parameter objects and
threads, so the threading behaviour described here should be regarded
as Guile-specific.
+@node SRFI-55
+@subsection SRFI-55 - Requiring Features
+@cindex SRFI-55
+
+SRFI-55 provides @code{require-extension} which is a portable
+mechanism to load selected SRFI modules. This is implemented in the
+Guile core, there's no module needed to get SRFI-55 itself.
+
+@deffn {library syntax} require-extension clause@dots{}
+Require each of the given @var{clause} features, throwing an error if
+any are unavailable.
+
+A @var{clause} is of the form @code{(@var{identifier} arg...)}. The
+only @var{identifier} currently supported is @code{srfi} and the
+arguments are SRFI numbers. For example to get SRFI-1 and SRFI-6,
+
+@example
+(require-extension (srfi 1 6))
+@end example
+
+@code{require-extension} can only be used at the top-level.
+
+A Guile-specific program can simply @code{use-modules} to load SRFIs
+not already in the core, @code{require-extension} is for programs
+designed to be portable to other Scheme implementations.
+@end deffn
+
+
+@node SRFI-60
+@subsection SRFI-60 - Integers as Bits
+@cindex SRFI-60
+@cindex integers as bits
+@cindex bitwise logical
+
+This SRFI provides various functions for treating integers as bits and
+for bitwise manipulations. These functions can be obtained with,
+
+@example
+(use-modules (srfi srfi-60))
+@end example
+
+Integers are treated as infinite precision twos-complement, the same
+as in the core logical functions (@pxref{Bitwise Operations}). And
+likewise bit indexes start from 0 for the least significant bit. The
+following functions in this SRFI are already in the Guile core,
+
+@quotation
+@code{logand},
+@code{logior},
+@code{logxor},
+@code{lognot},
+@code{logtest},
+@code{logcount},
+@code{integer-length},
+@code{logbit?},
+@code{ash}
+@end quotation
+
+@sp 1
+@defun bitwise-and n1 ...
+@defunx bitwise-ior n1 ...
+@defunx bitwise-xor n1 ...
+@defunx bitwise-not n
+@defunx any-bits-set? j k
+@defunx bit-set? index n
+@defunx arithmetic-shift n count
+@defunx bit-field n start end
+@defunx bit-count n
+Aliases for @code{logand}, @code{logior}, @code{logxor},
+@code{lognot}, @code{logtest}, @code{logbit?}, @code{ash},
+@code{bit-extract} and @code{logcount} respectively.
+
+Note that the name @code{bit-count} conflicts with @code{bit-count} in
+the core (@pxref{Bit Vectors}).
+@end defun
+
+@defun bitwise-if mask n1 n0
+@defunx bitwise-merge mask n1 n0
+Return an integer with bits selected from @var{n1} and @var{n0}
+according to @var{mask}. Those bits where @var{mask} has 1s are taken
+from @var{n1}, and those where @var{mask} has 0s are taken from
+@var{n0}.
+
+@example
+(bitwise-if 3 #b0101 #b1010) @result{} 9
+@end example
+@end defun
+
+@defun log2-binary-factors n
+@defunx first-set-bit n
+Return a count of how many factors of 2 are present in @var{n}. This
+is also the bit index of the lowest 1 bit in @var{n}. If @var{n} is
+0, the return is @math{-1}.
+
+@example
+(log2-binary-factors 6) @result{} 1
+(log2-binary-factors -8) @result{} 3
+@end example
+@end defun
+
+@defun copy-bit index n newbit
+Return @var{n} with the bit at @var{index} set according to
+@var{newbit}. @var{newbit} should be @code{#t} to set the bit to 1,
+or @code{#f} to set it to 0. Bits other than at @var{index} are
+unchanged in the return.
+
+@example
+(copy-bit 1 #b0101 #t) @result{} 7
+@end example
+@end defun
+
+@defun copy-bit-field n newbits start end
+Return @var{n} with the bits from @var{start} (inclusive) to @var{end}
+(exclusive) changed to the value @var{newbits}.
+
+The least significant bit in @var{newbits} goes to @var{start}, the
+next to @math{@var{start}+1}, etc. Anything in @var{newbits} past the
+@var{end} given is ignored.
+
+@example
+(copy-bit-field #b10000 #b11 1 3) @result{} #b10110
+@end example
+@end defun
+
+@defun rotate-bit-field n count start end
+Return @var{n} with the bit field from @var{start} (inclusive) to
+@var{end} (exclusive) rotated upwards by @var{count} bits.
+
+@var{count} can be positive or negative, and it can be more than the
+field width (it'll be reduced modulo the width).
+
+@example
+(rotate-bit-field #b0110 2 1 4) @result{} #b1010
+@end example
+@end defun
+
+@defun reverse-bit-field n start end
+Return @var{n} with the bits from @var{start} (inclusive) to @var{end}
+(exclusive) reversed.
+
+@example
+(reverse-bit-field #b101001 2 4) @result{} #b100101
+@end example
+@end defun
+
+@defun integer->list n [len]
+Return bits from @var{n} in the form of a list of @code{#t} for 1 and
+@code{#f} for 0. The least significant @var{len} bits are returned,
+and the first list element is the most significant of those bits. If
+@var{len} is not given, the default is @code{(integer-length @var{n})}
+(@pxref{Bitwise Operations}).
+
+@example
+(integer->list 6) @result{} (#t #t #f)
+(integer->list 1 4) @result{} (#f #f #f #t)
+@end example
+@end defun
+
+@defun list->integer lst
+@defunx booleans->integer bool@dots{}
+Return an integer formed bitwise from the given @var{lst} list of
+booleans, or for @code{booleans->integer} from the @var{bool}
+arguments.
+
+Each boolean is @code{#t} for a 1 and @code{#f} for a 0. The first
+element becomes the most significant bit in the return.
+
+@example
+(list->integer '(#t #f #t #f)) @result{} 10
+@end example
+@end defun
+
+
+@node SRFI-61
+@subsection SRFI-61 - A more general @code{cond} clause
+
+This SRFI extends RnRS @code{cond} to support test expressions that
+return multiple values, as well as arbitrary definitions of test
+success. SRFI 61 is implemented in the Guile core; there's no module
+needed to get SRFI-61 itself. Extended @code{cond} is documented in
+@ref{if cond case,, Simple Conditional Evaluation}.
+
+
+@node SRFI-69
+@subsection SRFI-69 - Basic hash tables
+@cindex SRFI-69
+
+This is a portable wrapper around Guile's built-in hash table and weak
+table support. @xref{Hash Tables}, for information on that built-in
+support. Above that, this hash-table interface provides association
+of equality and hash functions with tables at creation time, so
+variants of each function are not required, as well as a procedure
+that takes care of most uses for Guile hash table handles, which this
+SRFI does not provide as such.
+
+Access it with:
+
+@lisp
+(use-modules (srfi srfi-69))
+@end lisp
+
+@menu
+* SRFI-69 Creating hash tables::
+* SRFI-69 Accessing table items::
+* SRFI-69 Table properties::
+* SRFI-69 Hash table algorithms::
+@end menu
+
+@node SRFI-69 Creating hash tables
+@subsubsection Creating hash tables
+
+@deffn {Scheme Procedure} make-hash-table [equal-proc hash-proc #:weak weakness start-size]
+Create and answer a new hash table with @var{equal-proc} as the
+equality function and @var{hash-proc} as the hashing function.
+
+By default, @var{equal-proc} is @code{equal?}. It can be any
+two-argument procedure, and should answer whether two keys are the
+same for this table's purposes.
+
+My default @var{hash-proc} assumes that @code{equal-proc} is no
+coarser than @code{equal?} unless it is literally @code{string-ci=?}.
+If provided, @var{hash-proc} should be a two-argument procedure that
+takes a key and the current table size, and answers a reasonably good
+hash integer between 0 (inclusive) and the size (exclusive).
+
+@var{weakness} should be @code{#f} or a symbol indicating how ``weak''
+the hash table is:
+
+@table @code
+@item #f
+An ordinary non-weak hash table. This is the default.
+
+@item key
+When the key has no more non-weak references at GC, remove that entry.
+
+@item value
+When the value has no more non-weak references at GC, remove that
+entry.
+
+@item key-or-value
+When either has no more non-weak references at GC, remove the
+association.
+@end table
+
+As a legacy of the time when Guile couldn't grow hash tables,
+@var{start-size} is an optional integer argument that specifies the
+approximate starting size for the hash table, which will be rounded to
+an algorithmically-sounder number.
+@end deffn
+
+By @dfn{coarser} than @code{equal?}, we mean that for all @var{x} and
+@var{y} values where @code{(@var{equal-proc} @var{x} @var{y})},
+@code{(equal? @var{x} @var{y})} as well. If that does not hold for
+your @var{equal-proc}, you must provide a @var{hash-proc}.
+
+In the case of weak tables, remember that @dfn{references} above
+always refers to @code{eq?}-wise references. Just because you have a
+reference to some string @code{"foo"} doesn't mean that an association
+with key @code{"foo"} in a weak-key table @emph{won't} be collected;
+it only counts as a reference if the two @code{"foo"}s are @code{eq?},
+regardless of @var{equal-proc}. As such, it is usually only sensible
+to use @code{eq?} and @code{hashq} as the equivalence and hash
+functions for a weak table. @xref{Weak References}, for more
+information on Guile's built-in weak table support.
+
+@deffn {Scheme Procedure} alist->hash-table alist [equal-proc hash-proc #:weak weakness start-size]
+As with @code{make-hash-table}, but initialize it with the
+associations in @var{alist}. Where keys are repeated in @var{alist},
+the leftmost association takes precedence.
+@end deffn
+
+@node SRFI-69 Accessing table items
+@subsubsection Accessing table items
+
+@deffn {Scheme Procedure} hash-table-ref table key [default-thunk]
+@deffnx {Scheme Procedure} hash-table-ref/default table key default
+Answer the value associated with @var{key} in @var{table}. If
+@var{key} is not present, answer the result of invoking the thunk
+@var{default-thunk}, which signals an error instead by default.
+
+@code{hash-table-ref/default} is a variant that requires a third
+argument, @var{default}, and answers @var{default} itself instead of
+invoking it.
+@end deffn
+
+@deffn {Scheme Procedure} hash-table-set! table key new-value
+Set @var{key} to @var{new-value} in @var{table}.
+@end deffn
+
+@deffn {Scheme Procedure} hash-table-delete! table key
+Remove the association of @var{key} in @var{table}, if present. If
+absent, do nothing.
+@end deffn
+
+@deffn {Scheme Procedure} hash-table-exists? table key
+Answer whether @var{key} has an association in @var{table}.
+@end deffn
+
+@deffn {Scheme Procedure} hash-table-update! table key modifier [default-thunk]
+@deffnx {Scheme Procedure} hash-table-update!/default table key modifier default
+Replace @var{key}'s associated value in @var{table} by invoking
+@var{modifier} with one argument, the old value.
+
+If @var{key} is not present, and @var{default-thunk} is provided,
+invoke it with no arguments to get the ``old value'' to be passed to
+@var{modifier} as above. If @var{default-thunk} is not provided in
+such a case, signal an error.
+
+@code{hash-table-update!/default} is a variant that requires the
+fourth argument, which is used directly as the ``old value'' rather
+than as a thunk to be invoked to retrieve the ``old value''.
+@end deffn
+
+@node SRFI-69 Table properties
+@subsubsection Table properties
+
+@deffn {Scheme Procedure} hash-table-size table
+Answer the number of associations in @var{table}. This is guaranteed
+to run in constant time for non-weak tables.
+@end deffn
+
+@deffn {Scheme Procedure} hash-table-keys table
+Answer an unordered list of the keys in @var{table}.
+@end deffn
+
+@deffn {Scheme Procedure} hash-table-values table
+Answer an unordered list of the values in @var{table}.
+@end deffn
+
+@deffn {Scheme Procedure} hash-table-walk table proc
+Invoke @var{proc} once for each association in @var{table}, passing
+the key and value as arguments.
+@end deffn
+
+@deffn {Scheme Procedure} hash-table-fold table proc init
+Invoke @code{(@var{proc} @var{key} @var{value} @var{previous})} for
+each @var{key} and @var{value} in @var{table}, where @var{previous} is
+the result of the previous invocation, using @var{init} as the first
+@var{previous} value. Answer the final @var{proc} result.
+@end deffn
+
+@deffn {Scheme Procedure} hash-table->alist table
+Answer an alist where each association in @var{table} is an
+association in the result.
+@end deffn
+
+@node SRFI-69 Hash table algorithms
+@subsubsection Hash table algorithms
+
+Each hash table carries an @dfn{equivalence function} and a @dfn{hash
+function}, used to implement key lookups. Beginning users should
+follow the rules for consistency of the default @var{hash-proc}
+specified above. Advanced users can use these to implement their own
+equivalence and hash functions for specialized lookup semantics.
+
+@deffn {Scheme Procedure} hash-table-equivalence-function hash-table
+@deffnx {Scheme Procedure} hash-table-hash-function hash-table
+Answer the equivalence and hash function of @var{hash-table}, respectively.
+@end deffn
+
+@deffn {Scheme Procedure} hash obj [size]
+@deffnx {Scheme Procedure} string-hash obj [size]
+@deffnx {Scheme Procedure} string-ci-hash obj [size]
+@deffnx {Scheme Procedure} hash-by-identity obj [size]
+Answer a hash value appropriate for equality predicate @code{equal?},
+@code{string=?}, @code{string-ci=?}, and @code{eq?}, respectively.
+@end deffn
+
+@code{hash} is a backwards-compatible replacement for Guile's built-in
+@code{hash}.
+
+@node SRFI-88
+@subsection SRFI-88 Keyword Objects
+@cindex SRFI-88
+@cindex keyword objects
+
+@uref{http://srfi.schemers.org/srfi/srfi-88.html, SRFI-88} provides
+@dfn{keyword objects}, which are equivalent to Guile's keywords
+(@pxref{Keywords}). SRFI-88 keywords can be entered using the
+@dfn{postfix keyword syntax}, which consists of an identifier followed
+by @code{:} (@pxref{Reader options, @code{postfix} keyword syntax}).
+SRFI-88 can be made available with:
+
+@example
+(use-modules (srfi srfi-88))
+@end example
+
+Doing so installs the right reader option for keyword syntax, using
+@code{(read-set! keywords 'postfix)}. It also provides the procedures
+described below.
+
+@deffn {Scheme Procedure} keyword? obj
+Return @code{#t} if @var{obj} is a keyword. This is the same procedure
+as the same-named built-in procedure (@pxref{Keyword Procedures,
+@code{keyword?}}).
+
+@example
+(keyword? foo:) @result{} #t
+(keyword? 'foo:) @result{} #t
+(keyword? "foo") @result{} #f
+@end example
+@end deffn
+
+@deffn {Scheme Procedure} keyword->string kw
+Return the name of @var{kw} as a string, i.e., without the trailing
+colon. The returned string may not be modified, e.g., with
+@code{string-set!}.
+
+@example
+(keyword->string foo:) @result{} "foo"
+@end example
+@end deffn
+
+@deffn {Scheme Procedure} string->keyword str
+Return the keyword object whose name is @var{str}.
+
+@example
+(keyword->string (string->keyword "a b c")) @result{} "a b c"
+@end example
+@end deffn
+
+
@c srfi-modules.texi ends here
@c Local Variables: