Extend the #:replace list of the SRFI 69 module
[bpt/guile.git] / doc / ref / srfi-modules.texi
index 0dda78c..238484c 100644 (file)
@@ -1,10 +1,9 @@
 @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, 2009, 2010
 @c   Free Software Foundation, Inc.
 @c See the file guile.texi for copying conditions.
 
-@page
 @node SRFI Support
 @section SRFI Support Modules
 @cindex SRFI
@@ -29,17 +28,30 @@ get the relevant SRFI documents from the SRFI home page
 * SRFI-8::                      receive.
 * SRFI-9::                      define-record-type.
 * SRFI-10::                     Hash-Comma Reader Extension.
-* SRFI-11::                     let-values and let-values*.
+* SRFI-11::                     let-values and let*-values.
 * SRFI-13::                     String library.
 * SRFI-14::                     Character-set library.
 * SRFI-16::                     case-lambda
 * SRFI-17::                     Generalized set!
+* SRFI-18::                     Multithreading support
 * SRFI-19::                     Time/Date library.
 * SRFI-26::                     Specializing parameters
+* SRFI-27::                     Sources of Random Bits
+* SRFI-30::                     Nested multi-line block comments
 * 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-42::                     Eager comprehensions
+* SRFI-45::                     Primitives for expressing iterative lazy algorithms
 * SRFI-55::                     Requiring Features.
 * SRFI-60::                     Integers as bits.
+* SRFI-61::                     A more general `cond' clause
+* SRFI-67::                     Compare procedures
+* SRFI-69::                     Basic hash tables.
+* SRFI-88::                     Keyword objects.
+* SRFI-98::                     Accessing environment variables.
 @end menu
 
 
@@ -126,6 +138,7 @@ The Guile core has the following features,
 
 @example
 guile
+guile-2  ;; starting from Guile 2.x
 r5rs
 srfi-0
 srfi-4
@@ -153,6 +166,23 @@ how to load it with the Guile mechanism.
               (use-modules (srfi srfi-8))))
 @end example
 
+@cindex @code{guile-2} SRFI-0 feature
+@cindex portability between 2.0 and older versions
+Likewise, testing the @code{guile-2} feature allows code to be portable
+between Guile 2.0 and previous versions of Guile.  For instance, it
+makes it possible to write code that accounts for Guile 2.0's compiler,
+yet be correctly interpreted on 1.8 and earlier versions:
+
+@example
+(cond-expand (guile-2 (eval-when (compile)
+                        ;; This must be evaluated at compile time.
+                        (fluid-set! current-reader my-reader)))
+             (guile
+                      ;; Earlier versions of Guile do not have a
+                      ;; separate compilation phase.
+                      (fluid-set! current-reader my-reader)))
+@end example
+
 It should be noted that @code{cond-expand} is separate from the
 @code{*features*} mechanism (@pxref{Feature Tracking}), feature
 symbols in one are unrelated to those in the other.
@@ -413,9 +443,13 @@ have a limit on the number of arguments a function takes, which the
 
 @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.
@@ -936,12 +970,21 @@ Lists}.  The present section only documents the additional procedures
 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.
 
-This function extends the core @code{assoc} by accepting an equality
-predicate.  (@pxref{Association Lists})
+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,
+
+@example
+(assoc "yy" '(("XX" . 1) ("YY" . 2)) string-ci=?)
+@result{} ("YY" . 2)
+@end example
 @end deffn
 
 @deffn {Scheme Procedure} alist-cons key datum alist
@@ -1253,8 +1296,539 @@ from separate @code{and} and @code{let*}, or from @code{cond} with
 @subsection SRFI-4 - Homogeneous numeric vector datatypes
 @cindex SRFI-4
 
-The SRFI-4 procedures and data types are always available, @xref{Uniform
-Numeric Vectors}.
+SRFI-4 provides an interface to uniform numeric vectors: vectors whose elements
+are all of a single numeric type. Guile offers uniform numeric vectors for
+signed and unsigned 8-bit, 16-bit, 32-bit, and 64-bit integers, two sizes of
+floating point values, and, as an extension to SRFI-4, complex floating-point
+numbers of these two sizes.
+
+The standard SRFI-4 procedures and data types may be included via loading the
+appropriate module:
+
+@example
+(use-modules (srfi srfi-4))
+@end example
+
+This module is currently a part of the default Guile environment, but it is a
+good practice to explicitly import the module. In the future, using SRFI-4
+procedures without importing the SRFI-4 module will cause a deprecation message
+to be printed. (Of course, one may call the C functions at any time. Would that
+C had modules!)
+
+@menu
+* SRFI-4 Overview::             The warp and weft of uniform numeric vectors.
+* SRFI-4 API::                  Uniform vectors, from Scheme and from C.
+* SRFI-4 Generic Operations::   The general, operating on the specific.
+* SRFI-4 and Bytevectors::      SRFI-4 vectors are backed by bytevectors.
+* SRFI-4 Extensions::           Guile-specific extensions to the standard.
+@end menu
+
+@node SRFI-4 Overview
+@subsubsection SRFI-4 - Overview
+
+Uniform numeric vectors can be useful since they consume less memory
+than the non-uniform, general vectors.  Also, since the types they can
+store correspond directly to C types, it is easier to work with them
+efficiently on a low level.  Consider image processing as an example,
+where you want to apply a filter to some image.  While you could store
+the pixels of an image in a general vector and write a general
+convolution function, things are much more efficient with uniform
+vectors: the convolution function knows that all pixels are unsigned
+8-bit values (say), and can use a very tight inner loop.
+
+This is implemented in Scheme by having the compiler notice calls to the SRFI-4
+accessors, and inline them to appropriate compiled code. From C you have access
+to the raw array; functions for efficiently working with uniform numeric vectors
+from C are listed at the end of this section.
+
+Uniform numeric vectors are the special case of one dimensional uniform
+numeric arrays.
+
+There are 12 standard kinds of uniform numeric vectors, and they all have their
+own complement of constructors, accessors, and so on. Procedures that operate on
+a specific kind of uniform numeric vector have a ``tag'' in their name,
+indicating the element type.
+
+@table @nicode
+@item u8
+unsigned 8-bit integers
+
+@item s8
+signed 8-bit integers
+
+@item u16
+unsigned 16-bit integers
+
+@item s16
+signed 16-bit integers
+
+@item u32
+unsigned 32-bit integers
+
+@item s32
+signed 32-bit integers
+
+@item u64
+unsigned 64-bit integers
+
+@item s64
+signed 64-bit integers
+
+@item f32
+the C type @code{float}
+
+@item f64
+the C type @code{double}
+
+@end table
+
+In addition, Guile supports uniform arrays of complex numbers, with the
+nonstandard tags:
+
+@table @nicode
+
+@item c32
+complex numbers in rectangular form with the real and imaginary part
+being a @code{float}
+
+@item c64
+complex numbers in rectangular form with the real and imaginary part
+being a @code{double}
+
+@end table
+
+The external representation (ie.@: read syntax) for these vectors is
+similar to normal Scheme vectors, but with an additional tag from the
+tables above indicating the vector's type.  For example,
+
+@lisp
+#u16(1 2 3)
+#f64(3.1415 2.71)
+@end lisp
+
+Note that the read syntax for floating-point here conflicts with
+@code{#f} for false.  In Standard Scheme one can write @code{(1 #f3)}
+for a three element list @code{(1 #f 3)}, but for Guile @code{(1 #f3)}
+is invalid.  @code{(1 #f 3)} is almost certainly what one should write
+anyway to make the intention clear, so this is rarely a problem.
+
+
+@node SRFI-4 API
+@subsubsection SRFI-4 - API
+
+Note that the @nicode{c32} and @nicode{c64} functions are only available from
+@nicode{(srfi srfi-4 gnu)}.
+
+@deffn {Scheme Procedure} u8vector? obj
+@deffnx {Scheme Procedure} s8vector? obj
+@deffnx {Scheme Procedure} u16vector? obj
+@deffnx {Scheme Procedure} s16vector? obj
+@deffnx {Scheme Procedure} u32vector? obj
+@deffnx {Scheme Procedure} s32vector? obj
+@deffnx {Scheme Procedure} u64vector? obj
+@deffnx {Scheme Procedure} s64vector? obj
+@deffnx {Scheme Procedure} f32vector? obj
+@deffnx {Scheme Procedure} f64vector? obj
+@deffnx {Scheme Procedure} c32vector? obj
+@deffnx {Scheme Procedure} c64vector? obj
+@deffnx {C Function} scm_u8vector_p (obj)
+@deffnx {C Function} scm_s8vector_p (obj)
+@deffnx {C Function} scm_u16vector_p (obj)
+@deffnx {C Function} scm_s16vector_p (obj)
+@deffnx {C Function} scm_u32vector_p (obj)
+@deffnx {C Function} scm_s32vector_p (obj)
+@deffnx {C Function} scm_u64vector_p (obj)
+@deffnx {C Function} scm_s64vector_p (obj)
+@deffnx {C Function} scm_f32vector_p (obj)
+@deffnx {C Function} scm_f64vector_p (obj)
+@deffnx {C Function} scm_c32vector_p (obj)
+@deffnx {C Function} scm_c64vector_p (obj)
+Return @code{#t} if @var{obj} is a homogeneous numeric vector of the
+indicated type.
+@end deffn
+
+@deffn  {Scheme Procedure} make-u8vector n [value]
+@deffnx {Scheme Procedure} make-s8vector n [value]
+@deffnx {Scheme Procedure} make-u16vector n [value]
+@deffnx {Scheme Procedure} make-s16vector n [value]
+@deffnx {Scheme Procedure} make-u32vector n [value]
+@deffnx {Scheme Procedure} make-s32vector n [value]
+@deffnx {Scheme Procedure} make-u64vector n [value]
+@deffnx {Scheme Procedure} make-s64vector n [value]
+@deffnx {Scheme Procedure} make-f32vector n [value]
+@deffnx {Scheme Procedure} make-f64vector n [value]
+@deffnx {Scheme Procedure} make-c32vector n [value]
+@deffnx {Scheme Procedure} make-c64vector n [value]
+@deffnx {C Function} scm_make_u8vector n [value]
+@deffnx {C Function} scm_make_s8vector n [value]
+@deffnx {C Function} scm_make_u16vector n [value]
+@deffnx {C Function} scm_make_s16vector n [value]
+@deffnx {C Function} scm_make_u32vector n [value]
+@deffnx {C Function} scm_make_s32vector n [value]
+@deffnx {C Function} scm_make_u64vector n [value]
+@deffnx {C Function} scm_make_s64vector n [value]
+@deffnx {C Function} scm_make_f32vector n [value]
+@deffnx {C Function} scm_make_f64vector n [value]
+@deffnx {C Function} scm_make_c32vector n [value]
+@deffnx {C Function} scm_make_c64vector n [value]
+Return a newly allocated homogeneous numeric vector holding @var{n}
+elements of the indicated type.  If @var{value} is given, the vector
+is initialized with that value, otherwise the contents are
+unspecified.
+@end deffn
+
+@deffn  {Scheme Procedure} u8vector value @dots{}
+@deffnx {Scheme Procedure} s8vector value @dots{}
+@deffnx {Scheme Procedure} u16vector value @dots{}
+@deffnx {Scheme Procedure} s16vector value @dots{}
+@deffnx {Scheme Procedure} u32vector value @dots{}
+@deffnx {Scheme Procedure} s32vector value @dots{}
+@deffnx {Scheme Procedure} u64vector value @dots{}
+@deffnx {Scheme Procedure} s64vector value @dots{}
+@deffnx {Scheme Procedure} f32vector value @dots{}
+@deffnx {Scheme Procedure} f64vector value @dots{}
+@deffnx {Scheme Procedure} c32vector value @dots{}
+@deffnx {Scheme Procedure} c64vector value @dots{}
+@deffnx {C Function} scm_u8vector (values)
+@deffnx {C Function} scm_s8vector (values)
+@deffnx {C Function} scm_u16vector (values)
+@deffnx {C Function} scm_s16vector (values)
+@deffnx {C Function} scm_u32vector (values)
+@deffnx {C Function} scm_s32vector (values)
+@deffnx {C Function} scm_u64vector (values)
+@deffnx {C Function} scm_s64vector (values)
+@deffnx {C Function} scm_f32vector (values)
+@deffnx {C Function} scm_f64vector (values)
+@deffnx {C Function} scm_c32vector (values)
+@deffnx {C Function} scm_c64vector (values)
+Return a newly allocated homogeneous numeric vector of the indicated
+type, holding the given parameter @var{value}s.  The vector length is
+the number of parameters given.
+@end deffn
+
+@deffn {Scheme Procedure} u8vector-length vec
+@deffnx {Scheme Procedure} s8vector-length vec
+@deffnx {Scheme Procedure} u16vector-length vec
+@deffnx {Scheme Procedure} s16vector-length vec
+@deffnx {Scheme Procedure} u32vector-length vec
+@deffnx {Scheme Procedure} s32vector-length vec
+@deffnx {Scheme Procedure} u64vector-length vec
+@deffnx {Scheme Procedure} s64vector-length vec
+@deffnx {Scheme Procedure} f32vector-length vec
+@deffnx {Scheme Procedure} f64vector-length vec
+@deffnx {Scheme Procedure} c32vector-length vec
+@deffnx {Scheme Procedure} c64vector-length vec
+@deffnx {C Function} scm_u8vector_length (vec)
+@deffnx {C Function} scm_s8vector_length (vec)
+@deffnx {C Function} scm_u16vector_length (vec)
+@deffnx {C Function} scm_s16vector_length (vec)
+@deffnx {C Function} scm_u32vector_length (vec)
+@deffnx {C Function} scm_s32vector_length (vec)
+@deffnx {C Function} scm_u64vector_length (vec)
+@deffnx {C Function} scm_s64vector_length (vec)
+@deffnx {C Function} scm_f32vector_length (vec)
+@deffnx {C Function} scm_f64vector_length (vec)
+@deffnx {C Function} scm_c32vector_length (vec)
+@deffnx {C Function} scm_c64vector_length (vec)
+Return the number of elements in @var{vec}.
+@end deffn
+
+@deffn {Scheme Procedure} u8vector-ref vec i
+@deffnx {Scheme Procedure} s8vector-ref vec i
+@deffnx {Scheme Procedure} u16vector-ref vec i
+@deffnx {Scheme Procedure} s16vector-ref vec i
+@deffnx {Scheme Procedure} u32vector-ref vec i
+@deffnx {Scheme Procedure} s32vector-ref vec i
+@deffnx {Scheme Procedure} u64vector-ref vec i
+@deffnx {Scheme Procedure} s64vector-ref vec i
+@deffnx {Scheme Procedure} f32vector-ref vec i
+@deffnx {Scheme Procedure} f64vector-ref vec i
+@deffnx {Scheme Procedure} c32vector-ref vec i
+@deffnx {Scheme Procedure} c64vector-ref vec i
+@deffnx {C Function} scm_u8vector_ref (vec i)
+@deffnx {C Function} scm_s8vector_ref (vec i)
+@deffnx {C Function} scm_u16vector_ref (vec i)
+@deffnx {C Function} scm_s16vector_ref (vec i)
+@deffnx {C Function} scm_u32vector_ref (vec i)
+@deffnx {C Function} scm_s32vector_ref (vec i)
+@deffnx {C Function} scm_u64vector_ref (vec i)
+@deffnx {C Function} scm_s64vector_ref (vec i)
+@deffnx {C Function} scm_f32vector_ref (vec i)
+@deffnx {C Function} scm_f64vector_ref (vec i)
+@deffnx {C Function} scm_c32vector_ref (vec i)
+@deffnx {C Function} scm_c64vector_ref (vec i)
+Return the element at index @var{i} in @var{vec}.  The first element
+in @var{vec} is index 0.
+@end deffn
+
+@deffn {Scheme Procedure} u8vector-set! vec i value
+@deffnx {Scheme Procedure} s8vector-set! vec i value
+@deffnx {Scheme Procedure} u16vector-set! vec i value
+@deffnx {Scheme Procedure} s16vector-set! vec i value
+@deffnx {Scheme Procedure} u32vector-set! vec i value
+@deffnx {Scheme Procedure} s32vector-set! vec i value
+@deffnx {Scheme Procedure} u64vector-set! vec i value
+@deffnx {Scheme Procedure} s64vector-set! vec i value
+@deffnx {Scheme Procedure} f32vector-set! vec i value
+@deffnx {Scheme Procedure} f64vector-set! vec i value
+@deffnx {Scheme Procedure} c32vector-set! vec i value
+@deffnx {Scheme Procedure} c64vector-set! vec i value
+@deffnx {C Function} scm_u8vector_set_x (vec i value)
+@deffnx {C Function} scm_s8vector_set_x (vec i value)
+@deffnx {C Function} scm_u16vector_set_x (vec i value)
+@deffnx {C Function} scm_s16vector_set_x (vec i value)
+@deffnx {C Function} scm_u32vector_set_x (vec i value)
+@deffnx {C Function} scm_s32vector_set_x (vec i value)
+@deffnx {C Function} scm_u64vector_set_x (vec i value)
+@deffnx {C Function} scm_s64vector_set_x (vec i value)
+@deffnx {C Function} scm_f32vector_set_x (vec i value)
+@deffnx {C Function} scm_f64vector_set_x (vec i value)
+@deffnx {C Function} scm_c32vector_set_x (vec i value)
+@deffnx {C Function} scm_c64vector_set_x (vec i value)
+Set the element at index @var{i} in @var{vec} to @var{value}.  The
+first element in @var{vec} is index 0.  The return value is
+unspecified.
+@end deffn
+
+@deffn {Scheme Procedure} u8vector->list vec
+@deffnx {Scheme Procedure} s8vector->list vec
+@deffnx {Scheme Procedure} u16vector->list vec
+@deffnx {Scheme Procedure} s16vector->list vec
+@deffnx {Scheme Procedure} u32vector->list vec
+@deffnx {Scheme Procedure} s32vector->list vec
+@deffnx {Scheme Procedure} u64vector->list vec
+@deffnx {Scheme Procedure} s64vector->list vec
+@deffnx {Scheme Procedure} f32vector->list vec
+@deffnx {Scheme Procedure} f64vector->list vec
+@deffnx {Scheme Procedure} c32vector->list vec
+@deffnx {Scheme Procedure} c64vector->list vec
+@deffnx {C Function} scm_u8vector_to_list (vec)
+@deffnx {C Function} scm_s8vector_to_list (vec)
+@deffnx {C Function} scm_u16vector_to_list (vec)
+@deffnx {C Function} scm_s16vector_to_list (vec)
+@deffnx {C Function} scm_u32vector_to_list (vec)
+@deffnx {C Function} scm_s32vector_to_list (vec)
+@deffnx {C Function} scm_u64vector_to_list (vec)
+@deffnx {C Function} scm_s64vector_to_list (vec)
+@deffnx {C Function} scm_f32vector_to_list (vec)
+@deffnx {C Function} scm_f64vector_to_list (vec)
+@deffnx {C Function} scm_c32vector_to_list (vec)
+@deffnx {C Function} scm_c64vector_to_list (vec)
+Return a newly allocated list holding all elements of @var{vec}.
+@end deffn
+
+@deffn  {Scheme Procedure} list->u8vector lst
+@deffnx {Scheme Procedure} list->s8vector lst
+@deffnx {Scheme Procedure} list->u16vector lst
+@deffnx {Scheme Procedure} list->s16vector lst
+@deffnx {Scheme Procedure} list->u32vector lst
+@deffnx {Scheme Procedure} list->s32vector lst
+@deffnx {Scheme Procedure} list->u64vector lst
+@deffnx {Scheme Procedure} list->s64vector lst
+@deffnx {Scheme Procedure} list->f32vector lst
+@deffnx {Scheme Procedure} list->f64vector lst
+@deffnx {Scheme Procedure} list->c32vector lst
+@deffnx {Scheme Procedure} list->c64vector lst
+@deffnx {C Function} scm_list_to_u8vector (lst)
+@deffnx {C Function} scm_list_to_s8vector (lst)
+@deffnx {C Function} scm_list_to_u16vector (lst)
+@deffnx {C Function} scm_list_to_s16vector (lst)
+@deffnx {C Function} scm_list_to_u32vector (lst)
+@deffnx {C Function} scm_list_to_s32vector (lst)
+@deffnx {C Function} scm_list_to_u64vector (lst)
+@deffnx {C Function} scm_list_to_s64vector (lst)
+@deffnx {C Function} scm_list_to_f32vector (lst)
+@deffnx {C Function} scm_list_to_f64vector (lst)
+@deffnx {C Function} scm_list_to_c32vector (lst)
+@deffnx {C Function} scm_list_to_c64vector (lst)
+Return a newly allocated homogeneous numeric vector of the indicated type,
+initialized with the elements of the list @var{lst}.
+@end deffn
+
+@deftypefn  {C Function} SCM scm_take_u8vector (const scm_t_uint8 *data, size_t len)
+@deftypefnx {C Function} SCM scm_take_s8vector (const scm_t_int8 *data, size_t len)
+@deftypefnx {C Function} SCM scm_take_u16vector (const scm_t_uint16 *data, size_t len)
+@deftypefnx {C Function} SCM scm_take_s16vector (const scm_t_int16 *data, size_t len)
+@deftypefnx {C Function} SCM scm_take_u32vector (const scm_t_uint32 *data, size_t len)
+@deftypefnx {C Function} SCM scm_take_s32vector (const scm_t_int32 *data, size_t len)
+@deftypefnx {C Function} SCM scm_take_u64vector (const scm_t_uint64 *data, size_t len)
+@deftypefnx {C Function} SCM scm_take_s64vector (const scm_t_int64 *data, size_t len)
+@deftypefnx {C Function} SCM scm_take_f32vector (const float *data, size_t len)
+@deftypefnx {C Function} SCM scm_take_f64vector (const double *data, size_t len)
+@deftypefnx {C Function} SCM scm_take_c32vector (const float *data, size_t len)
+@deftypefnx {C Function} SCM scm_take_c64vector (const double *data, size_t len)
+Return a new uniform numeric vector of the indicated type and length
+that uses the memory pointed to by @var{data} to store its elements.
+This memory will eventually be freed with @code{free}.  The argument
+@var{len} specifies the number of elements in @var{data}, not its size
+in bytes.
+
+The @code{c32} and @code{c64} variants take a pointer to a C array of
+@code{float}s or @code{double}s.  The real parts of the complex numbers
+are at even indices in that array, the corresponding imaginary parts are
+at the following odd index.
+@end deftypefn
+
+@deftypefn {C Function} {const scm_t_uint8 *} scm_u8vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {const scm_t_int8 *} scm_s8vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {const scm_t_uint16 *} scm_u16vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {const scm_t_int16 *} scm_s16vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {const scm_t_uint32 *} scm_u32vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {const scm_t_int32 *} scm_s32vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {const scm_t_uint64 *} scm_u64vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {const scm_t_int64 *} scm_s64vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {const float *} scm_f23vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {const double *} scm_f64vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {const float *} scm_c32vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {const double *} scm_c64vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+Like @code{scm_vector_elements} (@pxref{Vector Accessing from C}), but
+returns a pointer to the elements of a uniform numeric vector of the
+indicated kind.
+@end deftypefn
+
+@deftypefn {C Function} {scm_t_uint8 *} scm_u8vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {scm_t_int8 *} scm_s8vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {scm_t_uint16 *} scm_u16vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {scm_t_int16 *} scm_s16vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {scm_t_uint32 *} scm_u32vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {scm_t_int32 *} scm_s32vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {scm_t_uint64 *} scm_u64vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {scm_t_int64 *} scm_s64vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {float *} scm_f23vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {double *} scm_f64vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {float *} scm_c32vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+@deftypefnx {C Function} {double *} scm_c64vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+Like @code{scm_vector_writable_elements} (@pxref{Vector Accessing from
+C}), but returns a pointer to the elements of a uniform numeric vector
+of the indicated kind.
+@end deftypefn
+
+@node SRFI-4 Generic Operations
+@subsubsection SRFI-4 - Generic operations
+
+Guile also provides procedures that operate on all types of uniform numeric
+vectors.  In what is probably a bug, these procedures are currently available in
+the default environment as well; however prudent hackers will make sure to
+import @code{(srfi srfi-4 gnu)} before using these.
+
+@deftypefn {C Function} int scm_is_uniform_vector (SCM uvec)
+Return non-zero when @var{uvec} is a uniform numeric vector, zero
+otherwise.
+@end deftypefn
+
+@deftypefn {C Function} size_t scm_c_uniform_vector_length (SCM uvec)
+Return the number of elements of @var{uvec} as a @code{size_t}.
+@end deftypefn
+
+@deffn  {Scheme Procedure} uniform-vector? obj
+@deffnx {C Function} scm_uniform_vector_p (obj)
+Return @code{#t} if @var{obj} is a homogeneous numeric vector of the
+indicated type.
+@end deffn
+
+@deffn  {Scheme Procedure} uniform-vector-length vec
+@deffnx {C Function} scm_uniform_vector_length (vec)
+Return the number of elements in @var{vec}.
+@end deffn
+
+@deffn  {Scheme Procedure} uniform-vector-ref vec i
+@deffnx {C Function} scm_uniform_vector_ref (vec i)
+Return the element at index @var{i} in @var{vec}.  The first element
+in @var{vec} is index 0.
+@end deffn
+
+@deffn  {Scheme Procedure} uniform-vector-set! vec i value
+@deffnx {C Function} scm_uniform_vector_set_x (vec i value)
+Set the element at index @var{i} in @var{vec} to @var{value}.  The
+first element in @var{vec} is index 0.  The return value is
+unspecified.
+@end deffn
+
+@deffn  {Scheme Procedure} uniform-vector->list vec
+@deffnx {C Function} scm_uniform_vector_to_list (vec)
+Return a newly allocated list holding all elements of @var{vec}.
+@end deffn
+
+@deftypefn  {C Function} {const void *} scm_uniform_vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+Like @code{scm_vector_elements} (@pxref{Vector Accessing from C}), but
+returns a pointer to the elements of a uniform numeric vector.
+@end deftypefn
+
+@deftypefn  {C Function} {void *} scm_uniform_vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
+Like @code{scm_vector_writable_elements} (@pxref{Vector Accessing from
+C}), but returns a pointer to the elements of a uniform numeric vector.
+@end deftypefn
+
+Unless you really need to the limited generality of these functions, it is best
+to use the type-specific functions, or the generalized vector accessors.
+
+@node SRFI-4 and Bytevectors
+@subsubsection SRFI-4 - Relation to bytevectors
+
+Guile implements SRFI-4 vectors using bytevectors (@pxref{Bytevectors}). Often
+when you have a numeric vector, you end up wanting to write its bytes somewhere,
+or have access to the underlying bytes, or read in bytes from somewhere else.
+Bytevectors are very good at this sort of thing. But the SRFI-4 APIs are nicer
+to use when doing number-crunching, because they are addressed by element and
+not by byte.
+
+So as a compromise, Guile allows all bytevector functions to operate on numeric
+vectors. They address the underlying bytes in the native endianness, as one
+would expect.
+
+Following the same reasoning, that it's just bytes underneath, Guile also allows
+uniform vectors of a given type to be accessed as if they were of any type. One
+can fill a @nicode{u32vector}, and access its elements with
+@nicode{u8vector-ref}. One can use @nicode{f64vector-ref} on bytevectors. It's
+all the same to Guile.
+
+In this way, uniform numeric vectors may be written to and read from
+input/output ports using the procedures that operate on bytevectors.
+
+@xref{Bytevectors}, for more information.
+
+
+@node SRFI-4 Extensions
+@subsubsection SRFI-4 - Guile extensions
+
+Guile defines some useful extensions to SRFI-4, which are not available in the
+default Guile environment. They may be imported by loading the extensions
+module:
+
+@example
+(use-modules (srfi srfi-4 gnu))
+@end example
+
+@deffn  {Scheme Procedure} any->u8vector obj
+@deffnx {Scheme Procedure} any->s8vector obj
+@deffnx {Scheme Procedure} any->u16vector obj
+@deffnx {Scheme Procedure} any->s16vector obj
+@deffnx {Scheme Procedure} any->u32vector obj
+@deffnx {Scheme Procedure} any->s32vector obj
+@deffnx {Scheme Procedure} any->u64vector obj
+@deffnx {Scheme Procedure} any->s64vector obj
+@deffnx {Scheme Procedure} any->f32vector obj
+@deffnx {Scheme Procedure} any->f64vector obj
+@deffnx {Scheme Procedure} any->c32vector obj
+@deffnx {Scheme Procedure} any->c64vector obj
+@deffnx {C Function} scm_any_to_u8vector (obj)
+@deffnx {C Function} scm_any_to_s8vector (obj)
+@deffnx {C Function} scm_any_to_u16vector (obj)
+@deffnx {C Function} scm_any_to_s16vector (obj)
+@deffnx {C Function} scm_any_to_u32vector (obj)
+@deffnx {C Function} scm_any_to_s32vector (obj)
+@deffnx {C Function} scm_any_to_u64vector (obj)
+@deffnx {C Function} scm_any_to_s64vector (obj)
+@deffnx {C Function} scm_any_to_f32vector (obj)
+@deffnx {C Function} scm_any_to_f64vector (obj)
+@deffnx {C Function} scm_any_to_c32vector (obj)
+@deffnx {C Function} scm_any_to_c64vector (obj)
+Return a (maybe newly allocated) uniform numeric vector of the indicated
+type, initialized with the elements of @var{obj}, which must be a list,
+a vector, or a uniform vector.  When @var{obj} is already a suitable
+uniform numeric vector, it is returned unchanged.
+@end deffn
+
 
 @node SRFI-6
 @subsection SRFI-6 - Basic String Ports
@@ -1352,6 +1926,28 @@ 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.
 
+@unnumberedsubsubsec 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.
+
+@deffn {Scheme Syntax} set-record-type-printer! name thunk
+Where @var{type} corresponds to the first argument of @code{define-record-type},
+and @var{thunk} is a procedure accepting two arguments, the record to print, and
+an output port.
+@end deffn
+
+@noindent
+This example prints the employee's name in brackets, for instance @code{[Fred]}.
+
+@example
+(set-record-type-printer! employee-type
+  (lambda (record port)
+    (write-char #\[ port)
+    (display (get-employee-name record) port)
+    (write-char #\] port)))
+@end example
 
 @node SRFI-10
 @subsection SRFI-10 - Hash-Comma Reader Extension
@@ -1430,8 +2026,8 @@ lookup.
   (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)
@@ -1494,9 +2090,9 @@ the anonymous and compact syntax of @nicode{#,()} is much better.
 @cindex SRFI-11
 
 @findex let-values
-@findex let-values*
+@findex let*-values
 This module implements the binding forms for multiple values
-@code{let-values} and @code{let-values*}.  These forms are similar to
+@code{let-values} and @code{let*-values}.  These forms are similar to
 @code{let} and @code{let*} (@pxref{Local Bindings}), but they support
 binding of the values returned by multiple-valued expressions.
 
@@ -1513,7 +2109,7 @@ available.
 
 @code{let-values} performs all bindings simultaneously, which means that
 no expression in the binding clauses may refer to variables bound in the
-same clause list.  @code{let-values*}, on the other hand, performs the
+same clause list.  @code{let*-values}, on the other hand, performs the
 bindings sequentially, just like @code{let*} does for single-valued
 expressions.
 
@@ -1537,89 +2133,407 @@ The SRFI-14 data type and procedures are always available,
 @cindex variable arity
 @cindex arity, variable
 
-@c FIXME::martin: Review me!
+SRFI-16 defines a variable-arity @code{lambda} form,
+@code{case-lambda}. This form is available in the default Guile
+environment. @xref{Case-lambda}, for more information.
 
-@findex case-lambda
-The syntactic form @code{case-lambda} creates procedures, just like
-@code{lambda}, but has syntactic extensions for writing procedures of
-varying arity easier.
+@node SRFI-17
+@subsection SRFI-17 - Generalized set!
+@cindex SRFI-17
 
-The syntax of the @code{case-lambda} form is defined in the following
-EBNF grammar.
+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
-@group
-<case-lambda>
-   --> (case-lambda <case-lambda-clause>)
-<case-lambda-clause>
-   --> (<formals> <definition-or-command>*)
-<formals>
-   --> (<identifier>*)
-     | (<identifier>* . <identifier>)
-     | <identifier>
-@end group
+(use-modules (srfi srfi-17))
 @end example
 
-The value returned by a @code{case-lambda} form is a procedure which
-matches the number of actual arguments against the formals in the
-various clauses, in order.  @dfn{Formals} means a formal argument list
-just like with @code{lambda} (@pxref{Lambda}). The first matching clause
-is selected, the corresponding values from the actual parameter list are
-bound to the variable names in the clauses and the body of the clause is
-evaluated.  If no clause matches, an error is signalled.
+@noindent
+For example @code{vector-ref} is extended so that
 
-The following (silly) definition creates a procedure @var{foo} which
-acts differently, depending on the number of actual arguments.  If one
-argument is given, the constant @code{#t} is returned, two arguments are
-added and if more arguments are passed, their product is calculated.
+@example
+(set! (vector-ref vec idx) new-value)
+@end example
 
-@lisp
-(define foo (case-lambda
-              ((x) #t)
-              ((x y) (+ x y))
-              (z
-                (apply * z))))
-(foo 'bar)
-@result{}
-#t
-(foo 2 4)
-@result{}
-6
-(foo 3 3 3)
-@result{}
-27
-(foo)
-@result{}
-1
-@end lisp
+@noindent
+is equivalent to
 
-The last expression evaluates to 1 because the last clause is matched,
-@var{z} is bound to the empty list and the following multiplication,
-applied to zero arguments, yields 1.
+@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.
 
-@node SRFI-17
-@subsection SRFI-17 - Generalized set!
-@cindex SRFI-17
+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-18
+@subsection SRFI-18 - Multithreading support
+@cindex SRFI-18
+
+This is an implementation of the SRFI-18 threading and synchronization
+library.  The functions and variables described here are provided by
+
+@example
+(use-modules (srfi srfi-18))
+@end example
+
+As a general rule, the data types and functions in this SRFI-18
+implementation are compatible with the types and functions in Guile's
+core threading code.  For example, mutexes created with the SRFI-18 
+@code{make-mutex} function can be passed to the built-in Guile 
+function @code{lock-mutex} (@pxref{Mutexes and Condition Variables}),
+and mutexes created with the built-in Guile function @code{make-mutex}
+can be passed to the SRFI-18 function @code{mutex-lock!}.  Cases in
+which this does not hold true are noted in the following sections.
+
+@menu
+* SRFI-18 Threads::             Executing code 
+* SRFI-18 Mutexes::             Mutual exclusion devices
+* SRFI-18 Condition variables:: Synchronizing of groups of threads
+* SRFI-18 Time::                Representation of times and durations
+* SRFI-18 Exceptions::          Signalling and handling errors
+@end menu
+
+@node SRFI-18 Threads
+@subsubsection SRFI-18 Threads
+
+Threads created by SRFI-18 differ in two ways from threads created by 
+Guile's built-in thread functions.  First, a thread created by SRFI-18
+@code{make-thread} begins in a blocked state and will not start 
+execution until @code{thread-start!} is called on it.  Second, SRFI-18
+threads are constructed with a top-level exception handler that 
+captures any exceptions that are thrown on thread exit.  In all other
+regards, SRFI-18 threads are identical to normal Guile threads.
+
+@defun current-thread
+Returns the thread that called this function.  This is the same
+procedure as the same-named built-in procedure @code{current-thread}
+(@pxref{Threads}).
+@end defun
+
+@defun thread? obj
+Returns @code{#t} if @var{obj} is a thread, @code{#f} otherwise.  This
+is the same procedure as the same-named built-in procedure 
+@code{thread?} (@pxref{Threads}).
+@end defun
+
+@defun make-thread thunk [name]
+Call @code{thunk} in a new thread and with a new dynamic state,
+returning the new thread and optionally assigning it the object name
+@var{name}, which may be any Scheme object.
+
+Note that the name @code{make-thread} conflicts with the 
+@code{(ice-9 threads)} function @code{make-thread}.  Applications 
+wanting to use both of these functions will need to refer to them by 
+different names.
+@end defun
+
+@defun thread-name thread
+Returns the name assigned to @var{thread} at the time of its creation,
+or @code{#f} if it was not given a name.
+@end defun
+
+@defun thread-specific thread
+@defunx thread-specific-set! thread obj
+Get or set the ``object-specific'' property of @var{thread}.  In
+Guile's implementation of SRFI-18, this value is stored as an object
+property, and will be @code{#f} if not set.
+@end defun
+
+@defun thread-start! thread
+Unblocks @var{thread} and allows it to begin execution if it has not
+done so already.
+@end defun
+
+@defun thread-yield!
+If one or more threads are waiting to execute, calling 
+@code{thread-yield!} forces an immediate context switch to one of them.
+Otherwise, @code{thread-yield!} has no effect.  @code{thread-yield!} 
+behaves identically to the Guile built-in function @code{yield}.
+@end defun
+
+@defun thread-sleep! timeout
+The current thread waits until the point specified by the time object
+@var{timeout} is reached (@pxref{SRFI-18 Time}).  This blocks the 
+thread only if @var{timeout} represents a point in the future.  it is 
+an error for @var{timeout} to be @code{#f}.
+@end defun
+
+@defun thread-terminate! thread
+Causes an abnormal termination of @var{thread}.  If @var{thread} is
+not already terminated, all mutexes owned by @var{thread} become
+unlocked/abandoned.  If @var{thread} is the current thread, 
+@code{thread-terminate!} does not return.  Otherwise 
+@code{thread-terminate!} returns an unspecified value; the termination
+of @var{thread} will occur before @code{thread-terminate!} returns.  
+Subsequent attempts to join on @var{thread} will cause a ``terminated 
+thread exception'' to be raised.
+
+@code{thread-terminate!} is compatible with the thread cancellation
+procedures in the core threads API (@pxref{Threads}) in that if a 
+cleanup handler has been installed for the target thread, it will be 
+called before the thread exits and its return value (or exception, if
+any) will be stored for later retrieval via a call to 
+@code{thread-join!}.
+@end defun
+
+@defun thread-join! thread [timeout [timeout-val]]
+Wait for @var{thread} to terminate and return its exit value.  When a 
+time value @var{timeout} is given, it specifies a point in time where
+the waiting should be aborted.  When the waiting is aborted, 
+@var{timeoutval} is returned if it is specified; otherwise, a
+@code{join-timeout-exception} exception is raised 
+(@pxref{SRFI-18 Exceptions}).  Exceptions may also be raised if the 
+thread was terminated by a call to @code{thread-terminate!} 
+(@code{terminated-thread-exception} will be raised) or if the thread 
+exited by raising an exception that was handled by the top-level 
+exception handler (@code{uncaught-exception} will be raised; the 
+original exception can be retrieved using 
+@code{uncaught-exception-reason}).
+@end defun
+
+
+@node SRFI-18 Mutexes
+@subsubsection SRFI-18 Mutexes
+
+The behavior of Guile's built-in mutexes is parameterized via a set of
+flags passed to the @code{make-mutex} procedure in the core
+(@pxref{Mutexes and Condition Variables}).  To satisfy the requirements
+for mutexes specified by SRFI-18, the @code{make-mutex} procedure
+described below sets the following flags:
+@itemize @bullet
+@item
+@code{recursive}: the mutex can be locked recursively
+@item
+@code{unchecked-unlock}: attempts to unlock a mutex that is already
+unlocked will not raise an exception
+@item
+@code{allow-external-unlock}: the mutex can be unlocked by any thread,
+not just the thread that locked it originally
+@end itemize
+
+@defun make-mutex [name]
+Returns a new mutex, optionally assigning it the object name 
+@var{name}, which may be any Scheme object.  The returned mutex will be
+created with the configuration described above.  Note that the name 
+@code{make-mutex} conflicts with Guile core function @code{make-mutex}.
+Applications wanting to use both of these functions will need to refer 
+to them by different names.
+@end defun
+
+@defun mutex-name mutex
+Returns the name assigned to @var{mutex} at the time of its creation, 
+or @code{#f} if it was not given a name.
+@end defun
+
+@defun mutex-specific mutex
+@defunx mutex-specific-set! mutex obj
+Get or set the ``object-specific'' property of @var{mutex}.  In Guile's
+implementation of SRFI-18, this value is stored as an object property, 
+and will be @code{#f} if not set.
+@end defun
+
+@defun mutex-state mutex
+Returns information about the state of @var{mutex}.  Possible values 
+are:
+@itemize @bullet
+@item
+thread @code{T}: the mutex is in the locked/owned state and thread T
+is the owner of the mutex
+@item 
+symbol @code{not-owned}: the mutex is in the locked/not-owned state
+@item
+symbol @code{abandoned}: the mutex is in the unlocked/abandoned state
+@item
+symbol @code{not-abandoned}: the mutex is in the 
+unlocked/not-abandoned state 
+@end itemize
+@end defun
+
+@defun mutex-lock! mutex [timeout [thread]]
+Lock @var{mutex}, optionally specifying a time object @var{timeout}
+after which to abort the lock attempt and a thread @var{thread} giving
+a new owner for @var{mutex} different than the current thread.  This 
+procedure has the same behavior as the @code{lock-mutex} procedure in 
+the core library.
+@end defun
+
+@defun mutex-unlock! mutex [condition-variable [timeout]]
+Unlock @var{mutex}, optionally specifying a condition variable
+@var{condition-variable} on which to wait, either indefinitely or,
+optionally, until the time object @var{timeout} has passed, to be
+signalled.  This procedure has the same behavior as the 
+@code{unlock-mutex} procedure in the core library.
+@end defun
+
+
+@node SRFI-18 Condition variables
+@subsubsection SRFI-18 Condition variables
+
+SRFI-18 does not specify a ``wait'' function for condition variables.
+Waiting on a condition variable can be simulated using the SRFI-18
+@code{mutex-unlock!} function described in the previous section, or
+Guile's built-in @code{wait-condition-variable} procedure can be used.
+
+@defun condition-variable? obj
+Returns @code{#t} if @var{obj} is a condition variable, @code{#f}
+otherwise.  This is the same procedure as the same-named built-in 
+procedure
+(@pxref{Mutexes and Condition Variables, @code{condition-variable?}}).
+@end defun
+
+@defun make-condition-variable [name]
+Returns a new condition variable, optionally assigning it the object
+name @var{name}, which may be any Scheme object.  This procedure 
+replaces a procedure of the same name in the core library.
+@end defun
 
-This is an implementation of SRFI-17: Generalized set!
+@defun condition-variable-name condition-variable
+Returns the name assigned to @var{thread} at the time of its creation,
+or @code{#f} if it was not given a name.
+@end defun
+
+@defun condition-variable-specific condition-variable
+@defunx condition-variable-specific-set! condition-variable obj
+Get or set the ``object-specific'' property of 
+@var{condition-variable}.  In Guile's implementation of SRFI-18, this
+value is stored as an object property, and will be @code{#f} if not 
+set.
+@end defun
+
+@defun condition-variable-signal! condition-variable
+@defunx condition-variable-broadcast! condition-variable
+Wake up one thread that is waiting for @var{condition-variable}, in
+the case of @code{condition-variable-signal!}, or all threads waiting
+for it, in the case of @code{condition-variable-broadcast!}.  The
+behavior of these procedures is equivalent to that of the procedures
+@code{signal-condition-variable} and 
+@code{broadcast-condition-variable} in the core library.
+@end defun
+
+
+@node SRFI-18 Time
+@subsubsection SRFI-18 Time
+
+The SRFI-18 time functions manipulate time in two formats: a 
+``time object'' type that represents an absolute point in time in some 
+implementation-specific way; and the number of seconds since some 
+unspecified ``epoch''.  In Guile's implementation, the epoch is the
+Unix epoch, 00:00:00 UTC, January 1, 1970.
+
+@defun current-time
+Return the current time as a time object.  This procedure replaces 
+the procedure of the same name in the core library, which returns the
+current time in seconds since the epoch.
+@end defun
+
+@defun time? obj
+Returns @code{#t} if @var{obj} is a time object, @code{#f} otherwise.
+@end defun
+
+@defun time->seconds time
+@defunx seconds->time seconds
+Convert between time objects and numerical values representing the
+number of seconds since the epoch.  When converting from a time object 
+to seconds, the return value is the number of seconds between 
+@var{time} and the epoch.  When converting from seconds to a time 
+object, the return value is a time object that represents a time 
+@var{seconds} seconds after the epoch.
+@end defun
 
-@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.
 
-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.
+@node SRFI-18 Exceptions
+@subsubsection SRFI-18 Exceptions
+
+SRFI-18 exceptions are identical to the exceptions provided by 
+Guile's implementation of SRFI-34.  The behavior of exception 
+handlers invoked to handle exceptions thrown from SRFI-18 functions,
+however, differs from the conventional behavior of SRFI-34 in that
+the continuation of the handler is the same as that of the call to
+the function.  Handlers are called in a tail-recursive manner; the
+exceptions do not ``bubble up''.
+
+@defun current-exception-handler
+Returns the current exception handler.
+@end defun
+
+@defun with-exception-handler handler thunk
+Installs @var{handler} as the current exception handler and calls the
+procedure @var{thunk} with no arguments, returning its value as the 
+value of the exception.  @var{handler} must be a procedure that accepts
+a single argument. The current exception handler at the time this 
+procedure is called will be restored after the call returns.
+@end defun
+
+@defun raise obj
+Raise @var{obj} as an exception.  This is the same procedure as the
+same-named procedure defined in SRFI 34.
+@end defun
+
+@defun join-timeout-exception? obj
+Returns @code{#t} if @var{obj} is an exception raised as the result of 
+performing a timed join on a thread that does not exit within the
+specified timeout, @code{#f} otherwise.
+@end defun
+
+@defun abandoned-mutex-exception? obj
+Returns @code{#t} if @var{obj} is an exception raised as the result of
+attempting to lock a mutex that has been abandoned by its owner thread,
+@code{#f} otherwise.
+@end defun
+
+@defun terminated-thread-exception? obj
+Returns @code{#t} if @var{obj} is an exception raised as the result of 
+joining on a thread that exited as the result of a call to
+@code{thread-terminate!}.
+@end defun
+
+@defun uncaught-exception? obj
+@defunx uncaught-exception-reason exc
+@code{uncaught-exception?} returns @code{#t} if @var{obj} is an 
+exception thrown as the result of joining a thread that exited by
+raising an exception that was handled by the top-level exception
+handler installed by @code{make-thread}.  When this occurs, the 
+original exception is preserved as part of the exception thrown by
+@code{thread-join!} and can be accessed by calling 
+@code{uncaught-exception-reason} on that exception.  Note that
+because this exception-preservation mechanism is a side-effect of
+@code{make-thread}, joining on threads that exited as described above
+but were created by other means will not raise this 
+@code{uncaught-exception} error.
+@end defun
 
 
 @node SRFI-19
@@ -1789,8 +2703,10 @@ Return the current time of the given @var{type}.  The default
 @var{type} is @code{time-utc}.
 
 Note that the name @code{current-time} conflicts with the Guile core
-@code{current-time} function (@pxref{Time}).  Applications wanting to
-use both will need to use a different name for one of them.
+@code{current-time} function (@pxref{Time}) as well as the SRFI-18
+@code{current-time} function (@pxref{SRFI-18 Time}).  Applications 
+wanting to use more than one of these functions will need to refer to
+them by different names.
 @end defun
 
 @defun time-resolution [type]
@@ -2081,10 +2997,10 @@ Conversions @samp{~D}, @samp{~x} and @samp{~X} are not currently
 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
@@ -2205,9 +3121,10 @@ Notice that the weekday matching forms don't affect the date object
 returned, instead the weekday will be derived from the day, month and
 year.
 
-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
 
 
@@ -2313,6 +3230,170 @@ or similar is typical.
 @end example
 @end deffn
 
+@node SRFI-27
+@subsection SRFI-27 - Sources of Random Bits
+@cindex SRFI-27
+
+This subsection is based on the
+@uref{http://srfi.schemers.org/srfi-27/srfi-27.html, specification of
+SRFI-27} written by Sebastian Egner.
+
+@c The copyright notice and license text of the SRFI-27 specification is
+@c reproduced below:
+
+@c Copyright (C) Sebastian Egner (2002). All Rights Reserved.
+
+@c Permission is hereby granted, free of charge, to any person obtaining a
+@c copy of this software and associated documentation files (the
+@c "Software"), to deal in the Software without restriction, including
+@c without limitation the rights to use, copy, modify, merge, publish,
+@c distribute, sublicense, and/or sell copies of the Software, and to
+@c permit persons to whom the Software is furnished to do so, subject to
+@c the following conditions:
+
+@c The above copyright notice and this permission notice shall be included
+@c in all copies or substantial portions of the Software.
+
+@c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+@c OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+@c MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+@c NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+@c LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+@c OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+@c WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+This SRFI provides access to a (pseudo) random number generator; for
+Guile's built-in random number facilities, which SRFI-27 is implemented
+upon, @xref{Random}.  With SRFI-27, random numbers are obtained from a
+@emph{random source}, which encapsulates a random number generation
+algorithm and its state.
+
+@menu
+* SRFI-27 Default Random Source::    Obtaining random numbers
+* SRFI-27 Random Sources::           Creating and manipulating random sources
+* SRFI-27 Random Number Generators:: Obtaining random number generators
+@end menu
+
+@node SRFI-27 Default Random Source
+@subsubsection The Default Random Source
+@cindex SRFI-27
+
+@defun random-integer n
+Return a random number between zero (inclusive) and @var{n} (exclusive),
+using the default random source.  The numbers returned have a uniform
+distribution.
+@end defun
+
+@defun random-real
+Return a random number in (0,1), using the default random source.  The
+numbers returned have a uniform distribution.
+@end defun
+
+@defun default-random-source
+A random source from which @code{random-integer} and @code{random-real}
+have been derived using @code{random-source-make-integers} and
+@code{random-source-make-reals} (@pxref{SRFI-27 Random Number Generators}
+for those procedures).  Note that an assignment to
+@code{default-random-source} does not change @code{random-integer} or
+@code{random-real}; it is also strongly recommended not to assign a new
+value.
+@end defun
+
+@node SRFI-27 Random Sources
+@subsubsection Random Sources
+@cindex SRFI-27
+
+@defun make-random-source
+Create a new random source.  The stream of random numbers obtained from
+each random source created by this procedure will be identical, unless
+its state is changed by one of the procedures below.
+@end defun
+
+@defun random-source? object
+Tests whether @var{object} is a random source.  Random sources are a
+disjoint type.
+@end defun
+
+@defun random-source-randomize! source
+Attempt to set the state of the random source to a truly random value.
+The current implementation uses a seed based on the current system time.
+@end defun
+
+@defun random-source-pseudo-randomize! source i j
+Changes the state of the random source s into the initial state of the
+(@var{i}, @var{j})-th independent random source, where @var{i} and
+@var{j} are non-negative integers.  This procedure provides a mechanism
+to obtain a large number of independent random sources (usually all
+derived from the same backbone generator), indexed by two integers. In
+contrast to @code{random-source-randomize!}, this procedure is entirely
+deterministic.
+@end defun
+
+The state associated with a random state can be obtained an reinstated
+with the following procedures:
+
+@defun random-source-state-ref source
+@defunx random-source-state-set! source state
+Get and set the state of a random source.  No assumptions should be made
+about the nature of the state object, besides it having an external
+representation (i.e. it can be passed to @code{write} and subsequently
+@code{read} back).
+@end defun
+
+@node SRFI-27 Random Number Generators
+@subsubsection Obtaining random number generator procedures
+@cindex SRFI-27
+
+@defun random-source-make-integers source
+Obtains a procedure to generate random integers using the random source
+@var{source}.  The returned procedure takes a single argument @var{n},
+which must be a positive integer, and returns the next uniformly
+distributed random integer from the interval @{0, ..., @var{n}-1@} by
+advancing the state of @var{source}.
+
+If an application obtains and uses several generators for the same
+random source @var{source}, a call to any of these generators advances
+the state of @var{source}.  Hence, the generators do not produce the
+same sequence of random integers each but rather share a state. This
+also holds for all other types of generators derived from a fixed random
+sources.  
+
+While the SRFI text specifies that ``Implementations that support
+concurrency make sure that the state of a generator is properly
+advanced'', this is currently not the case in Guile's implementation of
+SRFI-27, as it would cause a severe performance penalty.  So in
+multi-threaded programs, you either must perform locking on random
+sources shared between threads yourself, or use different random sources
+for multiple threads.
+@end defun
+
+@defun random-source-make-reals source
+@defunx random-source-make-reals source unit
+Obtains a procedure to generate random real numbers @math{0 < x < 1}
+using the random source @var{source}.  The procedure rand is called
+without arguments.
+
+The optional parameter @var{unit} determines the type of numbers being
+produced by the returned procedure and the quantization of the output.
+@var{unit} must be a number such that @math{0 < @var{unit} < 1}.  The
+numbers created by the returned procedure are of the same numerical type
+as @var{unit} and the potential output values are spaced by at most
+@var{unit}.  One can imagine rand to create numbers as @var{x} *
+@var{unit} where @var{x} is a random integer in @{1, ...,
+floor(1/unit)-1@}.  Note, however, that this need not be the way the
+values are actually created and that the actual resolution of rand can
+be much higher than unit. In case @var{unit} is absent it defaults to a
+reasonably small value (related to the width of the mantissa of an
+efficient number format).
+@end defun
+
+@node SRFI-30
+@subsection SRFI-30 - Nested Multi-line Comments
+@cindex SRFI-30
+
+Starting from version 2.0, Guile's @code{read} supports SRFI-30/R6RS
+nested multi-line comments by default, @ref{Block Comments}.
+
 @node SRFI-31
 @subsection SRFI-31 - A special form `rec' for recursive evaluation
 @cindex SRFI-31
@@ -2349,6 +3430,283 @@ The second syntax can be used to create anonymous recursive functions:
 @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 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
@@ -2385,7 +3743,7 @@ the new locations.
 (my-param) @result{} 456
 @end example
 
-Parameters are like dynamically bound variables in other Lisp dialets.
+Parameters are like dynamically bound variables in other Lisp dialects.
 They allow an application to establish parameter settings (as the name
 suggests) just for the execution of a particular bit of code,
 restoring when done.  Examples of such parameters might be
@@ -2393,7 +3751,7 @@ case-sensitivity for a search, or a prompt for user input.
 
 Global variables are not as good as parameter objects for this sort of
 thing.  Changes to them are visible to all threads, but in Guile
-parameter object locations are per-thread, thereby truely limiting the
+parameter object locations are per-thread, thereby truly limiting the
 effect of @code{parameterize} to just its dynamic execution.
 
 Passing arguments to functions is thread-safe, but that soon becomes
@@ -2511,6 +3869,155 @@ 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-42
+@subsection SRFI-42 - Eager Comprehensions
+@cindex SRFI-42
+
+See @uref{http://srfi.schemers.org/srfi-42/srfi-42.html, the
+specification of SRFI-42}.
+
+@node SRFI-45
+@subsection SRFI-45 - Primitives for Expressing Iterative Lazy Algorithms
+@cindex SRFI-45
+
+This subsection is based on @uref{http://srfi.schemers.org/srfi-45/srfi-45.html, the
+specification of SRFI-45} written by Andr@'e van Tonder.
+
+@c Copyright (C) AndrĂ© van Tonder (2003). All Rights Reserved.
+
+@c Permission is hereby granted, free of charge, to any person obtaining a
+@c copy of this software and associated documentation files (the
+@c "Software"), to deal in the Software without restriction, including
+@c without limitation the rights to use, copy, modify, merge, publish,
+@c distribute, sublicense, and/or sell copies of the Software, and to
+@c permit persons to whom the Software is furnished to do so, subject to
+@c the following conditions:
+
+@c The above copyright notice and this permission notice shall be included
+@c in all copies or substantial portions of the Software.
+
+@c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+@c OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+@c MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+@c NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+@c LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+@c OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+@c WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Lazy evaluation is traditionally simulated in Scheme using @code{delay}
+and @code{force}.  However, these primitives are not powerful enough to
+express a large class of lazy algorithms that are iterative.  Indeed, it
+is folklore in the Scheme community that typical iterative lazy
+algorithms written using delay and force will often require unbounded
+memory.
+
+This SRFI provides set of three operations: @{@code{lazy}, @code{delay},
+@code{force}@}, which allow the programmer to succinctly express lazy
+algorithms while retaining bounded space behavior in cases that are
+properly tail-recursive.  A general recipe for using these primitives is
+provided. An additional procedure @code{eager} is provided for the
+construction of eager promises in cases where efficiency is a concern.
+
+Although this SRFI redefines @code{delay} and @code{force}, the
+extension is conservative in the sense that the semantics of the subset
+@{@code{delay}, @code{force}@} in isolation (i.e., as long as the
+program does not use @code{lazy}) agrees with that in R5RS.  In other
+words, no program that uses the R5RS definitions of delay and force will
+break if those definition are replaced by the SRFI-45 definitions of
+delay and force.
+
+@deffn {Scheme Syntax} delay expression
+Takes an expression of arbitrary type @var{a} and returns a promise of
+type @code{(Promise @var{a})} which at some point in the future may be
+asked (by the @code{force} procedure) to evaluate the expression and
+deliver the resulting value.
+@end deffn
+
+@deffn {Scheme Syntax} lazy expression
+Takes an expression of type @code{(Promise @var{a})} and returns a
+promise of type @code{(Promise @var{a})} which at some point in the
+future may be asked (by the @code{force} procedure) to evaluate the
+expression and deliver the resulting promise.
+@end deffn
+
+@deffn {Scheme Procedure} force expression
+Takes an argument of type @code{(Promise @var{a})} and returns a value
+of type @var{a} as follows: If a value of type @var{a} has been computed
+for the promise, this value is returned.  Otherwise, the promise is
+first evaluated, then overwritten by the obtained promise or value, and
+then force is again applied (iteratively) to the promise.
+@end deffn
+
+@deffn {Scheme Procedure} eager expression
+Takes an argument of type @var{a} and returns a value of type
+@code{(Promise @var{a})}.  As opposed to @code{delay}, the argument is
+evaluated eagerly. Semantically, writing @code{(eager expression)} is
+equivalent to writing
+
+@lisp
+(let ((value expression)) (delay value)).
+@end lisp
+
+However, the former is more efficient since it does not require
+unnecessary creation and evaluation of thunks. We also have the
+equivalence
+
+@lisp
+(delay expression) = (lazy (eager expression))
+@end lisp
+@end deffn
+
+The following reduction rules may be helpful for reasoning about these
+primitives.  However, they do not express the memoization and memory
+usage semantics specified above:
+
+@lisp
+(force (delay expression)) -> expression
+(force (lazy  expression)) -> (force expression)
+(force (eager value))      -> value
+@end lisp
+
+@subsubheading Correct usage
+
+We now provide a general recipe for using the primitives @{@code{lazy},
+@code{delay}, @code{force}@} to express lazy algorithms in Scheme.  The
+transformation is best described by way of an example: Consider the
+stream-filter algorithm, expressed in a hypothetical lazy language as
+
+@lisp
+(define (stream-filter p? s)
+  (if (null? s) '()
+      (let ((h (car s))
+            (t (cdr s)))
+        (if (p? h)
+            (cons h (stream-filter p? t))
+            (stream-filter p? t)))))
+@end lisp
+
+This algorithm can be espressed as follows in Scheme:
+
+@lisp
+(define (stream-filter p? s)
+  (lazy
+     (if (null? (force s)) (delay '())
+         (let ((h (car (force s)))
+               (t (cdr (force s))))
+           (if (p? h)
+               (delay (cons h (stream-filter p? t)))
+               (stream-filter p? t))))))
+@end lisp
+
+In other words, we
+
+@itemize @bullet
+@item
+wrap all constructors (e.g., @code{'()}, @code{cons}) with @code{delay},
+@item 
+apply @code{force} to arguments of deconstructors (e.g., @code{car},
+@code{cdr} and @code{null?}),
+@item
+wrap procedure bodies with @code{(lazy ...)}.
+@end itemize
 
 @node SRFI-55
 @subsection SRFI-55 - Requiring Features
@@ -2685,6 +4192,280 @@ element becomes the most significant bit in the return.
 @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-67
+@subsection SRFI-67 - Compare procedures
+@cindex SRFI-67
+
+See @uref{http://srfi.schemers.org/srfi-67/srfi-67.html, the
+specification of SRFI-67}.
+
+@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-88/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{Scheme Read, @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
+
+@node SRFI-98
+@subsection SRFI-98 Accessing environment variables.
+@cindex SRFI-98
+@cindex environment variables
+
+This is a portable wrapper around Guile's built-in support for 
+interacting with the current environment, @xref{Runtime Environment}.
+
+@deffn {Scheme Procedure} get-environment-variable name
+Returns a string containing the value of the environment variable 
+given by the string @code{name}, or @code{#f} if the named 
+environment variable is not found.  This is equivalent to 
+@code{(getenv name)}.
+@end deffn
+
+@deffn {Scheme Procedure} get-environment-variables
+Returns the names and values of all the environment variables as an
+association list in which both the keys and the values are strings.
+@end deffn
+
 @c srfi-modules.texi ends here
 
 @c Local Variables: