Add implementation of SRFI 45
[bpt/guile.git] / doc / ref / srfi-modules.texi
index 7c107e7..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, 2006, 2007, 2008
+@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
@@ -37,14 +36,19 @@ get the relevant SRFI documents from the SRFI home page
 * 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.
@@ -134,6 +138,7 @@ The Guile core has the following features,
 
 @example
 guile
+guile-2  ;; starting from Guile 2.x
 r5rs
 srfi-0
 srfi-4
@@ -161,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.
@@ -1274,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
@@ -1373,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
@@ -1558,66 +2133,9 @@ The SRFI-14 data type and procedures are always available,
 @cindex variable arity
 @cindex arity, variable
 
-@c FIXME::martin: Review me!
-
-@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.
-
-The syntax of the @code{case-lambda} form is defined in the following
-EBNF grammar.
-
-@example
-@group
-<case-lambda>
-   --> (case-lambda <case-lambda-clause>)
-<case-lambda-clause>
-   --> (<formals> <definition-or-command>*)
-<formals>
-   --> (<identifier>*)
-     | (<identifier>* . <identifier>)
-     | <identifier>
-@end group
-@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.
-
-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.
-
-@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
-
-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.
-
+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.
 
 @node SRFI-17
 @subsection SRFI-17 - Generalized set!
@@ -2712,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
@@ -2846,7 +3528,7 @@ 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.
+@code{make-compound-condition} that created the condition.
 @end deffn
 
 Convenience macros are also available to create condition types and
@@ -3061,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
@@ -3069,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
@@ -3187,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
@@ -3370,6 +4201,12 @@ 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
@@ -3568,7 +4405,7 @@ Answer a hash value appropriate for equality predicate @code{equal?},
 @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}).
+by @code{:} (@pxref{Scheme Read, @code{postfix} keyword syntax}).
 SRFI-88 can be made available with:
 
 @example