X-Git-Url: https://git.hcoop.net/bpt/guile.git/blobdiff_plain/7c2e18cd7ad7641cf73bcbc95ea1b2965d4965ef..cdbbe19250efa534a937dde381ae3d5a84960b68:/doc/ref/srfi-modules.texi diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi index 3908455e8..ba8966d82 100644 --- a/doc/ref/srfi-modules.texi +++ b/doc/ref/srfi-modules.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. -@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 +@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -37,6 +37,15 @@ get the relevant SRFI documents from the SRFI home page * SRFI-19:: Time/Date library. * SRFI-26:: Specializing parameters * SRFI-31:: A special form `rec' for recursive evaluation +* SRFI-34:: Exception handling. +* SRFI-35:: Conditions. +* SRFI-37:: args-fold program argument processor +* SRFI-39:: Parameter objects +* SRFI-55:: Requiring Features. +* SRFI-60:: Integers as bits. +* SRFI-61:: A more general `cond' clause +* SRFI-69:: Basic hash tables. +* SRFI-88:: Keyword objects. @end menu @@ -118,10 +127,21 @@ available. @end example @end deffn -The Guile core provides features @code{guile}, @code{r5rs}, -@code{srfi-0} and @code{srfi-6} initially. Other SRFI feature symbols -are defined once their code has been loaded with @code{use-modules}, -since only then are their bindings available. +@noindent +The Guile core has the following features, + +@example +guile +r5rs +srfi-0 +srfi-4 +srfi-6 +srfi-13 +srfi-14 +@end example + +Other SRFI feature symbols are defined once their code has been loaded +with @code{use-modules}, since only then are their bindings available. The @samp{--use-srfi} command line option (@pxref{Invoking Guile}) is a good way to load SRFIs to satisfy @code{cond-expand} when running a @@ -234,21 +254,57 @@ APL language. 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 @@ -311,6 +367,7 @@ Return a list containing all but the first @var{i} elements of @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 @@ -318,8 +375,9 @@ Return the a list containing the @var{i} last elements of @var{lst}. 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 @@ -361,9 +419,13 @@ have a limit on the number of arguments a function takes, which the @deffn {Scheme Procedure} append-reverse rev-head tail @deffnx {Scheme Procedure} append-reverse! rev-head tail -Reverse @var{rev-head}, append @var{tail} and return the result. This -is equivalent to @code{(append (reverse @var{rev-head}) @var{tail})}, -but more efficient. +Reverse @var{rev-head}, append @var{tail} to it, and return the +result. This is equivalent to @code{(append (reverse @var{rev-head}) +@var{tail})}, but its implementation is more efficient. + +@example +(append-reverse '(1 2 3) '(4 5 6)) @result{} (3 2 1 4 5 6) +@end example @code{append-reverse!} may modify @var{rev-head} in order to produce the result. @@ -409,43 +471,123 @@ one list must be non-circular. @c FIXME::martin: Review me! -@deffn {Scheme Procedure} fold kons knil lst1 lst2 @dots{} -Fold the procedure @var{kons} across all elements of @var{lst1}, -@var{lst2}, @dots{}. Produce the result of +@deffn {Scheme Procedure} fold proc init lst1 @dots{} lstN +@deffnx {Scheme Procedure} fold-right proc init lst1 @dots{} lstN +Apply @var{proc} to the elements of @var{lst1} @dots{} @var{lstN} to +build a result, and return that result. -@code{(@var{kons} @var{en1} @var{en2} @dots{} (@var{kons} @var{e21} -@var{e22} (@var{kons} @var{e11} @var{e12} @var{knil})))}, +Each @var{proc} call is @code{(@var{proc} @var{elem1} @dots{} +@var{elemN} @var{previous})}, where @var{elem1} is from @var{lst1}, +through @var{elemN} from @var{lstN}. @var{previous} is the return +from the previous call to @var{proc}, or the given @var{init} for the +first call. If any list is empty, just @var{init} is returned. -if @var{enm} are the elements of the lists @var{lst1}, @var{lst2}, -@dots{}. -@end deffn +@code{fold} works through the list elements from first to last. The +following shows a list reversal and the calls it makes, -@deffn {Scheme Procedure} fold-right kons knil lst1 lst2 @dots{} -Similar to @code{fold}, but applies @var{kons} in right-to-left order -to the list elements, that is: +@example +(fold cons '() '(1 2 3)) -@code{(@var{kons} @var{e11} @var{e12}(@var{kons} @var{e21} -@var{e22} @dots{} (@var{kons} @var{en1} @var{en2} @var{knil})))}, -@end deffn +(cons 1 '()) +(cons 2 '(1)) +(cons 3 '(2 1) +@result{} (3 2 1) +@end example -@deffn {Scheme Procedure} pair-fold kons knil lst1 lst2 @dots{} -Like @code{fold}, but apply @var{kons} to the pairs of the list -instead of the list elements. -@end deffn +@code{fold-right} works through the list elements from last to first, +ie.@: from the right. So for example the following finds the longest +string, and the last among equal longest, + +@example +(fold-right (lambda (str prev) + (if (> (string-length str) (string-length prev)) + str + prev)) + "" + '("x" "abc" "xyz" "jk")) +@result{} "xyz" +@end example + +If @var{lst1} through @var{lstN} have different lengths, @code{fold} +stops when the end of the shortest is reached; @code{fold-right} +commences at the last element of the shortest. Ie.@: elements past +the length of the shortest are ignored in the other @var{lst}s. At +least one @var{lst} must be non-circular. + +@code{fold} should be preferred over @code{fold-right} if the order of +processing doesn't matter, or can be arranged either way, since +@code{fold} is a little more efficient. -@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. +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] @@ -705,18 +847,36 @@ 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}. + +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, -This function extends the core @code{member} by accepting an equality -predicate. (@pxref{List Searching}) +@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 @@ -724,8 +884,6 @@ predicate. (@pxref{List Searching}) @subsubsection Deleting @cindex list delete -@c FIXME::martin: Review me! - @deffn {Scheme Procedure} delete x lst [=] @deffnx {Scheme Procedure} delete! x lst [=] Return a list containing the elements of @var{lst} but with those @@ -744,8 +902,10 @@ deleted with @code{(delete 5 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 [=] @@ -786,23 +946,33 @@ Lists}. The present section only documents the additional procedures for dealing with association lists defined by SRFI-1. @deffn {Scheme Procedure} assoc key alist [=] -Return the pair from @var{alist} which matches @var{key}. Equality is -determined by @var{=}, which defaults to @code{equal?} if not given. -@var{alist} must be an association lists---a list of pairs. +Return the pair from @var{alist} which matches @var{key}. This +extends the core @code{assoc} (@pxref{Retrieving Alist Entries}) by +taking an optional @var{=} comparison procedure. + +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 @@ -833,83 +1003,198 @@ the list structure of @var{alist} to construct its return. @subsubsection Set Operations on Lists @cindex list set operation -@c FIXME::martin: Review me! +Lists can be used to represent sets of objects. The procedures in +this section operate on such lists as sets. + +Note that lists are not an efficient way to implement large sets. The +procedures here typically take time @math{@var{m}@cross{}@var{n}} when +operating on @var{m} and @var{n} element lists. Other data structures +like trees, bitsets (@pxref{Bit Vectors}) or hash tables (@pxref{Hash +Tables}) are faster. + +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. -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. +@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}. -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. +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)}. -@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 @@ -1164,8 +1449,8 @@ lookup. (lambda elems (let ((table (make-hash-table))) (for-each (lambda (elem) - (apply hash-set! table elem)) - elems) + (apply hash-set! table elem)) + elems) table))) (define (animal->family animal) @@ -1336,24 +1621,61 @@ applied to zero arguments, yields 1. @subsection SRFI-17 - Generalized set! @cindex SRFI-17 -This is an implementation of SRFI-17: Generalized set! +This SRFI implements a generalized @code{set!}, allowing some +``referencing'' functions to be used as the target location of a +@code{set!}. This feature is available from + +@example +(use-modules (srfi srfi-17)) +@end example + +@noindent +For example @code{vector-ref} is extended so that + +@example +(set! (vector-ref vec idx) new-value) +@end example -@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. +@noindent +is equivalent to -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. +@example +(vector-set! vec idx new-value) +@end example + +The idea is that a @code{vector-ref} expression identifies a location, +which may be either fetched or stored. The same form is used for the +location in both cases, encouraging visual clarity. This is similar +to the idea of an ``lvalue'' in C. + +The mechanism for this kind of @code{set!} is in the Guile core +(@pxref{Procedures with Setters}). This module adds definitions of +the following functions as procedures with setters, allowing them to +be targets of a @code{set!}, + +@quotation +@nicode{car}, @nicode{cdr}, @nicode{caar}, @nicode{cadr}, +@nicode{cdar}, @nicode{cddr}, @nicode{caaar}, @nicode{caadr}, +@nicode{cadar}, @nicode{caddr}, @nicode{cdaar}, @nicode{cdadr}, +@nicode{cddar}, @nicode{cdddr}, @nicode{caaaar}, @nicode{caaadr}, +@nicode{caadar}, @nicode{caaddr}, @nicode{cadaar}, @nicode{cadadr}, +@nicode{caddar}, @nicode{cadddr}, @nicode{cdaaar}, @nicode{cdaadr}, +@nicode{cdadar}, @nicode{cdaddr}, @nicode{cddaar}, @nicode{cddadr}, +@nicode{cdddar}, @nicode{cddddr} + +@nicode{string-ref}, @nicode{vector-ref} +@end quotation + +The SRFI specifies @code{setter} (@pxref{Procedures with Setters}) as +a procedure with setter, allowing the setter for a procedure to be +changed, eg.@: @code{(set! (setter foo) my-new-setter-handler)}. +Currently Guile does not implement this, a setter can only be +specified on creation (@code{getter-with-setter} below). + +@defun getter-with-setter +The same as the Guile core @code{make-procedure-with-setter} +(@pxref{Procedures with Setters}). +@end defun @node SRFI-19 @@ -1369,6 +1691,17 @@ functions and variables described here are provided by (use-modules (srfi srfi-19)) @end example +@strong{Caution}: The current code in this module incorrectly extends +the Gregorian calendar leap year rule back prior to the introduction +of those reforms in 1582 (or the appropriate year in various +countries). The Julian calendar was used prior to 1582, and there +were 10 days skipped for the reform, but the code doesn't implement +that. + +This will be fixed some time. Until then calculations for 1583 +onwards are correct, but prior to that any day/month/year and day of +the week calculations are wrong. + @menu * SRFI-19 Introduction:: * SRFI-19 Time:: @@ -1700,12 +2033,23 @@ 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, at the given time, as -provided by the system. - The @code{!} variants may modify their @var{time} argument to form their return. The plain functions create a new object. + +For conversions to dates, @var{tz-offset} is seconds east of +Greenwich. The default is the local timezone, at the given time, as +provided by the system, using @code{localtime} (@pxref{Time}). + +On 32-bit systems, @code{localtime} is limited to a 32-bit +@code{time_t}, so a default @var{tz-offset} is only available for +times between Dec 1901 and Jan 2038. For prior dates an application +might like to use the value in 1902, though some locations have zone +changes prior to that. For future dates an application might like to +assume today's rules extend indefinitely. But for correct daylight +savings transitions it will be necessary to take an offset for the +same day and time but a year in range and which has the same starting +weekday and same leap/non-leap (to support rules like last Sunday in +October). @end defun @node SRFI-19 Date to string @@ -1793,10 +2137,10 @@ Conversions @samp{~D}, @samp{~x} and @samp{~X} are not currently described here, since the specification and reference implementation differ. -Currently Guile doesn't implement any localizations for the above, all -outputs are in English, and the @samp{~c} conversion is POSIX -@code{ctime} style @samp{~a ~b ~d ~H:~M:~S~z ~Y}. This may change in -the future. +Conversion is locale-dependent on systems that support it +(@pxref{Accessing Locale Information}). @xref{Locales, +@code{setlocale}}, for information on how to change the current +locale. @node SRFI-19 String to date @@ -1917,9 +2261,10 @@ Notice that the weekday matching forms don't affect the date object returned, instead the weekday will be derived from the day, month and year. -Currently Guile doesn't implement any localizations for the above, -month and weekday names are always expected in English. This may -change in the future. +Conversion is locale-dependent on systems that support it +(@pxref{Accessing Locale Information}). @xref{Locales, +@code{setlocale}}, for information on how to change the current +locale. @end defun @@ -2060,6 +2405,869 @@ The second syntax can be used to create anonymous recursive functions: guile> @end lisp + +@node SRFI-34 +@subsection SRFI-34 - Exception handling for programs + +@cindex SRFI-34 +Guile provides an implementation of +@uref{http://srfi.schemers.org/srfi-34/srfi-34.html, SRFI-34's exception +handling mechanisms} as an alternative to its own built-in mechanisms +(@pxref{Exceptions}). It can be made available as follows: + +@lisp +(use-modules (srfi srfi-34)) +@end lisp + +@c FIXME: Document it. + + +@node SRFI-35 +@subsection SRFI-35 - Conditions + +@cindex SRFI-35 +@cindex conditions +@cindex exceptions + +@uref{http://srfi.schemers.org/srfi-35/srfi-35.html, SRFI-35} implements +@dfn{conditions}, a data structure akin to records designed to convey +information about exceptional conditions between parts of a program. It +is normally used in conjunction with SRFI-34's @code{raise}: + +@lisp +(raise (condition (&message + (message "An error occurred")))) +@end lisp + +Users can define @dfn{condition types} containing arbitrary information. +Condition types may inherit from one another. This allows the part of +the program that handles (or ``catches'') conditions to get accurate +information about the exceptional condition that arose. + +SRFI-35 conditions are made available using: + +@lisp +(use-modules (srfi srfi-35)) +@end lisp + +The procedures available to manipulate condition types are the +following: + +@deffn {Scheme Procedure} make-condition-type id parent field-names +Return a new condition type named @var{id}, inheriting from +@var{parent}, and with the fields whose names are listed in +@var{field-names}. @var{field-names} must be a list of symbols and must +not contain names already used by @var{parent} or one of its supertypes. +@end deffn + +@deffn {Scheme Procedure} condition-type? obj +Return true if @var{obj} is a condition type. +@end deffn + +Conditions can be created and accessed with the following procedures: + +@deffn {Scheme Procedure} make-condition type . field+value +Return a new condition of type @var{type} with fields initialized as +specified by @var{field+value}, a sequence of field names (symbols) and +values as in the following example: + +@lisp +(let ((&ct (make-condition-type 'foo &condition '(a b c)))) + (make-condition &ct 'a 1 'b 2 'c 3)) +@end lisp + +Note that all fields of @var{type} and its supertypes must be specified. +@end deffn + +@deffn {Scheme Procedure} make-compound-condition . conditions +Return a new compound condition composed of @var{conditions}. The +returned condition has the type of each condition of @var{conditions} +(per @code{condition-has-type?}). +@end deffn + +@deffn {Scheme Procedure} condition-has-type? c type +Return true if condition @var{c} has type @var{type}. +@end deffn + +@deffn {Scheme Procedure} condition-ref c field-name +Return the value of the field named @var{field-name} from condition @var{c}. + +If @var{c} is a compound condition and several underlying condition +types contain a field named @var{field-name}, then the value of the +first such field is returned, using the order in which conditions were +passed to @var{make-compound-condition}. +@end deffn + +@deffn {Scheme Procedure} extract-condition c type +Return a condition of condition type @var{type} with the field values +specified by @var{c}. + +If @var{c} is a compound condition, extract the field values from the +subcondition belonging to @var{type} that appeared first in the call to +@code{make-compound-condition} that created the the condition. +@end deffn + +Convenience macros are also available to create condition types and +conditions. + +@deffn {library syntax} define-condition-type type supertype predicate field-spec... +Define a new condition type named @var{type} that inherits from +@var{supertype}. In addition, bind @var{predicate} to a type predicate +that returns true when passed a condition of type @var{type} or any of +its subtypes. @var{field-spec} must have the form @code{(field +accessor)} where @var{field} is the name of field of @var{type} and +@var{accessor} is the name of a procedure to access field @var{field} in +conditions of type @var{type}. + +The example below defines condition type @code{&foo}, inheriting from +@code{&condition} with fields @code{a}, @code{b} and @code{c}: + +@lisp +(define-condition-type &foo &condition + foo-condition? + (a foo-a) + (b foo-b) + (c foo-c)) +@end lisp +@end deffn + +@deffn {library syntax} condition type-field-bindings... +Return a new condition, or compound condition, initialized according to +@var{type-field-bindings}. Each @var{type-field-binding} must have the +form @code{(type field-specs...)}, where @var{type} is the name of a +variable bound to condition type; each @var{field-spec} must have the +form @code{(field-name value)} where @var{field-name} is a symbol +denoting the field being initialized to @var{value}. As for +@code{make-condition}, all fields must be specified. + +The following example returns a simple condition: + +@lisp +(condition (&message (message "An error occurred"))) +@end lisp + +The one below returns a compound condition: + +@lisp +(condition (&message (message "An error occurred")) + (&serious)) +@end lisp +@end deffn + +Finally, SRFI-35 defines a several standard condition types. + +@defvar &condition +This condition type is the root of all condition types. It has no +fields. +@end defvar + +@defvar &message +A condition type that carries a message describing the nature of the +condition to humans. +@end defvar + +@deffn {Scheme Procedure} message-condition? c +Return true if @var{c} is of type @code{&message} or one of its +subtypes. +@end deffn + +@deffn {Scheme Procedure} condition-message c +Return the message associated with message condition @var{c}. +@end deffn + +@defvar &serious +This type describes conditions serious enough that they cannot safely be +ignored. It has no fields. +@end defvar + +@deffn {Scheme Procedure} serious-condition? c +Return true if @var{c} is of type @code{&serious} or one of its +subtypes. +@end deffn + +@defvar &error +This condition describes errors, typically caused by something that has +gone wrong in the interaction of the program with the external world or +the user. +@end defvar + +@deffn {Scheme Procedure} error? c +Return true if @var{c} is of type @code{&error} or one of its subtypes. +@end deffn + + +@node SRFI-37 +@subsection SRFI-37 - args-fold +@cindex SRFI-37 + +This is a processor for GNU @code{getopt_long}-style program +arguments. It provides an alternative, less declarative interface +than @code{getopt-long} in @code{(ice-9 getopt-long)} +(@pxref{getopt-long,,The (ice-9 getopt-long) Module}). Unlike +@code{getopt-long}, it supports repeated options and any number of +short and long names per option. Access it with: + +@lisp +(use-modules (srfi srfi-37)) +@end lisp + +@acronym{SRFI}-37 principally provides an @code{option} type and the +@code{args-fold} function. To use the library, create a set of +options with @code{option} and use it as a specification for invoking +@code{args-fold}. + +Here is an example of a simple argument processor for the typical +@samp{--version} and @samp{--help} options, which returns a backwards +list of files given on the command line: + +@lisp +(args-fold (cdr (program-arguments)) + (let ((display-and-exit-proc + (lambda (msg) + (lambda (opt name arg loads) + (display msg) (quit))))) + (list (option '(#\v "version") #f #f + (display-and-exit-proc "Foo version 42.0\n")) + (option '(#\h "help") #f #f + (display-and-exit-proc + "Usage: foo scheme-file ...")))) + (lambda (opt name arg loads) + (error "Unrecognized option `~A'" name)) + (lambda (op loads) (cons op loads)) + '()) +@end lisp + +@deffn {Scheme Procedure} option names required-arg? optional-arg? processor +Return an object that specifies a single kind of program option. + +@var{names} is a list of command-line option names, and should consist of +characters for traditional @code{getopt} short options and strings for +@code{getopt_long}-style long options. + +@var{required-arg?} and @var{optional-arg?} are mutually exclusive; +one or both must be @code{#f}. If @var{required-arg?}, the option +must be followed by an argument on the command line, such as +@samp{--opt=value} for long options, or an error will be signalled. +If @var{optional-arg?}, an argument will be taken if available. + +@var{processor} is a procedure that takes at least 3 arguments, called +when @code{args-fold} encounters the option: the containing option +object, the name used on the command line, and the argument given for +the option (or @code{#f} if none). The rest of the arguments are +@code{args-fold} ``seeds'', and the @var{processor} should return +seeds as well. +@end deffn + +@deffn {Scheme Procedure} option-names opt +@deffnx {Scheme Procedure} option-required-arg? opt +@deffnx {Scheme Procedure} option-optional-arg? opt +@deffnx {Scheme Procedure} option-processor opt +Return the specified field of @var{opt}, an option object, as +described above for @code{option}. +@end deffn + +@deffn {Scheme Procedure} args-fold args options unrecognized-option-proc operand-proc seeds @dots{} +Process @var{args}, a list of program arguments such as that returned +by @code{(cdr (program-arguments))}, in order against @var{options}, a +list of option objects as described above. All functions called take +the ``seeds'', or the last multiple-values as multiple arguments, +starting with @var{seeds}, and must return the new seeds. Return the +final seeds. + +Call @code{unrecognized-option-proc}, which is like an option object's +processor, for any options not found in @var{options}. + +Call @code{operand-proc} with any items on the command line that are +not named options. This includes arguments after @samp{--}. It is +called with the argument in question, as well as the seeds. +@end deffn + + +@node SRFI-39 +@subsection SRFI-39 - Parameters +@cindex SRFI-39 +@cindex parameter object +@tindex Parameter + +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 + +A parameter object is a procedure. Called with no arguments it +returns its value, called with one argument it sets the value. + +@example +(define my-param (make-parameter 123)) +(my-param) @result{} 123 +(my-param 456) +(my-param) @result{} 456 +@end example + +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. + +@example +(parameterize ((my-param 789)) + (my-param) @result{} 789 + ) +(my-param) @result{} 456 +@end example + +Parameters are like dynamically bound variables in other Lisp dialets. +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. + +Global variables are not as good as parameter objects for this sort of +thing. Changes to them are visible to all threads, but in Guile +parameter object locations are per-thread, thereby truely limiting the +effect of @code{parameterize} to just its dynamic execution. + +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. + + +@sp 1 +@defun make-parameter init [converter] +Return a new parameter object, with initial value @var{init}. + +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, + +@example +(define my-param (make-parameter 123)) +(my-param) @result{} 123 + +(my-param 456) +(my-param) @result{} 456 +@end example + +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. + +A @var{converter} allows values to be validated, or put into a +canonical form. For example, + +@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 + +@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}. + +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. + +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. + +For example, + +@example +(define prompt (make-parameter "Type something: ")) +(define (get-input) + (display (prompt)) + ...) + +(parameterize ((prompt "Type a number: ")) + (get-input) + ...) +@end example +@end deffn + +@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}.) + +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 + +@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 + + +@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-55 +@subsection SRFI-55 - Requiring Features +@cindex SRFI-55 + +SRFI-55 provides @code{require-extension} which is a portable +mechanism to load selected SRFI modules. This is implemented in the +Guile core, there's no module needed to get SRFI-55 itself. + +@deffn {library syntax} require-extension clause@dots{} +Require each of the given @var{clause} features, throwing an error if +any are unavailable. + +A @var{clause} is of the form @code{(@var{identifier} arg...)}. The +only @var{identifier} currently supported is @code{srfi} and the +arguments are SRFI numbers. For example to get SRFI-1 and SRFI-6, + +@example +(require-extension (srfi 1 6)) +@end example + +@code{require-extension} can only be used at the top-level. + +A Guile-specific program can simply @code{use-modules} to load SRFIs +not already in the core, @code{require-extension} is for programs +designed to be portable to other Scheme implementations. +@end deffn + + +@node SRFI-60 +@subsection SRFI-60 - Integers as Bits +@cindex SRFI-60 +@cindex integers as bits +@cindex bitwise logical + +This SRFI provides various functions for treating integers as bits and +for bitwise manipulations. These functions can be obtained with, + +@example +(use-modules (srfi srfi-60)) +@end example + +Integers are treated as infinite precision twos-complement, the same +as in the core logical functions (@pxref{Bitwise Operations}). And +likewise bit indexes start from 0 for the least significant bit. The +following functions in this SRFI are already in the Guile core, + +@quotation +@code{logand}, +@code{logior}, +@code{logxor}, +@code{lognot}, +@code{logtest}, +@code{logcount}, +@code{integer-length}, +@code{logbit?}, +@code{ash} +@end quotation + +@sp 1 +@defun bitwise-and n1 ... +@defunx bitwise-ior n1 ... +@defunx bitwise-xor n1 ... +@defunx bitwise-not n +@defunx any-bits-set? j k +@defunx bit-set? index n +@defunx arithmetic-shift n count +@defunx bit-field n start end +@defunx bit-count n +Aliases for @code{logand}, @code{logior}, @code{logxor}, +@code{lognot}, @code{logtest}, @code{logbit?}, @code{ash}, +@code{bit-extract} and @code{logcount} respectively. + +Note that the name @code{bit-count} conflicts with @code{bit-count} in +the core (@pxref{Bit Vectors}). +@end defun + +@defun bitwise-if mask n1 n0 +@defunx bitwise-merge mask n1 n0 +Return an integer with bits selected from @var{n1} and @var{n0} +according to @var{mask}. Those bits where @var{mask} has 1s are taken +from @var{n1}, and those where @var{mask} has 0s are taken from +@var{n0}. + +@example +(bitwise-if 3 #b0101 #b1010) @result{} 9 +@end example +@end defun + +@defun log2-binary-factors n +@defunx first-set-bit n +Return a count of how many factors of 2 are present in @var{n}. This +is also the bit index of the lowest 1 bit in @var{n}. If @var{n} is +0, the return is @math{-1}. + +@example +(log2-binary-factors 6) @result{} 1 +(log2-binary-factors -8) @result{} 3 +@end example +@end defun + +@defun copy-bit index n newbit +Return @var{n} with the bit at @var{index} set according to +@var{newbit}. @var{newbit} should be @code{#t} to set the bit to 1, +or @code{#f} to set it to 0. Bits other than at @var{index} are +unchanged in the return. + +@example +(copy-bit 1 #b0101 #t) @result{} 7 +@end example +@end defun + +@defun copy-bit-field n newbits start end +Return @var{n} with the bits from @var{start} (inclusive) to @var{end} +(exclusive) changed to the value @var{newbits}. + +The least significant bit in @var{newbits} goes to @var{start}, the +next to @math{@var{start}+1}, etc. Anything in @var{newbits} past the +@var{end} given is ignored. + +@example +(copy-bit-field #b10000 #b11 1 3) @result{} #b10110 +@end example +@end defun + +@defun rotate-bit-field n count start end +Return @var{n} with the bit field from @var{start} (inclusive) to +@var{end} (exclusive) rotated upwards by @var{count} bits. + +@var{count} can be positive or negative, and it can be more than the +field width (it'll be reduced modulo the width). + +@example +(rotate-bit-field #b0110 2 1 4) @result{} #b1010 +@end example +@end defun + +@defun reverse-bit-field n start end +Return @var{n} with the bits from @var{start} (inclusive) to @var{end} +(exclusive) reversed. + +@example +(reverse-bit-field #b101001 2 4) @result{} #b100101 +@end example +@end defun + +@defun integer->list n [len] +Return bits from @var{n} in the form of a list of @code{#t} for 1 and +@code{#f} for 0. The least significant @var{len} bits are returned, +and the first list element is the most significant of those bits. If +@var{len} is not given, the default is @code{(integer-length @var{n})} +(@pxref{Bitwise Operations}). + +@example +(integer->list 6) @result{} (#t #t #f) +(integer->list 1 4) @result{} (#f #f #f #t) +@end example +@end defun + +@defun list->integer lst +@defunx booleans->integer bool@dots{} +Return an integer formed bitwise from the given @var{lst} list of +booleans, or for @code{booleans->integer} from the @var{bool} +arguments. + +Each boolean is @code{#t} for a 1 and @code{#f} for a 0. The first +element becomes the most significant bit in the return. + +@example +(list->integer '(#t #f #t #f)) @result{} 10 +@end example +@end defun + + +@node SRFI-61 +@subsection SRFI-61 - A more general @code{cond} clause + +This SRFI extends RnRS @code{cond} to support test expressions that +return multiple values, as well as arbitrary definitions of test +success. SRFI 61 is implemented in the Guile core; there's no module +needed to get SRFI-61 itself. Extended @code{cond} is documented in +@ref{if cond case,, Simple Conditional Evaluation}. + + +@node SRFI-69 +@subsection SRFI-69 - Basic hash tables +@cindex SRFI-69 + +This is a portable wrapper around Guile's built-in hash table and weak +table support. @xref{Hash Tables}, for information on that built-in +support. Above that, this hash-table interface provides association +of equality and hash functions with tables at creation time, so +variants of each function are not required, as well as a procedure +that takes care of most uses for Guile hash table handles, which this +SRFI does not provide as such. + +Access it with: + +@lisp +(use-modules (srfi srfi-69)) +@end lisp + +@menu +* SRFI-69 Creating hash tables:: +* SRFI-69 Accessing table items:: +* SRFI-69 Table properties:: +* SRFI-69 Hash table algorithms:: +@end menu + +@node SRFI-69 Creating hash tables +@subsubsection Creating hash tables + +@deffn {Scheme Procedure} make-hash-table [equal-proc hash-proc #:weak weakness start-size] +Create and answer a new hash table with @var{equal-proc} as the +equality function and @var{hash-proc} as the hashing function. + +By default, @var{equal-proc} is @code{equal?}. It can be any +two-argument procedure, and should answer whether two keys are the +same for this table's purposes. + +My default @var{hash-proc} assumes that @code{equal-proc} is no +coarser than @code{equal?} unless it is literally @code{string-ci=?}. +If provided, @var{hash-proc} should be a two-argument procedure that +takes a key and the current table size, and answers a reasonably good +hash integer between 0 (inclusive) and the size (exclusive). + +@var{weakness} should be @code{#f} or a symbol indicating how ``weak'' +the hash table is: + +@table @code +@item #f +An ordinary non-weak hash table. This is the default. + +@item key +When the key has no more non-weak references at GC, remove that entry. + +@item value +When the value has no more non-weak references at GC, remove that +entry. + +@item key-or-value +When either has no more non-weak references at GC, remove the +association. +@end table + +As a legacy of the time when Guile couldn't grow hash tables, +@var{start-size} is an optional integer argument that specifies the +approximate starting size for the hash table, which will be rounded to +an algorithmically-sounder number. +@end deffn + +By @dfn{coarser} than @code{equal?}, we mean that for all @var{x} and +@var{y} values where @code{(@var{equal-proc} @var{x} @var{y})}, +@code{(equal? @var{x} @var{y})} as well. If that does not hold for +your @var{equal-proc}, you must provide a @var{hash-proc}. + +In the case of weak tables, remember that @dfn{references} above +always refers to @code{eq?}-wise references. Just because you have a +reference to some string @code{"foo"} doesn't mean that an association +with key @code{"foo"} in a weak-key table @emph{won't} be collected; +it only counts as a reference if the two @code{"foo"}s are @code{eq?}, +regardless of @var{equal-proc}. As such, it is usually only sensible +to use @code{eq?} and @code{hashq} as the equivalence and hash +functions for a weak table. @xref{Weak References}, for more +information on Guile's built-in weak table support. + +@deffn {Scheme Procedure} alist->hash-table alist [equal-proc hash-proc #:weak weakness start-size] +As with @code{make-hash-table}, but initialize it with the +associations in @var{alist}. Where keys are repeated in @var{alist}, +the leftmost association takes precedence. +@end deffn + +@node SRFI-69 Accessing table items +@subsubsection Accessing table items + +@deffn {Scheme Procedure} hash-table-ref table key [default-thunk] +@deffnx {Scheme Procedure} hash-table-ref/default table key default +Answer the value associated with @var{key} in @var{table}. If +@var{key} is not present, answer the result of invoking the thunk +@var{default-thunk}, which signals an error instead by default. + +@code{hash-table-ref/default} is a variant that requires a third +argument, @var{default}, and answers @var{default} itself instead of +invoking it. +@end deffn + +@deffn {Scheme Procedure} hash-table-set! table key new-value +Set @var{key} to @var{new-value} in @var{table}. +@end deffn + +@deffn {Scheme Procedure} hash-table-delete! table key +Remove the association of @var{key} in @var{table}, if present. If +absent, do nothing. +@end deffn + +@deffn {Scheme Procedure} hash-table-exists? table key +Answer whether @var{key} has an association in @var{table}. +@end deffn + +@deffn {Scheme Procedure} hash-table-update! table key modifier [default-thunk] +@deffnx {Scheme Procedure} hash-table-update!/default table key modifier default +Replace @var{key}'s associated value in @var{table} by invoking +@var{modifier} with one argument, the old value. + +If @var{key} is not present, and @var{default-thunk} is provided, +invoke it with no arguments to get the ``old value'' to be passed to +@var{modifier} as above. If @var{default-thunk} is not provided in +such a case, signal an error. + +@code{hash-table-update!/default} is a variant that requires the +fourth argument, which is used directly as the ``old value'' rather +than as a thunk to be invoked to retrieve the ``old value''. +@end deffn + +@node SRFI-69 Table properties +@subsubsection Table properties + +@deffn {Scheme Procedure} hash-table-size table +Answer the number of associations in @var{table}. This is guaranteed +to run in constant time for non-weak tables. +@end deffn + +@deffn {Scheme Procedure} hash-table-keys table +Answer an unordered list of the keys in @var{table}. +@end deffn + +@deffn {Scheme Procedure} hash-table-values table +Answer an unordered list of the values in @var{table}. +@end deffn + +@deffn {Scheme Procedure} hash-table-walk table proc +Invoke @var{proc} once for each association in @var{table}, passing +the key and value as arguments. +@end deffn + +@deffn {Scheme Procedure} hash-table-fold table proc init +Invoke @code{(@var{proc} @var{key} @var{value} @var{previous})} for +each @var{key} and @var{value} in @var{table}, where @var{previous} is +the result of the previous invocation, using @var{init} as the first +@var{previous} value. Answer the final @var{proc} result. +@end deffn + +@deffn {Scheme Procedure} hash-table->alist table +Answer an alist where each association in @var{table} is an +association in the result. +@end deffn + +@node SRFI-69 Hash table algorithms +@subsubsection Hash table algorithms + +Each hash table carries an @dfn{equivalence function} and a @dfn{hash +function}, used to implement key lookups. Beginning users should +follow the rules for consistency of the default @var{hash-proc} +specified above. Advanced users can use these to implement their own +equivalence and hash functions for specialized lookup semantics. + +@deffn {Scheme Procedure} hash-table-equivalence-function hash-table +@deffnx {Scheme Procedure} hash-table-hash-function hash-table +Answer the equivalence and hash function of @var{hash-table}, respectively. +@end deffn + +@deffn {Scheme Procedure} hash obj [size] +@deffnx {Scheme Procedure} string-hash obj [size] +@deffnx {Scheme Procedure} string-ci-hash obj [size] +@deffnx {Scheme Procedure} hash-by-identity obj [size] +Answer a hash value appropriate for equality predicate @code{equal?}, +@code{string=?}, @code{string-ci=?}, and @code{eq?}, respectively. +@end deffn + +@code{hash} is a backwards-compatible replacement for Guile's built-in +@code{hash}. + +@node SRFI-88 +@subsection SRFI-88 Keyword Objects +@cindex SRFI-88 +@cindex keyword objects + +@uref{http://srfi.schemers.org/srfi/srfi-88.html, SRFI-88} provides +@dfn{keyword objects}, which are equivalent to Guile's keywords +(@pxref{Keywords}). SRFI-88 keywords can be entered using the +@dfn{postfix keyword syntax}, which consists of an identifier followed +by @code{:} (@pxref{Reader options, @code{postfix} keyword syntax}). +SRFI-88 can be made available with: + +@example +(use-modules (srfi srfi-88)) +@end example + +Doing so installs the right reader option for keyword syntax, using +@code{(read-set! keywords 'postfix)}. It also provides the procedures +described below. + +@deffn {Scheme Procedure} keyword? obj +Return @code{#t} if @var{obj} is a keyword. This is the same procedure +as the same-named built-in procedure (@pxref{Keyword Procedures, +@code{keyword?}}). + +@example +(keyword? foo:) @result{} #t +(keyword? 'foo:) @result{} #t +(keyword? "foo") @result{} #f +@end example +@end deffn + +@deffn {Scheme Procedure} keyword->string kw +Return the name of @var{kw} as a string, i.e., without the trailing +colon. The returned string may not be modified, e.g., with +@code{string-set!}. + +@example +(keyword->string foo:) @result{} "foo" +@end example +@end deffn + +@deffn {Scheme Procedure} string->keyword str +Return the keyword object whose name is @var{str}. + +@example +(keyword->string (string->keyword "a b c")) @result{} "a b c" +@end example +@end deffn + + @c srfi-modules.texi ends here @c Local Variables: