@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
* 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
@end example
@end deffn
-The Guile core provides features @code{guile}, @code{r5rs},
-@code{srfi-0} and @code{srfi-6} initially. Other SRFI feature symbols
-are defined once their code has been loaded with @code{use-modules},
-since only then are their bindings available.
+@noindent
+The Guile core has the following features,
+
+@example
+guile
+guile-2 ;; starting from Guile 2.x
+r5rs
+srfi-0
+srfi-4
+srfi-6
+srfi-13
+srfi-14
+@end example
+
+Other SRFI feature symbols are defined once their code has been loaded
+with @code{use-modules}, since only then are their bindings available.
The @samp{--use-srfi} command line option (@pxref{Invoking Guile}) is
a good way to load SRFIs to satisfy @code{cond-expand} when running a
(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.
@node SRFI-1
@subsection SRFI-1 - List library
@cindex SRFI-1
+@cindex list
@c FIXME::martin: Review me!
@node SRFI-1 Constructors
@subsubsection Constructors
+@cindex list constructor
@c FIXME::martin: Review me!
@node SRFI-1 Predicates
@subsubsection Predicates
+@cindex list predicate
@c FIXME::martin: Review me!
The procedures in this section test specific properties of lists.
@deffn {Scheme Procedure} proper-list? obj
-Return @code{#t} if @var{obj} is a proper list, that is a finite list,
-terminated with the empty list. Otherwise, return @code{#f}.
+Return @code{#t} if @var{obj} is a proper list, or @code{#f}
+otherwise. This is the same as the core @code{list?} (@pxref{List
+Predicates}).
+
+A proper list is a list which ends with the empty list @code{()} in
+the usual way. The empty list @code{()} itself is a proper list too.
+
+@example
+(proper-list? '(1 2 3)) @result{} #t
+(proper-list? '()) @result{} #t
+@end example
@end deffn
@deffn {Scheme Procedure} circular-list? obj
-Return @code{#t} if @var{obj} is a circular list, otherwise return
-@code{#f}.
+Return @code{#t} if @var{obj} is a circular list, or @code{#f}
+otherwise.
+
+A circular list is a list where at some point the @code{cdr} refers
+back to a previous pair in the list (either the start or some later
+point), so that following the @code{cdr}s takes you around in a
+circle, with no end.
+
+@example
+(define x (list 1 2 3 4))
+(set-cdr! (last-pair x) (cddr x))
+x @result{} (1 2 3 4 3 4 3 4 ...)
+(circular-list? x) @result{} #t
+@end example
@end deffn
@deffn {Scheme Procedure} dotted-list? obj
-Return @code{#t} if @var{obj} is a dotted list, return @code{#f}
-otherwise. A dotted list is a finite list which is not terminated by
-the empty list, but some other value.
+Return @code{#t} if @var{obj} is a dotted list, or @code{#f}
+otherwise.
+
+A dotted list is a list where the @code{cdr} of the last pair is not
+the empty list @code{()}. Any non-pair @var{obj} is also considered a
+dotted list, with length zero.
+
+@example
+(dotted-list? '(1 2 . 3)) @result{} #t
+(dotted-list? 99) @result{} #t
+@end example
@end deffn
+It will be noted that any Scheme object passes exactly one of the
+above three tests @code{proper-list?}, @code{circular-list?} and
+@code{dotted-list?}. Non-lists are @code{dotted-list?}, finite lists
+are either @code{proper-list?} or @code{dotted-list?}, and infinite
+lists are @code{circular-list?}.
+
+@sp 1
@deffn {Scheme Procedure} null-list? lst
Return @code{#t} if @var{lst} is the empty list @code{()}, @code{#f}
otherwise. If something else than a proper or circular list is passed
@node SRFI-1 Selectors
@subsubsection Selectors
+@cindex list selector
@c FIXME::martin: Review me!
@deffn {Scheme Procedure} take-right lst i
Return the a list containing the @var{i} last elements of @var{lst}.
+The return shares a common tail with @var{lst}.
@end deffn
@deffn {Scheme Procedure} drop-right lst i
Return the a list containing all but the @var{i} last elements of
@var{lst}.
-@code{drop-right!} may modify the structure of the argument list
-@var{lst} in order to produce the result.
+@code{drop-right} always returns a new list, even when @var{i} is
+zero. @code{drop-right!} may modify the structure of the argument
+list @var{lst} in order to produce the result.
@end deffn
@deffn {Scheme Procedure} split-at lst i
@code{concatenate!} may modify the structure of the given lists in
order to produce the result.
+
+@code{concatenate} is the same as @code{(apply append
+@var{list-of-lists})}. It exists because some Scheme implementations
+have a limit on the number of arguments a function takes, which the
+@code{apply} might exceed. In Guile there is no such limit.
@end deffn
@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.
@node SRFI-1 Fold and Map
@subsubsection Fold, Unfold & Map
+@cindex list fold
+@cindex list map
@c FIXME::martin: Review me!
-@deffn {Scheme Procedure} fold kons knil lst1 lst2 @dots{}
-Fold the procedure @var{kons} across all elements of @var{lst1},
-@var{lst2}, @dots{}. Produce the result of
+@deffn {Scheme Procedure} fold proc init lst1 @dots{} lstN
+@deffnx {Scheme Procedure} fold-right proc init lst1 @dots{} lstN
+Apply @var{proc} to the elements of @var{lst1} @dots{} @var{lstN} to
+build a result, and return that result.
-@code{(@var{kons} @var{en1} @var{en2} @dots{} (@var{kons} @var{e21}
-@var{e22} (@var{kons} @var{e11} @var{e12} @var{knil})))},
+Each @var{proc} call is @code{(@var{proc} @var{elem1} @dots{}
+@var{elemN} @var{previous})}, where @var{elem1} is from @var{lst1},
+through @var{elemN} from @var{lstN}. @var{previous} is the return
+from the previous call to @var{proc}, or the given @var{init} for the
+first call. If any list is empty, just @var{init} is returned.
-if @var{enm} are the elements of the lists @var{lst1}, @var{lst2},
-@dots{}.
-@end deffn
+@code{fold} works through the list elements from first to last. The
+following shows a list reversal and the calls it makes,
-@deffn {Scheme Procedure} fold-right kons knil lst1 lst2 @dots{}
-Similar to @code{fold}, but applies @var{kons} in right-to-left order
-to the list elements, that is:
+@example
+(fold cons '() '(1 2 3))
-@code{(@var{kons} @var{e11} @var{e12}(@var{kons} @var{e21}
-@var{e22} @dots{} (@var{kons} @var{en1} @var{en2} @var{knil})))},
-@end deffn
+(cons 1 '())
+(cons 2 '(1))
+(cons 3 '(2 1)
+@result{} (3 2 1)
+@end example
-@deffn {Scheme Procedure} pair-fold kons knil lst1 lst2 @dots{}
-Like @code{fold}, but apply @var{kons} to the pairs of the list
-instead of the list elements.
-@end deffn
+@code{fold-right} works through the list elements from last to first,
+ie.@: from the right. So for example the following finds the longest
+string, and the last among equal longest,
+
+@example
+(fold-right (lambda (str prev)
+ (if (> (string-length str) (string-length prev))
+ str
+ prev))
+ ""
+ '("x" "abc" "xyz" "jk"))
+@result{} "xyz"
+@end example
+
+If @var{lst1} through @var{lstN} have different lengths, @code{fold}
+stops when the end of the shortest is reached; @code{fold-right}
+commences at the last element of the shortest. Ie.@: elements past
+the length of the shortest are ignored in the other @var{lst}s. At
+least one @var{lst} must be non-circular.
-@deffn {Scheme Procedure} pair-fold-right kons knil lst1 lst2 @dots{}
-Like @code{fold-right}, but apply @var{kons} to the pairs of the list
-instead of the list elements.
+@code{fold} should be preferred over @code{fold-right} if the order of
+processing doesn't matter, or can be arranged either way, since
+@code{fold} is a little more efficient.
+
+The way @code{fold} builds a result from iterating is quite general,
+it can do more than other iterations like say @code{map} or
+@code{filter}. The following for example removes adjacent duplicate
+elements from a list,
+
+@example
+(define (delete-adjacent-duplicates lst)
+ (fold-right (lambda (elem ret)
+ (if (equal? elem (first ret))
+ ret
+ (cons elem ret)))
+ (list (last lst))
+ lst))
+(delete-adjacent-duplicates '(1 2 3 3 4 4 4 5))
+@result{} (1 2 3 4 5)
+@end example
+
+Clearly the same sort of thing can be done with a @code{for-each} and
+a variable in which to build the result, but a self-contained
+@var{proc} can be re-used in multiple contexts, where a
+@code{for-each} would have to be written out each time.
@end deffn
-@deffn {Scheme Procedure} reduce f ridentity lst
-@code{reduce} is a variant of @code{fold}. If @var{lst} is
-@code{()}, @var{ridentity} is returned. Otherwise, @code{(fold f (car
-@var{lst}) (cdr @var{lst}))} is returned.
+@deffn {Scheme Procedure} pair-fold proc init lst1 @dots{} lstN
+@deffnx {Scheme Procedure} pair-fold-right proc init lst1 @dots{} lstN
+The same as @code{fold} and @code{fold-right}, but apply @var{proc} to
+the pairs of the lists instead of the list elements.
@end deffn
-@deffn {Scheme Procedure} reduce-right f ridentity lst
-This is the @code{fold-right} variant of @code{reduce}.
+@deffn {Scheme Procedure} reduce proc default lst
+@deffnx {Scheme Procedure} reduce-right proc default lst
+@code{reduce} is a variant of @code{fold}, where the first call to
+@var{proc} is on two elements from @var{lst}, rather than one element
+and a given initial value.
+
+If @var{lst} is empty, @code{reduce} returns @var{default} (this is
+the only use for @var{default}). If @var{lst} has just one element
+then that's the return value. Otherwise @var{proc} is called on the
+elements of @var{lst}.
+
+Each @var{proc} call is @code{(@var{proc} @var{elem} @var{previous})},
+where @var{elem} is from @var{lst} (the second and subsequent elements
+of @var{lst}), and @var{previous} is the return from the previous call
+to @var{proc}. The first element of @var{lst} is the @var{previous}
+for the first call to @var{proc}.
+
+For example, the following adds a list of numbers, the calls made to
+@code{+} are shown. (Of course @code{+} accepts multiple arguments
+and can add a list directly, with @code{apply}.)
+
+@example
+(reduce + 0 '(5 6 7)) @result{} 18
+
+(+ 6 5) @result{} 11
+(+ 7 11) @result{} 18
+@end example
+
+@code{reduce} can be used instead of @code{fold} where the @var{init}
+value is an ``identity'', meaning a value which under @var{proc}
+doesn't change the result, in this case 0 is an identity since
+@code{(+ 5 0)} is just 5. @code{reduce} avoids that unnecessary call.
+
+@code{reduce-right} is a similar variation on @code{fold-right},
+working from the end (ie.@: the right) of @var{lst}. The last element
+of @var{lst} is the @var{previous} for the first call to @var{proc},
+and the @var{elem} values go from the second last.
+
+@code{reduce} should be preferred over @code{reduce-right} if the
+order of processing doesn't matter, or can be arranged either way,
+since @code{reduce} is a little more efficient.
@end deffn
@deffn {Scheme Procedure} unfold p f g seed [tail-gen]
@node SRFI-1 Filtering and Partitioning
@subsubsection Filtering and Partitioning
+@cindex list filter
+@cindex list partition
@c FIXME::martin: Review me!
@node SRFI-1 Searching
@subsubsection Searching
+@cindex list search
@c FIXME::martin: Review me!
to make a new define under a different name.
@end deffn
-@deffn {Scheme Procedure} any pred lst1 lst2 @dots{}
-Apply @var{pred} across the lists and return a true value if the
-predicate returns true for any of the list elements(s); return
-@code{#f} otherwise. The true value returned is always the result of
-the first successful application of @var{pred}.
+@deffn {Scheme Procedure} any pred lst1 lst2 @dots{} lstN
+Test whether any set of elements from @var{lst1} @dots{} lstN
+satisfies @var{pred}. If so the return value is the return from the
+successful @var{pred} call, or if not the return is @code{#f}.
+
+Each @var{pred} call is @code{(@var{pred} @var{elem1} @dots{}
+@var{elemN})} taking an element from each @var{lst}. The calls are
+made successively for the first, second, etc elements of the lists,
+stopping when @var{pred} returns non-@code{#f}, or when the end of the
+shortest list is reached.
+
+The @var{pred} call on the last set of elements (ie.@: when the end of
+the shortest list has been reached), if that point is reached, is a
+tail call.
@end deffn
-@deffn {Scheme Procedure} every pred lst1 lst2 @dots{}
-Apply @var{pred} across the lists and return a true value if the
-predicate returns true for every of the list elements(s); return
-@code{#f} otherwise. The true value returned is always the result of
-the final successful application of @var{pred}.
+@deffn {Scheme Procedure} every pred lst1 lst2 @dots{} lstN
+Test whether every set of elements from @var{lst1} @dots{} lstN
+satisfies @var{pred}. If so the return value is the return from the
+final @var{pred} call, or if not the return is @code{#f}.
+
+Each @var{pred} call is @code{(@var{pred} @var{elem1} @dots{}
+@var{elemN})} taking an element from each @var{lst}. The calls are
+made successively for the first, second, etc elements of the lists,
+stopping if @var{pred} returns @code{#f}, or when the end of any of
+the lists is reached.
+
+The @var{pred} call on the last set of elements (ie.@: when the end of
+the shortest list has been reached) is a tail call.
+
+If one of @var{lst1} @dots{} @var{lstN} is empty then no calls to
+@var{pred} are made, and the return is @code{#t}.
@end deffn
-@deffn {Scheme Procedure} list-index pred lst1 lst2 @dots{}
-Return the index of the leftmost element that satisfies @var{pred}.
+@deffn {Scheme Procedure} list-index pred lst1 @dots{} lstN
+Return the index of the first set of elements, one from each of
+@var{lst1}@dots{}@var{lstN}, which satisfies @var{pred}.
+
+@var{pred} is called as @code{(@var{pred} elem1 @dots{} elemN)}.
+Searching stops when the end of the shortest @var{lst} is reached.
+The return index starts from 0 for the first set of elements. If no
+set of elements pass then the return is @code{#f}.
+
+@example
+(list-index odd? '(2 4 6 9)) @result{} 3
+(list-index = '(1 2 3) '(3 1 2)) @result{} #f
+@end example
@end deffn
@deffn {Scheme Procedure} member x lst [=]
Return the first sublist of @var{lst} whose @sc{car} is equal to
-@var{x}. If @var{x} does no appear in @var{lst}, return @code{#f}.
-Equality is determined by the equality predicate @var{=}, or
-@code{equal?} if @var{=} is not given.
+@var{x}. If @var{x} does not appear in @var{lst}, return @code{#f}.
-This function extends the core @code{member} by accepting an equality
-predicate. (@pxref{List Searching})
+Equality is determined by @code{equal?}, or by the equality predicate
+@var{=} if given. @var{=} is called @code{(= @var{x} elem)},
+ie.@: with the given @var{x} first, so for example to find the first
+element greater than 5,
+
+@example
+(member 5 '(3 5 1 7 2 9) <) @result{} (7 2 9)
+@end example
+
+This version of @code{member} extends the core @code{member}
+(@pxref{List Searching}) by accepting an equality predicate.
@end deffn
@node SRFI-1 Deleting
@subsubsection Deleting
-
-@c FIXME::martin: Review me!
+@cindex list delete
@deffn {Scheme Procedure} delete x lst [=]
@deffnx {Scheme Procedure} delete! x lst [=]
common tail with @var{lst}. @code{delete!} may modify the structure
of @var{lst} to construct its return.
-These functions extend the core @code{delete} and @code{delete!} in
-accepting an equality predicate. (@pxref{List Modification})
+These functions extend the core @code{delete} and @code{delete!}
+(@pxref{List Modification}) in accepting an equality predicate. See
+also @code{lset-difference} (@pxref{SRFI-1 Set Operations}) for
+deleting multiple elements from a list.
@end deffn
@deffn {Scheme Procedure} delete-duplicates lst [=]
@node SRFI-1 Association Lists
@subsubsection Association Lists
+@cindex association list
+@cindex alist
@c FIXME::martin: Review me!
for dealing with association lists defined by SRFI-1.
@deffn {Scheme Procedure} assoc key alist [=]
-Return the pair from @var{alist} which matches @var{key}. Equality is
-determined by @var{=}, which defaults to @code{equal?} if not given.
-@var{alist} must be an association lists---a list of pairs.
+Return the pair from @var{alist} which matches @var{key}. This
+extends the core @code{assoc} (@pxref{Retrieving Alist Entries}) by
+taking an optional @var{=} comparison procedure.
+
+The default comparison is @code{equal?}. If an @var{=} parameter is
+given it's called @code{(@var{=} @var{key} @var{alistcar})}, ie. the
+given target @var{key} is the first argument, and a @code{car} from
+@var{alist} is second.
+
+For example a case-insensitive string lookup,
-This function extends the core @code{assoc} by accepting an equality
-predicate. (@pxref{Association Lists})
+@example
+(assoc "yy" '(("XX" . 1) ("YY" . 2)) string-ci=?)
+@result{} ("YY" . 2)
+@end example
@end deffn
@deffn {Scheme Procedure} alist-cons key datum alist
-Equivalent to
+Cons a new association @var{key} and @var{datum} onto @var{alist} and
+return the result. This is equivalent to
@lisp
(cons (cons @var{key} @var{datum}) @var{alist})
@end lisp
-This procedure is used to coons a new pair onto an existing
-association list.
+@code{acons} (@pxref{Adding or Setting Alist Entries}) in the Guile
+core does the same thing.
@end deffn
@deffn {Scheme Procedure} alist-copy alist
@node SRFI-1 Set Operations
@subsubsection Set Operations on Lists
+@cindex list set operation
+
+Lists can be used to represent sets of objects. The procedures in
+this section operate on such lists as sets.
+
+Note that lists are not an efficient way to implement large sets. The
+procedures here typically take time @math{@var{m}@cross{}@var{n}} when
+operating on @var{m} and @var{n} element lists. Other data structures
+like trees, bitsets (@pxref{Bit Vectors}) or hash tables (@pxref{Hash
+Tables}) are faster.
+
+All these procedures take an equality predicate as the first argument.
+This predicate is used for testing the objects in the list sets for
+sameness. This predicate must be consistent with @code{eq?}
+(@pxref{Equality}) in the sense that if two list elements are
+@code{eq?} then they must also be equal under the predicate. This
+simply means a given object must be equal to itself.
+
+@deffn {Scheme Procedure} lset<= = list1 list2 @dots{}
+Return @code{#t} if each list is a subset of the one following it.
+Ie.@: @var{list1} a subset of @var{list2}, @var{list2} a subset of
+@var{list3}, etc, for as many lists as given. If only one list or no
+lists are given then the return is @code{#t}.
+
+A list @var{x} is a subset of @var{y} if each element of @var{x} is
+equal to some element in @var{y}. Elements are compared using the
+given @var{=} procedure, called as @code{(@var{=} xelem yelem)}.
-@c FIXME::martin: Review me!
-
-Lists can be used for representing sets of objects. The procedures
-documented in this section can be used for such set representations.
-Man combining several sets or adding elements, they make sure that no
-object is contained more than once in a given list. Please note that
-lists are not a too efficient implementation method for sets, so if
-you need high performance, you should think about implementing a
-custom data structure for representing sets, such as trees, bitsets,
-hash tables or something similar.
-
-All these procedures accept an equality predicate as the first
-argument. This predicate is used for testing the objects in the list
-sets for sameness.
-
-@deffn {Scheme Procedure} lset<= = list1 @dots{}
-Return @code{#t} if every @var{listi} is a subset of @var{listi+1},
-otherwise return @code{#f}. Returns @code{#t} if called with less
-than two arguments. @var{=} is used for testing element equality.
+@example
+(lset<= eq?) @result{} #t
+(lset<= eqv? '(1 2 3) '(1)) @result{} #f
+(lset<= eqv? '(1 3 2) '(4 3 1 2)) @result{} #t
+@end example
@end deffn
@deffn {Scheme Procedure} lset= = list1 list2 @dots{}
-Return @code{#t} if all argument lists are equal. @var{=} is used for
-testing element equality.
+Return @code{#t} if all argument lists are set-equal. @var{list1} is
+compared to @var{list2}, @var{list2} to @var{list3}, etc, for as many
+lists as given. If only one list or no lists are given then the
+return is @code{#t}.
+
+Two lists @var{x} and @var{y} are set-equal if each element of @var{x}
+is equal to some element of @var{y} and conversely each element of
+@var{y} is equal to some element of @var{x}. The order of the
+elements in the lists doesn't matter. Element equality is determined
+with the given @var{=} procedure, called as @code{(@var{=} xelem
+yelem)}, but exactly which calls are made is unspecified.
+
+@example
+(lset= eq?) @result{} #t
+(lset= eqv? '(1 2 3) '(3 2 1)) @result{} #t
+(lset= string-ci=? '("a" "A" "b") '("B" "b" "a")) @result{} #t
+@end example
@end deffn
-@deffn {Scheme Procedure} lset-adjoin = list elt1 @dots{}
-@deffnx {Scheme Procedure} lset-adjoin! = list elt1 @dots{}
-Add all @var{elts} to the list @var{list}, suppressing duplicates and
-return the resulting list. @code{lset-adjoin!} is allowed, but not
-required to modify its first argument. @var{=} is used for testing
-element equality.
+@deffn {Scheme Procedure} lset-adjoin = list elem1 @dots{}
+Add to @var{list} any of the given @var{elem}s not already in the
+list. @var{elem}s are @code{cons}ed onto the start of @var{list} (so
+the return shares a common tail with @var{list}), but the order
+they're added is unspecified.
+
+The given @var{=} procedure is used for comparing elements, called as
+@code{(@var{=} listelem elem)}, ie.@: the second argument is one of
+the given @var{elem} parameters.
+
+@example
+(lset-adjoin eqv? '(1 2 3) 4 1 5) @result{} (5 4 1 2 3)
+@end example
@end deffn
-@deffn {Scheme Procedure} lset-union = list1 @dots{}
-@deffnx {Scheme Procedure} lset-union! = list1 @dots{}
-Return the union of all argument list sets. The union is the set of
-all elements which appear in any of the argument sets.
-@code{lset-union!} is allowed, but not required to modify its first
-argument. @var{=} is used for testing element equality.
+@deffn {Scheme Procedure} lset-union = list1 list2 @dots{}
+@deffnx {Scheme Procedure} lset-union! = list1 list2 @dots{}
+Return the union of the argument list sets. The result is built by
+taking the union of @var{list1} and @var{list2}, then the union of
+that with @var{list3}, etc, for as many lists as given. For one list
+argument that list itself is the result, for no list arguments the
+result is the empty list.
+
+The union of two lists @var{x} and @var{y} is formed as follows. If
+@var{x} is empty then the result is @var{y}. Otherwise start with
+@var{x} as the result and consider each @var{y} element (from first to
+last). A @var{y} element not equal to something already in the result
+is @code{cons}ed onto the result.
+
+The given @var{=} procedure is used for comparing elements, called as
+@code{(@var{=} relem yelem)}. The first argument is from the result
+accumulated so far, and the second is from the list being union-ed in.
+But exactly which calls are made is otherwise unspecified.
+
+Notice that duplicate elements in @var{list1} (or the first non-empty
+list) are preserved, but that repeated elements in subsequent lists
+are only added once.
+
+@example
+(lset-union eqv?) @result{} ()
+(lset-union eqv? '(1 2 3)) @result{} (1 2 3)
+(lset-union eqv? '(1 2 1 3) '(2 4 5) '(5)) @result{} (5 4 1 2 1 3)
+@end example
+
+@code{lset-union} doesn't change the given lists but the result may
+share a tail with the first non-empty list. @code{lset-union!} can
+modify all of the given lists to form the result.
@end deffn
@deffn {Scheme Procedure} lset-intersection = list1 list2 @dots{}
@deffnx {Scheme Procedure} lset-intersection! = list1 list2 @dots{}
-Return the intersection of all argument list sets. The intersection
-is the set containing all elements which appear in all argument sets.
-@code{lset-intersection!} is allowed, but not required to modify its
-first argument. @var{=} is used for testing element equality.
+Return the intersection of @var{list1} with the other argument lists,
+meaning those elements of @var{list1} which are also in all of
+@var{list2} etc. For one list argument, just that list is returned.
+
+The test for an element of @var{list1} to be in the return is simply
+that it's equal to some element in each of @var{list2} etc. Notice
+this means an element appearing twice in @var{list1} but only once in
+each of @var{list2} etc will go into the return twice. The return has
+its elements in the same order as they were in @var{list1}.
+
+The given @var{=} procedure is used for comparing elements, called as
+@code{(@var{=} elem1 elemN)}. The first argument is from @var{list1}
+and the second is from one of the subsequent lists. But exactly which
+calls are made and in what order is unspecified.
+
+@example
+(lset-intersection eqv? '(x y)) @result{} (x y)
+(lset-intersection eqv? '(1 2 3) '(4 3 2)) @result{} (2 3)
+(lset-intersection eqv? '(1 1 2 2) '(1 2) '(2 1) '(2)) @result{} (2 2)
+@end example
+
+The return from @code{lset-intersection} may share a tail with
+@var{list1}. @code{lset-intersection!} may modify @var{list1} to form
+its result.
@end deffn
@deffn {Scheme Procedure} lset-difference = list1 list2 @dots{}
@deffnx {Scheme Procedure} lset-difference! = list1 list2 @dots{}
-Return the difference of all argument list sets. The difference is
-the the set containing all elements of the first list which do not
-appear in the other lists. @code{lset-difference!} is allowed, but
-not required to modify its first argument. @var{=} is used for testing
-element equality.
-@end deffn
+Return @var{list1} with any elements in @var{list2}, @var{list3} etc
+removed (ie.@: subtracted). For one list argument, just that list is
+returned.
+
+The given @var{=} procedure is used for comparing elements, called as
+@code{(@var{=} elem1 elemN)}. The first argument is from @var{list1}
+and the second from one of the subsequent lists. But exactly which
+calls are made and in what order is unspecified.
+
+@example
+(lset-difference eqv? '(x y)) @result{} (x y)
+(lset-difference eqv? '(1 2 3) '(3 1)) @result{} (2)
+(lset-difference eqv? '(1 2 3) '(3) '(2)) @result{} (1)
+@end example
-@deffn {Scheme Procedure} lset-xor = list1 @dots{}
-@deffnx {Scheme Procedure} lset-xor! = list1 @dots{}
-Return the set containing all elements which appear in the first
-argument list set, but not in the second; or, more generally: which
-appear in an odd number of sets. @code{lset-xor!} is allowed, but
-not required to modify its first argument. @var{=} is used for testing
-element equality.
+The return from @code{lset-difference} may share a tail with
+@var{list1}. @code{lset-difference!} may modify @var{list1} to form
+its result.
@end deffn
@deffn {Scheme Procedure} lset-diff+intersection = list1 list2 @dots{}
@deffnx {Scheme Procedure} lset-diff+intersection! = list1 list2 @dots{}
-Return two values, the difference and the intersection of the argument
-list sets. This works like a combination of @code{lset-difference} and
-@code{lset-intersection}, but is more efficient.
-@code{lset-diff+intersection!} is allowed, but not required to modify
-its first argument. @var{=} is used for testing element equality. You
-have to use some means to deal with the multiple values these
-procedures return (@pxref{Multiple Values}).
+Return two values (@pxref{Multiple Values}), the difference and
+intersection of the argument lists as per @code{lset-difference} and
+@code{lset-intersection} above.
+
+For two list arguments this partitions @var{list1} into those elements
+of @var{list1} which are in @var{list2} and not in @var{list2}. (But
+for more than two arguments there can be elements of @var{list1} which
+are neither part of the difference nor the intersection.)
+
+One of the return values from @code{lset-diff+intersection} may share
+a tail with @var{list1}. @code{lset-diff+intersection!} may modify
+@var{list1} to form its results.
+@end deffn
+
+@deffn {Scheme Procedure} lset-xor = list1 list2 @dots{}
+@deffnx {Scheme Procedure} lset-xor! = list1 list2 @dots{}
+Return an XOR of the argument lists. For two lists this means those
+elements which are in exactly one of the lists. For more than two
+lists it means those elements which appear in an odd number of the
+lists.
+
+To be precise, the XOR of two lists @var{x} and @var{y} is formed by
+taking those elements of @var{x} not equal to any element of @var{y},
+plus those elements of @var{y} not equal to any element of @var{x}.
+Equality is determined with the given @var{=} procedure, called as
+@code{(@var{=} e1 e2)}. One argument is from @var{x} and the other
+from @var{y}, but which way around is unspecified. Exactly which
+calls are made is also unspecified, as is the order of the elements in
+the result.
+
+@example
+(lset-xor eqv? '(x y)) @result{} (x y)
+(lset-xor eqv? '(1 2 3) '(4 3 2)) @result{} (4 1)
+@end example
+
+The return from @code{lset-xor} may share a tail with one of the list
+arguments. @code{lset-xor!} may modify @var{list1} to form its
+result.
@end deffn
Each @var{clause} is evaluated in turn, and if @code{#f} is obtained
then evaluation stops and @code{#f} is returned. If all are
non-@code{#f} then @var{body} is evaluated and the last form gives the
-return value. Each @var{clause} should be one of the following,
+return value, or if @var{body} is empty then the result is @code{#t}.
+Each @var{clause} should be one of the following,
@table @code
@item (symbol expr)
@subsection SRFI-4 - Homogeneous numeric vector datatypes
@cindex SRFI-4
-@c FIXME::martin: Review me!
-
-SRFI-4 defines a set of datatypes and functions for vectors whose
-elements are numbers, all of the same numeric type. Vectors for
-signed and unsigned exact integers and inexact reals in several
-precisions are available. Being homogeneous means they require less
-memory than normal 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 functions and the read syntax in this section are made available
-with
+The standard SRFI-4 procedures and data types may be included via loading the
+appropriate module:
-@lisp
+@example
(use-modules (srfi srfi-4))
-@end lisp
+@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}
-Procedures similar to the vector procedures (@pxref{Vectors}) are
-provided for handling these homogeneous vectors, but they are distinct
-datatypes and the two cannot be inter-mixed.
+@item c64
+complex numbers in rectangular form with the real and imaginary part
+being a @code{double}
-Ten vector data types are provided: Unsigned and signed integer values
-with 8, 16, 32 and 64 bits and floating point values with 32 and 64
-bits. The type is indicated by a tag in the function names,
-@code{u8}, @code{s8}, @code{u16}, @code{s16}, @code{u32}, @code{s32},
-@code{u64}, @code{s64}, @code{f32}, @code{f64}.
+@end table
The external representation (ie.@: read syntax) for these vectors is
-similar to normal Scheme vectors, but with an additional tag
-indiciating the vector's type. For example,
+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)
@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 with the SRFI-4
-module @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.
+@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} 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]
+@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-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{}
+@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} 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.
@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
@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-ref vec i value
-@deffnx {Scheme Procedure} s8vector-ref vec i value
-@deffnx {Scheme Procedure} u16vector-ref vec i value
-@deffnx {Scheme Procedure} s16vector-ref vec i value
-@deffnx {Scheme Procedure} u32vector-ref vec i value
-@deffnx {Scheme Procedure} s32vector-ref vec i value
-@deffnx {Scheme Procedure} u64vector-ref vec i value
-@deffnx {Scheme Procedure} s64vector-ref vec i value
-@deffnx {Scheme Procedure} f32vector-ref vec i value
-@deffnx {Scheme Procedure} f64vector-ref vec i value
+@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.
@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
+@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->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
@node SRFI-9
@subsection SRFI-9 - define-record-type
@cindex SRFI-9
+@cindex record
This SRFI is a syntax for defining new record types and creating
predicate, constructor, and field getter and setter functions. In
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
@cindex hash-comma
@cindex #,()
-The module @code{(srfi srfi-10)} implements the syntax extension
-@code{#,()}, also called hash-comma, which is defined in SRFI-10.
+This SRFI implements a reader extension @code{#,()} called hash-comma.
+It allows the reader to give new kinds of objects, for use both in
+data and as constants or literals in source code. This feature is
+available with
+
+@example
+(use-modules (srfi srfi-10))
+@end example
-The support for SRFI-10 consists of the procedure
-@code{define-reader-ctor} for defining new reader constructors and the
-read syntax form
+@noindent
+The new read syntax is of the form
@example
-#,(@var{ctor} @var{datum} ...)
+#,(@var{tag} @var{arg}@dots{})
@end example
-where @var{ctor} must be a symbol for which a read constructor was
-defined previously, using @code{define-reader-ctor}.
+@noindent
+where @var{tag} is a symbol and the @var{arg}s are objects taken as
+parameters. @var{tag}s are registered with the following procedure.
+
+@deffn {Scheme Procedure} define-reader-ctor tag proc
+Register @var{proc} as the constructor for a hash-comma read syntax
+starting with symbol @var{tag}, ie. @nicode{#,(@var{tag} arg@dots{})}.
+@var{proc} is called with the given arguments @code{(@var{proc}
+arg@dots{})} and the object it returns is the result of the read.
+@end deffn
-Example:
+@noindent
+For example, a syntax giving a list of @var{N} copies of an object.
-@lisp
-(use-modules (ice-9 rdelim)) ; for read-line
-(define-reader-ctor 'file open-input-file)
-(define f '#,(file "/etc/passwd"))
-(read-line f)
+@example
+(define-reader-ctor 'repeat
+ (lambda (obj reps)
+ (make-list reps obj)))
+
+(display '#,(repeat 99 3))
+@print{} (99 99 99)
+@end example
+
+Notice the quote @nicode{'} when the @nicode{#,( )} is used. The
+@code{repeat} handler returns a list and the program must quote to use
+it literally, the same as any other list. Ie.
+
+@example
+(display '#,(repeat 99 3))
@result{}
-"root:x:0:0:root:/root:/bin/bash"
-@end lisp
+(display '(99 99 99))
+@end example
-Please note the quote before the @code{#,(file ...)} expression. This
-is necessary because ports are not self-evaluating in Guile.
+When a handler returns an object which is self-evaluating, like a
+number or a string, then there's no need for quoting, just as there's
+no need when giving those directly as literals. For example an
+addition,
-@deffn {Scheme Procedure} define-reader-ctor symbol proc
-Define @var{proc} as the reader constructor for hash-comma forms with a
-tag @var{symbol}. @var{proc} will be applied to the datum(s) following
-the tag in the hash-comma expression after the complete form has been
-read in. The result of @var{proc} is returned by the Scheme reader.
-@end deffn
+@example
+(define-reader-ctor 'sum
+ (lambda (x y)
+ (+ x y)))
+(display #,(sum 123 456)) @print{} 579
+@end example
+
+A typical use for @nicode{#,()} is to get a read syntax for objects
+which don't otherwise have one. For example, the following allows a
+hash table to be given literally, with tags and values, ready for fast
+lookup.
+
+@example
+(define-reader-ctor 'hash
+ (lambda elems
+ (let ((table (make-hash-table)))
+ (for-each (lambda (elem)
+ (apply hash-set! table elem))
+ elems)
+ table)))
+
+(define (animal->family animal)
+ (hash-ref '#,(hash ("tiger" "cat")
+ ("lion" "cat")
+ ("wolf" "dog"))
+ animal))
+
+(animal->family "lion") @result{} "cat"
+@end example
+
+Or for example the following is a syntax for a compiled regular
+expression (@pxref{Regular Expressions}).
+
+@example
+(use-modules (ice-9 regex))
+
+(define-reader-ctor 'regexp make-regexp)
+
+(define (extract-angs str)
+ (let ((match (regexp-exec '#,(regexp "<([A-Z0-9]+)>") str)))
+ (and match
+ (match:substring match 1))))
+
+(extract-angs "foo <BAR> quux") @result{} "BAR"
+@end example
+
+@sp 1
+@nicode{#,()} is somewhat similar to @code{define-macro}
+(@pxref{Macros}) in that handler code is run to produce a result, but
+@nicode{#,()} operates at the read stage, so it can appear in data for
+@code{read} (@pxref{Scheme Read}), not just in code to be executed.
+
+Because @nicode{#,()} is handled at read-time it has no direct access
+to variables etc. A symbol in the arguments is just a symbol, not a
+variable reference. The arguments are essentially constants, though
+the handler procedure can use them in any complicated way it might
+want.
+
+Once @code{(srfi srfi-10)} has loaded, @nicode{#,()} is available
+globally, there's no need to use @code{(srfi srfi-10)} in later
+modules. Similarly the tags registered are global and can be used
+anywhere once registered.
+
+There's no attempt to record what previous @nicode{#,()} forms have
+been seen, if two identical forms occur then two calls are made to the
+handler procedure. The handler might like to maintain a cache or
+similar to avoid making copies of large objects, depending on expected
+usage.
+
+In code the best uses of @nicode{#,()} are generally when there's a
+lot of objects of a particular kind as literals or constants. If
+there's just a few then some local variables and initializers are
+fine, but that becomes tedious and error prone when there's a lot, and
+the anonymous and compact syntax of @nicode{#,()} is much better.
@node SRFI-11
@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.
@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.
@subsection SRFI-13 - String Library
@cindex SRFI-13
-In this section, we will describe all procedures defined in SRFI-13
-(string library) and implemented by the module @code{(srfi srfi-13)}.
+The SRFI-13 procedures are always available, @xref{Strings}.
-Note that only the procedures from SRFI-13 are documented here which are
-not already contained in Guile. For procedures not documented here
-please refer to the relevant chapters in the Guile Reference Manual, for
-example the documentation of strings and string procedures
-(@pxref{Strings}).
-
-All of the procedures defined in SRFI-13, which are not already
-included in the Guile core library, are implemented in the module
-@code{(srfi srfi-13)}. The procedures which are both in Guile and in
-SRFI-13 are slightly extended in this module. Their bindings
-overwrite those in the Guile core.
-
-The procedures which are defined in the section @emph{Low-level
-procedures} of SRFI-13 for parsing optional string indices, substring
-specification checking and Knuth-Morris-Pratt-Searching are not
-implemented.
+@node SRFI-14
+@subsection SRFI-14 - Character-set Library
+@cindex SRFI-14
-The procedures @code{string-contains} and @code{string-contains-ci} are
-not implemented very efficiently at the moment. This will be changed as
-soon as possible.
+The SRFI-14 data type and procedures are always available,
+@xref{Character Sets}.
-@menu
-* Loading SRFI-13:: How to load SRFI-13 support.
-* SRFI-13 Predicates:: String predicates.
-* SRFI-13 Constructors:: String constructing procedures.
-* SRFI-13 List/String Conversion:: Conversion from/to lists.
-* SRFI-13 Selection:: Selection portions of strings.
-* SRFI-13 Modification:: Modify strings in-place.
-* SRFI-13 Comparison:: Compare strings.
-* SRFI-13 Prefixes/Suffixes:: Detect common pre-/suffixes.
-* SRFI-13 Searching:: Searching for substrings.
-* SRFI-13 Case Mapping:: Mapping to lower-/upper-case.
-* SRFI-13 Reverse/Append:: Reverse and append strings.
-* SRFI-13 Fold/Unfold/Map:: Construct/deconstruct strings.
-* SRFI-13 Replicate/Rotate:: Replicate and rotate portions of strings.
-* SRFI-13 Miscellaneous:: Left-over string procedures.
-* SRFI-13 Filtering/Deleting:: Filter and delete characters from strings.
-@end menu
+@node SRFI-16
+@subsection SRFI-16 - case-lambda
+@cindex SRFI-16
+@cindex variable arity
+@cindex arity, variable
+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 Loading SRFI-13
-@subsubsection Loading SRFI-13
+@node SRFI-17
+@subsection SRFI-17 - Generalized set!
+@cindex SRFI-17
-When Guile is properly installed, SRFI-13 support can be loaded into a
-running Guile by using the @code{(srfi srfi-13)} module.
+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
-$ guile
-guile> (use-modules (srfi srfi-13))
-guile>
+(use-modules (srfi srfi-17))
@end example
-When this step causes any errors, Guile is not properly installed.
+@noindent
+For example @code{vector-ref} is extended so that
-One possible reason is that Guile cannot find either the Scheme module
-file @file{srfi-13.scm}, or it cannot find the shared object file
-@file{libguile-srfi-srfi-13-14.so}. Make sure that the former is in the
-Guile load path and that the latter is either installed in some default
-location like @file{/usr/local/lib} or that the directory it was
-installed to is in your @code{LTDL_LIBRARY_PATH}. The same applies to
-@file{srfi-14.scm}.
+@example
+(set! (vector-ref vec idx) new-value)
+@end example
-Now you can test whether the SRFI-13 procedures are working by calling
-the @code{string-concatenate} procedure.
+@noindent
+is equivalent to
@example
-guile> (string-concatenate '("Hello" " " "World!"))
-"Hello World!"
+(vector-set! vec idx new-value)
@end example
-@node SRFI-13 Predicates
-@subsubsection Predicates
-
-In addition to the primitives @code{string?} and @code{string-null?},
-which are already in the Guile core, the string predicates
-@code{string-any} and @code{string-every} are defined by SRFI-13.
+The idea is that a @code{vector-ref} expression identifies a location,
+which may be either fetched or stored. The same form is used for the
+location in both cases, encouraging visual clarity. This is similar
+to the idea of an ``lvalue'' in C.
+
+The mechanism for this kind of @code{set!} is in the Guile core
+(@pxref{Procedures with Setters}). This module adds definitions of
+the following functions as procedures with setters, allowing them to
+be targets of a @code{set!},
+
+@quotation
+@nicode{car}, @nicode{cdr}, @nicode{caar}, @nicode{cadr},
+@nicode{cdar}, @nicode{cddr}, @nicode{caaar}, @nicode{caadr},
+@nicode{cadar}, @nicode{caddr}, @nicode{cdaar}, @nicode{cdadr},
+@nicode{cddar}, @nicode{cdddr}, @nicode{caaaar}, @nicode{caaadr},
+@nicode{caadar}, @nicode{caaddr}, @nicode{cadaar}, @nicode{cadadr},
+@nicode{caddar}, @nicode{cadddr}, @nicode{cdaaar}, @nicode{cdaadr},
+@nicode{cdadar}, @nicode{cdaddr}, @nicode{cddaar}, @nicode{cddadr},
+@nicode{cdddar}, @nicode{cddddr}
+
+@nicode{string-ref}, @nicode{vector-ref}
+@end quotation
+
+The SRFI specifies @code{setter} (@pxref{Procedures with Setters}) as
+a procedure with setter, allowing the setter for a procedure to be
+changed, eg.@: @code{(set! (setter foo) my-new-setter-handler)}.
+Currently Guile does not implement this, a setter can only be
+specified on creation (@code{getter-with-setter} below).
+
+@defun getter-with-setter
+The same as the Guile core @code{make-procedure-with-setter}
+(@pxref{Procedures with Setters}).
+@end defun
-@deffn {Scheme Procedure} string-any char_pred s [start end]
-Return true if @code{char_pred} is satisfied for any character in the
-string @var{s}. @var{char_pred} can be
-@itemize @bullet
-@item
-A character, to to test for any in @var{s} equal to that.
-@item
-A character set (@pxref{SRFI-14}), to test for any character in
-@var{s} in that character set.
-@item
-A predicate function, called as @code{(@var{char_pred} c)} for each
-character in @var{s}, from left to right, to test for any on which
-@var{char_pred} returns true.
+@node SRFI-18
+@subsection SRFI-18 - Multithreading support
+@cindex SRFI-18
-When @var{char_pred} does return true (ie.@: non-@code{#f}), that
-value is the value returned by @code{string-any}.
-@end itemize
+This is an implementation of the SRFI-18 threading and synchronization
+library. The functions and variables described here are provided by
-If there are no characters in @var{s} (ie.@: @var{start} equals
-@var{end}) then the return is @code{#f}.
+@example
+(use-modules (srfi srfi-18))
+@end example
-SRFI-13 specifies that when @var{char_pred} is a predicate function,
-the call on the last character of @var{s} (assuming that point is
-reached) is a tail call, but currently in Guile this is not the case.
-@end deffn
+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.
-@deffn {Scheme Procedure} string-every char_pred s [start end]
-Return true if @var{char_pred} is satisifed for every character in the
-string @var{s}. @var{char_pred} can be
-
-@itemize @bullet
-@item
-A character, to to test for every character in @var{s} equal to that.
-@item
-A character set (@pxref{SRFI-14}), to test for every character in
-@var{s} being in that character set.
-@item
-A predicate function, called as @code{(@var{char_pred} c)} for each
-character in @var{s}, from left to right, to test that it returns true
-for every character in @var{s}.
-
-When @var{char_pred} does return true (ie.@: non-@code{#f}) for every
-character, the return from the last call is the value returned by
-@code{string-every}.
-@end itemize
-
-If there are no characters in @var{s} (ie.@: @var{start} equals
-@var{end}) then the return is @code{#t}.
-
-SRFI-13 specifies that when @var{char_pred} is a predicate function,
-the call on the last character of @var{s} (assuming that point is
-reached) is a tail call, but currently in Guile this is not the case.
-@end deffn
-
-@c ===================================================================
-
-@node SRFI-13 Constructors
-@subsubsection Constructors
-
-SRFI-13 defines several procedures for constructing new strings. In
-addition to @code{make-string} and @code{string} (available in the Guile
-core library), the procedure @code{string-tabulate} does exist.
-
-@deffn {Scheme Procedure} string-tabulate proc len
-@var{proc} is an integer->char procedure. Construct a string
-of size @var{len} by applying @var{proc} to each index to
-produce the corresponding string element. The order in which
-@var{proc} is applied to the indices is not specified.
-@end deffn
-
-
-@c ===================================================================
-
-@node SRFI-13 List/String Conversion
-@subsubsection List/String Conversion
-
-The procedure @code{string->list} is extended by SRFI-13, that is why it
-is included in @code{(srfi srfi-13)}. The other procedures are new.
-The Guile core already contains the procedure @code{list->string} for
-converting a list of characters into a string (@pxref{List/String
-Conversion}).
-
-@deffn {Scheme Procedure} string->list str [start end]
-Convert the string @var{str} into a list of characters.
-@end deffn
-
-@deffn {Scheme Procedure} reverse-list->string chrs
-An efficient implementation of @code{(compose string->list
-reverse)}:
-
-@smalllisp
-(reverse-list->string '(#\a #\B #\c)) @result{} "cBa"
-@end smalllisp
-@end deffn
-
-@deffn {Scheme Procedure} string-join ls [delimiter grammar]
-Append the string in the string list @var{ls}, using the string
-@var{delim} as a delimiter between the elements of @var{ls}.
-@var{grammar} is a symbol which specifies how the delimiter is
-placed between the strings, and defaults to the symbol
-@code{infix}.
+@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
-@table @code
-@item infix
-Insert the separator between list elements. An empty string
-will produce an empty list.
+@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
-@item string-infix
-Like @code{infix}, but will raise an error if given the empty
-list.
+@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
-@item suffix
-Insert the separator after every list element.
+@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.
-@item prefix
-Insert the separator before each list element.
-@end table
-@end deffn
+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
-@c ===================================================================
+@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
-@node SRFI-13 Selection
-@subsubsection Selection
+@defun thread-start! thread
+Unblocks @var{thread} and allows it to begin execution if it has not
+done so already.
+@end defun
-These procedures are called @dfn{selectors}, because they access
-information about the string or select pieces of a given string.
+@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
-Additional selector procedures are documented in the Strings section
-(@pxref{String Selection}), like @code{string-length} or
-@code{string-ref}.
+@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
-@code{string-copy} is also available in core Guile, but this version
-accepts additional start/end indices.
+@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
-@deffn {Scheme Procedure} string-copy str [start end]
-Return a freshly allocated copy of the string @var{str}. If
-given, @var{start} and @var{end} delimit the portion of
-@var{str} which is copied.
-@end deffn
+@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
-@deffn {Scheme Procedure} substring/shared str start [end]
-Like @code{substring}, but the result may share memory with the
-argument @var{str}.
-@end deffn
-@deffn {Scheme Procedure} string-copy! target tstart s [start end]
-Copy the sequence of characters from index range [@var{start},
-@var{end}) in string @var{s} to string @var{target}, beginning
-at index @var{tstart}. The characters are copied left-to-right
-or right-to-left as needed - the copy is guaranteed to work,
-even if @var{target} and @var{s} are the same string. It is an
-error if the copy operation runs off the end of the target
-string.
-@end deffn
+@node SRFI-18 Mutexes
+@subsubsection SRFI-18 Mutexes
-@deffn {Scheme Procedure} string-take s n
-@deffnx {Scheme Procedure} string-take-right s n
-Return the @var{n} first/last characters of @var{s}.
-@end deffn
+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
-@deffn {Scheme Procedure} string-drop s n
-@deffnx {Scheme Procedure} string-drop-right s n
-Return all but the first/last @var{n} characters of @var{s}.
-@end deffn
+@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
-@deffn {Scheme Procedure} string-pad s len [chr start end]
-@deffnx {Scheme Procedure} string-pad-right s len [chr start end]
-Take that characters from @var{start} to @var{end} from the
-string @var{s} and return a new string, right(left)-padded by the
-character @var{chr} to length @var{len}. If the resulting
-string is longer than @var{len}, it is truncated on the right (left).
-@end deffn
+@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
-@deffn {Scheme Procedure} string-trim s [char_pred start end]
-@deffnx {Scheme Procedure} string-trim-right s [char_pred start end]
-@deffnx {Scheme Procedure} string-trim-both s [char_pred start end]
-Trim @var{s} by skipping over all characters on the left/right/both
-sides of the string that satisfy the parameter @var{char_pred}:
+@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
-if it is the character @var{ch}, characters equal to
-@var{ch} are trimmed,
-
+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
-if it is a procedure @var{pred} characters that
-satisfy @var{pred} are trimmed,
-
+symbol @code{abandoned}: the mutex is in the unlocked/abandoned state
@item
-if it is a character set, characters in that set are trimmed.
+symbol @code{not-abandoned}: the mutex is in the
+unlocked/not-abandoned state
@end itemize
+@end defun
-If called without a @var{char_pred} argument, all whitespace is
-trimmed.
-@end deffn
+@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
-@c ===================================================================
-@node SRFI-13 Modification
-@subsubsection Modification
+@node SRFI-18 Condition variables
+@subsubsection SRFI-18 Condition variables
-The procedure @code{string-fill!} is extended from R5RS because it
-accepts optional start/end indices. This bindings shadows the procedure
-of the same name in the Guile core. The second modification procedure
-@code{string-set!} is documented in the Strings section (@pxref{String
-Modification}).
+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.
-@deffn {Scheme Procedure} string-fill! str chr [start end]
-Stores @var{chr} in every element of the given @var{str} and
-returns an unspecified value.
-@end deffn
+@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
-@c ===================================================================
+@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
-@node SRFI-13 Comparison
-@subsubsection Comparison
+@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
-The procedures in this section are used for comparing strings in
-different ways. The comparison predicates differ from those in R5RS in
-that they do not only return @code{#t} or @code{#f}, but the mismatch
-index in the case of a true return value.
+@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
-@code{string-hash} and @code{string-hash-ci} are for calculating hash
-values for strings, useful for implementing fast lookup mechanisms.
-@deffn {Scheme Procedure} string-compare s1 s2 proc_lt proc_eq proc_gt [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-compare-ci s1 s2 proc_lt proc_eq proc_gt [start1 end1 start2 end2]
-Apply @var{proc_lt}, @var{proc_eq}, @var{proc_gt} to the
-mismatch index, depending upon whether @var{s1} is less than,
-equal to, or greater than @var{s2}. The mismatch index is the
-largest index @var{i} such that for every 0 <= @var{j} <
-@var{i}, @var{s1}[@var{j}] = @var{s2}[@var{j}] - that is,
-@var{i} is the first position that does not match. The
-character comparison is done case-insensitively.
-@end deffn
+@node SRFI-18 Time
+@subsubsection SRFI-18 Time
-@deffn {Scheme Procedure} string= s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string<> s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string< s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string> s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string<= s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string>= s1 s2 [start1 end1 start2 end2]
-Compare @var{s1} and @var{s2} and return @code{#f} if the predicate
-fails. Otherwise, the mismatch index is returned (or @var{end1} in the
-case of @code{string=}.
-@end deffn
+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.
-@deffn {Scheme Procedure} string-ci= s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-ci<> s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-ci< s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-ci> s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-ci<= s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-ci>= s1 s2 [start1 end1 start2 end2]
-Compare @var{s1} and @var{s2} and return @code{#f} if the predicate
-fails. Otherwise, the mismatch index is returned (or @var{end1} in the
-case of @code{string=}. These are the case-insensitive variants.
-@end deffn
+@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
-@deffn {Scheme Procedure} string-hash s [bound start end]
-@deffnx {Scheme Procedure} string-hash-ci s [bound start end]
-Return a hash value of the string @var{s} in the range 0 @dots{}
-@var{bound} - 1. @code{string-hash-ci} is the case-insensitive variant.
-@end deffn
+@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
-@c ===================================================================
-@node SRFI-13 Prefixes/Suffixes
-@subsubsection Prefixes/Suffixes
+@node SRFI-18 Exceptions
+@subsubsection SRFI-18 Exceptions
-Using these procedures you can determine whether a given string is a
-prefix or suffix of another string or how long a common prefix/suffix
-is.
+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''.
-@deffn {Scheme Procedure} string-prefix-length s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-prefix-length-ci s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-suffix-length s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-suffix-length-ci s1 s2 [start1 end1 start2 end2]
-Return the length of the longest common prefix/suffix of the two
-strings. @code{string-prefix-length-ci} and
-@code{string-suffix-length-ci} are the case-insensitive variants.
-@end deffn
+@defun current-exception-handler
+Returns the current exception handler.
+@end defun
-@deffn {Scheme Procedure} string-prefix? s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-prefix-ci? s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-suffix? s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-suffix-ci? s1 s2 [start1 end1 start2 end2]
-Is @var{s1} a prefix/suffix of @var{s2}. @code{string-prefix-ci?} and
-@code{string-suffix-ci?} are the case-insensitive variants.
-@end deffn
+@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
-@c ===================================================================
+@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
-@node SRFI-13 Searching
-@subsubsection Searching
+@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
-Use these procedures to find out whether a string contains a given
-character or a given substring, or a character from a set of characters.
+@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
-@deffn {Scheme Procedure} string-index s char_pred [start end]
-@deffnx {Scheme Procedure} string-index-right s char_pred [start end]
-Search through the string @var{s} from left to right (right to left),
-returning the index of the first (last) occurrence of a character which
+@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
-@itemize @bullet
-@item
-equals @var{char_pred}, if it is character,
-@item
-satisfies the predicate @var{char_pred}, if it is a
-procedure,
+@node SRFI-19
+@subsection SRFI-19 - Time/Date Library
+@cindex SRFI-19
+@cindex time
+@cindex date
-@item
-is in the set @var{char_pred}, if it is a character set.
-@end itemize
-@end deffn
+This is an implementation of the SRFI-19 time/date library. The
+functions and variables described here are provided by
-@deffn {Scheme Procedure} string-skip s char_pred [start end]
-@deffnx {Scheme Procedure} string-skip-right s char_pred [start end]
-Search through the string @var{s} from left to right (right to left),
-returning the index of the first (last) occurrence of a character which
+@example
+(use-modules (srfi srfi-19))
+@end example
-@itemize @bullet
-@item
-does not equal @var{char_pred}, if it is character,
+@strong{Caution}: The current code in this module incorrectly extends
+the Gregorian calendar leap year rule back prior to the introduction
+of those reforms in 1582 (or the appropriate year in various
+countries). The Julian calendar was used prior to 1582, and there
+were 10 days skipped for the reform, but the code doesn't implement
+that.
-@item
-does not satisfy the predicate @var{char_pred}, if it is
-a procedure.
+This will be fixed some time. Until then calculations for 1583
+onwards are correct, but prior to that any day/month/year and day of
+the week calculations are wrong.
-@item
-is not in the set if @var{char_pred} is a character set.
-@end itemize
-@end deffn
+@menu
+* SRFI-19 Introduction::
+* SRFI-19 Time::
+* SRFI-19 Date::
+* SRFI-19 Time/Date conversions::
+* SRFI-19 Date to string::
+* SRFI-19 String to date::
+@end menu
-@deffn {Scheme Procedure} string-count s char_pred [start end]
-Return the count of the number of characters in the string
-@var{s} which
+@node SRFI-19 Introduction
+@subsubsection SRFI-19 Introduction
-@itemize @bullet
-@item
-equals @var{char_pred}, if it is character,
+@cindex universal time
+@cindex atomic time
+@cindex UTC
+@cindex TAI
+This module implements time and date representations and calculations,
+in various time systems, including universal time (UTC) and atomic
+time (TAI).
-@item
-satisfies the predicate @var{char_pred}, if it is a procedure.
+For those not familiar with these time systems, TAI is based on a
+fixed length second derived from oscillations of certain atoms. UTC
+differs from TAI by an integral number of seconds, which is increased
+or decreased at announced times to keep UTC aligned to a mean solar
+day (the orbit and rotation of the earth are not quite constant).
-@item
-is in the set @var{char_pred}, if it is a character set.
-@end itemize
-@end deffn
+@cindex leap second
+So far, only increases in the TAI
+@tex
+$\leftrightarrow$
+@end tex
+@ifnottex
+<->
+@end ifnottex
+UTC difference have been needed. Such an increase is a ``leap
+second'', an extra second of TAI introduced at the end of a UTC day.
+When working entirely within UTC this is never seen, every day simply
+has 86400 seconds. But when converting from TAI to a UTC date, an
+extra 23:59:60 is present, where normally a day would end at 23:59:59.
+Effectively the UTC second from 23:59:59 to 00:00:00 has taken two TAI
+seconds.
-@deffn {Scheme Procedure} string-contains s1 s2 [start1 end1 start2 end2]
-@deffnx {Scheme Procedure} string-contains-ci s1 s2 [start1 end1 start2 end2]
-Does string @var{s1} contain string @var{s2}? Return the index
-in @var{s1} where @var{s2} occurs as a substring, or false.
-The optional start/end indices restrict the operation to the
-indicated substrings.
+@cindex system clock
+In the current implementation, the system clock is assumed to be UTC,
+and a table of leap seconds in the code converts to TAI. See comments
+in @file{srfi-19.scm} for how to update this table.
-@code{string-contains-ci} is the case-insensitive variant.
-@end deffn
+@cindex julian day
+@cindex modified julian day
+Also, for those not familiar with the terminology, a @dfn{Julian Day}
+is a real number which is a count of days and fraction of a day, in
+UTC, starting from -4713-01-01T12:00:00Z, ie.@: midday Monday 1 Jan
+4713 B.C. A @dfn{Modified Julian Day} is the same, but starting from
+1858-11-17T00:00:00Z, ie.@: midnight 17 November 1858 UTC. That time
+is julian day 2400000.5.
+@c The SRFI-1 spec says -4714-11-24T12:00:00Z (November 24, -4714 at
+@c noon, UTC), but this is incorrect. It looks like it might have
+@c arisen from the code incorrectly treating years a multiple of 100
+@c but not 400 prior to 1582 as non-leap years, where instead the Julian
+@c calendar should be used so all multiples of 4 before 1582 are leap
+@c years.
-@c ===================================================================
-@node SRFI-13 Case Mapping
-@subsubsection Alphabetic Case Mapping
+@node SRFI-19 Time
+@subsubsection SRFI-19 Time
+@cindex time
-These procedures convert the alphabetic case of strings. They are
-similar to the procedures in the Guile core, but are extended to handle
-optional start/end indices.
+A @dfn{time} object has type, seconds and nanoseconds fields
+representing a point in time starting from some epoch. This is an
+arbitrary point in time, not just a time of day. Although times are
+represented in nanoseconds, the actual resolution may be lower.
-@deffn {Scheme Procedure} string-upcase s [start end]
-@deffnx {Scheme Procedure} string-upcase! s [start end]
-Upcase every character in @var{s}. @code{string-upcase!} is the
-side-effecting variant.
-@end deffn
+The following variables hold the possible time types. For instance
+@code{(current-time time-process)} would give the current CPU process
+time.
-@deffn {Scheme Procedure} string-downcase s [start end]
-@deffnx {Scheme Procedure} string-downcase! s [start end]
-Downcase every character in @var{s}. @code{string-downcase!} is the
-side-effecting variant.
-@end deffn
+@defvar time-utc
+Universal Coordinated Time (UTC).
+@cindex UTC
+@end defvar
-@deffn {Scheme Procedure} string-titlecase s [start end]
-@deffnx {Scheme Procedure} string-titlecase! s [start end]
-Upcase every first character in every word in @var{s}, downcase the
-other characters. @code{string-titlecase!} is the side-effecting
-variant.
-@end deffn
+@defvar time-tai
+International Atomic Time (TAI).
+@cindex TAI
+@end defvar
+@defvar time-monotonic
+Monotonic time, meaning a monotonically increasing time starting from
+an unspecified epoch.
-@c ===================================================================
+Note that in the current implementation @code{time-monotonic} is the
+same as @code{time-tai}, and unfortunately is therefore affected by
+adjustments to the system clock. Perhaps this will change in the
+future.
+@end defvar
-@node SRFI-13 Reverse/Append
-@subsubsection Reverse/Append
+@defvar time-duration
+A duration, meaning simply a difference between two times.
+@end defvar
-One appending procedure, @code{string-append} is the same in R5RS and in
-SRFI-13, so it is not redefined.
+@defvar time-process
+CPU time spent in the current process, starting from when the process
+began.
+@cindex process time
+@end defvar
-@deffn {Scheme Procedure} string-reverse str [start end]
-@deffnx {Scheme Procedure} string-reverse! str [start end]
-Reverse the string @var{str}. The optional arguments
-@var{start} and @var{end} delimit the region of @var{str} to
-operate on.
+@defvar time-thread
+CPU time spent in the current thread. Not currently implemented.
+@cindex thread time
+@end defvar
-@code{string-reverse!} modifies the argument string and returns an
-unspecified value.
-@end deffn
+@sp 1
+@defun time? obj
+Return @code{#t} if @var{obj} is a time object, or @code{#f} if not.
+@end defun
-@deffn {Scheme Procedure} string-append/shared ls @dots{}
-Like @code{string-append}, but the result may share memory
-with the argument strings.
-@end deffn
+@defun make-time type nanoseconds seconds
+Create a time object with the given @var{type}, @var{seconds} and
+@var{nanoseconds}.
+@end defun
-@deffn {Scheme Procedure} string-concatenate ls
-Append the elements of @var{ls} (which must be strings)
-together into a single string. Guaranteed to return a freshly
-allocated string.
-@end deffn
+@defun time-type time
+@defunx time-nanosecond time
+@defunx time-second time
+@defunx set-time-type! time type
+@defunx set-time-nanosecond! time nsec
+@defunx set-time-second! time sec
+Get or set the type, seconds or nanoseconds fields of a time object.
-@deffn {Scheme Procedure} string-concatenate/shared ls
-Like @code{string-concatenate}, but the result may share memory
-with the strings in the list @var{ls}.
-@end deffn
+@code{set-time-type!} merely changes the field, it doesn't convert the
+time value. For conversions, see @ref{SRFI-19 Time/Date conversions}.
+@end defun
-@deffn {Scheme Procedure} string-concatenate-reverse ls final_string end
-Without optional arguments, this procedure is equivalent to
+@defun copy-time time
+Return a new time object, which is a copy of the given @var{time}.
+@end defun
-@smalllisp
-(string-concatenate (reverse ls))
-@end smalllisp
+@defun current-time [type]
+Return the current time of the given @var{type}. The default
+@var{type} is @code{time-utc}.
-If the optional argument @var{final_string} is specified, it is
-consed onto the beginning to @var{ls} before performing the
-list-reverse and string-concatenate operations. If @var{end}
-is given, only the characters of @var{final_string} up to index
-@var{end} are used.
+Note that the name @code{current-time} conflicts with the Guile core
+@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
-Guaranteed to return a freshly allocated string.
-@end deffn
+@defun time-resolution [type]
+Return the resolution, in nanoseconds, of the given time @var{type}.
+The default @var{type} is @code{time-utc}.
+@end defun
-@deffn {Scheme Procedure} string-concatenate-reverse/shared ls final_string end
-Like @code{string-concatenate-reverse}, but the result may
-share memory with the the strings in the @var{ls} arguments.
-@end deffn
+@defun time<=? t1 t2
+@defunx time<? t1 t2
+@defunx time=? t1 t2
+@defunx time>=? t1 t2
+@defunx time>? t1 t2
+Return @code{#t} or @code{#f} according to the respective relation
+between time objects @var{t1} and @var{t2}. @var{t1} and @var{t2}
+must be the same time type.
+@end defun
+@defun time-difference t1 t2
+@defunx time-difference! t1 t2
+Return a time object of type @code{time-duration} representing the
+period between @var{t1} and @var{t2}. @var{t1} and @var{t2} must be
+the same time type.
-@c ===================================================================
+@code{time-difference} returns a new time object,
+@code{time-difference!} may modify @var{t1} to form its return.
+@end defun
-@node SRFI-13 Fold/Unfold/Map
-@subsubsection Fold/Unfold/Map
+@defun add-duration time duration
+@defunx add-duration! time duration
+@defunx subtract-duration time duration
+@defunx subtract-duration! time duration
+Return a time object which is @var{time} with the given @var{duration}
+added or subtracted. @var{duration} must be a time object of type
+@code{time-duration}.
-@code{string-map}, @code{string-for-each} etc. are for iterating over
-the characters a string is composed of. The fold and unfold procedures
-are list iterators and constructors.
+@code{add-duration} and @code{subtract-duration} return a new time
+object. @code{add-duration!} and @code{subtract-duration!} may modify
+the given @var{time} to form their return.
+@end defun
-@deffn {Scheme Procedure} string-map proc s [start end]
-@var{proc} is a char->char procedure, it is mapped over
-@var{s}. The order in which the procedure is applied to the
-string elements is not specified.
-@end deffn
-@deffn {Scheme Procedure} string-map! proc s [start end]
-@var{proc} is a char->char procedure, it is mapped over
-@var{s}. The order in which the procedure is applied to the
-string elements is not specified. The string @var{s} is
-modified in-place, the return value is not specified.
-@end deffn
+@node SRFI-19 Date
+@subsubsection SRFI-19 Date
+@cindex date
-@deffn {Scheme Procedure} string-fold kons knil s [start end]
-@deffnx {Scheme Procedure} string-fold-right kons knil s [start end]
-Fold @var{kons} over the characters of @var{s}, with @var{knil} as the
-terminating element, from left to right (or right to left, for
-@code{string-fold-right}). @var{kons} must expect two arguments: The
-actual character and the last result of @var{kons}' application.
-@end deffn
+A @dfn{date} object represents a date in the Gregorian calendar and a
+time of day on that date in some timezone.
-@deffn {Scheme Procedure} string-unfold p f g seed [base make_final]
-@deffnx {Scheme Procedure} string-unfold-right p f g seed [base make_final]
-These are the fundamental string constructors.
-@itemize @bullet
-@item @var{g} is used to generate a series of @emph{seed}
-values from the initial @var{seed}: @var{seed}, (@var{g}
-@var{seed}), (@var{g}^2 @var{seed}), (@var{g}^3 @var{seed}),
-@dots{}
-@item @var{p} tells us when to stop - when it returns true
-when applied to one of these seed values.
-@item @var{f} maps each seed value to the corresponding
-character in the result string. These chars are assembled into the
-string in a left-to-right (right-to-left) order.
-@item @var{base} is the optional initial/leftmost (rightmost)
- portion of the constructed string; it default to the empty string.
-@item @var{make_final} is applied to the terminal seed
-value (on which @var{p} returns true) to produce the final/rightmost
-(leftmost) portion of the constructed string. It defaults to
-@code{(lambda (x) "")}.
-@end itemize
-@end deffn
+The fields are year, month, day, hour, minute, second, nanoseconds and
+timezone. A date object is immutable, its fields can be read but they
+cannot be modified once the object is created.
-@deffn {Scheme Procedure} string-for-each proc s [start end]
-@var{proc} is mapped over @var{s} in left-to-right order. The
-return value is not specified.
-@end deffn
+@defun date? obj
+Return @code{#t} if @var{obj} is a date object, or @code{#f} if not.
+@end defun
+@defun make-date nsecs seconds minutes hours date month year zone-offset
+Create a new date object.
+@c
+@c FIXME: What can we say about the ranges of the values. The
+@c current code looks it doesn't normalize, but expects then in their
+@c usual range already.
+@c
+@end defun
-@c ===================================================================
+@defun date-nanosecond date
+Nanoseconds, 0 to 999999999.
+@end defun
-@node SRFI-13 Replicate/Rotate
-@subsubsection Replicate/Rotate
+@defun date-second date
+Seconds, 0 to 59, or 60 for a leap second. 60 is never seen when working
+entirely within UTC, it's only when converting to or from TAI.
+@end defun
-These procedures are special substring procedures, which can also be
-used for replicating strings. They are a bit tricky to use, but
-consider this code fragment, which replicates the input string
-@code{"foo"} so often that the resulting string has a length of six.
+@defun date-minute date
+Minutes, 0 to 59.
+@end defun
-@lisp
-(xsubstring "foo" 0 6)
-@result{}
-"foofoo"
-@end lisp
+@defun date-hour date
+Hour, 0 to 23.
+@end defun
-@deffn {Scheme Procedure} xsubstring s from [to start end]
-This is the @emph{extended substring} procedure that implements
-replicated copying of a substring of some string.
+@defun date-day date
+Day of the month, 1 to 31 (or less, according to the month).
+@end defun
-@var{s} is a string, @var{start} and @var{end} are optional
-arguments that demarcate a substring of @var{s}, defaulting to
-0 and the length of @var{s}. Replicate this substring up and
-down index space, in both the positive and negative directions.
-@code{xsubstring} returns the substring of this string
-beginning at index @var{from}, and ending at @var{to}, which
-defaults to @var{from} + (@var{end} - @var{start}).
-@end deffn
+@defun date-month date
+Month, 1 to 12.
+@end defun
-@deffn {Scheme Procedure} string-xcopy! target tstart s sfrom [sto start end]
-Exactly the same as @code{xsubstring}, but the extracted text
-is written into the string @var{target} starting at index
-@var{tstart}. The operation is not defined if @code{(eq?
-@var{target} @var{s})} or these arguments share storage - you
-cannot copy a string on top of itself.
-@end deffn
+@defun date-year date
+Year, eg.@: 2003. Dates B.C.@: are negative, eg.@: @math{-46} is 46
+B.C. There is no year 0, year @math{-1} is followed by year 1.
+@end defun
+@defun date-zone-offset date
+Time zone, an integer number of seconds east of Greenwich.
+@end defun
-@c ===================================================================
+@defun date-year-day date
+Day of the year, starting from 1 for 1st January.
+@end defun
-@node SRFI-13 Miscellaneous
-@subsubsection Miscellaneous
+@defun date-week-day date
+Day of the week, starting from 0 for Sunday.
+@end defun
-@code{string-replace} is for replacing a portion of a string with
-another string and @code{string-tokenize} splits a string into a list of
-strings, breaking it up at a specified character.
+@defun date-week-number date dstartw
+Week of the year, ignoring a first partial week. @var{dstartw} is the
+day of the week which is taken to start a week, 0 for Sunday, 1 for
+Monday, etc.
+@c
+@c FIXME: The spec doesn't say whether numbering starts at 0 or 1.
+@c The code looks like it's 0, if that's the correct intention.
+@c
+@end defun
-@deffn {Scheme Procedure} string-replace s1 s2 [start1 end1 start2 end2]
-Return the string @var{s1}, but with the characters
-@var{start1} @dots{} @var{end1} replaced by the characters
-@var{start2} @dots{} @var{end2} from @var{s2}.
+@c The SRFI text doesn't actually give the default for tz-offset, but
+@c the reference implementation has the local timezone and the
+@c conversions functions all specify that, so it should be ok to
+@c document it here.
+@c
+@defun current-date [tz-offset]
+Return a date object representing the current date/time, in UTC offset
+by @var{tz-offset}. @var{tz-offset} is seconds east of Greenwich and
+defaults to the local timezone.
+@end defun
-For reference, note that SRFI-13 specifies @var{start1} and @var{end1}
-as mandatory, but in Guile they are optional.
-@end deffn
+@defun current-julian-day
+@cindex julian day
+Return the current Julian Day.
+@end defun
-@deffn {Scheme Procedure} string-tokenize s [token-set start end]
-Split the string @var{s} into a list of substrings, where each
-substring is a maximal non-empty contiguous sequence of characters
-from the character set @var{token_set}, which defaults to an
-equivalent of @code{char-set:graphic}. If @var{start} or @var{end}
-indices are provided, they restrict @code{string-tokenize} to
-operating on the indicated substring of @var{s}.
-@end deffn
+@defun current-modified-julian-day
+@cindex modified julian day
+Return the current Modified Julian Day.
+@end defun
-@c ===================================================================
+@node SRFI-19 Time/Date conversions
+@subsubsection SRFI-19 Time/Date conversions
+@cindex time conversion
+@cindex date conversion
-@node SRFI-13 Filtering/Deleting
-@subsubsection Filtering/Deleting
+@defun date->julian-day date
+@defunx date->modified-julian-day date
+@defunx date->time-monotonic date
+@defunx date->time-tai date
+@defunx date->time-utc date
+@end defun
+@defun julian-day->date jdn [tz-offset]
+@defunx julian-day->time-monotonic jdn
+@defunx julian-day->time-tai jdn
+@defunx julian-day->time-utc jdn
+@end defun
+@defun modified-julian-day->date jdn [tz-offset]
+@defunx modified-julian-day->time-monotonic jdn
+@defunx modified-julian-day->time-tai jdn
+@defunx modified-julian-day->time-utc jdn
+@end defun
+@defun time-monotonic->date time [tz-offset]
+@defunx time-monotonic->time-tai time
+@defunx time-monotonic->time-tai! time
+@defunx time-monotonic->time-utc time
+@defunx time-monotonic->time-utc! time
+@end defun
+@defun time-tai->date time [tz-offset]
+@defunx time-tai->julian-day time
+@defunx time-tai->modified-julian-day time
+@defunx time-tai->time-monotonic time
+@defunx time-tai->time-monotonic! time
+@defunx time-tai->time-utc time
+@defunx time-tai->time-utc! time
+@end defun
+@defun time-utc->date time [tz-offset]
+@defunx time-utc->julian-day time
+@defunx time-utc->modified-julian-day time
+@defunx time-utc->time-monotonic time
+@defunx time-utc->time-monotonic! time
+@defunx time-utc->time-tai time
+@defunx time-utc->time-tai! time
+@sp 1
+Convert between dates, times and days of the respective types. For
+instance @code{time-tai->time-utc} accepts a @var{time} object of type
+@code{time-tai} and returns an object of type @code{time-utc}.
-@dfn{Filtering} means to remove all characters from a string which do
-not match a given criteria, @dfn{deleting} means the opposite.
+The @code{!} variants may modify their @var{time} argument to form
+their return. The plain functions create a new object.
-@deffn {Scheme Procedure} string-filter s char_pred [start end]
-Filter the string @var{s}, retaining only those characters that
-satisfy the @var{char_pred} argument. If the argument is a
-procedure, it is applied to each character as a predicate, if
-it is a character, it is tested for equality and if it is a
-character set, it is tested for membership.
-@end deffn
+For conversions to dates, @var{tz-offset} is seconds east of
+Greenwich. The default is the local timezone, at the given time, as
+provided by the system, using @code{localtime} (@pxref{Time}).
+
+On 32-bit systems, @code{localtime} is limited to a 32-bit
+@code{time_t}, so a default @var{tz-offset} is only available for
+times between Dec 1901 and Jan 2038. For prior dates an application
+might like to use the value in 1902, though some locations have zone
+changes prior to that. For future dates an application might like to
+assume today's rules extend indefinitely. But for correct daylight
+savings transitions it will be necessary to take an offset for the
+same day and time but a year in range and which has the same starting
+weekday and same leap/non-leap (to support rules like last Sunday in
+October).
+@end defun
-@deffn {Scheme Procedure} string-delete s char_pred [start end]
-Filter the string @var{s}, retaining only those characters that
-do not satisfy the @var{char_pred} argument. If the argument
-is a procedure, it is applied to each character as a predicate,
-if it is a character, it is tested for equality and if it is a
-character set, it is tested for membership.
-@end deffn
+@node SRFI-19 Date to string
+@subsubsection SRFI-19 Date to string
+@cindex date to string
+@cindex string, from date
+@defun date->string date [format]
+Convert a date to a string under the control of a format.
+@var{format} should be a string containing @samp{~} escapes, which
+will be expanded as per the following conversion table. The default
+@var{format} is @samp{~c}, a locale-dependent date and time.
-@node SRFI-14
-@subsection SRFI-14 - Character-set Library
-@cindex SRFI-14
+Many of these conversion characters are the same as POSIX
+@code{strftime} (@pxref{Time}), but there are some extras and some
+variations.
-SRFI-14 defines the data type @dfn{character set}, and also defines a
-lot of procedures for handling this character type, and a few standard
-character sets like whitespace, alphabetic characters and others.
+@multitable {MMMM} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
+@item @nicode{~~} @tab literal ~
+@item @nicode{~a} @tab locale abbreviated weekday, eg.@: @samp{Sun}
+@item @nicode{~A} @tab locale full weekday, eg.@: @samp{Sunday}
+@item @nicode{~b} @tab locale abbreviated month, eg.@: @samp{Jan}
+@item @nicode{~B} @tab locale full month, eg.@: @samp{January}
+@item @nicode{~c} @tab locale date and time, eg.@: @*
+@samp{Fri Jul 14 20:28:42-0400 2000}
+@item @nicode{~d} @tab day of month, zero padded, @samp{01} to @samp{31}
-All procedures from SRFI-14 (character-set library) are implemented in
-the module @code{(srfi srfi-14)}, as well as the standard variables
-@code{char-set:letter}, @code{char-set:digit} etc.
+@c Spec says d/m/y, reference implementation says m/d/y.
+@c Apparently the reference code was the intention, but would like to
+@c see an errata published for the spec before contradicting it here.
+@c
+@c @item @nicode{~D} @tab date @nicode{~d/~m/~y}
-@menu
-* Loading SRFI-14:: How to make charsets available.
-* SRFI-14 Character Set Data Type:: Underlying data type for charsets.
-* SRFI-14 Predicates/Comparison:: Charset predicates.
-* SRFI-14 Iterating Over Character Sets:: Enumerate charset elements.
-* SRFI-14 Creating Character Sets:: Making new charsets.
-* SRFI-14 Querying Character Sets:: Test charsets for membership etc.
-* SRFI-14 Character-Set Algebra:: Calculating new charsets.
-* SRFI-14 Standard Character Sets:: Variables containing predefined charsets.
-@end menu
+@item @nicode{~e} @tab day of month, blank padded, @samp{ 1} to @samp{31}
+@item @nicode{~f} @tab seconds and fractional seconds,
+with locale decimal point, eg.@: @samp{5.2}
+@item @nicode{~h} @tab same as @nicode{~b}
+@item @nicode{~H} @tab hour, 24-hour clock, zero padded, @samp{00} to @samp{23}
+@item @nicode{~I} @tab hour, 12-hour clock, zero padded, @samp{01} to @samp{12}
+@item @nicode{~j} @tab day of year, zero padded, @samp{001} to @samp{366}
+@item @nicode{~k} @tab hour, 24-hour clock, blank padded, @samp{ 0} to @samp{23}
+@item @nicode{~l} @tab hour, 12-hour clock, blank padded, @samp{ 1} to @samp{12}
+@item @nicode{~m} @tab month, zero padded, @samp{01} to @samp{12}
+@item @nicode{~M} @tab minute, zero padded, @samp{00} to @samp{59}
+@item @nicode{~n} @tab newline
+@item @nicode{~N} @tab nanosecond, zero padded, @samp{000000000} to @samp{999999999}
+@item @nicode{~p} @tab locale AM or PM
+@item @nicode{~r} @tab time, 12 hour clock, @samp{~I:~M:~S ~p}
+@item @nicode{~s} @tab number of full seconds since ``the epoch'' in UTC
+@item @nicode{~S} @tab second, zero padded @samp{00} to @samp{60} @*
+(usual limit is 59, 60 is a leap second)
+@item @nicode{~t} @tab horizontal tab character
+@item @nicode{~T} @tab time, 24 hour clock, @samp{~H:~M:~S}
+@item @nicode{~U} @tab week of year, Sunday first day of week,
+@samp{00} to @samp{52}
+@item @nicode{~V} @tab week of year, Monday first day of week,
+@samp{01} to @samp{53}
+@item @nicode{~w} @tab day of week, 0 for Sunday, @samp{0} to @samp{6}
+@item @nicode{~W} @tab week of year, Monday first day of week,
+@samp{00} to @samp{52}
+@c The spec has ~x as an apparent duplicate of ~W, and ~X as a locale
+@c date. The reference code has ~x as the locale date and ~X as a
+@c locale time. The rule is apparently that the code should be
+@c believed, but would like to see an errata for the spec before
+@c contradicting it here.
+@c
+@c @item @nicode{~x} @tab week of year, Monday as first day of week,
+@c @samp{00} to @samp{53}
+@c @item @nicode{~X} @tab locale date, eg.@: @samp{07/31/00}
-@node Loading SRFI-14
-@subsubsection Loading SRFI-14
+@item @nicode{~y} @tab year, two digits, @samp{00} to @samp{99}
+@item @nicode{~Y} @tab year, full, eg.@: @samp{2003}
+@item @nicode{~z} @tab time zone, RFC-822 style
+@item @nicode{~Z} @tab time zone symbol (not currently implemented)
+@item @nicode{~1} @tab ISO-8601 date, @samp{~Y-~m-~d}
+@item @nicode{~2} @tab ISO-8601 time+zone, @samp{~k:~M:~S~z}
+@item @nicode{~3} @tab ISO-8601 time, @samp{~k:~M:~S}
+@item @nicode{~4} @tab ISO-8601 date/time+zone, @samp{~Y-~m-~dT~k:~M:~S~z}
+@item @nicode{~5} @tab ISO-8601 date/time, @samp{~Y-~m-~dT~k:~M:~S}
+@end multitable
+@end defun
+
+Conversions @samp{~D}, @samp{~x} and @samp{~X} are not currently
+described here, since the specification and reference implementation
+differ.
+
+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
+@subsubsection SRFI-19 String to date
+@cindex string to date
+@cindex date, from string
+
+@c FIXME: Can we say what happens when an incomplete date is
+@c converted? Ie. fields left as 0, or what? The spec seems to be
+@c silent on this.
+
+@defun string->date input template
+Convert an @var{input} string to a date under the control of a
+@var{template} string. Return a newly created date object.
+
+Literal characters in @var{template} must match characters in
+@var{input} and @samp{~} escapes must match the input forms described
+in the table below. ``Skip to'' means characters up to one of the
+given type are ignored, or ``no skip'' for no skipping. ``Read'' is
+what's then read, and ``Set'' is the field affected in the date
+object.
+
+For example @samp{~Y} skips input characters until a digit is reached,
+at which point it expects a year and stores that to the year field of
+the date.
+
+@multitable {MMMM} {@nicode{char-alphabetic?}} {MMMMMMMMMMMMMMMMMMMMMMMMM} {@nicode{date-zone-offset}}
+@item
+@tab Skip to
+@tab Read
+@tab Set
+
+@item @nicode{~~}
+@tab no skip
+@tab literal ~
+@tab nothing
+
+@item @nicode{~a}
+@tab @nicode{char-alphabetic?}
+@tab locale abbreviated weekday name
+@tab nothing
-When Guile is properly installed, SRFI-14 support can be loaded into a
-running Guile by using the @code{(srfi srfi-14)} module.
+@item @nicode{~A}
+@tab @nicode{char-alphabetic?}
+@tab locale full weekday name
+@tab nothing
+
+@c Note that the SRFI spec says that ~b and ~B don't set anything,
+@c but that looks like a mistake. The reference implementation sets
+@c the month field, which seems sensible and is what we describe
+@c here.
+
+@item @nicode{~b}
+@tab @nicode{char-alphabetic?}
+@tab locale abbreviated month name
+@tab @nicode{date-month}
+
+@item @nicode{~B}
+@tab @nicode{char-alphabetic?}
+@tab locale full month name
+@tab @nicode{date-month}
+
+@item @nicode{~d}
+@tab @nicode{char-numeric?}
+@tab day of month
+@tab @nicode{date-day}
+
+@item @nicode{~e}
+@tab no skip
+@tab day of month, blank padded
+@tab @nicode{date-day}
+
+@item @nicode{~h}
+@tab same as @samp{~b}
+
+@item @nicode{~H}
+@tab @nicode{char-numeric?}
+@tab hour
+@tab @nicode{date-hour}
+
+@item @nicode{~k}
+@tab no skip
+@tab hour, blank padded
+@tab @nicode{date-hour}
+
+@item @nicode{~m}
+@tab @nicode{char-numeric?}
+@tab month
+@tab @nicode{date-month}
+
+@item @nicode{~M}
+@tab @nicode{char-numeric?}
+@tab minute
+@tab @nicode{date-minute}
+
+@item @nicode{~S}
+@tab @nicode{char-numeric?}
+@tab second
+@tab @nicode{date-second}
+
+@item @nicode{~y}
+@tab no skip
+@tab 2-digit year
+@tab @nicode{date-year} within 50 years
+
+@item @nicode{~Y}
+@tab @nicode{char-numeric?}
+@tab year
+@tab @nicode{date-year}
+
+@item @nicode{~z}
+@tab no skip
+@tab time zone
+@tab date-zone-offset
+@end multitable
+
+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.
+
+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
+
+
+@node SRFI-26
+@subsection SRFI-26 - specializing parameters
+@cindex SRFI-26
+@cindex parameter specialize
+@cindex argument specialize
+@cindex specialize parameter
+
+This SRFI provides a syntax for conveniently specializing selected
+parameters of a function. It can be used with,
@example
-$ guile
-guile> (use-modules (srfi srfi-14))
-guile> (char-set-union (char-set #\f #\o #\o) (string->char-set "bar"))
-#<charset @{#\a #\b #\f #\o #\r@}>
-guile>
+(use-modules (srfi srfi-26))
@end example
+@deffn {library syntax} cut slot @dots{}
+@deffnx {library syntax} cute slot @dots{}
+Return a new procedure which will make a call (@var{slot} @dots{}) but
+with selected parameters specialized to given expressions.
-@node SRFI-14 Character Set Data Type
-@subsubsection Character Set Data Type
+An example will illustrate the idea. The following is a
+specialization of @code{write}, sending output to
+@code{my-output-port},
-The data type @dfn{charset} implements sets of characters
-(@pxref{Characters}). Because the internal representation of character
-sets is not visible to the user, a lot of procedures for handling them
-are provided.
+@example
+(cut write <> my-output-port)
+@result{}
+(lambda (obj) (write obj my-output-port))
+@end example
-Character sets can be created, extended, tested for the membership of a
-characters and be compared to other character sets.
+The special symbol @code{<>} indicates a slot to be filled by an
+argument to the new procedure. @code{my-output-port} on the other
+hand is an expression to be evaluated and passed, ie.@: it specializes
+the behaviour of @code{write}.
-The Guile implementation of character sets deals with 8-bit characters.
-In the standard variables, only the ASCII part of the character range is
-really used, so that for example @dfn{Umlaute} and other accented
-characters are not considered to be letters. In the future, as Guile
-may get support for international character sets, this will change, so
-don't rely on these ``features''.
+@table @nicode
+@item <>
+A slot to be filled by an argument from the created procedure.
+Arguments are assigned to @code{<>} slots in the order they appear in
+the @code{cut} form, there's no way to re-arrange arguments.
+The first argument to @code{cut} is usually a procedure (or expression
+giving a procedure), but @code{<>} is allowed there too. For example,
-@c ===================================================================
+@example
+(cut <> 1 2 3)
+@result{}
+(lambda (proc) (proc 1 2 3))
+@end example
-@node SRFI-14 Predicates/Comparison
-@subsubsection Predicates/Comparison
+@item <...>
+A slot to be filled by all remaining arguments from the new procedure.
+This can only occur at the end of a @code{cut} form.
-Use these procedures for testing whether an object is a character set,
-or whether several character sets are equal or subsets of each other.
-@code{char-set-hash} can be used for calculating a hash value, maybe for
-usage in fast lookup procedures.
+For example, a procedure taking a variable number of arguments like
+@code{max} but in addition enforcing a lower bound,
-@deffn {Scheme Procedure} char-set? obj
-Return @code{#t} if @var{obj} is a character set, @code{#f}
-otherwise.
-@end deffn
+@example
+(define my-lower-bound 123)
-@deffn {Scheme Procedure} char-set= cs1 @dots{}
-Return @code{#t} if all given character sets are equal.
-@end deffn
+(cut max my-lower-bound <...>)
+@result{}
+(lambda arglist (apply max my-lower-bound arglist))
+@end example
+@end table
+
+For @code{cut} the specializing expressions are evaluated each time
+the new procedure is called. For @code{cute} they're evaluated just
+once, when the new procedure is created. The name @code{cute} stands
+for ``@code{cut} with evaluated arguments''. In all cases the
+evaluations take place in an unspecified order.
+
+The following illustrates the difference between @code{cut} and
+@code{cute},
+
+@example
+(cut format <> "the time is ~s" (current-time))
+@result{}
+(lambda (port) (format port "the time is ~s" (current-time)))
+
+(cute format <> "the time is ~s" (current-time))
+@result{}
+(let ((val (current-time)))
+ (lambda (port) (format port "the time is ~s" val))
+@end example
+
+(There's no provision for a mixture of @code{cut} and @code{cute}
+where some expressions would be evaluated every time but others
+evaluated only once.)
+
+@code{cut} is really just a shorthand for the sort of @code{lambda}
+forms shown in the above examples. But notice @code{cut} avoids the
+need to name unspecialized parameters, and is more compact. Use in
+functional programming style or just with @code{map}, @code{for-each}
+or similar is typical.
-@deffn {Scheme Procedure} char-set<= cs1 @dots{}
-Return @code{#t} if every character set @var{cs}i is a subset
-of character set @var{cs}i+1.
-@end deffn
+@example
+(map (cut * 2 <>) '(1 2 3 4))
-@deffn {Scheme Procedure} char-set-hash cs [bound]
-Compute a hash value for the character set @var{cs}. If
-@var{bound} is given and not @code{#f}, it restricts the
-returned value to the range 0 @dots{} @var{bound - 1}.
+(for-each (cut write <> my-port) my-list)
+@end example
@end deffn
+@node SRFI-27
+@subsection SRFI-27 - Sources of Random Bits
+@cindex SRFI-27
-@c ===================================================================
-
-@node SRFI-14 Iterating Over Character Sets
-@subsubsection Iterating Over Character Sets
+This subsection is based on the
+@uref{http://srfi.schemers.org/srfi-27/srfi-27.html, specification of
+SRFI-27} written by Sebastian Egner.
-Character set cursors are a means for iterating over the members of a
-character sets. After creating a character set cursor with
-@code{char-set-cursor}, a cursor can be dereferenced with
-@code{char-set-ref}, advanced to the next member with
-@code{char-set-cursor-next}. Whether a cursor has passed past the last
-element of the set can be checked with @code{end-of-char-set?}.
+@c The copyright notice and license text of the SRFI-27 specification is
+@c reproduced below:
-Additionally, mapping and (un-)folding procedures for character sets are
-provided.
+@c Copyright (C) Sebastian Egner (2002). All Rights Reserved.
-@deffn {Scheme Procedure} char-set-cursor cs
-Return a cursor into the character set @var{cs}.
-@end deffn
+@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:
-@deffn {Scheme Procedure} char-set-ref cs cursor
-Return the character at the current cursor position
-@var{cursor} in the character set @var{cs}. It is an error to
-pass a cursor for which @code{end-of-char-set?} returns true.
-@end deffn
+@c The above copyright notice and this permission notice shall be included
+@c in all copies or substantial portions of the Software.
-@deffn {Scheme Procedure} char-set-cursor-next cs cursor
-Advance the character set cursor @var{cursor} to the next
-character in the character set @var{cs}. It is an error if the
-cursor given satisfies @code{end-of-char-set?}.
-@end deffn
+@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.
-@deffn {Scheme Procedure} end-of-char-set? cursor
-Return @code{#t} if @var{cursor} has reached the end of a
-character set, @code{#f} otherwise.
-@end deffn
+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.
-@deffn {Scheme Procedure} char-set-fold kons knil cs
-Fold the procedure @var{kons} over the character set @var{cs},
-initializing it with @var{knil}.
-@end deffn
+@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
-@deffn {Scheme Procedure} char-set-unfold p f g seed [base_cs]
-@deffnx {Scheme Procedure} char-set-unfold! p f g seed base_cs
-This is a fundamental constructor for character sets.
-@itemize @bullet
-@item @var{g} is used to generate a series of ``seed'' values
-from the initial seed: @var{seed}, (@var{g} @var{seed}),
-(@var{g}^2 @var{seed}), (@var{g}^3 @var{seed}), @dots{}
-@item @var{p} tells us when to stop -- when it returns true
-when applied to one of the seed values.
-@item @var{f} maps each seed value to a character. These
-characters are added to the base character set @var{base_cs} to
-form the result; @var{base_cs} defaults to the empty set.
-@end itemize
+@node SRFI-27 Default Random Source
+@subsubsection The Default Random Source
+@cindex SRFI-27
-@code{char-set-unfold!} is the side-effecting variant.
-@end deffn
+@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
-@deffn {Scheme Procedure} char-set-for-each proc cs
-Apply @var{proc} to every character in the character set
-@var{cs}. The return value is not specified.
-@end deffn
+@defun random-real
+Return a random number in (0,1), using the default random source. The
+numbers returned have a uniform distribution.
+@end defun
-@deffn {Scheme Procedure} char-set-map proc cs
-Map the procedure @var{proc} over every character in @var{cs}.
-@var{proc} must be a character -> character procedure.
-@end deffn
+@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
-@c ===================================================================
+@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
-@node SRFI-14 Creating Character Sets
-@subsubsection Creating Character Sets
+@defun random-source? object
+Tests whether @var{object} is a random source. Random sources are a
+disjoint type.
+@end defun
-New character sets are produced with these procedures.
+@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
-@deffn {Scheme Procedure} char-set-copy cs
-Return a newly allocated character set containing all
-characters in @var{cs}.
-@end deffn
+@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
-@deffn {Scheme Procedure} char-set char1 @dots{}
-Return a character set containing all given characters.
-@end deffn
+The state associated with a random state can be obtained an reinstated
+with the following procedures:
-@deffn {Scheme Procedure} list->char-set char_list [base_cs]
-@deffnx {Scheme Procedure} list->char-set! char_list base_cs
-Convert the character list @var{list} to a character set. If
-the character set @var{base_cs} is given, the character in this
-set are also included in the result.
+@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
-@code{list->char-set!} is the side-effecting variant.
-@end deffn
+@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
-@deffn {Scheme Procedure} string->char-set s [base_cs]
-@deffnx {Scheme Procedure} string->char-set! s base_cs
-Convert the string @var{str} to a character set. If the
-character set @var{base_cs} is given, the characters in this
-set are also included in the result.
+@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
-@code{string->char-set!} is the side-effecting variant.
-@end deffn
+@node SRFI-30
+@subsection SRFI-30 - Nested Multi-line Comments
+@cindex SRFI-30
-@deffn {Scheme Procedure} char-set-filter pred cs [base_cs]
-@deffnx {Scheme Procedure} char-set-filter! pred cs base_cs
-Return a character set containing every character from @var{cs}
-so that it satisfies @var{pred}. If provided, the characters
-from @var{base_cs} are added to the result.
+Starting from version 2.0, Guile's @code{read} supports SRFI-30/R6RS
+nested multi-line comments by default, @ref{Block Comments}.
-@code{char-set-filter!} is the side-effecting variant.
-@end deffn
+@node SRFI-31
+@subsection SRFI-31 - A special form `rec' for recursive evaluation
+@cindex SRFI-31
+@cindex recursive expression
+@findex rec
-@deffn {Scheme Procedure} ucs-range->char-set lower upper [error? base_cs]
-@deffnx {Scheme Procedure} uce-range->char-set! lower upper error? base_cs
-Return a character set containing all characters whose
-character codes lie in the half-open range
-[@var{lower},@var{upper}).
+SRFI-31 defines a special form that can be used to create
+self-referential expressions more conveniently. The syntax is as
+follows:
-If @var{error} is a true value, an error is signalled if the
-specified range contains characters which are not contained in
-the implemented character range. If @var{error} is @code{#f},
-these characters are silently left out of the resulting
-character set.
+@example
+@group
+<rec expression> --> (rec <variable> <expression>)
+<rec expression> --> (rec (<variable>+) <body>)
+@end group
+@end example
-The characters in @var{base_cs} are added to the result, if
-given.
+The first syntax can be used to create self-referential expressions,
+for example:
-@code{ucs-range->char-set!} is the side-effecting variant.
-@end deffn
+@lisp
+ guile> (define tmp (rec ones (cons 1 (delay ones))))
+@end lisp
-@deffn {Scheme Procedure} ->char-set x
-Coerce @var{x} into a character set. @var{x} may be a string, a
-character or a character set.
-@end deffn
+The second syntax can be used to create anonymous recursive functions:
+@lisp
+ guile> (define tmp (rec (display-n item n)
+ (if (positive? n)
+ (begin (display n) (display-n (- n 1))))))
+ guile> (tmp 42 3)
+ 424242
+ guile>
+@end lisp
-@c ===================================================================
-@node SRFI-14 Querying Character Sets
-@subsubsection Querying Character Sets
+@node SRFI-34
+@subsection SRFI-34 - Exception handling for programs
-Access the elements and other information of a character set with these
-procedures.
+@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:
-@deffn {Scheme Procedure} char-set-size cs
-Return the number of elements in character set @var{cs}.
-@end deffn
+@lisp
+(use-modules (srfi srfi-34))
+@end lisp
-@deffn {Scheme Procedure} char-set-count pred cs
-Return the number of the elements int the character set
-@var{cs} which satisfy the predicate @var{pred}.
-@end deffn
+@c FIXME: Document it.
-@deffn {Scheme Procedure} char-set->list cs
-Return a list containing the elements of the character set
-@var{cs}.
-@end deffn
-@deffn {Scheme Procedure} char-set->string cs
-Return a string containing the elements of the character set
-@var{cs}. The order in which the characters are placed in the
-string is not defined.
-@end deffn
+@node SRFI-35
+@subsection SRFI-35 - Conditions
-@deffn {Scheme Procedure} char-set-contains? cs char
-Return @code{#t} iff the character @var{ch} is contained in the
-character set @var{cs}.
-@end deffn
+@cindex SRFI-35
+@cindex conditions
+@cindex exceptions
-@deffn {Scheme Procedure} char-set-every pred cs
-Return a true value if every character in the character set
-@var{cs} satisfies the predicate @var{pred}.
-@end deffn
+@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}:
-@deffn {Scheme Procedure} char-set-any pred cs
-Return a true value if any character in the character set
-@var{cs} satisfies the predicate @var{pred}.
-@end deffn
+@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.
-@c ===================================================================
+SRFI-35 conditions are made available using:
-@node SRFI-14 Character-Set Algebra
-@subsubsection Character-Set Algebra
+@lisp
+(use-modules (srfi srfi-35))
+@end lisp
-Character sets can be manipulated with the common set algebra operation,
-such as union, complement, intersection etc. All of these procedures
-provide side-effecting variants, which modify their character set
-argument(s).
+The procedures available to manipulate condition types are the
+following:
-@deffn {Scheme Procedure} char-set-adjoin cs char1 @dots{}
-@deffnx {Scheme Procedure} char-set-adjoin! cs char1 @dots{}
-Add all character arguments to the first argument, which must
-be a character set.
+@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} char-set-delete cs char1 @dots{}
-@deffnx {Scheme Procedure} char-set-delete! cs char1 @dots{}
-Delete all character arguments from the first argument, which
-must be a character set.
+@deffn {Scheme Procedure} condition-type? obj
+Return true if @var{obj} is a condition type.
@end deffn
-@deffn {Scheme Procedure} char-set-complement cs
-@deffnx {Scheme Procedure} char-set-complement! cs
-Return the complement of the character set @var{cs}.
-@end deffn
+Conditions can be created and accessed with the following procedures:
-@deffn {Scheme Procedure} char-set-union cs1 @dots{}
-@deffnx {Scheme Procedure} char-set-union! cs1 @dots{}
-Return the union of all argument character sets.
-@end deffn
+@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:
-@deffn {Scheme Procedure} char-set-intersection cs1 @dots{}
-@deffnx {Scheme Procedure} char-set-intersection! cs1 @dots{}
-Return the intersection of all argument character sets.
-@end deffn
+@lisp
+(let ((&ct (make-condition-type 'foo &condition '(a b c))))
+ (make-condition &ct 'a 1 'b 2 'c 3))
+@end lisp
-@deffn {Scheme Procedure} char-set-difference cs1 @dots{}
-@deffnx {Scheme Procedure} char-set-difference! cs1 @dots{}
-Return the difference of all argument character sets.
+Note that all fields of @var{type} and its supertypes must be specified.
@end deffn
-@deffn {Scheme Procedure} char-set-xor cs1 @dots{}
-@deffnx {Scheme Procedure} char-set-xor! cs1 @dots{}
-Return the exclusive-or of all argument character sets.
+@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} char-set-diff+intersection cs1 @dots{}
-@deffnx {Scheme Procedure} char-set-diff+intersection! cs1 @dots{}
-Return the difference and the intersection of all argument
-character sets.
+@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}.
-@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
-@node SRFI-14 Standard Character Sets
-@subsubsection Standard Character Sets
+@deffn {Scheme Procedure} extract-condition c type
+Return a condition of condition type @var{type} with the field values
+specified by @var{c}.
-In order to make the use of the character set data type and procedures
-useful, several predefined character set variables exist.
+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
-@defvar char-set:lower-case
-All lower-case characters.
-@end defvar
+Convenience macros are also available to create condition types and
+conditions.
-@defvar char-set:upper-case
-All upper-case characters.
-@end defvar
+@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}.
-@defvar char-set:title-case
-This is empty, because ASCII has no titlecase characters.
-@end defvar
+The example below defines condition type @code{&foo}, inheriting from
+@code{&condition} with fields @code{a}, @code{b} and @code{c}:
-@defvar char-set:letter
-All letters, e.g. the union of @code{char-set:lower-case} and
-@code{char-set:upper-case}.
-@end defvar
+@lisp
+(define-condition-type &foo &condition
+ foo-condition?
+ (a foo-a)
+ (b foo-b)
+ (c foo-c))
+@end lisp
+@end deffn
-@defvar char-set:digit
-All digits.
-@end defvar
+@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.
-@defvar char-set:letter+digit
-The union of @code{char-set:letter} and @code{char-set:digit}.
-@end defvar
+The following example returns a simple condition:
-@defvar char-set:graphic
-All characters which would put ink on the paper.
-@end defvar
+@lisp
+(condition (&message (message "An error occurred")))
+@end lisp
-@defvar char-set:printing
-The union of @code{char-set:graphic} and @code{char-set:whitespace}.
-@end defvar
+The one below returns a compound condition:
-@defvar char-set:whitespace
-All whitespace characters.
-@end defvar
+@lisp
+(condition (&message (message "An error occurred"))
+ (&serious))
+@end lisp
+@end deffn
-@defvar char-set:blank
-All horizontal whitespace characters, that is @code{#\space} and
-@code{#\tab}.
-@end defvar
+Finally, SRFI-35 defines a several standard condition types.
-@defvar char-set:iso-control
-The ISO control characters with the codes 0--31 and 127.
+@defvar &condition
+This condition type is the root of all condition types. It has no
+fields.
@end defvar
-@defvar char-set:punctuation
-The characters @code{!"#%&'()*,-./:;?@@[\\]_@{@}}
+@defvar &message
+A condition type that carries a message describing the nature of the
+condition to humans.
@end defvar
-@defvar char-set:symbol
-The characters @code{$+<=>^`|~}.
-@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
-@defvar char-set:hex-digit
-The hexadecimal digits @code{0123456789abcdefABCDEF}.
-@end defvar
+@deffn {Scheme Procedure} condition-message c
+Return the message associated with message condition @var{c}.
+@end deffn
-@defvar char-set:ascii
-All ASCII characters.
+@defvar &serious
+This type describes conditions serious enough that they cannot safely be
+ignored. It has no fields.
@end defvar
-@defvar char-set:empty
-The empty character set.
-@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 char-set:full
-This character set contains all possible characters.
+@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
-@node SRFI-16
-@subsection SRFI-16 - case-lambda
-@cindex SRFI-16
-
-@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.
+@deffn {Scheme Procedure} error? c
+Return true if @var{c} is of type @code{&error} or one of its subtypes.
+@end deffn
-@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.
+@node SRFI-37
+@subsection SRFI-37 - args-fold
+@cindex SRFI-37
-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.
+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
-(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
+(use-modules (srfi srfi-37))
@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.
-
-
-@node SRFI-17
-@subsection SRFI-17 - Generalized set!
-@cindex SRFI-17
-
-This is an implementation of SRFI-17: Generalized set!
-
-@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.
+@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}.
-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.
+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
-@node SRFI-19
-@subsection SRFI-19 - Time/Date Library
-@cindex SRFI-19
+@deffn {Scheme Procedure} option names required-arg? optional-arg? processor
+Return an object that specifies a single kind of program option.
-This is an implementation of the SRFI-19 time/date library. The
-functions and variables described here are provided by
+@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.
-@example
-(use-modules (srfi srfi-19))
-@end example
+@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.
-@menu
-* SRFI-19 Introduction::
-* SRFI-19 Time::
-* SRFI-19 Date::
-* SRFI-19 Time/Date conversions::
-* SRFI-19 Date to string::
-* SRFI-19 String to date::
-@end menu
+@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
-@node SRFI-19 Introduction
-@subsubsection SRFI-19 Introduction
+@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
-@cindex universal time
-@cindex atomic time
-@cindex UTC
-@cindex TAI
-This module implements time and date representations and calculations,
-in various time systems, including universal time (UTC) and atomic
-time (TAI).
+@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.
-For those not familiar with these time systems, TAI is based on a
-fixed length second derived from oscillations of certain atoms. UTC
-differs from TAI by an integral number of seconds, which is increased
-or decreased at announced times to keep UTC aligned to a mean solar
-day (the orbit and rotation of the earth are not quite constant).
+Call @code{unrecognized-option-proc}, which is like an option object's
+processor, for any options not found in @var{options}.
-@cindex leap second
-So far, only increases in the TAI
-@tex
-$\leftrightarrow$
-@end tex
-@ifnottex
-<->
-@end ifnottex
-UTC difference have been needed. Such an increase is a ``leap
-second'', an extra second of TAI introduced at the end of a UTC day.
-When working entirely within UTC this is never seen, every day simply
-has 86400 seconds. But when converting from TAI to a UTC date, an
-extra 23:59:60 is present, where normally a day would end at 23:59:59.
-Effectively the UTC second from 23:59:59 to 00:00:00 has taken two TAI
-seconds.
+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
-@cindex system clock
-In the current implementation, the system clock is assumed to be UTC,
-and a table of leap seconds in the code converts to TAI. See comments
-in @file{srfi-19.scm} for how to update this table.
-@cindex julian day
-@cindex modified julian day
-Also, for those not familiar with the terminology, a @dfn{Julian Day}
-is a real number which is a count of days and fraction of a day, in
-UTC, starting from -4713-01-01T12:00:00Z, ie.@: midday Monday 1 Jan
-4713 B.C. And a @dfn{Modified Julian Day} is the same, but starting
-from 1858-11-17T00:00:00Z, ie.@: midnight 17 November 1858 UTC.
+@node SRFI-39
+@subsection SRFI-39 - Parameters
+@cindex SRFI-39
+@cindex parameter object
+@tindex Parameter
-@c The SRFI-1 spec says -4714-11-24T12:00:00Z (November 24, -4714 at
-@c noon, UTC), but this is incorrect. It looks like it might have
-@c arisen from the code incorrectly treating years a multiple of 100
-@c but not 400 prior to 1582 as leap years, where instead the Julian
-@c calendar should be used so all multiples of 4 before 1582 are leap
-@c years.
+This SRFI provides parameter objects, which implement dynamically
+bound locations for values. The functions below are available from
+@example
+(use-modules (srfi srfi-39))
+@end example
-@node SRFI-19 Time
-@subsubsection SRFI-19 Time
-@cindex time
+A parameter object is a procedure. Called with no arguments it
+returns its value, called with one argument it sets the value.
-A @dfn{time} object has type, seconds and nanoseconds fields
-representing a point in time starting from some epoch. This is an
-arbitrary point in time, not just a time of day. Although times are
-represented in nanoseconds, the actual resolution may be lower.
+@example
+(define my-param (make-parameter 123))
+(my-param) @result{} 123
+(my-param 456)
+(my-param) @result{} 456
+@end example
-The following variables hold the possible time types. For instance
-@code{(current-time time-process)} would give the current CPU process
-time.
+The @code{parameterize} special form establishes new locations for
+parameters, those new locations having effect within the dynamic scope
+of the @code{parameterize} body. Leaving restores the previous
+locations, or re-entering through a saved continuation will again use
+the new locations.
-@defvar time-utc
-Universal Coordinated Time (UTC).
-@cindex UTC
-@end defvar
+@example
+(parameterize ((my-param 789))
+ (my-param) @result{} 789
+ )
+(my-param) @result{} 456
+@end example
-@defvar time-tai
-International Atomic Time (TAI).
-@cindex TAI
-@end defvar
+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
+case-sensitivity for a search, or a prompt for user input.
-@defvar time-monotonic
-Monotonic time, meaning a monotonically increasing time starting from
-an unspecified epoch.
+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 truly limiting the
+effect of @code{parameterize} to just its dynamic execution.
-Note that in the current implementation @code{time-monotonic} is the
-same as @code{time-tai}, and unfortunately is therefore affected by
-adjustments to the system clock. Perhaps this will change in the
-future.
-@end defvar
+Passing arguments to functions is thread-safe, but that soon becomes
+tedious when there's more than a few or when they need to pass down
+through several layers of calls before reaching the point they should
+affect. And introducing a new setting to existing code is often
+easier with a parameter object than adding arguments.
-@defvar time-duration
-A duration, meaning simply a difference between two times.
-@end defvar
-@defvar time-process
-CPU time spent in the current process, starting from when the process
-began.
-@cindex process time
-@end defvar
+@sp 1
+@defun make-parameter init [converter]
+Return a new parameter object, with initial value @var{init}.
-@defvar time-thread
-CPU time spent in the current thread. Not currently implemented.
-@cindex thread time
-@end defvar
+A parameter object is a procedure. When called @code{(param)} it
+returns its value, or a call @code{(param val)} sets its value. For
+example,
-@sp 1
-@defun time? obj
-Return @code{#t} if @var{obj} is a time object, or @code{#f} if not.
-@end defun
+@example
+(define my-param (make-parameter 123))
+(my-param) @result{} 123
-@defun make-time type nanoseconds seconds
-Create a time object with the given @var{type}, @var{seconds} and
-@var{nanoseconds}.
-@end defun
+(my-param 456)
+(my-param) @result{} 456
+@end example
-@defun time-type time
-@defunx time-nanosecond time
-@defunx time-second time
-@defunx set-time-type! time type
-@defunx set-time-nanosecond! time nsec
-@defunx set-time-second! time sec
-Get or set the type, seconds or nanoseconds fields of a time object.
+If a @var{converter} is given, then a call @code{(@var{converter}
+val)} is made for each value set, its return is the value stored.
+Such a call is made for the @var{init} initial value too.
-@code{set-time-type!} merely changes the field, it doesn't convert the
-time value. For conversions, see @ref{SRFI-19 Time/Date conversions}.
-@end defun
+A @var{converter} allows values to be validated, or put into a
+canonical form. For example,
-@defun copy-time time
-Return a new time object, which is a copy of the given @var{time}.
+@example
+(define my-param (make-parameter 123
+ (lambda (val)
+ (if (not (number? val))
+ (error "must be a number"))
+ (inexact->exact val))))
+(my-param 0.75)
+(my-param) @result{} 3/4
+@end example
@end defun
-@defun current-time [type]
-Return the current time of the given @var{type}. The default
-@var{type} is @code{time-utc}.
+@deffn {library syntax} parameterize ((param value) @dots{}) body @dots{}
+Establish a new dynamic scope with the given @var{param}s bound to new
+locations and set to the given @var{value}s. @var{body} is evaluated
+in that environment, the result is the return from the last form in
+@var{body}.
-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.
-@end defun
+Each @var{param} is an expression which is evaluated to get the
+parameter object. Often this will just be the name of a variable
+holding the object, but it can be anything that evaluates to a
+parameter.
-@defun time-resolution [type]
-Return the resolution, in nanoseconds, of the given time @var{type}.
-The default @var{type} is @code{time-utc}.
-@end defun
+The @var{param} expressions and @var{value} expressions are all
+evaluated before establishing the new dynamic bindings, and they're
+evaluated in an unspecified order.
-@defun time<=? t1 t2
-@defunx time<? t1 t2
-@defunx time=? t1 t2
-@defunx time>=? t1 t2
-@defunx time>? t1 t2
-Return @code{#t} or @code{#f} according to the respective relation
-between time objects @var{t1} and @var{t2}. @var{t1} and @var{t2}
-must be the same time type.
-@end defun
+For example,
-@defun time-difference t1 t2
-@defunx time-difference! t1 t2
-Return a time object of type @code{time-duration} representing the
-period between @var{t1} and @var{t2}. @var{t1} and @var{t2} must be
-the same time type.
+@example
+(define prompt (make-parameter "Type something: "))
+(define (get-input)
+ (display (prompt))
+ ...)
+
+(parameterize ((prompt "Type a number: "))
+ (get-input)
+ ...)
+@end example
+@end deffn
-@code{time-difference} returns a new time object,
-@code{time-difference!} may modify @var{t1} to form its return.
-@end defun
+@deffn {Parameter object} current-input-port [new-port]
+@deffnx {Parameter object} current-output-port [new-port]
+@deffnx {Parameter object} current-error-port [new-port]
+This SRFI extends the core @code{current-input-port} and
+@code{current-output-port}, making them parameter objects. The
+Guile-specific @code{current-error-port} is extended too, for
+consistency. (@pxref{Default Ports}.)
-@defun add-duration time duration
-@defunx add-duration! time duration
-@defunx subtract-duration time duration
-@defunx subtract-duration! time duration
-Return a time object which is @var{time} with the given @var{duration}
-added or subtracted. @var{duration} must be a time object of type
-@code{time-duration}.
+This is an upwardly compatible extension, a plain call like
+@code{(current-input-port)} still returns the current input port, and
+@code{set-current-input-port} can still be used. But the port can now
+also be set with @code{(current-input-port my-port)} and bound
+dynamically with @code{parameterize}.
+@end deffn
-@code{add-duration} and @code{subtract-duration} return a new time
-object. @code{add-duration!} and @code{subtract-duration!} may modify
-the given @var{time} to form their return.
+@defun with-parameters* param-list value-list thunk
+Establish a new dynamic scope, as per @code{parameterize} above,
+taking parameters from @var{param-list} and corresponding values from
+@var{values-list}. A call @code{(@var{thunk})} is made in the new
+scope and the result from that @var{thunk} is the return from
+@code{with-parameters*}.
+
+This function is a Guile-specific addition to the SRFI, it's similar
+to the core @code{with-fluids*} (@pxref{Fluids and Dynamic States}).
@end defun
-@node SRFI-19 Date
-@subsubsection SRFI-19 Date
-@cindex date
+@sp 1
+Parameter objects are implemented using fluids (@pxref{Fluids and
+Dynamic States}), so each dynamic state has it's own parameter
+locations. That includes the separate locations when outside any
+@code{parameterize} form. When a parameter is created it gets a
+separate initial location in each dynamic state, all initialized to
+the given @var{init} value.
+
+As alluded to above, because each thread usually has a separate
+dynamic state, each thread has it's own locations behind parameter
+objects, and changes in one thread are not visible to any other. When
+a new dynamic state or thread is created, the values of parameters in
+the originating context are copied, into new locations.
+
+SRFI-39 doesn't specify the interaction between parameter objects and
+threads, so the threading behaviour described here should be regarded
+as Guile-specific.
+
+@node SRFI-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
-A @dfn{date} object represents a date in the Gregorian calendar and a
-time of day on that date in some timezone.
+@lisp
+(let ((value expression)) (delay value)).
+@end lisp
-The fields are year, month, day, hour, minute, second, nanoseconds and
-timezone. A date object is immutable, its fields can be read but they
-cannot be modified once the object is created.
+However, the former is more efficient since it does not require
+unnecessary creation and evaluation of thunks. We also have the
+equivalence
-@defun date? obj
-Return @code{#t} if @var{obj} is a date object, or @code{#f} if not.
-@end defun
+@lisp
+(delay expression) = (lazy (eager expression))
+@end lisp
+@end deffn
-@defun make-date nsecs seconds minutes hours date month year zone-offset
-Create a new date object.
-@c
-@c FIXME: What can we say about the ranges of the values. The
-@c current code looks it doesn't normalize, but expects then in their
-@c usual range already.
-@c
-@end defun
+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:
-@defun date-nanosecond date
-Nanoseconds, 0 to 999999999.
-@end defun
+@lisp
+(force (delay expression)) -> expression
+(force (lazy expression)) -> (force expression)
+(force (eager value)) -> value
+@end lisp
-@defun date-second date
-Seconds, 0 to 60. 0 to 59 is the usual range, 60 is for a leap second.
-@end defun
+@subsubheading Correct usage
-@defun date-minute date
-Minutes, 0 to 59.
-@end defun
+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
-@defun date-hour date
-Hour, 0 to 23.
-@end defun
+@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
-@defun date-day date
-Day of the month, 1 to 31 (or less, according to the month).
-@end defun
+This algorithm can be espressed as follows in Scheme:
-@defun date-month date
-Month, 1 to 12.
-@end defun
+@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
-@defun date-year date
-Year, eg.@: 2003.
-@end defun
+In other words, we
-@defun date-zone-offset date
-Time zone, an integer number of seconds east of Greenwich.
-@end defun
+@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
-@defun date-year-day date
-Day of the year, starting from 1 for 1st January.
-@end defun
+@node SRFI-55
+@subsection SRFI-55 - Requiring Features
+@cindex SRFI-55
-@defun date-week-day date
-Day of the week, starting from 0 for Sunday.
-@end defun
+SRFI-55 provides @code{require-extension} which is a portable
+mechanism to load selected SRFI modules. This is implemented in the
+Guile core, there's no module needed to get SRFI-55 itself.
-@defun date-week-number date dstartw
-Week of the year, ignoring a first partial week. @var{dstartw} is the
-day of the week which is taken to start a week, 0 for Sunday, 1 for
-Monday, etc.
-@c
-@c FIXME: The spec doesn't say whether numbering starts at 0 or 1.
-@c The code looks like it's 0, if that's the correct intention.
-@c
-@end defun
+@deffn {library syntax} require-extension clause@dots{}
+Require each of the given @var{clause} features, throwing an error if
+any are unavailable.
-@c The SRFI text doesn't actually give the default for tz-offset, but
-@c the reference implementation has the local timezone and the
-@c conversions functions all specify that, so it should be ok to
-@c document it here.
-@c
-@defun current-date [tz-offset]
-Return a date object representing the current date/time UTC.
-@var{tz-offset} is seconds east of Greenwich, and defaults to the
-local timezone.
-@end defun
+A @var{clause} is of the form @code{(@var{identifier} arg...)}. The
+only @var{identifier} currently supported is @code{srfi} and the
+arguments are SRFI numbers. For example to get SRFI-1 and SRFI-6,
-@defun current-julian-day
-@cindex julian day
-Return the current Julian Day.
-@end defun
+@example
+(require-extension (srfi 1 6))
+@end example
-@defun current-modified-julian-day
-@cindex modified julian day
-Return the current Modified Julian Day.
-@end defun
+@code{require-extension} can only be used at the top-level.
+A Guile-specific program can simply @code{use-modules} to load SRFIs
+not already in the core, @code{require-extension} is for programs
+designed to be portable to other Scheme implementations.
+@end deffn
-@node SRFI-19 Time/Date conversions
-@subsubsection SRFI-19 Time/Date conversions
-@defun date->julian-day date
-@defunx date->modified-julian-day date
-@defunx date->time-monotonic date
-@defunx date->time-tai date
-@defunx date->time-utc date
-@end defun
-@defun julian-day->date jdn [tz-offset]
-@defunx julian-day->time-monotonic jdn
-@defunx julian-day->time-tai jdn
-@defunx julian-day->time-utc jdn
-@end defun
-@defun modified-julian-day->date jdn [tz-offset]
-@defunx modified-julian-day->time-monotonic jdn
-@defunx modified-julian-day->time-tai jdn
-@defunx modified-julian-day->time-utc jdn
+@node SRFI-60
+@subsection SRFI-60 - Integers as Bits
+@cindex SRFI-60
+@cindex integers as bits
+@cindex bitwise logical
+
+This SRFI provides various functions for treating integers as bits and
+for bitwise manipulations. These functions can be obtained with,
+
+@example
+(use-modules (srfi srfi-60))
+@end example
+
+Integers are treated as infinite precision twos-complement, the same
+as in the core logical functions (@pxref{Bitwise Operations}). And
+likewise bit indexes start from 0 for the least significant bit. The
+following functions in this SRFI are already in the Guile core,
+
+@quotation
+@code{logand},
+@code{logior},
+@code{logxor},
+@code{lognot},
+@code{logtest},
+@code{logcount},
+@code{integer-length},
+@code{logbit?},
+@code{ash}
+@end quotation
+
+@sp 1
+@defun bitwise-and n1 ...
+@defunx bitwise-ior n1 ...
+@defunx bitwise-xor n1 ...
+@defunx bitwise-not n
+@defunx any-bits-set? j k
+@defunx bit-set? index n
+@defunx arithmetic-shift n count
+@defunx bit-field n start end
+@defunx bit-count n
+Aliases for @code{logand}, @code{logior}, @code{logxor},
+@code{lognot}, @code{logtest}, @code{logbit?}, @code{ash},
+@code{bit-extract} and @code{logcount} respectively.
+
+Note that the name @code{bit-count} conflicts with @code{bit-count} in
+the core (@pxref{Bit Vectors}).
@end defun
-@defun time-monotonic->date time [tz-offset]
-@defunx time-monotonic->time-tai time
-@defunx time-monotonic->time-tai! time
-@defunx time-monotonic->time-utc time
-@defunx time-monotonic->time-utc! time
+
+@defun bitwise-if mask n1 n0
+@defunx bitwise-merge mask n1 n0
+Return an integer with bits selected from @var{n1} and @var{n0}
+according to @var{mask}. Those bits where @var{mask} has 1s are taken
+from @var{n1}, and those where @var{mask} has 0s are taken from
+@var{n0}.
+
+@example
+(bitwise-if 3 #b0101 #b1010) @result{} 9
+@end example
@end defun
-@defun time-tai->date time [tz-offset]
-@defunx time-tai->julian-day time
-@defunx time-tai->modified-julian-day time
-@defunx time-tai->time-monotonic time
-@defunx time-tai->time-monotonic! time
-@defunx time-tai->time-utc time
-@defunx time-tai->time-utc! time
+
+@defun log2-binary-factors n
+@defunx first-set-bit n
+Return a count of how many factors of 2 are present in @var{n}. This
+is also the bit index of the lowest 1 bit in @var{n}. If @var{n} is
+0, the return is @math{-1}.
+
+@example
+(log2-binary-factors 6) @result{} 1
+(log2-binary-factors -8) @result{} 3
+@end example
@end defun
-@defun time-utc->date time [tz-offset]
-@defunx time-utc->julian-day time
-@defunx time-utc->modified-julian-day time
-@defunx time-utc->time-monotonic time
-@defunx time-utc->time-monotonic! time
-@defunx time-utc->time-tai time
-@defunx time-utc->time-tai! time
-@sp 1
-Convert between dates, times and days of the respective types. For
-instance @code{time-tai->time-utc} accepts a @var{time} object of type
-@code{time-tai} and returns an object of type @code{time-utc}.
-For conversions to dates, @var{tz-offset} is seconds east of
-Greenwich. The default is the local timezone.
+@defun copy-bit index n newbit
+Return @var{n} with the bit at @var{index} set according to
+@var{newbit}. @var{newbit} should be @code{#t} to set the bit to 1,
+or @code{#f} to set it to 0. Bits other than at @var{index} are
+unchanged in the return.
-The @code{!} variants may modify their @var{time} argument to form
-their return. The plain functions create a new object.
+@example
+(copy-bit 1 #b0101 #t) @result{} 7
+@end example
@end defun
-@node SRFI-19 Date to string
-@subsubsection SRFI-19 Date to string
-@cindex date to string
+@defun copy-bit-field n newbits start end
+Return @var{n} with the bits from @var{start} (inclusive) to @var{end}
+(exclusive) changed to the value @var{newbits}.
-@defun date->string date [format]
-Convert a date to a string under the control of a format.
-@var{format} should be a string containing @samp{~} escapes, which
-will be expanded as per the following conversion table. The default
-@var{format} is @samp{~c}, a locale-dependent date and time.
+The least significant bit in @var{newbits} goes to @var{start}, the
+next to @math{@var{start}+1}, etc. Anything in @var{newbits} past the
+@var{end} given is ignored.
-Many of these conversion characters are the same as POSIX
-@code{strftime} (@pxref{Time}), but there are some extras and some
-variations.
+@example
+(copy-bit-field #b10000 #b11 1 3) @result{} #b10110
+@end example
+@end defun
-@multitable {MMMM} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
-@item @nicode{~~} @tab literal ~
-@item @nicode{~a} @tab locale abbreviated weekday, eg.@: @samp{Sun}
-@item @nicode{~A} @tab locale full weekday, eg.@: @samp{Sunday}
-@item @nicode{~b} @tab locale abbreviated month, eg.@: @samp{Jan}
-@item @nicode{~B} @tab locale full month, eg.@: @samp{January}
-@item @nicode{~c} @tab locale date and time, eg.@: @*
-@samp{Fri Jul 14 20:28:42-0400 2000}
-@item @nicode{~d} @tab day of month, zero padded, @samp{01} to @samp{31}
+@defun rotate-bit-field n count start end
+Return @var{n} with the bit field from @var{start} (inclusive) to
+@var{end} (exclusive) rotated upwards by @var{count} bits.
-@c Spec says d/m/y, reference implementation says m/d/y.
-@c Apparently the reference code was the intention, but would like to
-@c see an errata published for the spec before contradicting it here.
-@c
-@c @item @nicode{~D} @tab date @nicode{~d/~m/~y}
+@var{count} can be positive or negative, and it can be more than the
+field width (it'll be reduced modulo the width).
-@item @nicode{~e} @tab day of month, blank padded, @samp{ 1} to @samp{31}
-@item @nicode{~f} @tab seconds and fractional seconds,
-with locale decimal point, eg.@: @samp{5.2}
-@item @nicode{~h} @tab same as @nicode{~b}
-@item @nicode{~H} @tab hour, 24-hour clock, zero padded, @samp{00} to @samp{23}
-@item @nicode{~I} @tab hour, 12-hour clock, zero padded, @samp{01} to @samp{12}
-@item @nicode{~j} @tab day of year, zero padded, @samp{001} to @samp{366}
-@item @nicode{~k} @tab hour, 24-hour clock, blank padded, @samp{ 0} to @samp{23}
-@item @nicode{~l} @tab hour, 12-hour clock, blank padded, @samp{ 1} to @samp{12}
-@item @nicode{~m} @tab month, zero padded, @samp{01} to @samp{12}
-@item @nicode{~M} @tab minute, zero padded, @samp{00} to @samp{59}
-@item @nicode{~n} @tab newline
-@item @nicode{~N} @tab nanosecond, zero padded, @samp{000000000} to @samp{999999999}
-@item @nicode{~p} @tab locale AM or PM
-@item @nicode{~r} @tab time, 12 hour clock, @samp{~I:~M:~S ~p}
-@item @nicode{~s} @tab number of full seconds since ``the epoch'' in UTC
-@item @nicode{~S} @tab second, zero padded @samp{00} to @samp{60} @*
-(usual limit is 59, 60 is a leap second)
-@item @nicode{~t} @tab horizontal tab character
-@item @nicode{~T} @tab time, 24 hour clock, @samp{~H:~M:~S}
-@item @nicode{~U} @tab week of year, Sunday first day of week,
-@samp{00} to @samp{52}
-@item @nicode{~V} @tab week of year, Monday first day of week,
-@samp{01} to @samp{53}
-@item @nicode{~w} @tab day of week, 0 for Sunday, @samp{0} to @samp{6}
-@item @nicode{~W} @tab week of year, Monday first day of week,
-@samp{00} to @samp{52}
+@example
+(rotate-bit-field #b0110 2 1 4) @result{} #b1010
+@end example
+@end defun
-@c The spec has ~x as an apparent duplicate of ~W, and ~X as a locale
-@c date. The reference code has ~x as the locale date and ~X as a
-@c locale time. The rule is apparently that the code should be
-@c believed, but would like to see an errata for the spec before
-@c contradicting it here.
-@c
-@c @item @nicode{~x} @tab week of year, Monday as first day of week,
-@c @samp{00} to @samp{53}
-@c @item @nicode{~X} @tab locale date, eg.@: @samp{07/31/00}
+@defun reverse-bit-field n start end
+Return @var{n} with the bits from @var{start} (inclusive) to @var{end}
+(exclusive) reversed.
-@item @nicode{~y} @tab year, two digits, @samp{00} to @samp{99}
-@item @nicode{~Y} @tab year, full, eg.@: @samp{2003}
-@item @nicode{~z} @tab time zone, RFC-822 style
-@item @nicode{~Z} @tab time zone symbol (not currently implemented)
-@item @nicode{~1} @tab ISO-8601 date, @samp{~Y-~m-~d}
-@item @nicode{~2} @tab ISO-8601 time+zone, @samp{~k:~M:~S~z}
-@item @nicode{~3} @tab ISO-8601 time, @samp{~k:~M:~S}
-@item @nicode{~4} @tab ISO-8601 date/time+zone, @samp{~Y-~m-~dT~k:~M:~S~z}
-@item @nicode{~5} @tab ISO-8601 date/time, @samp{~Y-~m-~dT~k:~M:~S}
-@end multitable
+@example
+(reverse-bit-field #b101001 2 4) @result{} #b100101
+@end example
@end defun
-Conversions @samp{~D}, @samp{~x} and @samp{~X} are not currently
-described here, since the specification and reference implementation
-differ.
+@defun integer->list n [len]
+Return bits from @var{n} in the form of a list of @code{#t} for 1 and
+@code{#f} for 0. The least significant @var{len} bits are returned,
+and the first list element is the most significant of those bits. If
+@var{len} is not given, the default is @code{(integer-length @var{n})}
+(@pxref{Bitwise Operations}).
-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.
+@example
+(integer->list 6) @result{} (#t #t #f)
+(integer->list 1 4) @result{} (#f #f #f #t)
+@end example
+@end defun
+
+@defun list->integer lst
+@defunx booleans->integer bool@dots{}
+Return an integer formed bitwise from the given @var{lst} list of
+booleans, or for @code{booleans->integer} from the @var{bool}
+arguments.
+Each boolean is @code{#t} for a 1 and @code{#f} for a 0. The first
+element becomes the most significant bit in the return.
-@node SRFI-19 String to date
-@subsubsection SRFI-19 String to date
-@cindex string to date
+@example
+(list->integer '(#t #f #t #f)) @result{} 10
+@end example
+@end defun
-@c FIXME: Can we say what happens when an incomplete date is
-@c converted? Ie. fields left as 0, or what? The spec seems to be
-@c silent on this.
-@defun string->date input template
-Convert an @var{input} string to a date under the control of a
-@var{template} string. Return a newly created date object.
+@node SRFI-61
+@subsection SRFI-61 - A more general @code{cond} clause
-Literal characters in @var{template} must match characters in
-@var{input} and @samp{~} escapes must match the input forms described
-in the table below. ``Skip to'' means characters up to one of the
-given type are ignored, or ``no skip'' for no skipping. ``Read'' is
-what's then read, and ``Set'' is the field affected in the date
-object.
+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}.
-For example @samp{~Y} skips input characters until a digit is reached,
-at which point it expects a year and stores that to the year field of
-the date.
+@node SRFI-67
+@subsection SRFI-67 - Compare procedures
+@cindex SRFI-67
-@multitable {MMMM} {@nicode{char-alphabetic?}} {MMMMMMMMMMMMMMMMMMMMMMMMM} {@nicode{date-zone-offset}}
-@item
-@tab Skip to
-@tab Read
-@tab Set
+See @uref{http://srfi.schemers.org/srfi-67/srfi-67.html, the
+specification of SRFI-67}.
-@item @nicode{~~}
-@tab no skip
-@tab literal ~
-@tab nothing
+@node SRFI-69
+@subsection SRFI-69 - Basic hash tables
+@cindex SRFI-69
-@item @nicode{~a}
-@tab @nicode{char-alphabetic?}
-@tab locale abbreviated weekday name
-@tab nothing
+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.
-@item @nicode{~A}
-@tab @nicode{char-alphabetic?}
-@tab locale full weekday name
-@tab nothing
+Access it with:
-@c Note that the SRFI spec says that ~b and ~B don't set anything,
-@c but that looks like a mistake. The reference implementation sets
-@c the month field, which seems sensible and is what we describe
-@c here.
+@lisp
+(use-modules (srfi srfi-69))
+@end lisp
-@item @nicode{~b}
-@tab @nicode{char-alphabetic?}
-@tab locale abbreviated month name
-@tab @nicode{date-month}
+@menu
+* SRFI-69 Creating hash tables::
+* SRFI-69 Accessing table items::
+* SRFI-69 Table properties::
+* SRFI-69 Hash table algorithms::
+@end menu
-@item @nicode{~B}
-@tab @nicode{char-alphabetic?}
-@tab locale full month name
-@tab @nicode{date-month}
+@node SRFI-69 Creating hash tables
+@subsubsection Creating hash tables
-@item @nicode{~d}
-@tab @nicode{char-numeric?}
-@tab day of month
-@tab @nicode{date-day}
+@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.
-@item @nicode{~e}
-@tab no skip
-@tab day of month, blank padded
-@tab @nicode{date-day}
+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.
-@item @nicode{~h}
-@tab same as @samp{~b}
+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).
-@item @nicode{~H}
-@tab @nicode{char-numeric?}
-@tab hour
-@tab @nicode{date-hour}
+@var{weakness} should be @code{#f} or a symbol indicating how ``weak''
+the hash table is:
-@item @nicode{~k}
-@tab no skip
-@tab hour, blank padded
-@tab @nicode{date-hour}
+@table @code
+@item #f
+An ordinary non-weak hash table. This is the default.
-@item @nicode{~m}
-@tab @nicode{char-numeric?}
-@tab month
-@tab @nicode{date-month}
+@item key
+When the key has no more non-weak references at GC, remove that entry.
-@item @nicode{~M}
-@tab @nicode{char-numeric?}
-@tab minute
-@tab @nicode{date-minute}
+@item value
+When the value has no more non-weak references at GC, remove that
+entry.
-@item @nicode{~S}
-@tab @nicode{char-numeric?}
-@tab second
-@tab @nicode{date-second}
+@item key-or-value
+When either has no more non-weak references at GC, remove the
+association.
+@end table
-@item @nicode{~y}
-@tab no skip
-@tab 2-digit year
-@tab @nicode{date-year} within 50 years
+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
-@item @nicode{~Y}
-@tab @nicode{char-numeric?}
-@tab year
-@tab @nicode{date-year}
+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}.
-@item @nicode{~z}
-@tab no skip
-@tab time zone
-@tab date-zone-offset
-@end multitable
+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.
-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.
+@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
-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.
-@end defun
+@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.
-@node SRFI-26
-@subsection SRFI-26 - specializing parameters
-@cindex SRFI-26
+@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
-This SRFI provides a syntax for conveniently specializing selected
-parameters of a function. It can be used with,
+@deffn {Scheme Procedure} hash-table-set! table key new-value
+Set @var{key} to @var{new-value} in @var{table}.
+@end deffn
-@example
-(use-modules (srfi srfi-26))
-@end example
+@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 {library syntax} cut slot @dots{}
-@deffnx {library syntax} cute slot @dots{}
-Return a new procedure which will make a call (@var{slot} @dots{}) but
-with selected parameters specialized to given expressions.
+@deffn {Scheme Procedure} hash-table-exists? table key
+Answer whether @var{key} has an association in @var{table}.
+@end deffn
-An example will illustrate the idea. The following is a
-specialization of @code{write}, sending output to
-@code{my-output-port},
+@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.
-@example
-(cut write <> my-output-port)
-@result{}
-(lambda (obj) (write obj my-output-port))
-@end example
+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.
-The special symbol @code{<>} indicates a slot to be filled by an
-argument to the new procedure. @code{my-output-port} on the other
-hand is an expression to be evaluated and passed, ie.@: it specializes
-the behaviour of @code{write}.
+@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
-@table @nicode
-@item <>
-A slot to be filled by an argument from the created procedure.
-Arguments are assigned to @code{<>} slots in the order they appear in
-the @code{cut} form, there's no way to re-arrange arguments.
+@node SRFI-69 Table properties
+@subsubsection Table properties
-The first argument to @code{cut} is usually a procedure (or expression
-giving a procedure), but @code{<>} is allowed there too. For example,
+@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
-@example
-(cut <> 1 2 3)
-@result{}
-(lambda (proc) (proc 1 2 3))
-@end example
+@deffn {Scheme Procedure} hash-table-keys table
+Answer an unordered list of the keys in @var{table}.
+@end deffn
-@item <...>
-A slot to be filled by all remaining arguments from the new procedure.
-This can only occur at the end of a @code{cut} form.
+@deffn {Scheme Procedure} hash-table-values table
+Answer an unordered list of the values in @var{table}.
+@end deffn
-For example, a procedure taking a variable number of arguments like
-@code{max} but in addition enforcing a lower bound,
+@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
-@example
-(define my-lower-bound 123)
+@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
-(cut max my-lower-bound <...>)
-@result{}
-(lambda arglist (apply max my-lower-bound arglist))
-@end example
-@end table
+@deffn {Scheme Procedure} hash-table->alist table
+Answer an alist where each association in @var{table} is an
+association in the result.
+@end deffn
-For @code{cut} the specializing expressions are evaluated each time
-the new procedure is called. For @code{cute} they're evaluated just
-once, when the new procedure is created. The name @code{cute} stands
-for ``@code{cut} with evaluated arguments''. In all cases the
-evaluations take place in an unspecified order.
+@node SRFI-69 Hash table algorithms
+@subsubsection Hash table algorithms
-The following illustrates the difference between @code{cut} and
-@code{cute},
+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.
-@example
-(cut format <> "the time is ~s" (current-time))
-@result{}
-(lambda (port) (format port "the time is ~s" (current-time)))
+@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
-(cute format <> "the time is ~s" (current-time))
-@result{}
-(let ((val (current-time)))
- (lambda (port) (format port "the time is ~s" val))
-@end example
+@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
-(There's no provision for a mixture of @code{cut} and @code{cute}
-where some expressions would be evaluated every time but others
-evaluated only once.)
+@code{hash} is a backwards-compatible replacement for Guile's built-in
+@code{hash}.
-@code{cut} is really just a shorthand for the sort of @code{lambda}
-forms shown in the above examples. But notice @code{cut} avoids the
-need to name unspecialized parameters, and is more compact. Use in
-functional programming style or just with @code{map}, @code{for-each}
-or similar is typical.
+@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
-(map (cut * 2 <>) '(1 2 3 4))
+(use-modules (srfi srfi-88))
+@end example
-(for-each (cut write <> my-port) my-list)
+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
-@node SRFI-31
-@subsection SRFI-31 - A special form `rec' for recursive evaluation
-@cindex SRFI-31
-@findex rec
+@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!}.
-SRFI-31 defines a special form that can be used to create
-self-referential expressions more conveniently. The syntax is as
-follows:
+@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
-@group
-<rec expression> --> (rec <variable> <expression>)
-<rec expression> --> (rec (<variable>+) <body>)
-@end group
+(keyword->string (string->keyword "a b c")) @result{} "a b c"
@end example
+@end deffn
-The first syntax can be used to create self-referential expressions,
-for example:
+@node SRFI-98
+@subsection SRFI-98 Accessing environment variables.
+@cindex SRFI-98
+@cindex environment variables
-@lisp
- guile> (define tmp (rec ones (cons 1 (delay ones))))
-@end lisp
+This is a portable wrapper around Guile's built-in support for
+interacting with the current environment, @xref{Runtime Environment}.
-The second syntax can be used to create anonymous recursive functions:
+@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
-@lisp
- guile> (define tmp (rec (display-n item n)
- (if (positive? n)
- (begin (display n) (display-n (- n 1))))))
- guile> (tmp 42 3)
- 424242
- guile>
-@end lisp
+@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