mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-29 19:30:36 +02:00
* NEWS: * README: * doc/r5rs/r5rs.texi: * doc/ref/api-data.texi: * doc/ref/api-debug.texi: * doc/ref/api-evaluation.texi: * doc/ref/api-io.texi: * doc/ref/api-macros.texi: * doc/ref/api-procedures.texi: * doc/ref/api-scheduling.texi: * doc/ref/api-undocumented.texi: * doc/ref/libguile-concepts.texi: * doc/ref/posix.texi: * doc/ref/srfi-modules.texi: * doc/ref/vm.texi: * doc/ref/web.texi: * examples/box-dynamic-module/box.c: * examples/box-dynamic/box.c: * examples/box-module/box.c: * examples/box/box.c: * examples/safe/safe: * examples/scripts/README: * examples/scripts/hello: * gc-benchmarks/larceny/twobit-input-long.sch: * gc-benchmarks/larceny/twobit-smaller.sch: * gc-benchmarks/larceny/twobit.sch: * libguile/expand.c: * libguile/load.c: * libguile/net_db.c: * libguile/scmsigs.c: * libguile/srfi-14.c: * libguile/threads.c: * meta/guile.m4: * module/ice-9/match.upstream.scm: * module/ice-9/ports.scm: * module/language/cps/graphs.scm: * module/scripts/doc-snarf.scm: * module/srfi/srfi-19.scm: * module/system/repl/command.scm: * test-suite/tests/srfi-18.test: Fix typos. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
6155 lines
222 KiB
Text
6155 lines
222 KiB
Text
@c -*-texinfo-*-
|
|
@c This is part of the GNU Guile Reference Manual.
|
|
@c Copyright (C) 1996, 1997, 2000-2004, 2006, 2007-2014, 2017, 2018, 2019, 2020
|
|
@c Free Software Foundation, Inc.
|
|
@c See the file guile.texi for copying conditions.
|
|
|
|
@node SRFI Support
|
|
@section SRFI Support Modules
|
|
@cindex SRFI
|
|
|
|
SRFI is an acronym for Scheme Request For Implementation. The SRFI
|
|
documents define a lot of syntactic and procedure extensions to standard
|
|
Scheme as defined in R5RS.
|
|
|
|
Guile has support for a number of SRFIs. This chapter gives an overview
|
|
over the available SRFIs and some usage hints. For complete
|
|
documentation, design rationales and further examples, we advise you to
|
|
get the relevant SRFI documents from the SRFI home page
|
|
@url{http://srfi.schemers.org/}.
|
|
|
|
@menu
|
|
* About SRFI Usage:: What to know about Guile's SRFI support.
|
|
* SRFI-0:: cond-expand
|
|
* SRFI-1:: List library.
|
|
* SRFI-2:: and-let*.
|
|
* SRFI-4:: Homogeneous numeric vector datatypes.
|
|
* SRFI-6:: Basic String Ports.
|
|
* SRFI-8:: receive.
|
|
* SRFI-9:: define-record-type.
|
|
* SRFI-10:: Hash-Comma Reader Extension.
|
|
* 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-23:: Error reporting
|
|
* SRFI-26:: Specializing parameters
|
|
* SRFI-27:: Sources of Random Bits
|
|
* SRFI-28:: Basic format strings.
|
|
* 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-38:: External Representation for Data With Shared Structure
|
|
* SRFI-39:: Parameter objects
|
|
* SRFI-41:: Streams.
|
|
* SRFI-42:: Eager comprehensions
|
|
* SRFI-43:: Vector Library.
|
|
* SRFI-45:: Primitives for expressing iterative lazy algorithms
|
|
* SRFI-46:: Basic syntax-rules Extensions.
|
|
* SRFI-55:: Requiring Features.
|
|
* SRFI-60:: Integers as bits.
|
|
* SRFI-61:: A more general `cond' clause
|
|
* SRFI-62:: S-expression comments.
|
|
* SRFI-64:: A Scheme API for test suites.
|
|
* SRFI-67:: Compare procedures
|
|
* SRFI-69:: Basic hash tables.
|
|
* SRFI-71:: Extended let-syntax for multiple values.
|
|
* SRFI-87:: => in case clauses.
|
|
* SRFI-88:: Keyword objects.
|
|
* SRFI-98:: Accessing environment variables.
|
|
* SRFI-105:: Curly-infix expressions.
|
|
* SRFI-111:: Boxes.
|
|
* SRFI-171:: Transducers
|
|
@end menu
|
|
|
|
|
|
@node About SRFI Usage
|
|
@subsection About SRFI Usage
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
SRFI support in Guile is currently implemented partly in the core
|
|
library, and partly as add-on modules. That means that some SRFIs are
|
|
automatically available when the interpreter is started, whereas the
|
|
other SRFIs require you to use the appropriate support module
|
|
explicitly.
|
|
|
|
There are several reasons for this inconsistency. First, the feature
|
|
checking syntactic form @code{cond-expand} (@pxref{SRFI-0}) must be
|
|
available immediately, because it must be there when the user wants to
|
|
check for the Scheme implementation, that is, before she can know that
|
|
it is safe to use @code{use-modules} to load SRFI support modules. The
|
|
second reason is that some features defined in SRFIs had been
|
|
implemented in Guile before the developers started to add SRFI
|
|
implementations as modules (for example SRFI-13 (@pxref{SRFI-13})). In
|
|
the future, it is possible that SRFIs in the core library might be
|
|
factored out into separate modules, requiring explicit module loading
|
|
when they are needed. So you should be prepared to have to use
|
|
@code{use-modules} someday in the future to access SRFI-13 bindings. If
|
|
you want, you can do that already. We have included the module
|
|
@code{(srfi srfi-13)} in the distribution, which currently does nothing,
|
|
but ensures that you can write future-safe code.
|
|
|
|
Generally, support for a specific SRFI is made available by using
|
|
modules named @code{(srfi srfi-@var{number})}, where @var{number} is the
|
|
number of the SRFI needed. Another possibility is to use the command
|
|
line option @code{--use-srfi}, which will load the necessary modules
|
|
automatically (@pxref{Invoking Guile}).
|
|
|
|
|
|
@node SRFI-0
|
|
@subsection SRFI-0 - cond-expand
|
|
@cindex SRFI-0
|
|
|
|
This SRFI lets a portable Scheme program test for the presence of
|
|
certain features, and adapt itself by using different blocks of code,
|
|
or fail if the necessary features are not available. There's no
|
|
module to load, this is in the Guile core.
|
|
|
|
A program designed only for Guile will generally not need this
|
|
mechanism, such a program can of course directly use the various
|
|
documented parts of Guile.
|
|
|
|
@deffn syntax cond-expand (feature body@dots{}) @dots{}
|
|
Expand to the @var{body} of the first clause whose @var{feature}
|
|
specification is satisfied. It is an error if no @var{feature} is
|
|
satisfied.
|
|
|
|
Features are symbols such as @code{srfi-1}, and a feature
|
|
specification can use @code{and}, @code{or} and @code{not} forms to
|
|
test combinations. The last clause can be an @code{else}, to be used
|
|
if no other passes.
|
|
|
|
For example, define a private version of @code{alist-cons} if SRFI-1
|
|
is not available.
|
|
|
|
@example
|
|
(cond-expand (srfi-1
|
|
)
|
|
(else
|
|
(define (alist-cons key val alist)
|
|
(cons (cons key val) alist))))
|
|
@end example
|
|
|
|
Or demand a certain set of SRFIs (list operations, string ports,
|
|
@code{receive} and string operations), failing if they're not
|
|
available.
|
|
|
|
@example
|
|
(cond-expand ((and srfi-1 srfi-6 srfi-8 srfi-13)
|
|
))
|
|
@end example
|
|
@end deffn
|
|
|
|
@noindent
|
|
The Guile core has the following features,
|
|
|
|
@example
|
|
guile
|
|
guile-2 ;; starting from Guile 2.x
|
|
guile-2.2 ;; starting from Guile 2.2
|
|
guile-3 ;; starting from Guile 3.x
|
|
guile-3.0 ;; starting from Guile 3.0
|
|
r5rs
|
|
r6rs
|
|
r7rs
|
|
exact-closed ieee-float full-unicode ratios ;; R7RS features
|
|
srfi-0
|
|
srfi-4
|
|
srfi-6
|
|
srfi-13
|
|
srfi-14
|
|
srfi-16
|
|
srfi-23
|
|
srfi-30
|
|
srfi-39
|
|
srfi-46
|
|
srfi-55
|
|
srfi-61
|
|
srfi-62
|
|
srfi-87
|
|
srfi-105
|
|
@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
|
|
portable program.
|
|
|
|
Testing the @code{guile} feature allows a program to adapt itself to
|
|
the Guile module system, but still run on other Scheme systems. For
|
|
example the following demands SRFI-8 (@code{receive}), but also knows
|
|
how to load it with the Guile mechanism.
|
|
|
|
@example
|
|
(cond-expand (srfi-8
|
|
)
|
|
(guile
|
|
(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.@var{x} and previous versions of Guile. For instance, it
|
|
makes it possible to write code that accounts for Guile 2.@var{x}'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!
|
|
|
|
The list library defined in SRFI-1 contains a lot of useful list
|
|
processing procedures for construction, examining, destructuring and
|
|
manipulating lists and pairs.
|
|
|
|
Since SRFI-1 also defines some procedures which are already contained
|
|
in R5RS and thus are supported by the Guile core library, some list
|
|
and pair procedures which appear in the SRFI-1 document may not appear
|
|
in this section. So when looking for a particular list/pair
|
|
processing procedure, you should also have a look at the sections
|
|
@ref{Lists} and @ref{Pairs}.
|
|
|
|
@menu
|
|
* SRFI-1 Constructors:: Constructing new lists.
|
|
* SRFI-1 Predicates:: Testing list for specific properties.
|
|
* SRFI-1 Selectors:: Selecting elements from lists.
|
|
* SRFI-1 Length Append etc:: Length calculation and list appending.
|
|
* SRFI-1 Fold and Map:: Higher-order list processing.
|
|
* SRFI-1 Filtering and Partitioning:: Filter lists based on predicates.
|
|
* SRFI-1 Searching:: Search for elements.
|
|
* SRFI-1 Deleting:: Delete elements from lists.
|
|
* SRFI-1 Association Lists:: Handle association lists.
|
|
* SRFI-1 Set Operations:: Use lists for representing sets.
|
|
@end menu
|
|
|
|
@node SRFI-1 Constructors
|
|
@subsubsection Constructors
|
|
@cindex list constructor
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
New lists can be constructed by calling one of the following
|
|
procedures.
|
|
|
|
@deffn {Scheme Procedure} xcons d a
|
|
Like @code{cons}, but with interchanged arguments. Useful mostly when
|
|
passed to higher-order procedures.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list-tabulate n init-proc
|
|
Return an @var{n}-element list, where each list element is produced by
|
|
applying the procedure @var{init-proc} to the corresponding list
|
|
index. The order in which @var{init-proc} is applied to the indices
|
|
is not specified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list-copy lst
|
|
Return a new list containing the elements of the list @var{lst}.
|
|
|
|
This function differs from the core @code{list-copy} (@pxref{List
|
|
Constructors}) in accepting improper lists too. And if @var{lst} is
|
|
not a pair at all then it's treated as the final tail of an improper
|
|
list and simply returned.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} circular-list elt1 elt2 @dots{}
|
|
Return a circular list containing the given arguments @var{elt1}
|
|
@var{elt2} @dots{}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} iota count [start step]
|
|
Return a list containing @var{count} numbers, starting from
|
|
@var{start} and adding @var{step} each time. The default @var{start}
|
|
is 0, the default @var{step} is 1. For example,
|
|
|
|
@example
|
|
(iota 6) @result{} (0 1 2 3 4 5)
|
|
(iota 4 2.5 -2) @result{} (2.5 0.5 -1.5 -3.5)
|
|
@end example
|
|
|
|
This function takes its name from the corresponding primitive in the
|
|
APL language.
|
|
@end deffn
|
|
|
|
|
|
@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, 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, 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, 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
|
|
as @var{lst}, an error is signaled. This procedure is recommended
|
|
for checking for the end of a list in contexts where dotted lists are
|
|
not allowed.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} not-pair? obj
|
|
Return @code{#t} is @var{obj} is not a pair, @code{#f} otherwise.
|
|
This is shorthand notation @code{(not (pair? @var{obj}))} and is
|
|
supposed to be used for end-of-list checking in contexts where dotted
|
|
lists are allowed.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list= elt= list1 @dots{}
|
|
Return @code{#t} if all argument lists are equal, @code{#f} otherwise.
|
|
List equality is determined by testing whether all lists have the same
|
|
length and the corresponding elements are equal in the sense of the
|
|
equality predicate @var{elt=}. If no or only one list is given,
|
|
@code{#t} is returned.
|
|
@end deffn
|
|
|
|
|
|
@node SRFI-1 Selectors
|
|
@subsubsection Selectors
|
|
@cindex list selector
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
@deffn {Scheme Procedure} first pair
|
|
@deffnx {Scheme Procedure} second pair
|
|
@deffnx {Scheme Procedure} third pair
|
|
@deffnx {Scheme Procedure} fourth pair
|
|
@deffnx {Scheme Procedure} fifth pair
|
|
@deffnx {Scheme Procedure} sixth pair
|
|
@deffnx {Scheme Procedure} seventh pair
|
|
@deffnx {Scheme Procedure} eighth pair
|
|
@deffnx {Scheme Procedure} ninth pair
|
|
@deffnx {Scheme Procedure} tenth pair
|
|
These are synonyms for @code{car}, @code{cadr}, @code{caddr}, @dots{}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} car+cdr pair
|
|
Return two values, the @sc{car} and the @sc{cdr} of @var{pair}.
|
|
@end deffn
|
|
|
|
@lisp
|
|
(car+cdr '(0 1 2 3))
|
|
@result{}
|
|
0
|
|
(1 2 3)
|
|
@end lisp
|
|
|
|
@deffn {Scheme Procedure} take lst i
|
|
@deffnx {Scheme Procedure} take! lst i
|
|
Return a list containing the first @var{i} elements of @var{lst}.
|
|
|
|
@code{take!} may modify the structure of the argument list @var{lst}
|
|
in order to produce the result.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} drop lst i
|
|
Return a list containing all but the first @var{i} elements of
|
|
@var{lst}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} take-right lst i
|
|
Return 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
|
|
@deffnx {Scheme Procedure} drop-right! lst i
|
|
Return a list containing all but the @var{i} last elements of
|
|
@var{lst}.
|
|
|
|
@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
|
|
@deffnx {Scheme Procedure} split-at! lst i
|
|
Return two values, a list containing the first @var{i} elements of the
|
|
list @var{lst} and a list containing the remaining elements.
|
|
|
|
@code{split-at!} may modify the structure of the argument list
|
|
@var{lst} in order to produce the result.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} last lst
|
|
Return the last element of the non-empty, finite list @var{lst}.
|
|
@end deffn
|
|
|
|
|
|
@node SRFI-1 Length Append etc
|
|
@subsubsection Length, Append, Concatenate, etc.
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
@deffn {Scheme Procedure} length+ lst
|
|
Return the length of the argument list @var{lst}. When @var{lst} is a
|
|
circular list, @code{#f} is returned.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} concatenate list-of-lists
|
|
@deffnx {Scheme Procedure} concatenate! list-of-lists
|
|
Construct a list by appending all lists in @var{list-of-lists}.
|
|
|
|
@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} 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.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} zip lst1 lst2 @dots{}
|
|
Return a list as long as the shortest of the argument lists, where
|
|
each element is a list. The first list contains the first elements of
|
|
the argument lists, the second list contains the second elements, and
|
|
so on.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} unzip1 lst
|
|
@deffnx {Scheme Procedure} unzip2 lst
|
|
@deffnx {Scheme Procedure} unzip3 lst
|
|
@deffnx {Scheme Procedure} unzip4 lst
|
|
@deffnx {Scheme Procedure} unzip5 lst
|
|
@code{unzip1} takes a list of lists, and returns a list containing the
|
|
first elements of each list, @code{unzip2} returns two lists, the
|
|
first containing the first elements of each lists and the second
|
|
containing the second elements of each lists, and so on.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} count pred lst1 lst2 @dots{}
|
|
Return a count of the number of times @var{pred} returns true when
|
|
called on elements from the given lists.
|
|
|
|
@var{pred} is called with @var{N} parameters @code{(@var{pred}
|
|
@var{elem1} @dots{} @var{elemN} )}, each element being from the
|
|
corresponding list. The first call is with the first element of each
|
|
list, the second with the second element from each, and so on.
|
|
|
|
Counting stops when the end of the shortest list is reached. At least
|
|
one list must be non-circular.
|
|
@end deffn
|
|
|
|
|
|
@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 proc init lst1 lst2 @dots{}
|
|
@deffnx {Scheme Procedure} fold-right proc init lst1 lst2 @dots{}
|
|
Apply @var{proc} to the elements of @var{lst1} @var{lst2} @dots{} to
|
|
build a result, and return that result.
|
|
|
|
Each @var{proc} call is @code{(@var{proc} @var{elem1} @var{elem2}
|
|
@dots{} @var{previous})}, where @var{elem1} is from @var{lst1},
|
|
@var{elem2} is from @var{lst2}, and so on. @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.
|
|
|
|
@code{fold} works through the list elements from first to last. The
|
|
following shows a list reversal and the calls it makes,
|
|
|
|
@example
|
|
(fold cons '() '(1 2 3))
|
|
|
|
(cons 1 '())
|
|
(cons 2 '(1))
|
|
(cons 3 '(2 1)
|
|
@result{} (3 2 1)
|
|
@end example
|
|
|
|
@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} @var{lst2} @dots{} have different lengths, @code{fold}
|
|
stops when the end of the shortest is reached; @code{fold-right}
|
|
commences at the last element of the shortest. Ie.@: elements past the
|
|
length of the shortest are ignored in the other @var{lst}s. At least
|
|
one @var{lst} must be non-circular.
|
|
|
|
@code{fold} should be preferred over @code{fold-right} if the order of
|
|
processing doesn't matter, or can be arranged either way, since
|
|
@code{fold} is a little more efficient.
|
|
|
|
The way @code{fold} builds a result from iterating is quite general,
|
|
it can do more than other iterations like say @code{map} or
|
|
@code{filter}. The following for example removes adjacent duplicate
|
|
elements from a list,
|
|
|
|
@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} pair-fold proc init lst1 lst2 @dots{}
|
|
@deffnx {Scheme Procedure} pair-fold-right proc init lst1 lst2 @dots{}
|
|
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 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]
|
|
@code{unfold} is defined as follows:
|
|
|
|
@lisp
|
|
(unfold p f g seed) =
|
|
(if (p seed) (tail-gen seed)
|
|
(cons (f seed)
|
|
(unfold p f g (g seed))))
|
|
@end lisp
|
|
|
|
@table @var
|
|
@item p
|
|
Determines when to stop unfolding.
|
|
|
|
@item f
|
|
Maps each seed value to the corresponding list element.
|
|
|
|
@item g
|
|
Maps each seed value to next seed value.
|
|
|
|
@item seed
|
|
The state value for the unfold.
|
|
|
|
@item tail-gen
|
|
Creates the tail of the list; defaults to @code{(lambda (x) '())}.
|
|
@end table
|
|
|
|
@var{g} produces a series of seed values, which are mapped to list
|
|
elements by @var{f}. These elements are put into a list in
|
|
left-to-right order, and @var{p} tells when to stop unfolding.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} unfold-right p f g seed [tail]
|
|
Construct a list with the following loop.
|
|
|
|
@lisp
|
|
(let lp ((seed seed) (lis tail))
|
|
(if (p seed) lis
|
|
(lp (g seed)
|
|
(cons (f seed) lis))))
|
|
@end lisp
|
|
|
|
@table @var
|
|
@item p
|
|
Determines when to stop unfolding.
|
|
|
|
@item f
|
|
Maps each seed value to the corresponding list element.
|
|
|
|
@item g
|
|
Maps each seed value to next seed value.
|
|
|
|
@item seed
|
|
The state value for the unfold.
|
|
|
|
@item tail
|
|
The tail of the list; defaults to @code{'()}.
|
|
@end table
|
|
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} map f lst1 lst2 @dots{}
|
|
Map the procedure over the list(s) @var{lst1}, @var{lst2}, @dots{} and
|
|
return a list containing the results of the procedure applications.
|
|
This procedure is extended with respect to R5RS, because the argument
|
|
lists may have different lengths. The result list will have the same
|
|
length as the shortest argument lists. The order in which @var{f}
|
|
will be applied to the list element(s) is not specified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} for-each f lst1 lst2 @dots{}
|
|
Apply the procedure @var{f} to each pair of corresponding elements of
|
|
the list(s) @var{lst1}, @var{lst2}, @dots{}. The return value is not
|
|
specified. This procedure is extended with respect to R5RS, because
|
|
the argument lists may have different lengths. The shortest argument
|
|
list determines the number of times @var{f} is called. @var{f} will
|
|
be applied to the list elements in left-to-right order.
|
|
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} append-map f lst1 lst2 @dots{}
|
|
@deffnx {Scheme Procedure} append-map! f lst1 lst2 @dots{}
|
|
Equivalent to
|
|
|
|
@lisp
|
|
(apply append (map f clist1 clist2 ...))
|
|
@end lisp
|
|
|
|
and
|
|
|
|
@lisp
|
|
(apply append! (map f clist1 clist2 ...))
|
|
@end lisp
|
|
|
|
Map @var{f} over the elements of the lists, just as in the @code{map}
|
|
function. However, the results of the applications are appended
|
|
together to make the final result. @code{append-map} uses
|
|
@code{append} to append the results together; @code{append-map!} uses
|
|
@code{append!}.
|
|
|
|
The dynamic order in which the various applications of @var{f} are
|
|
made is not specified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} map! f lst1 lst2 @dots{}
|
|
Linear-update variant of @code{map} -- @code{map!} is allowed, but not
|
|
required, to alter the cons cells of @var{lst1} to construct the
|
|
result list.
|
|
|
|
The dynamic order in which the various applications of @var{f} are
|
|
made is not specified. In the n-ary case, @var{lst2}, @var{lst3},
|
|
@dots{} must have at least as many elements as @var{lst1}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} pair-for-each f lst1 lst2 @dots{}
|
|
Like @code{for-each}, but applies the procedure @var{f} to the pairs
|
|
from which the argument lists are constructed, instead of the list
|
|
elements. The return value is not specified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} filter-map f lst1 lst2 @dots{}
|
|
Like @code{map}, but only results from the applications of @var{f}
|
|
which are true are saved in the result list.
|
|
@end deffn
|
|
|
|
|
|
@node SRFI-1 Filtering and Partitioning
|
|
@subsubsection Filtering and Partitioning
|
|
@cindex list filter
|
|
@cindex list partition
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
Filtering means to collect all elements from a list which satisfy a
|
|
specific condition. Partitioning a list means to make two groups of
|
|
list elements, one which contains the elements satisfying a condition,
|
|
and the other for the elements which don't.
|
|
|
|
The @code{filter} and @code{filter!} functions are implemented in the
|
|
Guile core, @xref{List Modification}.
|
|
|
|
@deffn {Scheme Procedure} partition pred lst
|
|
@deffnx {Scheme Procedure} partition! pred lst
|
|
Split @var{lst} into those elements which do and don't satisfy the
|
|
predicate @var{pred}.
|
|
|
|
The return is two values (@pxref{Multiple Values}), the first being a
|
|
list of all elements from @var{lst} which satisfy @var{pred}, the
|
|
second a list of those which do not.
|
|
|
|
The elements in the result lists are in the same order as in @var{lst}
|
|
but the order in which the calls @code{(@var{pred} elem)} are made on
|
|
the list elements is unspecified.
|
|
|
|
@code{partition} does not change @var{lst}, but one of the returned
|
|
lists may share a tail with it. @code{partition!} may modify
|
|
@var{lst} to construct its return.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} remove pred lst
|
|
@deffnx {Scheme Procedure} remove! pred lst
|
|
Return a list containing all elements from @var{lst} which do not
|
|
satisfy the predicate @var{pred}. The elements in the result list
|
|
have the same order as in @var{lst}. The order in which @var{pred} is
|
|
applied to the list elements is not specified.
|
|
|
|
@code{remove!} is allowed, but not required to modify the structure of
|
|
the input list.
|
|
@end deffn
|
|
|
|
|
|
@node SRFI-1 Searching
|
|
@subsubsection Searching
|
|
@cindex list search
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
The procedures for searching elements in lists either accept a
|
|
predicate or a comparison object for determining which elements are to
|
|
be searched.
|
|
|
|
@deffn {Scheme Procedure} find pred lst
|
|
Return the first element of @var{lst} that satisfies the predicate
|
|
@var{pred} and @code{#f} if no such element is found.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} find-tail pred lst
|
|
Return the first pair of @var{lst} whose @sc{car} satisfies the
|
|
predicate @var{pred} and @code{#f} if no such element is found.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} take-while pred lst
|
|
@deffnx {Scheme Procedure} take-while! pred lst
|
|
Return the longest initial prefix of @var{lst} whose elements all
|
|
satisfy the predicate @var{pred}.
|
|
|
|
@code{take-while!} is allowed, but not required to modify the input
|
|
list while producing the result.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} drop-while pred lst
|
|
Drop the longest initial prefix of @var{lst} whose elements all
|
|
satisfy the predicate @var{pred}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} span pred lst
|
|
@deffnx {Scheme Procedure} span! pred lst
|
|
@deffnx {Scheme Procedure} break pred lst
|
|
@deffnx {Scheme Procedure} break! pred lst
|
|
@code{span} splits the list @var{lst} into the longest initial prefix
|
|
whose elements all satisfy the predicate @var{pred}, and the remaining
|
|
tail. @code{break} inverts the sense of the predicate.
|
|
|
|
@code{span!} and @code{break!} are allowed, but not required to modify
|
|
the structure of the input list @var{lst} in order to produce the
|
|
result.
|
|
|
|
Note that the name @code{break} conflicts with the @code{break}
|
|
binding established by @code{while} (@pxref{while do}). Applications
|
|
wanting to use @code{break} from within a @code{while} loop will need
|
|
to make a new define under a different name.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} any pred lst1 lst2 @dots{}
|
|
Test whether any set of elements from @var{lst1} @var{lst2} @dots{}
|
|
satisfies @var{pred}. If so, the return value is the return value from
|
|
the successful @var{pred} call, or if not, the return value is
|
|
@code{#f}.
|
|
|
|
If there are n list arguments, then @var{pred} must be a predicate
|
|
taking n arguments. Each @var{pred} call is @code{(@var{pred}
|
|
@var{elem1} @var{elem2} @dots{} )} 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 (i.e., 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{}
|
|
Test whether every set of elements from @var{lst1} @var{lst2} @dots{}
|
|
satisfies @var{pred}. If so, the return value is the return from the
|
|
final @var{pred} call, or if not, the return value is @code{#f}.
|
|
|
|
If there are n list arguments, then @var{pred} must be a predicate
|
|
taking n arguments. Each @var{pred} call is @code{(@var{pred}
|
|
@var{elem1} @var{elem2 @dots{}})} 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 (i.e., when the end of
|
|
the shortest list has been reached) is a tail call.
|
|
|
|
If one of @var{lst1} @var{lst2} @dots{}is empty then no calls to
|
|
@var{pred} are made, and the return value is @code{#t}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list-index pred lst1 lst2 @dots{}
|
|
Return the index of the first set of elements, one from each of
|
|
@var{lst1} @var{lst2} @dots{}, which satisfies @var{pred}.
|
|
|
|
@var{pred} is called as @code{(@var{elem1} @var{elem2 @dots{}})}.
|
|
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 value 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 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,
|
|
|
|
@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
|
|
@cindex list delete
|
|
|
|
@deffn {Scheme Procedure} delete x lst [=]
|
|
@deffnx {Scheme Procedure} delete! x lst [=]
|
|
Return a list containing the elements of @var{lst} but with those
|
|
equal to @var{x} deleted. The returned elements will be in the same
|
|
order as they were in @var{lst}.
|
|
|
|
Equality is determined by the @var{=} predicate, or @code{equal?} if
|
|
not given. An equality call is made just once for each element, but
|
|
the order in which the calls are made on the elements is unspecified.
|
|
|
|
The equality calls are always @code{(= x elem)}, ie.@: the given @var{x}
|
|
is first. This means for instance elements greater than 5 can be
|
|
deleted with @code{(delete 5 lst <)}.
|
|
|
|
@code{delete} does not modify @var{lst}, but the return might share a
|
|
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!}
|
|
(@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 [=]
|
|
@deffnx {Scheme Procedure} delete-duplicates! lst [=]
|
|
Return a list containing the elements of @var{lst} but without
|
|
duplicates.
|
|
|
|
When elements are equal, only the first in @var{lst} is retained.
|
|
Equal elements can be anywhere in @var{lst}, they don't have to be
|
|
adjacent. The returned list will have the retained elements in the
|
|
same order as they were in @var{lst}.
|
|
|
|
Equality is determined by the @var{=} predicate, or @code{equal?} if
|
|
not given. Calls @code{(= x y)} are made with element @var{x} being
|
|
before @var{y} in @var{lst}. A call is made at most once for each
|
|
combination, but the sequence of the calls across the elements is
|
|
unspecified.
|
|
|
|
@code{delete-duplicates} does not modify @var{lst}, but the return
|
|
might share a common tail with @var{lst}. @code{delete-duplicates!}
|
|
may modify the structure of @var{lst} to construct its return.
|
|
|
|
In the worst case, this is an @math{O(N^2)} algorithm because it must
|
|
check each element against all those preceding it. For long lists it
|
|
is more efficient to sort and then compare only adjacent elements.
|
|
@end deffn
|
|
|
|
|
|
@node SRFI-1 Association Lists
|
|
@subsubsection Association Lists
|
|
@cindex association list
|
|
@cindex alist
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
Association lists are described in detail in section @ref{Association
|
|
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}. 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})}, i.e.@: the
|
|
given target @var{key} is the first argument, and a @code{car} from
|
|
@var{alist} is second.
|
|
|
|
For example a case-insensitive string lookup,
|
|
|
|
@example
|
|
(assoc "yy" '(("XX" . 1) ("YY" . 2)) string-ci=?)
|
|
@result{} ("YY" . 2)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} alist-cons key datum alist
|
|
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
|
|
|
|
@code{acons} (@pxref{Adding or Setting Alist Entries}) in the Guile
|
|
core does the same thing.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} alist-copy alist
|
|
Return a newly allocated copy of @var{alist}, that means that the
|
|
spine of the list as well as the pairs are copied.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} alist-delete key alist [=]
|
|
@deffnx {Scheme Procedure} alist-delete! key alist [=]
|
|
Return a list containing the elements of @var{alist} but with those
|
|
elements whose keys are equal to @var{key} deleted. The returned
|
|
elements will be in the same order as they were in @var{alist}.
|
|
|
|
Equality is determined by the @var{=} predicate, or @code{equal?} if
|
|
not given. The order in which elements are tested is unspecified, but
|
|
each equality call is made @code{(= key alistkey)}, i.e.@: the given
|
|
@var{key} parameter is first and the key from @var{alist} second.
|
|
This means for instance all associations with a key greater than 5 can
|
|
be removed with @code{(alist-delete 5 alist <)}.
|
|
|
|
@code{alist-delete} does not modify @var{alist}, but the return might
|
|
share a common tail with @var{alist}. @code{alist-delete!} may modify
|
|
the list structure of @var{alist} to construct its return.
|
|
@end deffn
|
|
|
|
|
|
@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<= = list @dots{}
|
|
Return @code{#t} if each list is a subset of the one following it.
|
|
I.e., @var{list1} is a subset of @var{list2}, @var{list2} is a subset of
|
|
@var{list3}, etc., for as many lists as given. If only one list or no
|
|
lists are given, the return value 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)}.
|
|
|
|
@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= = list @dots{}
|
|
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, the return
|
|
value 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 elem @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 value shares a common tail with @var{list}), but the order that
|
|
the @var{elem}s are added is unspecified.
|
|
|
|
The given @var{=} procedure is used for comparing elements, called as
|
|
@code{(@var{=} listelem elem)}, i.e., 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 = list @dots{}
|
|
@deffnx {Scheme Procedure} lset-union! = list @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 @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 @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
|
|
|
|
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 (@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 = list @dots{}
|
|
@deffnx {Scheme Procedure} lset-xor! = list @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
|
|
|
|
|
|
@node SRFI-2
|
|
@subsection SRFI-2 - and-let*
|
|
@cindex SRFI-2
|
|
|
|
@noindent
|
|
The following syntax can be obtained with
|
|
|
|
@lisp
|
|
(use-modules (srfi srfi-2))
|
|
@end lisp
|
|
|
|
or alternatively
|
|
|
|
@lisp
|
|
(use-modules (ice-9 and-let-star))
|
|
@end lisp
|
|
|
|
@deffn {library syntax} and-let* (clause @dots{}) body @dots{}
|
|
A combination of @code{and} and @code{let*}.
|
|
|
|
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, 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)
|
|
Evaluate @var{expr}, check for @code{#f}, and bind it to @var{symbol}.
|
|
Like @code{let*}, that binding is available to subsequent clauses.
|
|
@item (expr)
|
|
Evaluate @var{expr} and check for @code{#f}.
|
|
@item symbol
|
|
Get the value bound to @var{symbol} and check for @code{#f}.
|
|
@end table
|
|
|
|
Notice that @code{(expr)} has an ``extra'' pair of parentheses, for
|
|
instance @code{((eq? x y))}. One way to remember this is to imagine
|
|
the @code{symbol} in @code{(symbol expr)} is omitted.
|
|
|
|
@code{and-let*} is good for calculations where a @code{#f} value means
|
|
termination, but where a non-@code{#f} value is going to be needed in
|
|
subsequent expressions.
|
|
|
|
The following illustrates this, it returns text between brackets
|
|
@samp{[...]} in a string, or @code{#f} if there are no such brackets
|
|
(ie.@: either @code{string-index} gives @code{#f}).
|
|
|
|
@example
|
|
(define (extract-brackets str)
|
|
(and-let* ((start (string-index str #\[))
|
|
(end (string-index str #\] start)))
|
|
(substring str (1+ start) end)))
|
|
@end example
|
|
|
|
The following shows plain variables and expressions tested too.
|
|
@code{diagnostic-levels} is taken to be an alist associating a
|
|
diagnostic type with a level. @code{str} is printed only if the type
|
|
is known and its level is high enough.
|
|
|
|
@example
|
|
(define (show-diagnostic type str)
|
|
(and-let* (want-diagnostics
|
|
(level (assq-ref diagnostic-levels type))
|
|
((>= level current-diagnostic-level)))
|
|
(display str)))
|
|
@end example
|
|
|
|
The advantage of @code{and-let*} is that an extended sequence of
|
|
expressions and tests doesn't require lots of nesting as would arise
|
|
from separate @code{and} and @code{let*}, or from @code{cond} with
|
|
@code{=>}.
|
|
|
|
@end deffn
|
|
|
|
|
|
@node SRFI-4
|
|
@subsection SRFI-4 - Homogeneous numeric vector datatypes
|
|
@cindex SRFI-4
|
|
|
|
SRFI-4 provides an interface to uniform numeric vectors: vectors whose elements
|
|
are all of a single numeric type. Guile offers uniform numeric vectors for
|
|
signed and unsigned 8-bit, 16-bit, 32-bit, and 64-bit integers, two sizes of
|
|
floating point values, and, as an extension to SRFI-4, complex floating-point
|
|
numbers of these two sizes.
|
|
|
|
The standard SRFI-4 procedures and data types may be included via loading the
|
|
appropriate module:
|
|
|
|
@example
|
|
(use-modules (srfi srfi-4))
|
|
@end example
|
|
|
|
This module is currently a part of the default Guile environment, but it is a
|
|
good practice to explicitly import the module. In the future, using SRFI-4
|
|
procedures without importing the SRFI-4 module will cause a deprecation message
|
|
to be printed. (Of course, one may call the C functions at any time. Would that
|
|
C had modules!)
|
|
|
|
@menu
|
|
* SRFI-4 Overview:: The warp and weft of uniform numeric vectors.
|
|
* SRFI-4 API:: Uniform vectors, from Scheme and from C.
|
|
* SRFI-4 and Bytevectors:: SRFI-4 vectors are backed by bytevectors.
|
|
* SRFI-4 Extensions:: Guile-specific extensions to the standard.
|
|
@end menu
|
|
|
|
@node SRFI-4 Overview
|
|
@subsubsection SRFI-4 - Overview
|
|
|
|
Uniform numeric vectors can be useful since they consume less memory
|
|
than the non-uniform, general vectors. Also, since the types they can
|
|
store correspond directly to C types, it is easier to work with them
|
|
efficiently on a low level. Consider image processing as an example,
|
|
where you want to apply a filter to some image. While you could store
|
|
the pixels of an image in a general vector and write a general
|
|
convolution function, things are much more efficient with uniform
|
|
vectors: the convolution function knows that all pixels are unsigned
|
|
8-bit values (say), and can use a very tight inner loop.
|
|
|
|
This is implemented in Scheme by having the compiler notice calls to the SRFI-4
|
|
accessors, and inline them to appropriate compiled code. From C you have access
|
|
to the raw array; functions for efficiently working with uniform numeric vectors
|
|
from C are listed at the end of this section.
|
|
|
|
Uniform numeric vectors are the special case of one dimensional uniform
|
|
numeric arrays.
|
|
|
|
There are 12 standard kinds of uniform numeric vectors, and they all have their
|
|
own complement of constructors, accessors, and so on. Procedures that operate on
|
|
a specific kind of uniform numeric vector have a ``tag'' in their name,
|
|
indicating the element type.
|
|
|
|
@table @nicode
|
|
@item u8
|
|
unsigned 8-bit integers
|
|
|
|
@item s8
|
|
signed 8-bit integers
|
|
|
|
@item u16
|
|
unsigned 16-bit integers
|
|
|
|
@item s16
|
|
signed 16-bit integers
|
|
|
|
@item u32
|
|
unsigned 32-bit integers
|
|
|
|
@item s32
|
|
signed 32-bit integers
|
|
|
|
@item u64
|
|
unsigned 64-bit integers
|
|
|
|
@item s64
|
|
signed 64-bit integers
|
|
|
|
@item f32
|
|
the C type @code{float}
|
|
|
|
@item f64
|
|
the C type @code{double}
|
|
|
|
@end table
|
|
|
|
In addition, Guile supports uniform arrays of complex numbers, with the
|
|
nonstandard tags:
|
|
|
|
@table @nicode
|
|
|
|
@item c32
|
|
complex numbers in rectangular form with the real and imaginary part
|
|
being a @code{float}
|
|
|
|
@item c64
|
|
complex numbers in rectangular form with the real and imaginary part
|
|
being a @code{double}
|
|
|
|
@end table
|
|
|
|
The external representation (ie.@: read syntax) for these vectors is
|
|
similar to normal Scheme vectors, but with an additional tag from the
|
|
tables above indicating the vector's type. For example,
|
|
|
|
@lisp
|
|
#u16(1 2 3)
|
|
#f64(3.1415 2.71)
|
|
@end lisp
|
|
|
|
Note that the read syntax for floating-point here conflicts with
|
|
@code{#f} for false. In Standard Scheme one can write @code{(1 #f3)}
|
|
for a three element list @code{(1 #f 3)}, but for Guile @code{(1 #f3)}
|
|
is invalid. @code{(1 #f 3)} is almost certainly what one should write
|
|
anyway to make the intention clear, so this is rarely a problem.
|
|
|
|
|
|
@node SRFI-4 API
|
|
@subsubsection SRFI-4 - API
|
|
|
|
Note that the @nicode{c32} and @nicode{c64} functions are only available from
|
|
@nicode{(srfi srfi-4 gnu)}.
|
|
|
|
@deffn {Scheme Procedure} u8vector? obj
|
|
@deffnx {Scheme Procedure} s8vector? obj
|
|
@deffnx {Scheme Procedure} u16vector? obj
|
|
@deffnx {Scheme Procedure} s16vector? obj
|
|
@deffnx {Scheme Procedure} u32vector? obj
|
|
@deffnx {Scheme Procedure} s32vector? obj
|
|
@deffnx {Scheme Procedure} u64vector? obj
|
|
@deffnx {Scheme Procedure} s64vector? obj
|
|
@deffnx {Scheme Procedure} f32vector? obj
|
|
@deffnx {Scheme Procedure} f64vector? obj
|
|
@deffnx {Scheme Procedure} c32vector? obj
|
|
@deffnx {Scheme Procedure} c64vector? obj
|
|
@deffnx {C Function} scm_u8vector_p (obj)
|
|
@deffnx {C Function} scm_s8vector_p (obj)
|
|
@deffnx {C Function} scm_u16vector_p (obj)
|
|
@deffnx {C Function} scm_s16vector_p (obj)
|
|
@deffnx {C Function} scm_u32vector_p (obj)
|
|
@deffnx {C Function} scm_s32vector_p (obj)
|
|
@deffnx {C Function} scm_u64vector_p (obj)
|
|
@deffnx {C Function} scm_s64vector_p (obj)
|
|
@deffnx {C Function} scm_f32vector_p (obj)
|
|
@deffnx {C Function} scm_f64vector_p (obj)
|
|
@deffnx {C Function} scm_c32vector_p (obj)
|
|
@deffnx {C Function} scm_c64vector_p (obj)
|
|
Return @code{#t} if @var{obj} is a homogeneous numeric vector of the
|
|
indicated type.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} make-u8vector n [value]
|
|
@deffnx {Scheme Procedure} make-s8vector n [value]
|
|
@deffnx {Scheme Procedure} make-u16vector n [value]
|
|
@deffnx {Scheme Procedure} make-s16vector n [value]
|
|
@deffnx {Scheme Procedure} make-u32vector n [value]
|
|
@deffnx {Scheme Procedure} make-s32vector n [value]
|
|
@deffnx {Scheme Procedure} make-u64vector n [value]
|
|
@deffnx {Scheme Procedure} make-s64vector n [value]
|
|
@deffnx {Scheme Procedure} make-f32vector n [value]
|
|
@deffnx {Scheme Procedure} make-f64vector n [value]
|
|
@deffnx {Scheme Procedure} make-c32vector n [value]
|
|
@deffnx {Scheme Procedure} make-c64vector n [value]
|
|
@deffnx {C Function} scm_make_u8vector (n, value)
|
|
@deffnx {C Function} scm_make_s8vector (n, value)
|
|
@deffnx {C Function} scm_make_u16vector (n, value)
|
|
@deffnx {C Function} scm_make_s16vector (n, value)
|
|
@deffnx {C Function} scm_make_u32vector (n, value)
|
|
@deffnx {C Function} scm_make_s32vector (n, value)
|
|
@deffnx {C Function} scm_make_u64vector (n, value)
|
|
@deffnx {C Function} scm_make_s64vector (n, value)
|
|
@deffnx {C Function} scm_make_f32vector (n, value)
|
|
@deffnx {C Function} scm_make_f64vector (n, value)
|
|
@deffnx {C Function} scm_make_c32vector (n, value)
|
|
@deffnx {C Function} scm_make_c64vector (n, value)
|
|
Return a newly allocated homogeneous numeric vector holding @var{n}
|
|
elements of the indicated type. If @var{value} is given, the vector
|
|
is initialized with that value, otherwise the contents are
|
|
unspecified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} u8vector value @dots{}
|
|
@deffnx {Scheme Procedure} s8vector value @dots{}
|
|
@deffnx {Scheme Procedure} u16vector value @dots{}
|
|
@deffnx {Scheme Procedure} s16vector value @dots{}
|
|
@deffnx {Scheme Procedure} u32vector value @dots{}
|
|
@deffnx {Scheme Procedure} s32vector value @dots{}
|
|
@deffnx {Scheme Procedure} u64vector value @dots{}
|
|
@deffnx {Scheme Procedure} s64vector value @dots{}
|
|
@deffnx {Scheme Procedure} f32vector value @dots{}
|
|
@deffnx {Scheme Procedure} f64vector value @dots{}
|
|
@deffnx {Scheme Procedure} c32vector value @dots{}
|
|
@deffnx {Scheme Procedure} c64vector value @dots{}
|
|
@deffnx {C Function} scm_u8vector (values)
|
|
@deffnx {C Function} scm_s8vector (values)
|
|
@deffnx {C Function} scm_u16vector (values)
|
|
@deffnx {C Function} scm_s16vector (values)
|
|
@deffnx {C Function} scm_u32vector (values)
|
|
@deffnx {C Function} scm_s32vector (values)
|
|
@deffnx {C Function} scm_u64vector (values)
|
|
@deffnx {C Function} scm_s64vector (values)
|
|
@deffnx {C Function} scm_f32vector (values)
|
|
@deffnx {C Function} scm_f64vector (values)
|
|
@deffnx {C Function} scm_c32vector (values)
|
|
@deffnx {C Function} scm_c64vector (values)
|
|
Return a newly allocated homogeneous numeric vector of the indicated
|
|
type, holding the given parameter @var{value}s. The vector length is
|
|
the number of parameters given.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} u8vector-length vec
|
|
@deffnx {Scheme Procedure} s8vector-length vec
|
|
@deffnx {Scheme Procedure} u16vector-length vec
|
|
@deffnx {Scheme Procedure} s16vector-length vec
|
|
@deffnx {Scheme Procedure} u32vector-length vec
|
|
@deffnx {Scheme Procedure} s32vector-length vec
|
|
@deffnx {Scheme Procedure} u64vector-length vec
|
|
@deffnx {Scheme Procedure} s64vector-length vec
|
|
@deffnx {Scheme Procedure} f32vector-length vec
|
|
@deffnx {Scheme Procedure} f64vector-length vec
|
|
@deffnx {Scheme Procedure} c32vector-length vec
|
|
@deffnx {Scheme Procedure} c64vector-length vec
|
|
@deffnx {C Function} scm_u8vector_length (vec)
|
|
@deffnx {C Function} scm_s8vector_length (vec)
|
|
@deffnx {C Function} scm_u16vector_length (vec)
|
|
@deffnx {C Function} scm_s16vector_length (vec)
|
|
@deffnx {C Function} scm_u32vector_length (vec)
|
|
@deffnx {C Function} scm_s32vector_length (vec)
|
|
@deffnx {C Function} scm_u64vector_length (vec)
|
|
@deffnx {C Function} scm_s64vector_length (vec)
|
|
@deffnx {C Function} scm_f32vector_length (vec)
|
|
@deffnx {C Function} scm_f64vector_length (vec)
|
|
@deffnx {C Function} scm_c32vector_length (vec)
|
|
@deffnx {C Function} scm_c64vector_length (vec)
|
|
Return the number of elements in @var{vec}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} u8vector-ref vec i
|
|
@deffnx {Scheme Procedure} s8vector-ref vec i
|
|
@deffnx {Scheme Procedure} u16vector-ref vec i
|
|
@deffnx {Scheme Procedure} s16vector-ref vec i
|
|
@deffnx {Scheme Procedure} u32vector-ref vec i
|
|
@deffnx {Scheme Procedure} s32vector-ref vec i
|
|
@deffnx {Scheme Procedure} u64vector-ref vec i
|
|
@deffnx {Scheme Procedure} s64vector-ref vec i
|
|
@deffnx {Scheme Procedure} f32vector-ref vec i
|
|
@deffnx {Scheme Procedure} f64vector-ref vec i
|
|
@deffnx {Scheme Procedure} c32vector-ref vec i
|
|
@deffnx {Scheme Procedure} c64vector-ref vec i
|
|
@deffnx {C Function} scm_u8vector_ref (vec, i)
|
|
@deffnx {C Function} scm_s8vector_ref (vec, i)
|
|
@deffnx {C Function} scm_u16vector_ref (vec, i)
|
|
@deffnx {C Function} scm_s16vector_ref (vec, i)
|
|
@deffnx {C Function} scm_u32vector_ref (vec, i)
|
|
@deffnx {C Function} scm_s32vector_ref (vec, i)
|
|
@deffnx {C Function} scm_u64vector_ref (vec, i)
|
|
@deffnx {C Function} scm_s64vector_ref (vec, i)
|
|
@deffnx {C Function} scm_f32vector_ref (vec, i)
|
|
@deffnx {C Function} scm_f64vector_ref (vec, i)
|
|
@deffnx {C Function} scm_c32vector_ref (vec, i)
|
|
@deffnx {C Function} scm_c64vector_ref (vec, i)
|
|
Return the element at index @var{i} in @var{vec}. The first element
|
|
in @var{vec} is index 0.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} u8vector-set! vec i value
|
|
@deffnx {Scheme Procedure} s8vector-set! vec i value
|
|
@deffnx {Scheme Procedure} u16vector-set! vec i value
|
|
@deffnx {Scheme Procedure} s16vector-set! vec i value
|
|
@deffnx {Scheme Procedure} u32vector-set! vec i value
|
|
@deffnx {Scheme Procedure} s32vector-set! vec i value
|
|
@deffnx {Scheme Procedure} u64vector-set! vec i value
|
|
@deffnx {Scheme Procedure} s64vector-set! vec i value
|
|
@deffnx {Scheme Procedure} f32vector-set! vec i value
|
|
@deffnx {Scheme Procedure} f64vector-set! vec i value
|
|
@deffnx {Scheme Procedure} c32vector-set! vec i value
|
|
@deffnx {Scheme Procedure} c64vector-set! vec i value
|
|
@deffnx {C Function} scm_u8vector_set_x (vec, i, value)
|
|
@deffnx {C Function} scm_s8vector_set_x (vec, i, value)
|
|
@deffnx {C Function} scm_u16vector_set_x (vec, i, value)
|
|
@deffnx {C Function} scm_s16vector_set_x (vec, i, value)
|
|
@deffnx {C Function} scm_u32vector_set_x (vec, i, value)
|
|
@deffnx {C Function} scm_s32vector_set_x (vec, i, value)
|
|
@deffnx {C Function} scm_u64vector_set_x (vec, i, value)
|
|
@deffnx {C Function} scm_s64vector_set_x (vec, i, value)
|
|
@deffnx {C Function} scm_f32vector_set_x (vec, i, value)
|
|
@deffnx {C Function} scm_f64vector_set_x (vec, i, value)
|
|
@deffnx {C Function} scm_c32vector_set_x (vec, i, value)
|
|
@deffnx {C Function} scm_c64vector_set_x (vec, i, value)
|
|
Set the element at index @var{i} in @var{vec} to @var{value}. The
|
|
first element in @var{vec} is index 0. The return value is
|
|
unspecified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} u8vector->list vec
|
|
@deffnx {Scheme Procedure} s8vector->list vec
|
|
@deffnx {Scheme Procedure} u16vector->list vec
|
|
@deffnx {Scheme Procedure} s16vector->list vec
|
|
@deffnx {Scheme Procedure} u32vector->list vec
|
|
@deffnx {Scheme Procedure} s32vector->list vec
|
|
@deffnx {Scheme Procedure} u64vector->list vec
|
|
@deffnx {Scheme Procedure} s64vector->list vec
|
|
@deffnx {Scheme Procedure} f32vector->list vec
|
|
@deffnx {Scheme Procedure} f64vector->list vec
|
|
@deffnx {Scheme Procedure} c32vector->list vec
|
|
@deffnx {Scheme Procedure} c64vector->list vec
|
|
@deffnx {C Function} scm_u8vector_to_list (vec)
|
|
@deffnx {C Function} scm_s8vector_to_list (vec)
|
|
@deffnx {C Function} scm_u16vector_to_list (vec)
|
|
@deffnx {C Function} scm_s16vector_to_list (vec)
|
|
@deffnx {C Function} scm_u32vector_to_list (vec)
|
|
@deffnx {C Function} scm_s32vector_to_list (vec)
|
|
@deffnx {C Function} scm_u64vector_to_list (vec)
|
|
@deffnx {C Function} scm_s64vector_to_list (vec)
|
|
@deffnx {C Function} scm_f32vector_to_list (vec)
|
|
@deffnx {C Function} scm_f64vector_to_list (vec)
|
|
@deffnx {C Function} scm_c32vector_to_list (vec)
|
|
@deffnx {C Function} scm_c64vector_to_list (vec)
|
|
Return a newly allocated list holding all elements of @var{vec}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list->u8vector lst
|
|
@deffnx {Scheme Procedure} list->s8vector lst
|
|
@deffnx {Scheme Procedure} list->u16vector lst
|
|
@deffnx {Scheme Procedure} list->s16vector lst
|
|
@deffnx {Scheme Procedure} list->u32vector lst
|
|
@deffnx {Scheme Procedure} list->s32vector lst
|
|
@deffnx {Scheme Procedure} list->u64vector lst
|
|
@deffnx {Scheme Procedure} list->s64vector lst
|
|
@deffnx {Scheme Procedure} list->f32vector lst
|
|
@deffnx {Scheme Procedure} list->f64vector lst
|
|
@deffnx {Scheme Procedure} list->c32vector lst
|
|
@deffnx {Scheme Procedure} list->c64vector lst
|
|
@deffnx {C Function} scm_list_to_u8vector (lst)
|
|
@deffnx {C Function} scm_list_to_s8vector (lst)
|
|
@deffnx {C Function} scm_list_to_u16vector (lst)
|
|
@deffnx {C Function} scm_list_to_s16vector (lst)
|
|
@deffnx {C Function} scm_list_to_u32vector (lst)
|
|
@deffnx {C Function} scm_list_to_s32vector (lst)
|
|
@deffnx {C Function} scm_list_to_u64vector (lst)
|
|
@deffnx {C Function} scm_list_to_s64vector (lst)
|
|
@deffnx {C Function} scm_list_to_f32vector (lst)
|
|
@deffnx {C Function} scm_list_to_f64vector (lst)
|
|
@deffnx {C Function} scm_list_to_c32vector (lst)
|
|
@deffnx {C Function} scm_list_to_c64vector (lst)
|
|
Return a newly allocated homogeneous numeric vector of the indicated type,
|
|
initialized with the elements of the list @var{lst}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} SCM scm_take_u8vector (const scm_t_uint8 *data, size_t len)
|
|
@deftypefnx {C Function} SCM scm_take_s8vector (const scm_t_int8 *data, size_t len)
|
|
@deftypefnx {C Function} SCM scm_take_u16vector (const scm_t_uint16 *data, size_t len)
|
|
@deftypefnx {C Function} SCM scm_take_s16vector (const scm_t_int16 *data, size_t len)
|
|
@deftypefnx {C Function} SCM scm_take_u32vector (const scm_t_uint32 *data, size_t len)
|
|
@deftypefnx {C Function} SCM scm_take_s32vector (const scm_t_int32 *data, size_t len)
|
|
@deftypefnx {C Function} SCM scm_take_u64vector (const scm_t_uint64 *data, size_t len)
|
|
@deftypefnx {C Function} SCM scm_take_s64vector (const scm_t_int64 *data, size_t len)
|
|
@deftypefnx {C Function} SCM scm_take_f32vector (const float *data, size_t len)
|
|
@deftypefnx {C Function} SCM scm_take_f64vector (const double *data, size_t len)
|
|
@deftypefnx {C Function} SCM scm_take_c32vector (const float *data, size_t len)
|
|
@deftypefnx {C Function} SCM scm_take_c64vector (const double *data, size_t len)
|
|
Return a new uniform numeric vector of the indicated type and length
|
|
that uses the memory pointed to by @var{data} to store its elements.
|
|
This memory will eventually be freed with @code{free}. The argument
|
|
@var{len} specifies the number of elements in @var{data}, not its size
|
|
in bytes.
|
|
|
|
The @code{c32} and @code{c64} variants take a pointer to a C array of
|
|
@code{float}s or @code{double}s. The real parts of the complex numbers
|
|
are at even indices in that array, the corresponding imaginary parts are
|
|
at the following odd index.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {const scm_t_uint8 *} scm_u8vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
|
|
@deftypefnx {C Function} {const scm_t_int8 *} scm_s8vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
|
|
@deftypefnx {C Function} {const scm_t_uint16 *} scm_u16vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
|
|
@deftypefnx {C Function} {const scm_t_int16 *} scm_s16vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
|
|
@deftypefnx {C Function} {const scm_t_uint32 *} scm_u32vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
|
|
@deftypefnx {C Function} {const scm_t_int32 *} scm_s32vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
|
|
@deftypefnx {C Function} {const scm_t_uint64 *} scm_u64vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
|
|
@deftypefnx {C Function} {const scm_t_int64 *} scm_s64vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
|
|
@deftypefnx {C Function} {const float *} scm_f32vector_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_f32vector_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 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} srfi-4-vector-type-size obj
|
|
Return the size, in bytes, of each element of SRFI-4 vector
|
|
@var{obj}. For example, @code{(srfi-4-vector-type-size #u32())} returns
|
|
@code{4}.
|
|
@end deffn
|
|
|
|
@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
|
|
|
|
@deffn {Scheme Procedure} u8vector-copy! dst at src [start [end]]
|
|
@deffnx {Scheme Procedure} s8vector-copy! dst at src [start [end]]
|
|
@deffnx {Scheme Procedure} u16vector-copy! dst at src [start [end]]
|
|
@deffnx {Scheme Procedure} s16vector-copy! dst at src [start [end]]
|
|
@deffnx {Scheme Procedure} u32vector-copy! dst at src [start [end]]
|
|
@deffnx {Scheme Procedure} s32vector-copy! dst at src [start [end]]
|
|
@deffnx {Scheme Procedure} u64vector-copy! dst at src [start [end]]
|
|
@deffnx {Scheme Procedure} s64vector-copy! dst at src [start [end]]
|
|
@deffnx {Scheme Procedure} f32vector-copy! dst at src [start [end]]
|
|
@deffnx {Scheme Procedure} f64vector-copy! dst at src [start [end]]
|
|
@deffnx {Scheme Procedure} c32vector-copy! dst at src [start [end]]
|
|
@deffnx {Scheme Procedure} c64vector-copy! dst at src [start [end]]
|
|
Copy a block of elements from @var{src} to @var{dst}, both of which must
|
|
be vectors of the indicated type, starting in @var{dst} at @var{at} and
|
|
starting in @var{src} at @var{start} and ending at @var{end}. It is an
|
|
error for @var{dst} to have a length less than @var{at} + (@var{end} -
|
|
@var{start}). @var{at} and @var{start} default to 0 and @var{end}
|
|
defaults to the length of @var{src}.
|
|
|
|
If source and destination overlap, copying takes place as if the
|
|
source is first copied into a temporary vector and then into the
|
|
destination.
|
|
|
|
See also @ref{x-vector-copy!,@code{vector-copy!}}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} u8vector-copy src [start [end]]
|
|
@deffnx {Scheme Procedure} s8vector-copy src [start [end]]
|
|
@deffnx {Scheme Procedure} u16vector-copy src [start [end]]
|
|
@deffnx {Scheme Procedure} s16vector-copy src [start [end]]
|
|
@deffnx {Scheme Procedure} u32vector-copy src [start [end]]
|
|
@deffnx {Scheme Procedure} s32vector-copy src [start [end]]
|
|
@deffnx {Scheme Procedure} u64vector-copy src [start [end]]
|
|
@deffnx {Scheme Procedure} s64vector-copy src [start [end]]
|
|
@deffnx {Scheme Procedure} f32vector-copy src [start [end]]
|
|
@deffnx {Scheme Procedure} f64vector-copy src [start [end]]
|
|
@deffnx {Scheme Procedure} c32vector-copy src [start [end]]
|
|
@deffnx {Scheme Procedure} c64vector-copy src [start [end]]
|
|
Returns a freshly allocated vector of the indicated type, which must be
|
|
the same as that of @var{src}, containing the elements of @var{src}
|
|
between @var{start} and @var{end}. @var{start} defaults to 0 and
|
|
@var{end} defaults to the length of @var{src}.
|
|
|
|
See also @ref{x-vector-copy,@code{vector-copy}}.
|
|
@end deffn
|
|
|
|
|
|
@node SRFI-6
|
|
@subsection SRFI-6 - Basic String Ports
|
|
@cindex SRFI-6
|
|
|
|
SRFI-6 defines the procedures @code{open-input-string},
|
|
@code{open-output-string} and @code{get-output-string}. These
|
|
procedures are included in the Guile core, so using this module does not
|
|
make any difference at the moment. But it is possible that support for
|
|
SRFI-6 will be factored out of the core library in the future, so using
|
|
this module does not hurt, after all.
|
|
|
|
@node SRFI-8
|
|
@subsection SRFI-8 - receive
|
|
@cindex SRFI-8
|
|
|
|
@code{receive} is a syntax for making the handling of multiple-value
|
|
procedures easier. It is documented in @xref{Multiple Values}.
|
|
|
|
|
|
@node SRFI-9
|
|
@subsection SRFI-9 - define-record-type
|
|
|
|
This SRFI is a syntax for defining new record types and creating
|
|
predicate, constructor, and field getter and setter functions. It is
|
|
documented in the ``Data Types'' section of the manual (@pxref{SRFI-9
|
|
Records}).
|
|
|
|
|
|
@node SRFI-10
|
|
@subsection SRFI-10 - Hash-Comma Reader Extension
|
|
@cindex SRFI-10
|
|
|
|
@cindex hash-comma
|
|
@cindex #,()
|
|
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
|
|
|
|
@noindent
|
|
The new read syntax is of the form
|
|
|
|
@example
|
|
#,(@var{tag} @var{arg}@dots{})
|
|
@end example
|
|
|
|
@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}, i.e.@: @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
|
|
|
|
@noindent
|
|
For example, a syntax giving a list of @var{N} copies of an object.
|
|
|
|
@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{}
|
|
(display '(99 99 99))
|
|
@end example
|
|
|
|
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,
|
|
|
|
@example
|
|
(define-reader-ctor 'sum
|
|
(lambda (x y)
|
|
(+ x y)))
|
|
(display #,(sum 123 456)) @print{} 579
|
|
@end example
|
|
|
|
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.
|
|
|
|
We do not recommend @nicode{#,()} reader extensions, however, and for
|
|
three reasons.
|
|
|
|
First of all, this SRFI is not modular: the tag is matched by name, not
|
|
as an identifier within a scope. Defining a reader extension in one
|
|
part of a program can thus affect unrelated parts of a program because
|
|
the tag is not scoped.
|
|
|
|
Secondly, reader extensions can be hard to manage from a time
|
|
perspective: when does the reader extension take effect? @xref{Eval
|
|
When}, for more discussion.
|
|
|
|
Finally, reader extensions can easily produce objects that can't be
|
|
reified to an object file by the compiler. For example if you define a
|
|
reader extension that makes a hash table (@pxref{Hash Tables}), then it
|
|
will work fine when run with the interpreter, and you think you have a
|
|
neat hack. But then if you try to compile your program, after wrangling
|
|
with the @code{eval-when} concerns mentioned above, the compiler will
|
|
carp that it doesn't know how to serialize a hash table to disk.
|
|
|
|
In the specific case of hash tables, it would be possible for Guile to
|
|
know how to pack hash tables into compiled files, but this doesn't work
|
|
in general. What if the object you produce is an instance of a record
|
|
type? Guile would then have to serialize the record type to disk too,
|
|
and then what happens if the program independently loads the code that
|
|
defines the record type? Does it define the same type or a different
|
|
type? Guile's record types are nominal, not structural, so the answer
|
|
is not clear at all.
|
|
|
|
For all of these reasons we recommend macros over reader extensions.
|
|
Macros fulfill many of the same needs while preserving modular
|
|
composition, and their interaction with @code{eval-when} is well-known.
|
|
If you need brevity, instead use @code{read-hash-extend} and make your
|
|
reader extension expand to a macro invocation. In that way we preserve
|
|
scoping as much as possible. @xref{Reader Extensions}.
|
|
|
|
|
|
@node SRFI-11
|
|
@subsection SRFI-11 - let-values
|
|
@cindex SRFI-11
|
|
|
|
@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} and @code{let*} (@pxref{Local Bindings}), but they support
|
|
binding of the values returned by multiple-valued expressions.
|
|
|
|
Write @code{(use-modules (srfi srfi-11))} to make the bindings
|
|
available.
|
|
|
|
@lisp
|
|
(let-values (((x y) (values 1 2))
|
|
((z f) (values 3 4)))
|
|
(+ x y z f))
|
|
@result{}
|
|
10
|
|
@end lisp
|
|
|
|
@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
|
|
bindings sequentially, just like @code{let*} does for single-valued
|
|
expressions.
|
|
|
|
|
|
@node SRFI-13
|
|
@subsection SRFI-13 - String Library
|
|
@cindex SRFI-13
|
|
|
|
The SRFI-13 procedures are always available, @xref{Strings}.
|
|
|
|
@node SRFI-14
|
|
@subsection SRFI-14 - Character-set Library
|
|
@cindex SRFI-14
|
|
|
|
The SRFI-14 data type and procedures are always available,
|
|
@xref{Character Sets}.
|
|
|
|
@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 SRFI-17
|
|
@subsection SRFI-17 - Generalized set!
|
|
@cindex SRFI-17
|
|
|
|
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
|
|
|
|
@noindent
|
|
is equivalent to
|
|
|
|
@example
|
|
(vector-set! vec idx new-value)
|
|
@end example
|
|
|
|
The idea is that a @code{vector-ref} expression identifies a location,
|
|
which may be either fetched or stored. The same form is used for the
|
|
location in both cases, encouraging visual clarity. This is similar
|
|
to the idea of an ``lvalue'' in C.
|
|
|
|
The mechanism for this kind of @code{set!} is in the Guile core
|
|
(@pxref{Procedures with Setters}). This module adds definitions of
|
|
the following functions as procedures with setters, allowing them to
|
|
be targets of a @code{set!},
|
|
|
|
@quotation
|
|
@nicode{car}, @nicode{cdr}, @nicode{caar}, @nicode{cadr},
|
|
@nicode{cdar}, @nicode{cddr}, @nicode{caaar}, @nicode{caadr},
|
|
@nicode{cadar}, @nicode{caddr}, @nicode{cdaar}, @nicode{cdadr},
|
|
@nicode{cddar}, @nicode{cdddr}, @nicode{caaaar}, @nicode{caaadr},
|
|
@nicode{caadar}, @nicode{caaddr}, @nicode{cadaar}, @nicode{cadadr},
|
|
@nicode{caddar}, @nicode{cadddr}, @nicode{cdaaar}, @nicode{cdaadr},
|
|
@nicode{cdadar}, @nicode{cdaddr}, @nicode{cddaar}, @nicode{cddadr},
|
|
@nicode{cdddar}, @nicode{cddddr}
|
|
|
|
@nicode{string-ref}, @nicode{vector-ref}
|
|
@end quotation
|
|
|
|
The SRFI specifies @code{setter} (@pxref{Procedures with Setters}) as
|
|
a procedure with setter, allowing the setter for a procedure to be
|
|
changed, eg.@: @code{(set! (setter foo) my-new-setter-handler)}.
|
|
Currently Guile does not implement this, a setter can only be
|
|
specified on creation (@code{getter-with-setter} below).
|
|
|
|
@defun getter-with-setter
|
|
The same as the Guile core @code{make-procedure-with-setter}
|
|
(@pxref{Procedures with Setters}).
|
|
@end defun
|
|
|
|
|
|
@node SRFI-18
|
|
@subsection SRFI-18 - Multithreading support
|
|
@cindex SRFI-18
|
|
|
|
This is an implementation of the SRFI-18 threading and synchronization
|
|
library. The functions and variables described here are provided by
|
|
|
|
@example
|
|
(use-modules (srfi srfi-18))
|
|
@end example
|
|
|
|
SRFI-18 defines facilities for threads, mutexes, condition variables,
|
|
time, and exception handling. Because these facilities are at a higher
|
|
level than Guile's primitives, they are implemented as a layer on top of
|
|
what Guile provides. In particular this means that a Guile mutex is not
|
|
a SRFI-18 mutex, and a Guile thread is not a SRFI-18 thread, and so on.
|
|
Guile provides a set of primitives and SRFI-18 is one of the systems built in terms of those primitives.
|
|
|
|
@menu
|
|
* SRFI-18 Threads:: Executing code
|
|
* SRFI-18 Mutexes:: Mutual exclusion devices
|
|
* SRFI-18 Condition variables:: Synchronizing of groups of threads
|
|
* SRFI-18 Time:: Representation of times and durations
|
|
* SRFI-18 Exceptions:: Signalling and handling errors
|
|
@end menu
|
|
|
|
@node SRFI-18 Threads
|
|
@subsubsection SRFI-18 Threads
|
|
|
|
Threads created by SRFI-18 differ in two ways from threads created by
|
|
Guile's built-in thread functions. First, a thread created by SRFI-18
|
|
@code{make-thread} begins in a blocked state and will not start
|
|
execution until @code{thread-start!} is called on it. Second, SRFI-18
|
|
threads are constructed with a top-level exception handler that
|
|
captures any exceptions that are thrown on thread exit.
|
|
|
|
SRFI-18 threads are disjoint from Guile's primitive threads.
|
|
@xref{Threads}, for more on Guile's primitive facility.
|
|
|
|
@defun current-thread
|
|
Returns the thread that called this function. This is the same
|
|
procedure as the same-named built-in procedure @code{current-thread}
|
|
(@pxref{Threads}).
|
|
@end defun
|
|
|
|
@defun thread? obj
|
|
Returns @code{#t} if @var{obj} is a thread, @code{#f} otherwise. This
|
|
is the same procedure as the same-named built-in procedure
|
|
@code{thread?} (@pxref{Threads}).
|
|
@end defun
|
|
|
|
@defun make-thread thunk [name]
|
|
Call @code{thunk} in a new thread and with a new dynamic state,
|
|
returning the new thread and optionally assigning it the object name
|
|
@var{name}, which may be any Scheme object.
|
|
|
|
Note that the name @code{make-thread} conflicts with the
|
|
@code{(ice-9 threads)} function @code{make-thread}. Applications
|
|
wanting to use both of these functions will need to refer to them by
|
|
different names.
|
|
@end defun
|
|
|
|
@defun thread-name thread
|
|
Returns the name assigned to @var{thread} at the time of its creation,
|
|
or @code{#f} if it was not given a name.
|
|
@end defun
|
|
|
|
@defun thread-specific thread
|
|
@defunx thread-specific-set! thread obj
|
|
Get or set the ``object-specific'' property of @var{thread}. In
|
|
Guile's implementation of SRFI-18, this value is stored as an object
|
|
property, and will be @code{#f} if not set.
|
|
@end defun
|
|
|
|
@defun thread-start! thread
|
|
Unblocks @var{thread} and allows it to begin execution if it has not
|
|
done so already.
|
|
@end defun
|
|
|
|
@defun thread-yield!
|
|
If one or more threads are waiting to execute, calling
|
|
@code{thread-yield!} forces an immediate context switch to one of them.
|
|
Otherwise, @code{thread-yield!} has no effect. @code{thread-yield!}
|
|
behaves identically to the Guile built-in function @code{yield}.
|
|
@end defun
|
|
|
|
@defun thread-sleep! timeout
|
|
The current thread waits until the point specified by the time object
|
|
@var{timeout} is reached (@pxref{SRFI-18 Time}). This blocks the
|
|
thread only if @var{timeout} represents a point in the future. it is
|
|
an error for @var{timeout} to be @code{#f}.
|
|
@end defun
|
|
|
|
@defun thread-terminate! thread
|
|
Causes an abnormal termination of @var{thread}. If @var{thread} is
|
|
not already terminated, all mutexes owned by @var{thread} become
|
|
unlocked/abandoned. If @var{thread} is the current thread,
|
|
@code{thread-terminate!} does not return. Otherwise
|
|
@code{thread-terminate!} returns an unspecified value; the termination
|
|
of @var{thread} will occur before @code{thread-terminate!} returns.
|
|
Subsequent attempts to join on @var{thread} will cause a ``terminated
|
|
thread exception'' to be raised.
|
|
|
|
@code{thread-terminate!} is compatible with the thread cancellation
|
|
procedures in the core threads API (@pxref{Threads}) in that if a
|
|
cleanup handler has been installed for the target thread, it will be
|
|
called before the thread exits and its return value (or exception, if
|
|
any) will be stored for later retrieval via a call to
|
|
@code{thread-join!}.
|
|
@end defun
|
|
|
|
@defun thread-join! thread [timeout [timeout-val]]
|
|
Wait for @var{thread} to terminate and return its exit value. When a
|
|
time value @var{timeout} is given, it specifies a point in time where
|
|
the waiting should be aborted. When the waiting is aborted,
|
|
@var{timeout-val} is returned if it is specified; otherwise, a
|
|
@code{join-timeout-exception} exception is raised
|
|
(@pxref{SRFI-18 Exceptions}). Exceptions may also be raised if the
|
|
thread was terminated by a call to @code{thread-terminate!}
|
|
(@code{terminated-thread-exception} will be raised) or if the thread
|
|
exited by raising an exception that was handled by the top-level
|
|
exception handler (@code{uncaught-exception} will be raised; the
|
|
original exception can be retrieved using
|
|
@code{uncaught-exception-reason}).
|
|
@end defun
|
|
|
|
|
|
@node SRFI-18 Mutexes
|
|
@subsubsection SRFI-18 Mutexes
|
|
|
|
SRFI-18 mutexes are disjoint from Guile's primitive mutexes.
|
|
@xref{Mutexes and Condition Variables}, for more on Guile's primitive
|
|
facility.
|
|
|
|
@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.
|
|
@end defun
|
|
|
|
@defun mutex-name mutex
|
|
Returns the name assigned to @var{mutex} at the time of its creation, or
|
|
@code{#f} if it was not given a name.
|
|
@end defun
|
|
|
|
@defun mutex-specific mutex
|
|
Return the ``object-specific'' property of @var{mutex}, or @code{#f} if
|
|
none is set.
|
|
@end defun
|
|
|
|
@defun mutex-specific-set! mutex obj
|
|
Set the ``object-specific'' property of @var{mutex}.
|
|
@end defun
|
|
|
|
@defun mutex-state mutex
|
|
Returns information about the state of @var{mutex}. Possible values
|
|
are:
|
|
@itemize @bullet
|
|
@item
|
|
thread @var{t}: the mutex is in the locked/owned state and thread
|
|
@var{t} is the owner of the mutex
|
|
@item
|
|
symbol @code{not-owned}: the mutex is in the locked/not-owned state
|
|
@item
|
|
symbol @code{abandoned}: the mutex is in the unlocked/abandoned state
|
|
@item
|
|
symbol @code{not-abandoned}: the mutex is in the
|
|
unlocked/not-abandoned state
|
|
@end itemize
|
|
@end defun
|
|
|
|
@defun mutex-lock! mutex [timeout [thread]]
|
|
Lock @var{mutex}, optionally specifying a time object @var{timeout}
|
|
after which to abort the lock attempt and a thread @var{thread} giving
|
|
a new owner for @var{mutex} different than the current thread.
|
|
@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
|
|
signaled.
|
|
@end defun
|
|
|
|
|
|
@node SRFI-18 Condition variables
|
|
@subsubsection SRFI-18 Condition variables
|
|
|
|
SRFI-18 does not specify a ``wait'' function for condition variables.
|
|
Waiting on a condition variable can be simulated using the SRFI-18
|
|
@code{mutex-unlock!} function described in the previous section.
|
|
|
|
SRFI-18 condition variables are disjoint from Guile's primitive
|
|
condition variables. @xref{Mutexes and Condition Variables}, for more
|
|
on Guile's primitive facility.
|
|
|
|
@defun condition-variable? obj
|
|
Returns @code{#t} if @var{obj} is a condition variable, @code{#f}
|
|
otherwise.
|
|
@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.
|
|
@end defun
|
|
|
|
@defun condition-variable-name condition-variable
|
|
Returns the name assigned to @var{condition-variable} at the time of its
|
|
creation, or @code{#f} if it was not given a name.
|
|
@end defun
|
|
|
|
@defun condition-variable-specific condition-variable
|
|
Return the ``object-specific'' property of @var{condition-variable}, or
|
|
@code{#f} if none is set.
|
|
@end defun
|
|
|
|
@defun condition-variable-specific-set! condition-variable obj
|
|
Set the ``object-specific'' property of @var{condition-variable}.
|
|
@end defun
|
|
|
|
@defun condition-variable-signal! condition-variable
|
|
@defunx condition-variable-broadcast! condition-variable
|
|
Wake up one thread that is waiting for @var{condition-variable}, in
|
|
the case of @code{condition-variable-signal!}, or all threads waiting
|
|
for it, in the case of @code{condition-variable-broadcast!}.
|
|
@end defun
|
|
|
|
|
|
@node SRFI-18 Time
|
|
@subsubsection SRFI-18 Time
|
|
|
|
The SRFI-18 time functions manipulate time in two formats: a
|
|
``time object'' type that represents an absolute point in time in some
|
|
implementation-specific way; and the number of seconds since some
|
|
unspecified ``epoch''. In Guile's implementation, the epoch is the
|
|
Unix epoch, 00:00:00 UTC, January 1, 1970.
|
|
|
|
@defun current-time
|
|
Return the current time as a time object. This procedure replaces
|
|
the procedure of the same name in the core library, which returns the
|
|
current time in seconds since the epoch.
|
|
@end defun
|
|
|
|
@defun time? obj
|
|
Returns @code{#t} if @var{obj} is a time object, @code{#f} otherwise.
|
|
@end defun
|
|
|
|
@defun time->seconds time
|
|
@defunx seconds->time seconds
|
|
Convert between time objects and numerical values representing the
|
|
number of seconds since the epoch. When converting from a time object
|
|
to seconds, the return value is the number of seconds between
|
|
@var{time} and the epoch. When converting from seconds to a time
|
|
object, the return value is a time object that represents a time
|
|
@var{seconds} seconds after the epoch.
|
|
@end defun
|
|
|
|
|
|
@node SRFI-18 Exceptions
|
|
@subsubsection SRFI-18 Exceptions
|
|
|
|
SRFI-18 exceptions are identical to the exceptions provided by
|
|
Guile's implementation of SRFI-34. The behavior of exception
|
|
handlers invoked to handle exceptions thrown from SRFI-18 functions,
|
|
however, differs from the conventional behavior of SRFI-34 in that
|
|
the continuation of the handler is the same as that of the call to
|
|
the function. Handlers are called in a tail-recursive manner; the
|
|
exceptions do not ``bubble up''.
|
|
|
|
@defun current-exception-handler
|
|
Returns the current exception handler.
|
|
@end defun
|
|
|
|
@defun with-exception-handler handler thunk
|
|
Installs @var{handler} as the current exception handler and calls the
|
|
procedure @var{thunk} with no arguments, returning its value as the
|
|
value of the exception. @var{handler} must be a procedure that accepts
|
|
a single argument. The current exception handler at the time this
|
|
procedure is called will be restored after the call returns.
|
|
@end defun
|
|
|
|
@defun raise obj
|
|
Raise @var{obj} as an exception. This is the same procedure as the
|
|
same-named procedure defined in SRFI 34.
|
|
@end defun
|
|
|
|
@defun join-timeout-exception? obj
|
|
Returns @code{#t} if @var{obj} is an exception raised as the result of
|
|
performing a timed join on a thread that does not exit within the
|
|
specified timeout, @code{#f} otherwise.
|
|
@end defun
|
|
|
|
@defun abandoned-mutex-exception? obj
|
|
Returns @code{#t} if @var{obj} is an exception raised as the result of
|
|
attempting to lock a mutex that has been abandoned by its owner thread,
|
|
@code{#f} otherwise.
|
|
@end defun
|
|
|
|
@defun terminated-thread-exception? obj
|
|
Returns @code{#t} if @var{obj} is an exception raised as the result of
|
|
joining on a thread that exited as the result of a call to
|
|
@code{thread-terminate!}.
|
|
@end defun
|
|
|
|
@defun uncaught-exception? obj
|
|
@defunx uncaught-exception-reason exc
|
|
@code{uncaught-exception?} returns @code{#t} if @var{obj} is an
|
|
exception thrown as the result of joining a thread that exited by
|
|
raising an exception that was handled by the top-level exception
|
|
handler installed by @code{make-thread}. When this occurs, the
|
|
original exception is preserved as part of the exception thrown by
|
|
@code{thread-join!} and can be accessed by calling
|
|
@code{uncaught-exception-reason} on that exception. Note that
|
|
because this exception-preservation mechanism is a side-effect of
|
|
@code{make-thread}, joining on threads that exited as described above
|
|
but were created by other means will not raise this
|
|
@code{uncaught-exception} error.
|
|
@end defun
|
|
|
|
|
|
@node SRFI-19
|
|
@subsection SRFI-19 - Time/Date Library
|
|
@cindex SRFI-19
|
|
@cindex time
|
|
@cindex date
|
|
|
|
This is an implementation of the SRFI-19 time/date library. The
|
|
functions and variables described here are provided by
|
|
|
|
@example
|
|
(use-modules (srfi srfi-19))
|
|
@end example
|
|
|
|
@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
|
|
|
|
@node SRFI-19 Introduction
|
|
@subsubsection SRFI-19 Introduction
|
|
|
|
@cindex universal time
|
|
@cindex atomic time
|
|
@cindex UTC
|
|
@cindex TAI
|
|
This module implements time and date representations and calculations,
|
|
in various time systems, including Coordinated Universal Time (UTC)
|
|
and International Atomic Time (TAI).
|
|
|
|
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).
|
|
|
|
@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.
|
|
|
|
@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}
|
|
represents a point in time as a real number of days since
|
|
-4713-11-24T12:00:00Z, i.e.@: midday UT on 24 November 4714 BC in the
|
|
proleptic Gregorian calendar (1 January 4713 BC in the proleptic Julian
|
|
calendar).
|
|
|
|
A @dfn{Modified Julian Day} represents a point in time as a real number
|
|
of days since 1858-11-17T00:00:00Z, i.e.@: midnight UT on Wednesday 17
|
|
November AD 1858. That time is julian day 2400000.5.
|
|
|
|
|
|
@node SRFI-19 Time
|
|
@subsubsection SRFI-19 Time
|
|
@cindex time
|
|
|
|
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.
|
|
|
|
The following variables hold the possible time types. For instance
|
|
@code{(current-time time-process)} would give the current CPU process
|
|
time.
|
|
|
|
@defvar time-utc
|
|
Universal Coordinated Time (UTC).
|
|
@cindex UTC
|
|
@end defvar
|
|
|
|
@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.
|
|
|
|
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
|
|
|
|
@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
|
|
|
|
@defvar time-thread
|
|
CPU time spent in the current thread. Not currently implemented.
|
|
@cindex thread time
|
|
@end defvar
|
|
|
|
@sp 1
|
|
@defun time? obj
|
|
Return @code{#t} if @var{obj} is a time object, or @code{#f} if not.
|
|
@end defun
|
|
|
|
@defun make-time type nanoseconds seconds
|
|
Create a time object with the given @var{type}, @var{seconds} and
|
|
@var{nanoseconds}.
|
|
@end defun
|
|
|
|
@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.
|
|
|
|
@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
|
|
|
|
@defun copy-time time
|
|
Return a new time object, which is a copy of the given @var{time}.
|
|
@end defun
|
|
|
|
@defun current-time [type]
|
|
Return the current time of the given @var{type}. The default
|
|
@var{type} is @code{time-utc}.
|
|
|
|
Note that the name @code{current-time} conflicts with the Guile core
|
|
@code{current-time} function (@pxref{Time}) as well as the SRFI-18
|
|
@code{current-time} function (@pxref{SRFI-18 Time}). Applications
|
|
wanting to use more than one of these functions will need to refer to
|
|
them by different names.
|
|
@end defun
|
|
|
|
@defun time-resolution [type]
|
|
Return the resolution, in nanoseconds, of the given time @var{type}.
|
|
The default @var{type} is @code{time-utc}.
|
|
@end defun
|
|
|
|
@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.
|
|
|
|
@code{time-difference} returns a new time object,
|
|
@code{time-difference!} may modify @var{t1} to form its return.
|
|
@end defun
|
|
|
|
@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{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
|
|
|
|
|
|
@node SRFI-19 Date
|
|
@subsubsection SRFI-19 Date
|
|
@cindex date
|
|
|
|
A @dfn{date} object represents a date in the Gregorian calendar and a
|
|
time of day on that date in some timezone.
|
|
|
|
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.
|
|
|
|
Historically, the Gregorian calendar was only used from the latter part
|
|
of the year 1582 onwards, and not until even later in many countries.
|
|
Prior to that most countries used the Julian calendar. SRFI-19 does
|
|
not deal with the Julian calendar at all, and so does not reflect this
|
|
historical calendar reform. Instead it projects the Gregorian calendar
|
|
back proleptically as far as necessary. When dealing with historical
|
|
data, especially prior to the British Empire's adoption of the Gregorian
|
|
calendar in 1752, one should be mindful of which calendar is used in
|
|
each context, and apply non-SRFI-19 facilities to convert where necessary.
|
|
|
|
@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
|
|
|
|
@defun date-nanosecond date
|
|
Nanoseconds, 0 to 999999999.
|
|
@end defun
|
|
|
|
@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
|
|
|
|
@defun date-minute date
|
|
Minutes, 0 to 59.
|
|
@end defun
|
|
|
|
@defun date-hour date
|
|
Hour, 0 to 23.
|
|
@end defun
|
|
|
|
@defun date-day date
|
|
Day of the month, 1 to 31 (or less, according to the month).
|
|
@end defun
|
|
|
|
@defun date-month date
|
|
Month, 1 to 12.
|
|
@end defun
|
|
|
|
@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
|
|
|
|
@defun date-year-day date
|
|
Day of the year, starting from 1 for 1st January.
|
|
@end defun
|
|
|
|
@defun date-week-day date
|
|
Day of the week, starting from 0 for Sunday.
|
|
@end defun
|
|
|
|
@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
|
|
|
|
@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
|
|
|
|
@defun current-julian-day
|
|
@cindex julian day
|
|
Return the current Julian Day.
|
|
@end defun
|
|
|
|
@defun current-modified-julian-day
|
|
@cindex modified julian day
|
|
Return the current Modified Julian Day.
|
|
@end defun
|
|
|
|
|
|
@node SRFI-19 Time/Date conversions
|
|
@subsubsection SRFI-19 Time/Date conversions
|
|
@cindex time conversion
|
|
@cindex date conversion
|
|
|
|
@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}.
|
|
|
|
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
|
|
@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.
|
|
|
|
Many of these conversion characters are the same as POSIX
|
|
@code{strftime} (@pxref{Time}), but there are some extras and some
|
|
variations.
|
|
|
|
@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}
|
|
|
|
@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}
|
|
|
|
@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}
|
|
|
|
@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{~H:~M:~S~z}
|
|
@item @nicode{~3} @tab ISO-8601 time, @samp{~H:~M:~S}
|
|
@item @nicode{~4} @tab ISO-8601 date/time+zone, @samp{~Y-~m-~dT~H:~M:~S~z}
|
|
@item @nicode{~5} @tab ISO-8601 date/time, @samp{~Y-~m-~dT~H:~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? I.e. 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
|
|
|
|
@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{~N}
|
|
@tab @nicode{char-numeric?}
|
|
@tab nanosecond
|
|
@tab @nicode{date-nanosecond}
|
|
|
|
@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-23
|
|
@subsection SRFI-23 - Error Reporting
|
|
@cindex SRFI-23
|
|
|
|
The SRFI-23 @code{error} procedure is always available.
|
|
|
|
@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
|
|
(use-modules (srfi srfi-26))
|
|
@end example
|
|
|
|
@deffn {library syntax} cut slot1 slot2 @dots{}
|
|
@deffnx {library syntax} cute slot1 slot2 @dots{}
|
|
Return a new procedure which will make a call (@var{slot1} @var{slot2}
|
|
@dots{}) but with selected parameters specialized to given expressions.
|
|
|
|
An example will illustrate the idea. The following is a
|
|
specialization of @code{write}, sending output to
|
|
@code{my-output-port},
|
|
|
|
@example
|
|
(cut write <> my-output-port)
|
|
@result{}
|
|
(lambda (obj) (write obj my-output-port))
|
|
@end example
|
|
|
|
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}.
|
|
|
|
@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,
|
|
|
|
@example
|
|
(cut <> 1 2 3)
|
|
@result{}
|
|
(lambda (proc) (proc 1 2 3))
|
|
@end example
|
|
|
|
@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.
|
|
|
|
For example, a procedure taking a variable number of arguments like
|
|
@code{max} but in addition enforcing a lower bound,
|
|
|
|
@example
|
|
(define my-lower-bound 123)
|
|
|
|
(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.
|
|
|
|
@example
|
|
(map (cut * 2 <>) '(1 2 3 4))
|
|
|
|
(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
|
|
|
|
This subsection is based on the
|
|
@uref{http://srfi.schemers.org/srfi-27/srfi-27.html, specification of
|
|
SRFI-27} written by Sebastian Egner.
|
|
|
|
@c The copyright notice and license text of the SRFI-27 specification is
|
|
@c reproduced below:
|
|
|
|
@c Copyright (C) Sebastian Egner (2002). All Rights Reserved.
|
|
|
|
@c Permission is hereby granted, free of charge, to any person obtaining a
|
|
@c copy of this software and associated documentation files (the
|
|
@c "Software"), to deal in the Software without restriction, including
|
|
@c without limitation the rights to use, copy, modify, merge, publish,
|
|
@c distribute, sublicense, and/or sell copies of the Software, and to
|
|
@c permit persons to whom the Software is furnished to do so, subject to
|
|
@c the following conditions:
|
|
|
|
@c The above copyright notice and this permission notice shall be included
|
|
@c in all copies or substantial portions of the Software.
|
|
|
|
@c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
@c OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
@c MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
@c NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
@c LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
@c OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
@c WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
This SRFI provides access to a (pseudo) random number generator; for
|
|
Guile's built-in random number facilities, which SRFI-27 is implemented
|
|
upon, @xref{Random}. With SRFI-27, random numbers are obtained from a
|
|
@emph{random source}, which encapsulates a random number generation
|
|
algorithm and its state.
|
|
|
|
@menu
|
|
* SRFI-27 Default Random Source:: Obtaining random numbers
|
|
* SRFI-27 Random Sources:: Creating and manipulating random sources
|
|
* SRFI-27 Random Number Generators:: Obtaining random number generators
|
|
@end menu
|
|
|
|
@node SRFI-27 Default Random Source
|
|
@subsubsection The Default Random Source
|
|
@cindex SRFI-27
|
|
|
|
@defun random-integer n
|
|
Return a random number between zero (inclusive) and @var{n} (exclusive),
|
|
using the default random source. The numbers returned have a uniform
|
|
distribution.
|
|
@end defun
|
|
|
|
@defun random-real
|
|
Return a random number in (0,1), using the default random source. The
|
|
numbers returned have a uniform distribution.
|
|
@end defun
|
|
|
|
@defun default-random-source
|
|
A random source from which @code{random-integer} and @code{random-real}
|
|
have been derived using @code{random-source-make-integers} and
|
|
@code{random-source-make-reals} (@pxref{SRFI-27 Random Number Generators}
|
|
for those procedures). Note that an assignment to
|
|
@code{default-random-source} does not change @code{random-integer} or
|
|
@code{random-real}; it is also strongly recommended not to assign a new
|
|
value.
|
|
@end defun
|
|
|
|
@node SRFI-27 Random Sources
|
|
@subsubsection Random Sources
|
|
@cindex SRFI-27
|
|
|
|
@defun make-random-source
|
|
Create a new random source. The stream of random numbers obtained from
|
|
each random source created by this procedure will be identical, unless
|
|
its state is changed by one of the procedures below.
|
|
@end defun
|
|
|
|
@defun random-source? object
|
|
Tests whether @var{object} is a random source. Random sources are a
|
|
disjoint type.
|
|
@end defun
|
|
|
|
@defun random-source-randomize! source
|
|
Attempt to set the state of the random source to a truly random value.
|
|
The current implementation uses a seed based on the current system time.
|
|
@end defun
|
|
|
|
@defun random-source-pseudo-randomize! source i j
|
|
Changes the state of the random source s into the initial state of the
|
|
(@var{i}, @var{j})-th independent random source, where @var{i} and
|
|
@var{j} are non-negative integers. This procedure provides a mechanism
|
|
to obtain a large number of independent random sources (usually all
|
|
derived from the same backbone generator), indexed by two integers. In
|
|
contrast to @code{random-source-randomize!}, this procedure is entirely
|
|
deterministic.
|
|
@end defun
|
|
|
|
The state associated with a random state can be obtained an reinstated
|
|
with the following procedures:
|
|
|
|
@defun random-source-state-ref source
|
|
@defunx random-source-state-set! source state
|
|
Get and set the state of a random source. No assumptions should be made
|
|
about the nature of the state object, besides it having an external
|
|
representation (i.e.@: it can be passed to @code{write} and subsequently
|
|
@code{read} back).
|
|
@end defun
|
|
|
|
@node SRFI-27 Random Number Generators
|
|
@subsubsection Obtaining random number generator procedures
|
|
@cindex SRFI-27
|
|
|
|
@defun random-source-make-integers source
|
|
Obtains a procedure to generate random integers using the random source
|
|
@var{source}. The returned procedure takes a single argument @var{n},
|
|
which must be a positive integer, and returns the next uniformly
|
|
distributed random integer from the interval @{0, ..., @var{n}-1@} by
|
|
advancing the state of @var{source}.
|
|
|
|
If an application obtains and uses several generators for the same
|
|
random source @var{source}, a call to any of these generators advances
|
|
the state of @var{source}. Hence, the generators do not produce the
|
|
same sequence of random integers each but rather share a state. This
|
|
also holds for all other types of generators derived from a fixed random
|
|
sources.
|
|
|
|
While the SRFI text specifies that ``Implementations that support
|
|
concurrency make sure that the state of a generator is properly
|
|
advanced'', this is currently not the case in Guile's implementation of
|
|
SRFI-27, as it would cause a severe performance penalty. So in
|
|
multi-threaded programs, you either must perform locking on random
|
|
sources shared between threads yourself, or use different random sources
|
|
for multiple threads.
|
|
@end defun
|
|
|
|
@defun random-source-make-reals source
|
|
@defunx random-source-make-reals source unit
|
|
Obtains a procedure to generate random real numbers @math{0 < x < 1}
|
|
using the random source @var{source}. The procedure rand is called
|
|
without arguments.
|
|
|
|
The optional parameter @var{unit} determines the type of numbers being
|
|
produced by the returned procedure and the quantization of the output.
|
|
@var{unit} must be a number such that @math{0 < @var{unit} < 1}. The
|
|
numbers created by the returned procedure are of the same numerical type
|
|
as @var{unit} and the potential output values are spaced by at most
|
|
@var{unit}. One can imagine rand to create numbers as @var{x} *
|
|
@var{unit} where @var{x} is a random integer in @{1, ...,
|
|
floor(1/unit)-1@}. Note, however, that this need not be the way the
|
|
values are actually created and that the actual resolution of rand can
|
|
be much higher than unit. In case @var{unit} is absent it defaults to a
|
|
reasonably small value (related to the width of the mantissa of an
|
|
efficient number format).
|
|
@end defun
|
|
|
|
@node SRFI-28
|
|
@subsection SRFI-28 - Basic Format Strings
|
|
@cindex SRFI-28
|
|
|
|
SRFI-28 provides a basic @code{format} procedure that provides only
|
|
the @code{~a}, @code{~s}, @code{~%}, and @code{~~} format specifiers.
|
|
You can import this procedure by using:
|
|
|
|
@lisp
|
|
(use-modules (srfi srfi-28))
|
|
@end lisp
|
|
|
|
@deffn {Scheme Procedure} format message arg @dots{}
|
|
Returns a formatted message, using @var{message} as the format string,
|
|
which can contain the following format specifiers:
|
|
|
|
@table @code
|
|
@item ~a
|
|
Insert the textual representation of the next @var{arg}, as if printed
|
|
by @code{display}.
|
|
|
|
@item ~s
|
|
Insert the textual representation of the next @var{arg}, as if printed
|
|
by @code{write}.
|
|
|
|
@item ~%
|
|
Insert a newline.
|
|
|
|
@item ~~
|
|
Insert a tilde.
|
|
@end table
|
|
|
|
This procedure is the same as calling @code{simple-format}
|
|
(@pxref{Simple Output}) with @code{#f} as the destination.
|
|
@end deffn
|
|
|
|
@node SRFI-30
|
|
@subsection SRFI-30 - Nested Multi-line Comments
|
|
@cindex SRFI-30
|
|
|
|
Starting from version 2.0, Guile's @code{read} supports SRFI-30/R6RS
|
|
nested multi-line comments by default, @ref{Block Comments}.
|
|
|
|
@node SRFI-31
|
|
@subsection SRFI-31 - A special form `rec' for recursive evaluation
|
|
@cindex SRFI-31
|
|
@cindex recursive expression
|
|
@findex rec
|
|
|
|
SRFI-31 defines a special form that can be used to create
|
|
self-referential expressions more conveniently. The syntax is as
|
|
follows:
|
|
|
|
@example
|
|
@group
|
|
<rec expression> --> (rec <variable> <expression>)
|
|
<rec expression> --> (rec (<variable>+) <body>)
|
|
@end group
|
|
@end example
|
|
|
|
The first syntax can be used to create self-referential expressions,
|
|
for example:
|
|
|
|
@lisp
|
|
guile> (define tmp (rec ones (cons 1 (delay ones))))
|
|
@end lisp
|
|
|
|
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
|
|
|
|
|
|
@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
|
|
|
|
@xref{Raising and Handling Exceptions}, for more on
|
|
@code{with-exception-handler} and @code{raise} (known as
|
|
@code{raise-exception} in core Guile).
|
|
|
|
SRFI-34's @code{guard} form is syntactic sugar over
|
|
@code{with-exception-handler}:
|
|
|
|
@deffn {Syntax} guard (var clause @dots{}) body @dots{}
|
|
Evaluate @var{body} with an exception handler that binds the raised
|
|
object to @var{var} and within the scope of that binding evaluates
|
|
@var{clause}@dots{} as if they were the clauses of a cond expression.
|
|
That implicit cond expression is evaluated with the continuation and
|
|
dynamic environment of the guard expression.
|
|
|
|
If every @var{clause}'s test evaluates to false and there is no
|
|
@code{else} clause, then @code{raise} is re-invoked on the raised object
|
|
within the dynamic environment of the original call to @code{raise}
|
|
except that the current exception handler is that of the @code{guard}
|
|
expression.
|
|
@end deffn
|
|
|
|
|
|
@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} defines
|
|
@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 condition1 condition2 @dots{}
|
|
Return a new compound condition composed of @var{condition1}
|
|
@var{condition2} @enddots{}. The returned condition has the type of
|
|
each condition of condition1 condition2 @dots{} (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 @code{make-compound-condition}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} extract-condition c type
|
|
Return a condition of condition type @var{type} with the field values
|
|
specified by @var{c}.
|
|
|
|
If @var{c} is a compound condition, extract the field values from the
|
|
subcondition belonging to @var{type} that appeared first in the call to
|
|
@code{make-compound-condition} that created the condition.
|
|
@end deffn
|
|
|
|
Convenience macros are also available to create condition types and
|
|
conditions.
|
|
|
|
@deffn {library syntax} define-condition-type type supertype predicate field-spec...
|
|
Define a new condition type named @var{type} that inherits from
|
|
@var{supertype}. In addition, bind @var{predicate} to a type predicate
|
|
that returns true when passed a condition of type @var{type} or any of
|
|
its subtypes. @var{field-spec} must have the form @code{(field
|
|
accessor)} where @var{field} is the name of field of @var{type} and
|
|
@var{accessor} is the name of a procedure to access field @var{field} in
|
|
conditions of type @var{type}.
|
|
|
|
The example below defines condition type @code{&foo}, inheriting from
|
|
@code{&condition} with fields @code{a}, @code{b} and @code{c}:
|
|
|
|
@lisp
|
|
(define-condition-type &foo &condition
|
|
foo-condition?
|
|
(a foo-a)
|
|
(b foo-b)
|
|
(c foo-c))
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {library syntax} condition type-field-binding1 type-field-binding2 @dots{}
|
|
Return a new condition or compound condition, initialized according to
|
|
@var{type-field-binding1} @var{type-field-binding2} @enddots{}. Each
|
|
@var{type-field-binding} must have the form @code{(type
|
|
field-specs...)}, where @var{type} is the name of a variable bound to a
|
|
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
|
|
|
|
As an implementation note, condition objects in Guile are the same as
|
|
``exception objects''. @xref{Exception Objects}. The
|
|
@code{&condition}, @code{&serious}, and @code{&error} condition types
|
|
are known in core Guile as @code{&exception}, @code{&error}, and
|
|
@code{&external-error}, respectively.
|
|
|
|
@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 signaled.
|
|
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 seed @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{seed} @dots{}, 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-38
|
|
@subsection SRFI-38 - External Representation for Data With Shared Structure
|
|
@cindex SRFI-38
|
|
|
|
This subsection is based on
|
|
@uref{http://srfi.schemers.org/srfi-38/srfi-38.html, the specification
|
|
of SRFI-38} written by Ray Dillinger.
|
|
|
|
@c Copyright (C) Ray Dillinger 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.
|
|
|
|
This SRFI creates an alternative external representation for data
|
|
written and read using @code{write-with-shared-structure} and
|
|
@code{read-with-shared-structure}. It is identical to the grammar for
|
|
external representation for data written and read with @code{write} and
|
|
@code{read} given in section 7 of R5RS, except that the single
|
|
production
|
|
|
|
@example
|
|
<datum> --> <simple datum> | <compound datum>
|
|
@end example
|
|
|
|
is replaced by the following five productions:
|
|
|
|
@example
|
|
<datum> --> <defining datum> | <nondefining datum> | <defined datum>
|
|
<defining datum> --> #<indexnum>=<nondefining datum>
|
|
<defined datum> --> #<indexnum>#
|
|
<nondefining datum> --> <simple datum> | <compound datum>
|
|
<indexnum> --> <digit 10>+
|
|
@end example
|
|
|
|
@deffn {Scheme procedure} write-with-shared-structure obj
|
|
@deffnx {Scheme procedure} write-with-shared-structure obj port
|
|
@deffnx {Scheme procedure} write-with-shared-structure obj port optarg
|
|
|
|
Writes an external representation of @var{obj} to the given port.
|
|
Strings that appear in the written representation are enclosed in
|
|
doublequotes, and within those strings backslash and doublequote
|
|
characters are escaped by backslashes. Character objects are written
|
|
using the @code{#\} notation.
|
|
|
|
Objects which denote locations rather than values (cons cells, vectors,
|
|
and non-zero-length strings in R5RS scheme; also Guile's structs,
|
|
bytevectors and ports and hash-tables), if they appear at more than one
|
|
point in the data being written, are preceded by @samp{#@var{N}=} the
|
|
first time they are written and replaced by @samp{#@var{N}#} all
|
|
subsequent times they are written, where @var{N} is a natural number
|
|
used to identify that particular object. If objects which denote
|
|
locations occur only once in the structure, then
|
|
@code{write-with-shared-structure} must produce the same external
|
|
representation for those objects as @code{write}.
|
|
|
|
@code{write-with-shared-structure} terminates in finite time and
|
|
produces a finite representation when writing finite data.
|
|
|
|
@code{write-with-shared-structure} returns an unspecified value. The
|
|
@var{port} argument may be omitted, in which case it defaults to the
|
|
value returned by @code{(current-output-port)}. The @var{optarg}
|
|
argument may also be omitted. If present, its effects on the output and
|
|
return value are unspecified but @code{write-with-shared-structure} must
|
|
still write a representation that can be read by
|
|
@code{read-with-shared-structure}. Some implementations may wish to use
|
|
@var{optarg} to specify formatting conventions, numeric radixes, or
|
|
return values. Guile's implementation ignores @var{optarg}.
|
|
|
|
For example, the code
|
|
|
|
@lisp
|
|
(begin (define a (cons 'val1 'val2))
|
|
(set-cdr! a a)
|
|
(write-with-shared-structure a))
|
|
@end lisp
|
|
|
|
should produce the output @code{#1=(val1 . #1#)}. This shows a cons
|
|
cell whose @code{cdr} contains itself.
|
|
|
|
@end deffn
|
|
|
|
@deffn {Scheme procedure} read-with-shared-structure
|
|
@deffnx {Scheme procedure} read-with-shared-structure port
|
|
|
|
@code{read-with-shared-structure} converts the external representations
|
|
of Scheme objects produced by @code{write-with-shared-structure} into
|
|
Scheme objects. That is, it is a parser for the nonterminal
|
|
@samp{<datum>} in the augmented external representation grammar defined
|
|
above. @code{read-with-shared-structure} returns the next object
|
|
parsable from the given input port, updating @var{port} to point to the
|
|
first character past the end of the external representation of the
|
|
object.
|
|
|
|
If an end-of-file is encountered in the input before any characters are
|
|
found that can begin an object, then an end-of-file object is returned.
|
|
The port remains open, and further attempts to read it (by
|
|
@code{read-with-shared-structure} or @code{read} will also return an
|
|
end-of-file object. If an end of file is encountered after the
|
|
beginning of an object's external representation, but the external
|
|
representation is incomplete and therefore not parsable, an error is
|
|
signaled.
|
|
|
|
The @var{port} argument may be omitted, in which case it defaults to the
|
|
value returned by @code{(current-input-port)}. It is an error to read
|
|
from a closed port.
|
|
|
|
@end deffn
|
|
|
|
@node SRFI-39
|
|
@subsection SRFI-39 - Parameters
|
|
@cindex SRFI-39
|
|
|
|
This SRFI adds support for dynamically-scoped parameters. SRFI 39 is
|
|
implemented in the Guile core; there's no module needed to get SRFI-39
|
|
itself. Parameters are documented in @ref{Parameters}.
|
|
|
|
This module does export one extra function: @code{with-parameters*}.
|
|
This is a Guile-specific addition to the SRFI, similar to the core
|
|
@code{with-fluids*} (@pxref{Fluids and Dynamic States}).
|
|
|
|
@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{value-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*}.
|
|
@end defun
|
|
|
|
@node SRFI-41
|
|
@subsection SRFI-41 - Streams
|
|
@cindex SRFI-41
|
|
|
|
This subsection is based on the
|
|
@uref{http://srfi.schemers.org/srfi-41/srfi-41.html, specification of
|
|
SRFI-41} by Philip L.@: Bewig.
|
|
|
|
@c The copyright notice and license text of the SRFI-41 specification is
|
|
@c reproduced below:
|
|
|
|
@c Copyright (C) Philip L. Bewig (2007). 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.
|
|
|
|
@noindent
|
|
This SRFI implements streams, sometimes called lazy lists, a sequential
|
|
data structure containing elements computed only on demand. A stream is
|
|
either null or is a pair with a stream in its cdr. Since elements of a
|
|
stream are computed only when accessed, streams can be infinite. Once
|
|
computed, the value of a stream element is cached in case it is needed
|
|
again. SRFI-41 can be made available with:
|
|
|
|
@example
|
|
(use-modules (srfi srfi-41))
|
|
@end example
|
|
|
|
@menu
|
|
* SRFI-41 Stream Fundamentals::
|
|
* SRFI-41 Stream Primitives::
|
|
* SRFI-41 Stream Library::
|
|
@end menu
|
|
|
|
@node SRFI-41 Stream Fundamentals
|
|
@subsubsection SRFI-41 Stream Fundamentals
|
|
|
|
SRFI-41 Streams are based on two mutually-recursive abstract data types:
|
|
An object of the @code{stream} abstract data type is a promise that,
|
|
when forced, is either @code{stream-null} or is an object of type
|
|
@code{stream-pair}. An object of the @code{stream-pair} abstract data
|
|
type contains a @code{stream-car} and a @code{stream-cdr}, which must be
|
|
a @code{stream}. The essential feature of streams is the systematic
|
|
suspensions of the recursive promises between the two data types.
|
|
|
|
The object stored in the @code{stream-car} of a @code{stream-pair} is a
|
|
promise that is forced the first time the @code{stream-car} is accessed;
|
|
its value is cached in case it is needed again. The object may have any
|
|
type, and different stream elements may have different types. If the
|
|
@code{stream-car} is never accessed, the object stored there is never
|
|
evaluated. Likewise, the @code{stream-cdr} is a promise to return a
|
|
stream, and is only forced on demand.
|
|
|
|
@node SRFI-41 Stream Primitives
|
|
@subsubsection SRFI-41 Stream Primitives
|
|
|
|
This library provides eight operators: constructors for
|
|
@code{stream-null} and @code{stream-pair}s, type predicates for streams
|
|
and the two kinds of streams, accessors for both fields of a
|
|
@code{stream-pair}, and a lambda that creates procedures that return
|
|
streams.
|
|
|
|
@defvr {Scheme Variable} stream-null
|
|
A promise that, when forced, is a single object, distinguishable from
|
|
all other objects, that represents the null stream. @code{stream-null}
|
|
is immutable and unique.
|
|
@end defvr
|
|
|
|
@deffn {Scheme Syntax} stream-cons object-expr stream-expr
|
|
Creates a newly-allocated stream containing a promise that, when forced,
|
|
is a @code{stream-pair} with @var{object-expr} in its @code{stream-car}
|
|
and @var{stream-expr} in its @code{stream-cdr}. Neither
|
|
@var{object-expr} nor @var{stream-expr} is evaluated when
|
|
@code{stream-cons} is called.
|
|
|
|
Once created, a @code{stream-pair} is immutable; there is no
|
|
@code{stream-set-car!} or @code{stream-set-cdr!} that modifies an
|
|
existing stream-pair. There is no dotted-pair or improper stream as
|
|
with lists.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream? object
|
|
Returns true if @var{object} is a stream, otherwise returns false. If
|
|
@var{object} is a stream, its promise will not be forced. If
|
|
@code{(stream? obj)} returns true, then one of @code{(stream-null? obj)}
|
|
or @code{(stream-pair? obj)} will return true and the other will return
|
|
false.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-null? object
|
|
Returns true if @var{object} is the distinguished null stream, otherwise
|
|
returns false. If @var{object} is a stream, its promise will be forced.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-pair? object
|
|
Returns true if @var{object} is a @code{stream-pair} constructed by
|
|
@code{stream-cons}, otherwise returns false. If @var{object} is a
|
|
stream, its promise will be forced.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-car stream
|
|
Returns the object stored in the @code{stream-car} of @var{stream}. An
|
|
error is signaled if the argument is not a @code{stream-pair}. This
|
|
causes the @var{object-expr} passed to @code{stream-cons} to be
|
|
evaluated if it had not yet been; the value is cached in case it is
|
|
needed again.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-cdr stream
|
|
Returns the stream stored in the @code{stream-cdr} of @var{stream}. An
|
|
error is signaled if the argument is not a @code{stream-pair}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Syntax} stream-lambda formals body @dots{}
|
|
Creates a procedure that returns a promise to evaluate the @var{body} of
|
|
the procedure. The last @var{body} expression to be evaluated must
|
|
yield a stream. As with normal @code{lambda}, @var{formals} may be a
|
|
single variable name, in which case all the formal arguments are
|
|
collected into a single list, or a list of variable names, which may be
|
|
null if there are no arguments, proper if there are an exact number of
|
|
arguments, or dotted if a fixed number of arguments is to be followed by
|
|
zero or more arguments collected into a list. @var{Body} must contain
|
|
at least one expression, and may contain internal definitions preceding
|
|
any expressions to be evaluated.
|
|
@end deffn
|
|
|
|
@example
|
|
(define strm123
|
|
(stream-cons 1
|
|
(stream-cons 2
|
|
(stream-cons 3
|
|
stream-null))))
|
|
|
|
(stream-car strm123) @result{} 1
|
|
(stream-car (stream-cdr strm123) @result{} 2
|
|
|
|
(stream-pair?
|
|
(stream-cdr
|
|
(stream-cons (/ 1 0) stream-null))) @result{} #f
|
|
|
|
(stream? (list 1 2 3)) @result{} #f
|
|
|
|
(define iter
|
|
(stream-lambda (f x)
|
|
(stream-cons x (iter f (f x)))))
|
|
|
|
(define nats (iter (lambda (x) (+ x 1)) 0))
|
|
|
|
(stream-car (stream-cdr nats)) @result{} 1
|
|
|
|
(define stream-add
|
|
(stream-lambda (s1 s2)
|
|
(stream-cons
|
|
(+ (stream-car s1) (stream-car s2))
|
|
(stream-add (stream-cdr s1)
|
|
(stream-cdr s2)))))
|
|
|
|
(define evens (stream-add nats nats))
|
|
|
|
(stream-car evens) @result{} 0
|
|
(stream-car (stream-cdr evens)) @result{} 2
|
|
(stream-car (stream-cdr (stream-cdr evens))) @result{} 4
|
|
@end example
|
|
|
|
@node SRFI-41 Stream Library
|
|
@subsubsection SRFI-41 Stream Library
|
|
|
|
@deffn {Scheme Syntax} define-stream (name args @dots{}) body @dots{}
|
|
Creates a procedure that returns a stream, and may appear anywhere a
|
|
normal @code{define} may appear, including as an internal definition.
|
|
It may contain internal definitions of its own. The defined procedure
|
|
takes arguments in the same way as @code{stream-lambda}.
|
|
@code{define-stream} is syntactic sugar on @code{stream-lambda}; see
|
|
also @code{stream-let}, which is also a sugaring of
|
|
@code{stream-lambda}.
|
|
|
|
A simple version of @code{stream-map} that takes only a single input
|
|
stream calls itself recursively:
|
|
|
|
@example
|
|
(define-stream (stream-map proc strm)
|
|
(if (stream-null? strm)
|
|
stream-null
|
|
(stream-cons
|
|
(proc (stream-car strm))
|
|
(stream-map proc (stream-cdr strm))))))
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list->stream list
|
|
Returns a newly-allocated stream containing the elements from
|
|
@var{list}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} port->stream [port]
|
|
Returns a newly-allocated stream containing in its elements the
|
|
characters on the port. If @var{port} is not given it defaults to the
|
|
current input port. The returned stream has finite length and is
|
|
terminated by @code{stream-null}.
|
|
|
|
It looks like one use of @code{port->stream} would be this:
|
|
|
|
@example
|
|
(define s ;wrong!
|
|
(with-input-from-file filename
|
|
(lambda () (port->stream))))
|
|
@end example
|
|
|
|
But that fails, because @code{with-input-from-file} is eager, and closes
|
|
the input port prematurely, before the first character is read. To read
|
|
a file into a stream, say:
|
|
|
|
@example
|
|
(define-stream (file->stream filename)
|
|
(let ((p (open-input-file filename)))
|
|
(stream-let loop ((c (read-char p)))
|
|
(if (eof-object? c)
|
|
(begin (close-input-port p)
|
|
stream-null)
|
|
(stream-cons c
|
|
(loop (read-char p)))))))
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Syntax} stream object-expr @dots{}
|
|
Creates a newly-allocated stream containing in its elements the objects,
|
|
in order. The @var{object-expr}s are evaluated when they are accessed,
|
|
not when the stream is created. If no objects are given, as in
|
|
(stream), the null stream is returned. See also @code{list->stream}.
|
|
|
|
@example
|
|
(define strm123 (stream 1 2 3))
|
|
|
|
; (/ 1 0) not evaluated when stream is created
|
|
(define s (stream 1 (/ 1 0) -1))
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream->list [n] stream
|
|
Returns a newly-allocated list containing in its elements the first
|
|
@var{n} items in @var{stream}. If @var{stream} has less than @var{n}
|
|
items, all the items in the stream will be included in the returned
|
|
list. If @var{n} is not given it defaults to infinity, which means that
|
|
unless @var{stream} is finite @code{stream->list} will never return.
|
|
|
|
@example
|
|
(stream->list 10
|
|
(stream-map (lambda (x) (* x x))
|
|
(stream-from 0)))
|
|
@result{} (0 1 4 9 16 25 36 49 64 81)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-append stream @dots{}
|
|
Returns a newly-allocated stream containing in its elements those
|
|
elements contained in its input @var{stream}s, in order of input. If
|
|
any of the input streams is infinite, no elements of any of the
|
|
succeeding input streams will appear in the output stream. See also
|
|
@code{stream-concat}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-concat stream
|
|
Takes a @var{stream} consisting of one or more streams and returns a
|
|
newly-allocated stream containing all the elements of the input streams.
|
|
If any of the streams in the input @var{stream} is infinite, any
|
|
remaining streams in the input stream will never appear in the output
|
|
stream. See also @code{stream-append}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-constant object @dots{}
|
|
Returns a newly-allocated stream containing in its elements the
|
|
@var{object}s, repeating in succession forever.
|
|
|
|
@example
|
|
(stream-constant 1) @result{} 1 1 1 @dots{}
|
|
(stream-constant #t #f) @result{} #t #f #t #f #t #f @dots{}
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-drop n stream
|
|
Returns the suffix of the input @var{stream} that starts at the next
|
|
element after the first @var{n} elements. The output stream shares
|
|
structure with the input @var{stream}; thus, promises forced in one
|
|
instance of the stream are also forced in the other instance of the
|
|
stream. If the input @var{stream} has less than @var{n} elements,
|
|
@code{stream-drop} returns the null stream. See also
|
|
@code{stream-take}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-drop-while pred stream
|
|
Returns the suffix of the input @var{stream} that starts at the first
|
|
element @var{x} for which @code{(pred x)} returns false. The output
|
|
stream shares structure with the input @var{stream}. See also
|
|
@code{stream-take-while}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-filter pred stream
|
|
Returns a newly-allocated stream that contains only those elements
|
|
@var{x} of the input @var{stream} which satisfy the predicate
|
|
@code{pred}.
|
|
|
|
@example
|
|
(stream-filter odd? (stream-from 0))
|
|
@result{} 1 3 5 7 9 @dots{}
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-fold proc base stream
|
|
Applies a binary procedure @var{proc} to @var{base} and the first
|
|
element of @var{stream} to compute a new @var{base}, then applies the
|
|
procedure to the new @var{base} and the next element of @var{stream} to
|
|
compute a succeeding @var{base}, and so on, accumulating a value that is
|
|
finally returned as the value of @code{stream-fold} when the end of the
|
|
stream is reached. @var{stream} must be finite, or @code{stream-fold}
|
|
will enter an infinite loop. See also @code{stream-scan}, which is
|
|
similar to @code{stream-fold}, but useful for infinite streams. For
|
|
readers familiar with other functional languages, this is a left-fold;
|
|
there is no corresponding right-fold, since right-fold relies on finite
|
|
streams that are fully-evaluated, in which case they may as well be
|
|
converted to a list.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-for-each proc stream @dots{}
|
|
Applies @var{proc} element-wise to corresponding elements of the input
|
|
@var{stream}s for side-effects; it returns nothing.
|
|
@code{stream-for-each} stops as soon as any of its input streams is
|
|
exhausted.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-from first [step]
|
|
Creates a newly-allocated stream that contains @var{first} as its first
|
|
element and increments each succeeding element by @var{step}. If
|
|
@var{step} is not given it defaults to 1. @var{first} and @var{step}
|
|
may be of any numeric type. @code{stream-from} is frequently useful as
|
|
a generator in @code{stream-of} expressions. See also
|
|
@code{stream-range} for a similar procedure that creates finite streams.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-iterate proc base
|
|
Creates a newly-allocated stream containing @var{base} in its first
|
|
element and applies @var{proc} to each element in turn to determine the
|
|
succeeding element. See also @code{stream-unfold} and
|
|
@code{stream-unfolds}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-length stream
|
|
Returns the number of elements in the @var{stream}; it does not evaluate
|
|
its elements. @code{stream-length} may only be used on finite streams;
|
|
it enters an infinite loop with infinite streams.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Syntax} stream-let tag ((var expr) @dots{}) body @dots{}
|
|
Creates a local scope that binds each variable to the value of its
|
|
corresponding expression. It additionally binds @var{tag} to a
|
|
procedure which takes the bound variables as arguments and @var{body} as
|
|
its defining expressions, binding the @var{tag} with
|
|
@code{stream-lambda}. @var{tag} is in scope within body, and may be
|
|
called recursively. When the expanded expression defined by the
|
|
@code{stream-let} is evaluated, @code{stream-let} evaluates the
|
|
expressions in its @var{body} in an environment containing the
|
|
newly-bound variables, returning the value of the last expression
|
|
evaluated, which must yield a stream.
|
|
|
|
@code{stream-let} provides syntactic sugar on @code{stream-lambda}, in
|
|
the same manner as normal @code{let} provides syntactic sugar on normal
|
|
@code{lambda}. However, unlike normal @code{let}, the @var{tag} is
|
|
required, not optional, because unnamed @code{stream-let} is
|
|
meaningless.
|
|
|
|
For example, @code{stream-member} returns the first @code{stream-pair}
|
|
of the input @var{strm} with a @code{stream-car} @var{x} that satisfies
|
|
@code{(eql? obj x)}, or the null stream if @var{x} is not present in
|
|
@var{strm}.
|
|
|
|
@example
|
|
(define-stream (stream-member eql? obj strm)
|
|
(stream-let loop ((strm strm))
|
|
(cond ((stream-null? strm) strm)
|
|
((eql? obj (stream-car strm)) strm)
|
|
(else (loop (stream-cdr strm))))))
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-map proc stream @dots{}
|
|
Applies @var{proc} element-wise to corresponding elements of the input
|
|
@var{stream}s, returning a newly-allocated stream containing elements
|
|
that are the results of those procedure applications. The output stream
|
|
has as many elements as the minimum-length input stream, and may be
|
|
infinite.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Syntax} stream-match stream clause @dots{}
|
|
Provides pattern-matching for streams. The input @var{stream} is an
|
|
expression that evaluates to a stream. Clauses are of the form
|
|
@code{(pattern [fender] expression)}, consisting of a @var{pattern} that
|
|
matches a stream of a particular shape, an optional @var{fender} that
|
|
must succeed if the pattern is to match, and an @var{expression} that is
|
|
evaluated if the pattern matches. There are four types of patterns:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
() matches the null stream.
|
|
|
|
@item
|
|
(@var{pat0} @var{pat1} @dots{}) matches a finite stream with length
|
|
exactly equal to the number of pattern elements.
|
|
|
|
@item
|
|
(@var{pat0} @var{pat1} @dots{} @code{.} @var{pat-rest}) matches an
|
|
infinite stream, or a finite stream with length at least as great as the
|
|
number of pattern elements before the literal dot.
|
|
|
|
@item
|
|
@var{pat} matches an entire stream. Should always appear last in the
|
|
list of clauses; it's not an error to appear elsewhere, but subsequent
|
|
clauses could never match.
|
|
@end itemize
|
|
|
|
Each pattern element may be either:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
An identifier, which matches any stream element. Additionally, the
|
|
value of the stream element is bound to the variable named by the
|
|
identifier, which is in scope in the @var{fender} and @var{expression}
|
|
of the corresponding @var{clause}. Each identifier in a single pattern
|
|
must be unique.
|
|
|
|
@item
|
|
A literal underscore (@code{_}), which matches any stream element but
|
|
creates no bindings.
|
|
@end itemize
|
|
|
|
The @var{pattern}s are tested in order, left-to-right, until a matching
|
|
pattern is found; if @var{fender} is present, it must evaluate to a true
|
|
value for the match to be successful. Pattern variables are bound in
|
|
the corresponding @var{fender} and @var{expression}. Once the matching
|
|
@var{pattern} is found, the corresponding @var{expression} is evaluated
|
|
and returned as the result of the match. An error is signaled if no
|
|
pattern matches the input @var{stream}.
|
|
|
|
@code{stream-match} is often used to distinguish null streams from
|
|
non-null streams, binding @var{head} and @var{tail}:
|
|
|
|
@example
|
|
(define (len strm)
|
|
(stream-match strm
|
|
(() 0)
|
|
((head . tail) (+ 1 (len tail)))))
|
|
@end example
|
|
|
|
Fenders can test the common case where two stream elements must be
|
|
identical; the @code{else} pattern is an identifier bound to the entire
|
|
stream, not a keyword as in @code{cond}.
|
|
|
|
@example
|
|
(stream-match strm
|
|
((x y . _) (equal? x y) 'ok)
|
|
(else 'error))
|
|
@end example
|
|
|
|
A more complex example uses two nested matchers to match two different
|
|
stream arguments; @code{(stream-merge lt? . strms)} stably merges two or
|
|
more streams ordered by the @code{lt?} predicate:
|
|
|
|
@example
|
|
(define-stream (stream-merge lt? . strms)
|
|
(define-stream (merge xx yy)
|
|
(stream-match xx (() yy) ((x . xs)
|
|
(stream-match yy (() xx) ((y . ys)
|
|
(if (lt? y x)
|
|
(stream-cons y (merge xx ys))
|
|
(stream-cons x (merge xs yy))))))))
|
|
(stream-let loop ((strms strms))
|
|
(cond ((null? strms) stream-null)
|
|
((null? (cdr strms)) (car strms))
|
|
(else (merge (car strms)
|
|
(apply stream-merge lt?
|
|
(cdr strms)))))))
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Syntax} stream-of expr clause @dots{}
|
|
Provides the syntax of stream comprehensions, which generate streams by
|
|
means of looping expressions. The result is a stream of objects of the
|
|
type returned by @var{expr}. There are four types of clauses:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
(@var{var} @code{in} @var{stream-expr}) loops over the elements of
|
|
@var{stream-expr}, in order from the start of the stream, binding each
|
|
element of the stream in turn to @var{var}. @code{stream-from} and
|
|
@code{stream-range} are frequently useful as generators for
|
|
@var{stream-expr}.
|
|
|
|
@item
|
|
(@var{var} @code{is} @var{expr}) binds @var{var} to the value obtained
|
|
by evaluating @var{expr}.
|
|
|
|
@item
|
|
(@var{pred} @var{expr}) includes in the output stream only those
|
|
elements @var{x} which satisfy the predicate @var{pred}.
|
|
@end itemize
|
|
|
|
The scope of variables bound in the stream comprehension is the clauses
|
|
to the right of the binding clause (but not the binding clause itself)
|
|
plus the result expression.
|
|
|
|
When two or more generators are present, the loops are processed as if
|
|
they are nested from left to right; that is, the rightmost generator
|
|
varies fastest. A consequence of this is that only the first generator
|
|
may be infinite and all subsequent generators must be finite. If no
|
|
generators are present, the result of a stream comprehension is a stream
|
|
containing the result expression; thus, @samp{(stream-of 1)} produces a
|
|
finite stream containing only the element 1.
|
|
|
|
@example
|
|
(stream-of (* x x)
|
|
(x in (stream-range 0 10))
|
|
(even? x))
|
|
@result{} 0 4 16 36 64
|
|
|
|
(stream-of (list a b)
|
|
(a in (stream-range 1 4))
|
|
(b in (stream-range 1 3)))
|
|
@result{} (1 1) (1 2) (2 1) (2 2) (3 1) (3 2)
|
|
|
|
(stream-of (list i j)
|
|
(i in (stream-range 1 5))
|
|
(j in (stream-range (+ i 1) 5)))
|
|
@result{} (1 2) (1 3) (1 4) (2 3) (2 4) (3 4)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-range first past [step]
|
|
Creates a newly-allocated stream that contains @var{first} as its first
|
|
element and increments each succeeding element by @var{step}. The
|
|
stream is finite and ends before @var{past}, which is not an element of
|
|
the stream. If @var{step} is not given it defaults to 1 if @var{first}
|
|
is less than past and -1 otherwise. @var{first}, @var{past} and
|
|
@var{step} may be of any real numeric type. @code{stream-range} is
|
|
frequently useful as a generator in @code{stream-of} expressions. See
|
|
also @code{stream-from} for a similar procedure that creates infinite
|
|
streams.
|
|
|
|
@example
|
|
(stream-range 0 10) @result{} 0 1 2 3 4 5 6 7 8 9
|
|
(stream-range 0 10 2) @result{} 0 2 4 6 8
|
|
@end example
|
|
|
|
Successive elements of the stream are calculated by adding @var{step} to
|
|
@var{first}, so if any of @var{first}, @var{past} or @var{step} are
|
|
inexact, the length of the output stream may differ from
|
|
@code{(ceiling (- (/ (- past first) step) 1)}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-ref stream n
|
|
Returns the @var{n}th element of stream, counting from zero. An error
|
|
is signaled if @var{n} is greater than or equal to the length of stream.
|
|
|
|
@example
|
|
(define (fact n)
|
|
(stream-ref
|
|
(stream-scan * 1 (stream-from 1))
|
|
n))
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-reverse stream
|
|
Returns a newly-allocated stream containing the elements of the input
|
|
@var{stream} but in reverse order. @code{stream-reverse} may only be
|
|
used with finite streams; it enters an infinite loop with infinite
|
|
streams. @code{stream-reverse} does not force evaluation of the
|
|
elements of the stream.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-scan proc base stream
|
|
Accumulates the partial folds of an input @var{stream} into a
|
|
newly-allocated output stream. The output stream is the @var{base}
|
|
followed by @code{(stream-fold proc base (stream-take i stream))} for
|
|
each of the first @var{i} elements of @var{stream}.
|
|
|
|
@example
|
|
(stream-scan + 0 (stream-from 1))
|
|
@result{} (stream 0 1 3 6 10 15 @dots{})
|
|
|
|
(stream-scan * 1 (stream-from 1))
|
|
@result{} (stream 1 1 2 6 24 120 @dots{})
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-take n stream
|
|
Returns a newly-allocated stream containing the first @var{n} elements
|
|
of the input @var{stream}. If the input @var{stream} has less than
|
|
@var{n} elements, so does the output stream. See also
|
|
@code{stream-drop}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-take-while pred stream
|
|
Takes a predicate and a @code{stream} and returns a newly-allocated
|
|
stream containing those elements @code{x} that form the maximal prefix
|
|
of the input stream which satisfy @var{pred}. See also
|
|
@code{stream-drop-while}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-unfold map pred gen base
|
|
The fundamental recursive stream constructor. It constructs a stream by
|
|
repeatedly applying @var{gen} to successive values of @var{base}, in the
|
|
manner of @code{stream-iterate}, then applying @var{map} to each of the
|
|
values so generated, appending each of the mapped values to the output
|
|
stream as long as @code{(pred? base)} returns a true value. See also
|
|
@code{stream-iterate} and @code{stream-unfolds}.
|
|
|
|
The expression below creates the finite stream @samp{0 1 4 9 16 25 36 49
|
|
64 81}. Initially the @var{base} is 0, which is less than 10, so
|
|
@var{map} squares the @var{base} and the mapped value becomes the first
|
|
element of the output stream. Then @var{gen} increments the @var{base}
|
|
by 1, so it becomes 1; this is less than 10, so @var{map} squares the
|
|
new @var{base} and 1 becomes the second element of the output stream.
|
|
And so on, until the base becomes 10, when @var{pred} stops the
|
|
recursion and stream-null ends the output stream.
|
|
|
|
@example
|
|
(stream-unfold
|
|
(lambda (x) (expt x 2)) ; map
|
|
(lambda (x) (< x 10)) ; pred?
|
|
(lambda (x) (+ x 1)) ; gen
|
|
0) ; base
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-unfolds proc seed
|
|
Returns @var{n} newly-allocated streams containing those elements
|
|
produced by successive calls to the generator @var{proc}, which takes
|
|
the current @var{seed} as its argument and returns @var{n}+1 values
|
|
|
|
(@var{proc} @var{seed}) @result{} @var{seed} @var{result_0} @dots{} @var{result_n-1}
|
|
|
|
where the returned @var{seed} is the input @var{seed} to the next call
|
|
to the generator and @var{result_i} indicates how to produce the next
|
|
element of the @var{i}th result stream:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
(@var{value}): @var{value} is the next car of the result stream.
|
|
|
|
@item
|
|
@code{#f}: no value produced by this iteration of the generator
|
|
@var{proc} for the result stream.
|
|
|
|
@item
|
|
(): the end of the result stream.
|
|
@end itemize
|
|
|
|
It may require multiple calls of @var{proc} to produce the next element
|
|
of any particular result stream. See also @code{stream-iterate} and
|
|
@code{stream-unfold}.
|
|
|
|
@example
|
|
(define (stream-partition pred? strm)
|
|
(stream-unfolds
|
|
(lambda (s)
|
|
(if (stream-null? s)
|
|
(values s '() '())
|
|
(let ((a (stream-car s))
|
|
(d (stream-cdr s)))
|
|
(if (pred? a)
|
|
(values d (list a) #f)
|
|
(values d #f (list a))))))
|
|
strm))
|
|
|
|
(call-with-values
|
|
(lambda ()
|
|
(stream-partition odd?
|
|
(stream-range 1 6)))
|
|
(lambda (odds evens)
|
|
(list (stream->list odds)
|
|
(stream->list evens))))
|
|
@result{} ((1 3 5) (2 4))
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stream-zip stream @dots{}
|
|
Returns a newly-allocated stream in which each element is a list (not a
|
|
stream) of the corresponding elements of the input @var{stream}s. The
|
|
output stream is as long as the shortest input @var{stream}, if any of
|
|
the input @var{stream}s is finite, or is infinite if all the input
|
|
@var{stream}s are infinite.
|
|
@end deffn
|
|
|
|
@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-43
|
|
@subsection SRFI-43 - Vector Library
|
|
@cindex SRFI-43
|
|
|
|
This subsection is based on the
|
|
@uref{http://srfi.schemers.org/srfi-43/srfi-43.html, specification of
|
|
SRFI-43} by Taylor Campbell.
|
|
|
|
@c The copyright notice and license text of the SRFI-43 specification is
|
|
@c reproduced below:
|
|
|
|
@c Copyright (C) Taylor Campbell (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.
|
|
|
|
@noindent
|
|
SRFI-43 implements a comprehensive library of vector operations. It can
|
|
be made available with:
|
|
|
|
@example
|
|
(use-modules (srfi srfi-43))
|
|
@end example
|
|
|
|
@menu
|
|
* SRFI-43 Constructors::
|
|
* SRFI-43 Predicates::
|
|
* SRFI-43 Selectors::
|
|
* SRFI-43 Iteration::
|
|
* SRFI-43 Searching::
|
|
* SRFI-43 Mutators::
|
|
* SRFI-43 Conversion::
|
|
@end menu
|
|
|
|
@node SRFI-43 Constructors
|
|
@subsubsection SRFI-43 Constructors
|
|
|
|
@deffn {Scheme Procedure} make-vector size [fill]
|
|
Create and return a vector of size @var{size}, optionally filling it
|
|
with @var{fill}. The default value of @var{fill} is unspecified.
|
|
|
|
@example
|
|
(make-vector 5 3) @result{} #(3 3 3 3 3)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector x @dots{}
|
|
Create and return a vector whose elements are @var{x} @enddots{}.
|
|
|
|
@example
|
|
(vector 0 1 2 3 4) @result{} #(0 1 2 3 4)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-unfold f length initial-seed @dots{}
|
|
The fundamental vector constructor. Create a vector whose length
|
|
is @var{length} and iterates across each index k from 0 up to
|
|
@var{length} - 1, applying @var{f} at each iteration to the current
|
|
index and current seeds, in that order, to receive n + 1 values: the
|
|
element to put in the kth slot of the new vector, and n new seeds for
|
|
the next iteration. It is an error for the number of seeds to vary
|
|
between iterations.
|
|
|
|
@example
|
|
(vector-unfold (lambda (i x) (values x (- x 1)))
|
|
10 0)
|
|
@result{} #(0 -1 -2 -3 -4 -5 -6 -7 -8 -9)
|
|
|
|
(vector-unfold values 10)
|
|
@result{} #(0 1 2 3 4 5 6 7 8 9)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-unfold-right f length initial-seed @dots{}
|
|
Like @code{vector-unfold}, but it uses @var{f} to generate elements from
|
|
right-to-left, rather than left-to-right.
|
|
|
|
@example
|
|
(vector-unfold-right (lambda (i x) (values x (+ x 1)))
|
|
10 0)
|
|
@result{} #(9 8 7 6 5 4 3 2 1 0)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-copy vec [start [end [fill]]]
|
|
Allocate a new vector whose length is @var{end} - @var{start} and fills
|
|
it with elements from @var{vec}, taking elements from @var{vec} starting
|
|
at index @var{start} and stopping at index @var{end}. @var{start}
|
|
defaults to 0 and @var{end} defaults to the value of
|
|
@code{(vector-length vec)}. If @var{end} extends beyond the length of
|
|
@var{vec}, the slots in the new vector that obviously cannot be filled
|
|
by elements from @var{vec} are filled with @var{fill}, whose default
|
|
value is unspecified.
|
|
|
|
@example
|
|
(vector-copy '#(a b c d e f g h i))
|
|
@result{} #(a b c d e f g h i)
|
|
|
|
(vector-copy '#(a b c d e f g h i) 6)
|
|
@result{} #(g h i)
|
|
|
|
(vector-copy '#(a b c d e f g h i) 3 6)
|
|
@result{} #(d e f)
|
|
|
|
(vector-copy '#(a b c d e f g h i) 6 12 'x)
|
|
@result{} #(g h i x x x)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-reverse-copy vec [start [end]]
|
|
Like @code{vector-copy}, but it copies the elements in the reverse order
|
|
from @var{vec}.
|
|
|
|
@example
|
|
(vector-reverse-copy '#(5 4 3 2 1 0) 1 5)
|
|
@result{} #(1 2 3 4)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-append vec @dots{}
|
|
Return a newly allocated vector that contains all elements in order from
|
|
the subsequent locations in @var{vec} @enddots{}.
|
|
|
|
@example
|
|
(vector-append '#(a) '#(b c d))
|
|
@result{} #(a b c d)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-concatenate list-of-vectors
|
|
Append each vector in @var{list-of-vectors}. Equivalent to
|
|
@code{(apply vector-append list-of-vectors)}.
|
|
|
|
@example
|
|
(vector-concatenate '(#(a b) #(c d)))
|
|
@result{} #(a b c d)
|
|
@end example
|
|
@end deffn
|
|
|
|
@node SRFI-43 Predicates
|
|
@subsubsection SRFI-43 Predicates
|
|
|
|
@deffn {Scheme Procedure} vector? obj
|
|
Return true if @var{obj} is a vector, else return false.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-empty? vec
|
|
Return true if @var{vec} is empty, i.e. its length is 0, else return
|
|
false.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector= elt=? vec @dots{}
|
|
Return true if the vectors @var{vec} @dots{} have equal lengths and
|
|
equal elements according to @var{elt=?}. @var{elt=?} is always applied
|
|
to two arguments. Element comparison must be consistent with @code{eq?}
|
|
in the following sense: if @code{(eq? a b)} returns true, then
|
|
@code{(elt=? a b)} must also return true. The order in which
|
|
comparisons are performed is unspecified.
|
|
@end deffn
|
|
|
|
@node SRFI-43 Selectors
|
|
@subsubsection SRFI-43 Selectors
|
|
|
|
@deffn {Scheme Procedure} vector-ref vec i
|
|
Return the element at index @var{i} in @var{vec}. Indexing is based on
|
|
zero.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-length vec
|
|
Return the length of @var{vec}.
|
|
@end deffn
|
|
|
|
@node SRFI-43 Iteration
|
|
@subsubsection SRFI-43 Iteration
|
|
|
|
@deffn {Scheme Procedure} vector-fold kons knil vec1 vec2 @dots{}
|
|
The fundamental vector iterator. @var{kons} is iterated over each index
|
|
in all of the vectors, stopping at the end of the shortest; @var{kons}
|
|
is applied as
|
|
@smalllisp
|
|
(kons i state (vector-ref vec1 i) (vector-ref vec2 i) ...)
|
|
@end smalllisp
|
|
where @var{state} is the current state value, and @var{i} is the current
|
|
index. The current state value begins with @var{knil}, and becomes
|
|
whatever @var{kons} returned at the respective iteration. The iteration
|
|
is strictly left-to-right.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-fold-right kons knil vec1 vec2 @dots{}
|
|
Similar to @code{vector-fold}, but it iterates right-to-left instead of
|
|
left-to-right.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-map f vec1 vec2 @dots{}
|
|
Return a new vector of the shortest size of the vector arguments. Each
|
|
element at index i of the new vector is mapped from the old vectors by
|
|
@smalllisp
|
|
(f i (vector-ref vec1 i) (vector-ref vec2 i) ...)
|
|
@end smalllisp
|
|
The dynamic order of application of @var{f} is unspecified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-map! f vec1 vec2 @dots{}
|
|
Similar to @code{vector-map}, but rather than mapping the new elements
|
|
into a new vector, the new mapped elements are destructively inserted
|
|
into @var{vec1}. The dynamic order of application of @var{f} is
|
|
unspecified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-for-each f vec1 vec2 @dots{}
|
|
Call @code{(f i (vector-ref vec1 i) (vector-ref vec2 i) ...)} for each
|
|
index i less than the length of the shortest vector passed. The
|
|
iteration is strictly left-to-right.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-count pred? vec1 vec2 @dots{}
|
|
Count the number of parallel elements in the vectors that satisfy
|
|
@var{pred?}, which is applied, for each index i less than the length of
|
|
the smallest vector, to i and each parallel element in the vectors at
|
|
that index, in order.
|
|
|
|
@example
|
|
(vector-count (lambda (i elt) (even? elt))
|
|
'#(3 1 4 1 5 9 2 5 6))
|
|
@result{} 3
|
|
(vector-count (lambda (i x y) (< x y))
|
|
'#(1 3 6 9) '#(2 4 6 8 10 12))
|
|
@result{} 2
|
|
@end example
|
|
@end deffn
|
|
|
|
@node SRFI-43 Searching
|
|
@subsubsection SRFI-43 Searching
|
|
|
|
@deffn {Scheme Procedure} vector-index pred? vec1 vec2 @dots{}
|
|
Find and return the index of the first elements in @var{vec1} @var{vec2}
|
|
@dots{} that satisfy @var{pred?}. If no matching element is found by
|
|
the end of the shortest vector, return @code{#f}.
|
|
|
|
@example
|
|
(vector-index even? '#(3 1 4 1 5 9))
|
|
@result{} 2
|
|
(vector-index < '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))
|
|
@result{} 1
|
|
(vector-index = '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))
|
|
@result{} #f
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-index-right pred? vec1 vec2 @dots{}
|
|
Like @code{vector-index}, but it searches right-to-left, rather than
|
|
left-to-right. Note that the SRFI 43 specification requires that all
|
|
the vectors must have the same length, but both the SRFI 43 reference
|
|
implementation and Guile's implementation allow vectors with unequal
|
|
lengths, and start searching from the last index of the shortest vector.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-skip pred? vec1 vec2 @dots{}
|
|
Find and return the index of the first elements in @var{vec1} @var{vec2}
|
|
@dots{} that do not satisfy @var{pred?}. If no matching element is
|
|
found by the end of the shortest vector, return @code{#f}. Equivalent
|
|
to @code{vector-index} but with the predicate inverted.
|
|
|
|
@example
|
|
(vector-skip number? '#(1 2 a b 3 4 c d)) @result{} 2
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-skip-right pred? vec1 vec2 @dots{}
|
|
Like @code{vector-skip}, but it searches for a non-matching element
|
|
right-to-left, rather than left-to-right. Note that the SRFI 43
|
|
specification requires that all the vectors must have the same length,
|
|
but both the SRFI 43 reference implementation and Guile's implementation
|
|
allow vectors with unequal lengths, and start searching from the last
|
|
index of the shortest vector.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-binary-search vec value cmp [start [end]]
|
|
Find and return an index of @var{vec} between @var{start} and @var{end}
|
|
whose value is @var{value} using a binary search. If no matching
|
|
element is found, return @code{#f}. The default @var{start} is 0 and
|
|
the default @var{end} is the length of @var{vec}.
|
|
|
|
@var{cmp} must be a procedure of two arguments such that @code{(cmp a
|
|
b)} returns a negative integer if @math{a < b}, a positive integer if
|
|
@math{a > b}, or zero if @math{a = b}. The elements of @var{vec} must
|
|
be sorted in non-decreasing order according to @var{cmp}.
|
|
|
|
Note that SRFI 43 does not document the @var{start} and @var{end}
|
|
arguments, but both its reference implementation and Guile's
|
|
implementation support them.
|
|
|
|
@example
|
|
(define (char-cmp c1 c2)
|
|
(cond ((char<? c1 c2) -1)
|
|
((char>? c1 c2) 1)
|
|
(else 0)))
|
|
|
|
(vector-binary-search '#(#\a #\b #\c #\d #\e #\f #\g #\h)
|
|
#\g
|
|
char-cmp)
|
|
@result{} 6
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-any pred? vec1 vec2 @dots{}
|
|
Find the first parallel set of elements from @var{vec1} @var{vec2}
|
|
@dots{} for which @var{pred?} returns a true value. If such a parallel
|
|
set of elements exists, @code{vector-any} returns the value that
|
|
@var{pred?} returned for that set of elements. The iteration is
|
|
strictly left-to-right.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-every pred? vec1 vec2 @dots{}
|
|
If, for every index i between 0 and the length of the shortest vector
|
|
argument, the set of elements @code{(vector-ref vec1 i)}
|
|
@code{(vector-ref vec2 i)} @dots{} satisfies @var{pred?},
|
|
@code{vector-every} returns the value that @var{pred?} returned for the
|
|
last set of elements, at the last index of the shortest vector.
|
|
Otherwise it returns @code{#f}. The iteration is strictly
|
|
left-to-right.
|
|
@end deffn
|
|
|
|
@node SRFI-43 Mutators
|
|
@subsubsection SRFI-43 Mutators
|
|
|
|
@deffn {Scheme Procedure} vector-set! vec i value
|
|
Assign the contents of the location at @var{i} in @var{vec} to
|
|
@var{value}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-swap! vec i j
|
|
Swap the values of the locations in @var{vec} at @var{i} and @var{j}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-fill! vec fill [start [end]]
|
|
Assign the value of every location in @var{vec} between @var{start} and
|
|
@var{end} to @var{fill}. @var{start} defaults to 0 and @var{end}
|
|
defaults to the length of @var{vec}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-reverse! vec [start [end]]
|
|
Destructively reverse the contents of @var{vec} between @var{start} and
|
|
@var{end}. @var{start} defaults to 0 and @var{end} defaults to the
|
|
length of @var{vec}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-copy! target tstart source [sstart [send]]
|
|
Copy a block of elements from @var{source} to @var{target}, both of
|
|
which must be vectors, starting in @var{target} at @var{tstart} and
|
|
starting in @var{source} at @var{sstart}, ending when (@var{send} -
|
|
@var{sstart}) elements have been copied. It is an error for
|
|
@var{target} to have a length less than (@var{tstart} + @var{send} -
|
|
@var{sstart}). @var{sstart} defaults to 0 and @var{send} defaults to
|
|
the length of @var{source}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-reverse-copy! target tstart source [sstart [send]]
|
|
Like @code{vector-copy!}, but this copies the elements in the reverse
|
|
order. It is an error if @var{target} and @var{source} are identical
|
|
vectors and the @var{target} and @var{source} ranges overlap; however,
|
|
if @var{tstart} = @var{sstart}, @code{vector-reverse-copy!} behaves as
|
|
@code{(vector-reverse! target tstart send)} would.
|
|
@end deffn
|
|
|
|
@node SRFI-43 Conversion
|
|
@subsubsection SRFI-43 Conversion
|
|
|
|
@deffn {Scheme Procedure} vector->list vec [start [end]]
|
|
Return a newly allocated list containing the elements in @var{vec}
|
|
between @var{start} and @var{end}. @var{start} defaults to 0 and
|
|
@var{end} defaults to the length of @var{vec}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} reverse-vector->list vec [start [end]]
|
|
Like @code{vector->list}, but the resulting list contains the specified
|
|
range of elements of @var{vec} in reverse order.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list->vector proper-list [start [end]]
|
|
Return a newly allocated vector of the elements from @var{proper-list}
|
|
with indices between @var{start} and @var{end}. @var{start} defaults to
|
|
0 and @var{end} defaults to the length of @var{proper-list}. Note that
|
|
SRFI 43 does not document the @var{start} and @var{end} arguments, but
|
|
both its reference implementation and Guile's implementation support
|
|
them.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} reverse-list->vector proper-list [start [end]]
|
|
Like @code{list->vector}, but the resulting vector contains the specified
|
|
range of elements of @var{proper-list} in reverse order. Note that SRFI
|
|
43 does not document the @var{start} and @var{end} arguments, but both
|
|
its reference implementation and Guile's implementation support them.
|
|
@end deffn
|
|
|
|
@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.
|
|
|
|
Guile also adds @code{promise?} to the list of exports, which is not
|
|
part of the official SRFI-45.
|
|
|
|
@deffn {Scheme Procedure} promise? obj
|
|
Return true if @var{obj} is an SRFI-45 promise, otherwise return false.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Syntax} delay expression
|
|
Takes an expression of arbitrary type @var{a} and returns a promise of
|
|
type @code{(Promise @var{a})} which at some point in the future may be
|
|
asked (by the @code{force} procedure) to evaluate the expression and
|
|
deliver the resulting value.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Syntax} lazy expression
|
|
Takes an expression of type @code{(Promise @var{a})} and returns a
|
|
promise of type @code{(Promise @var{a})} which at some point in the
|
|
future may be asked (by the @code{force} procedure) to evaluate the
|
|
expression and deliver the resulting promise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} force expression
|
|
Takes an argument of type @code{(Promise @var{a})} and returns a value
|
|
of type @var{a} as follows: If a value of type @var{a} has been computed
|
|
for the promise, this value is returned. Otherwise, the promise is
|
|
first evaluated, then overwritten by the obtained promise or value, and
|
|
then force is again applied (iteratively) to the promise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} eager expression
|
|
Takes an argument of type @var{a} and returns a value of type
|
|
@code{(Promise @var{a})}. As opposed to @code{delay}, the argument is
|
|
evaluated eagerly. Semantically, writing @code{(eager expression)} is
|
|
equivalent to writing
|
|
|
|
@lisp
|
|
(let ((value expression)) (delay value)).
|
|
@end lisp
|
|
|
|
However, the former is more efficient since it does not require
|
|
unnecessary creation and evaluation of thunks. We also have the
|
|
equivalence
|
|
|
|
@lisp
|
|
(delay expression) = (lazy (eager expression))
|
|
@end lisp
|
|
@end deffn
|
|
|
|
The following reduction rules may be helpful for reasoning about these
|
|
primitives. However, they do not express the memoization and memory
|
|
usage semantics specified above:
|
|
|
|
@lisp
|
|
(force (delay expression)) -> expression
|
|
(force (lazy expression)) -> (force expression)
|
|
(force (eager value)) -> value
|
|
@end lisp
|
|
|
|
@subsubheading Correct usage
|
|
|
|
We now provide a general recipe for using the primitives @{@code{lazy},
|
|
@code{delay}, @code{force}@} to express lazy algorithms in Scheme. The
|
|
transformation is best described by way of an example: Consider the
|
|
stream-filter algorithm, expressed in a hypothetical lazy language as
|
|
|
|
@lisp
|
|
(define (stream-filter p? s)
|
|
(if (null? s) '()
|
|
(let ((h (car s))
|
|
(t (cdr s)))
|
|
(if (p? h)
|
|
(cons h (stream-filter p? t))
|
|
(stream-filter p? t)))))
|
|
@end lisp
|
|
|
|
This algorithm can be expressed as follows in Scheme:
|
|
|
|
@lisp
|
|
(define (stream-filter p? s)
|
|
(lazy
|
|
(if (null? (force s)) (delay '())
|
|
(let ((h (car (force s)))
|
|
(t (cdr (force s))))
|
|
(if (p? h)
|
|
(delay (cons h (stream-filter p? t)))
|
|
(stream-filter p? t))))))
|
|
@end lisp
|
|
|
|
In other words, we
|
|
|
|
@itemize @bullet
|
|
@item
|
|
wrap all constructors (e.g., @code{'()}, @code{cons}) with @code{delay},
|
|
@item
|
|
apply @code{force} to arguments of deconstructors (e.g., @code{car},
|
|
@code{cdr} and @code{null?}),
|
|
@item
|
|
wrap procedure bodies with @code{(lazy ...)}.
|
|
@end itemize
|
|
|
|
@node SRFI-46
|
|
@subsection SRFI-46 Basic syntax-rules Extensions
|
|
@cindex SRFI-46
|
|
|
|
Guile's core @code{syntax-rules} supports the extensions specified by
|
|
SRFI-46/R7RS. Tail patterns have been supported since at least Guile
|
|
2.0, and custom ellipsis identifiers have been supported since Guile
|
|
2.0.10. @xref{Syntax Rules}.
|
|
|
|
@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 clause1 clause2 @dots{}
|
|
Require the features of @var{clause1} @var{clause2} @dots{} , 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{Conditionals,, Simple Conditional Evaluation}.
|
|
|
|
@node SRFI-62
|
|
@subsection SRFI-62 - S-expression comments.
|
|
@cindex SRFI-62
|
|
|
|
Starting from version 2.0, Guile's @code{read} supports SRFI-62/R7RS
|
|
S-expression comments by default.
|
|
|
|
@node SRFI-64
|
|
@subsection SRFI-64 - A Scheme API for test suites.
|
|
@cindex SRFI-64
|
|
|
|
See @uref{http://srfi.schemers.org/srfi-64/srfi-64.html, the
|
|
specification of SRFI-64}.
|
|
|
|
@node SRFI-67
|
|
@subsection SRFI-67 - Compare procedures
|
|
@cindex SRFI-67
|
|
|
|
See @uref{http://srfi.schemers.org/srfi-67/srfi-67.html, the
|
|
specification of SRFI-67}.
|
|
|
|
@node SRFI-69
|
|
@subsection SRFI-69 - Basic hash tables
|
|
@cindex SRFI-69
|
|
|
|
This is a portable wrapper around Guile's built-in hash table and weak
|
|
table support. @xref{Hash Tables}, for information on that built-in
|
|
support. Above that, this hash-table interface provides association
|
|
of equality and hash functions with tables at creation time, so
|
|
variants of each function are not required, as well as a procedure
|
|
that takes care of most uses for Guile hash table handles, which this
|
|
SRFI does not provide as such.
|
|
|
|
Access it with:
|
|
|
|
@lisp
|
|
(use-modules (srfi srfi-69))
|
|
@end lisp
|
|
|
|
@menu
|
|
* SRFI-69 Creating hash tables::
|
|
* SRFI-69 Accessing table items::
|
|
* SRFI-69 Table properties::
|
|
* SRFI-69 Hash table algorithms::
|
|
@end menu
|
|
|
|
@node SRFI-69 Creating hash tables
|
|
@subsubsection Creating hash tables
|
|
|
|
@deffn {Scheme Procedure} make-hash-table [equal-proc hash-proc #:weak weakness start-size]
|
|
Create and answer a new hash table with @var{equal-proc} as the
|
|
equality function and @var{hash-proc} as the hashing function.
|
|
|
|
By default, @var{equal-proc} is @code{equal?}. It can be any
|
|
two-argument procedure, and should answer whether two keys are the
|
|
same for this table's purposes.
|
|
|
|
By 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-71
|
|
@subsection SRFI-71 - Extended let-syntax for multiple values
|
|
@cindex SRFI-71
|
|
|
|
This SRFI shadows the forms for @code{let}, @code{let*}, and @code{letrec}
|
|
so that they may accept multiple values. For example:
|
|
|
|
@example
|
|
(use-modules (srfi srfi-71))
|
|
|
|
(let* ((x y (values 1 2))
|
|
(z (+ x y)))
|
|
(* z 2))
|
|
@result{} 6
|
|
@end example
|
|
|
|
See @uref{http://srfi.schemers.org/srfi-71/srfi-71.html, the
|
|
specification of SRFI-71}.
|
|
|
|
@node SRFI-87
|
|
@subsection SRFI-87 => in case clauses
|
|
@cindex SRFI-87
|
|
|
|
Starting from version 2.0.6, Guile's core @code{case} syntax supports
|
|
@code{=>} in clauses, as specified by SRFI-87/R7RS.
|
|
@xref{Conditionals}.
|
|
|
|
@node SRFI-88
|
|
@subsection SRFI-88 Keyword Objects
|
|
@cindex SRFI-88
|
|
@cindex keyword objects
|
|
|
|
@uref{http://srfi.schemers.org/srfi-88/srfi-88.html, SRFI-88} provides
|
|
@dfn{keyword objects}, which are equivalent to Guile's keywords
|
|
(@pxref{Keywords}). SRFI-88 keywords can be entered using the
|
|
@dfn{postfix keyword syntax}, which consists of an identifier followed
|
|
by @code{:} (@pxref{Scheme Read, @code{postfix} keyword syntax}).
|
|
SRFI-88 can be made available with:
|
|
|
|
@example
|
|
(use-modules (srfi srfi-88))
|
|
@end example
|
|
|
|
Doing so installs the right reader option for keyword syntax, using
|
|
@code{(read-set! keywords 'postfix)}. It also provides the procedures
|
|
described below.
|
|
|
|
@deffn {Scheme Procedure} keyword? obj
|
|
Return @code{#t} if @var{obj} is a keyword. This is the same procedure
|
|
as the same-named built-in procedure (@pxref{Keyword Procedures,
|
|
@code{keyword?}}).
|
|
|
|
@example
|
|
(keyword? foo:) @result{} #t
|
|
(keyword? 'foo:) @result{} #t
|
|
(keyword? "foo") @result{} #f
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} keyword->string kw
|
|
Return the name of @var{kw} as a string, i.e., without the trailing
|
|
colon. The returned string may not be modified, e.g., with
|
|
@code{string-set!}.
|
|
|
|
@example
|
|
(keyword->string foo:) @result{} "foo"
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string->keyword str
|
|
Return the keyword object whose name is @var{str}.
|
|
|
|
@example
|
|
(keyword->string (string->keyword "a b c")) @result{} "a b c"
|
|
@end example
|
|
@end deffn
|
|
|
|
@node SRFI-98
|
|
@subsection SRFI-98 Accessing environment variables.
|
|
@cindex SRFI-98
|
|
@cindex environment variables
|
|
|
|
This is a portable wrapper around Guile's built-in support for
|
|
interacting with the current environment, @xref{Runtime Environment}.
|
|
|
|
@deffn {Scheme Procedure} get-environment-variable name
|
|
Returns a string containing the value of the environment variable
|
|
given by the string @code{name}, or @code{#f} if the named
|
|
environment variable is not found. This is equivalent to
|
|
@code{(getenv name)}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} get-environment-variables
|
|
Returns the names and values of all the environment variables as an
|
|
association list in which both the keys and the values are strings.
|
|
@end deffn
|
|
|
|
@node SRFI-105
|
|
@subsection SRFI-105 Curly-infix expressions.
|
|
@cindex SRFI-105
|
|
@cindex curly-infix
|
|
@cindex curly-infix-and-bracket-lists
|
|
|
|
Guile's built-in reader includes support for SRFI-105 curly-infix
|
|
expressions. See @uref{http://srfi.schemers.org/srfi-105/srfi-105.html,
|
|
the specification of SRFI-105}. Some examples:
|
|
|
|
@example
|
|
@{n <= 5@} @result{} (<= n 5)
|
|
@{a + b + c@} @result{} (+ a b c)
|
|
@{a * @{b + c@}@} @result{} (* a (+ b c))
|
|
@{(- a) / b@} @result{} (/ (- a) b)
|
|
@{-(a) / b@} @result{} (/ (- a) b) as well
|
|
@{(f a b) + (g h)@} @result{} (+ (f a b) (g h))
|
|
@{f(a b) + g(h)@} @result{} (+ (f a b) (g h)) as well
|
|
@{f[a b] + g(h)@} @result{} (+ ($bracket-apply$ f a b) (g h))
|
|
'@{a + f(b) + x@} @result{} '(+ a (f b) x)
|
|
@{length(x) >= 6@} @result{} (>= (length x) 6)
|
|
@{n-1 + n-2@} @result{} (+ n-1 n-2)
|
|
@{n * factorial@{n - 1@}@} @result{} (* n (factorial (- n 1)))
|
|
@{@{a > 0@} and @{b >= 1@}@} @result{} (and (> a 0) (>= b 1))
|
|
@{f@{n - 1@}(x)@} @result{} ((f (- n 1)) x)
|
|
@{a . z@} @result{} ($nfx$ a . z)
|
|
@{a + b - c@} @result{} ($nfx$ a + b - c)
|
|
@end example
|
|
|
|
To enable curly-infix expressions within a file, place the reader
|
|
directive @code{#!curly-infix} before the first use of curly-infix
|
|
notation. To globally enable curly-infix expressions in Guile's reader,
|
|
set the @code{curly-infix} read option.
|
|
|
|
Guile also implements the following non-standard extension to SRFI-105:
|
|
if @code{curly-infix} is enabled and there is no other meaning assigned
|
|
to square brackets (i.e. the @code{square-brackets} read option is
|
|
turned off), then lists within square brackets are read as normal lists
|
|
but with the special symbol @code{$bracket-list$} added to the front.
|
|
To enable this combination of read options within a file, use the reader
|
|
directive @code{#!curly-infix-and-bracket-lists}. For example:
|
|
|
|
@example
|
|
[a b] @result{} ($bracket-list$ a b)
|
|
[a . b] @result{} ($bracket-list$ a . b)
|
|
@end example
|
|
|
|
|
|
For more information on reader options, @xref{Scheme Read}.
|
|
|
|
@node SRFI-111
|
|
@subsection SRFI-111 Boxes.
|
|
@cindex SRFI-111
|
|
|
|
@uref{http://srfi.schemers.org/srfi-111/srfi-111.html, SRFI-111}
|
|
provides boxes: objects with a single mutable cell.
|
|
|
|
@deffn {Scheme Procedure} box value
|
|
Return a newly allocated box whose contents is initialized to
|
|
@var{value}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} box? obj
|
|
Return true if @var{obj} is a box, otherwise return false.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} unbox box
|
|
Return the current contents of @var{box}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} set-box! box value
|
|
Set the contents of @var{box} to @var{value}.
|
|
@end deffn
|
|
|
|
@node SRFI-171
|
|
@subsection Transducers
|
|
@cindex SRFI-171
|
|
@cindex transducers
|
|
|
|
Some of the most common operations used in the Scheme language are those
|
|
transforming lists: map, filter, take and so on. They work well, are well
|
|
understood, and are used daily by most Scheme programmers. They are however not
|
|
general because they only work on lists, and they do not compose very well
|
|
since combining N of them builds @code{(- N 1)} intermediate lists.
|
|
|
|
Transducers are oblivious to what kind of process they are used in, and
|
|
are composable without building intermediate collections. This means we
|
|
can create a transducer that squares all odd numbers:
|
|
|
|
@example
|
|
(compose (tfilter odd?) (tmap (lambda (x) (* x x))))
|
|
@end example
|
|
|
|
and reuse it with lists, vectors, or in just about any context where
|
|
data flows in one direction. We could use it as a processing step for
|
|
asynchronous channels, with an event framework as a pre-processing step,
|
|
or even in lazy contexts where you pass a lazy collection and a
|
|
transducer to a function and get a new lazy collection back.
|
|
|
|
The traditional Scheme approach of having collection-specific procedures
|
|
is not changed. We instead specify a general form of transformations
|
|
that complement these procedures. The benefits are obvious: a clear,
|
|
well-understood way of describing common transformations in a way that
|
|
is faster than just chaining the collection-specific counterparts. For
|
|
guile in particular this means a lot better GC performance.
|
|
|
|
Notice however that @code{(compose @dots{})} composes transducers
|
|
left-to-right, due to how transducers are initiated.
|
|
|
|
@menu
|
|
* SRFI-171 General Discussion:: General information about transducers
|
|
* SRFI-171 Applying Transducers:: Documentation of collection-specific forms
|
|
* SRFI-171 Reducers:: Reducers specified by the SRFI
|
|
* SRFI-171 Transducers:: Transducers specified by the SRFI
|
|
* SRFI-171 Helpers:: Utilities for writing your own transducers
|
|
@end menu
|
|
|
|
@node SRFI-171 General Discussion
|
|
@subsubsection SRFI-171 General Discussion
|
|
@cindex transducers discussion
|
|
|
|
@subheading The concept of reducers
|
|
The central part of transducers are 3-arity reducing procedures.
|
|
|
|
@itemize
|
|
@item
|
|
no arguments: Produces the identity of the reducer.
|
|
|
|
@item
|
|
(result-so-far): completion. Returns @code{result-so-far} either with or
|
|
without transforming it first.
|
|
|
|
@item
|
|
(result-so-far input) combines @code{result-so-far} and @code{input} to produce
|
|
a new @code{result-so-far}.
|
|
@end itemize
|
|
|
|
In the case of a summing @code{+} reducer, the reducer would produce, in
|
|
arity order: @code{0}, @code{result-so-far}, @code{(+ result-so-far
|
|
input)}. This happens to be exactly what the regular @code{+} does.
|
|
|
|
@subheading The concept of transducers
|
|
A transducer is a one-arity procedure that takes a reducer and produces a
|
|
reducing function that behaves as follows:
|
|
|
|
@itemize
|
|
@item
|
|
no arguments: calls reducer with no arguments (producing its identity)
|
|
|
|
@item
|
|
(result-so-far): Maybe transform the result-so-far and call reducer with it.
|
|
|
|
@item
|
|
(result-so-far input) Maybe do something to input and maybe call the
|
|
reducer with result-so-far and the maybe-transformed input.
|
|
@end itemize
|
|
|
|
A simple example is as following:
|
|
|
|
@example
|
|
(list-transduce (tfilter odd?) + '(1 2 3 4 5)).
|
|
@end example
|
|
|
|
This first returns a transducer filtering all odd
|
|
elements, then it runs @code{+} without arguments to retrieve its
|
|
identity. It then starts the transduction by passing @code{+} to the
|
|
transducer returned by @code{(tfilter odd?)} which returns a reducing
|
|
function. It works not unlike reduce from SRFI 1, but also checks
|
|
whether one of the intermediate transducers returns a "reduced" value
|
|
(implemented as a SRFI 9 record), which means the reduction finished
|
|
early.
|
|
|
|
Because transducers compose and the final reduction is only executed in
|
|
the last step, composed transducers will not build any intermediate
|
|
result or collections. Although the normal way of thinking about
|
|
application of composed functions is right to left, due to how the
|
|
transduction is built it is applied left to right. @code{(compose
|
|
(tfilter odd?) (tmap sqrt))} will create a transducer that first filters
|
|
out any odd values and then computes the square root of the rest.
|
|
|
|
|
|
@subheading State
|
|
Even though transducers appear to be somewhat of a generalisation of
|
|
@code{map} and friends, this is not really true. Since transducers don't
|
|
know in which context they are being used, some transducers must keep
|
|
state where their collection-specific counterparts do not. The
|
|
transducers that keep state do so using hidden mutable state, and as
|
|
such all the caveats of mutation, parallelism, and multi-shot
|
|
continuations apply. Each transducer keeping state is clearly described
|
|
as doing so in the documentation.
|
|
|
|
@subheading Naming
|
|
|
|
Reducers exported from the transducers module are named as in their
|
|
SRFI-1 counterpart, but prepended with an r. Transducers also follow
|
|
that naming, but are prepended with a t.
|
|
|
|
|
|
@node SRFI-171 Applying Transducers
|
|
@subsubsection Applying Transducers
|
|
@cindex transducers applying
|
|
|
|
@deffn {Scheme Procedure} list-transduce xform f lst
|
|
@deffnx {Scheme Procedure} list-transduce xform f identity lst
|
|
Initialize the transducer @var{xform} by passing the reducer @var{f}
|
|
to it. If no identity is provided, @var{f} runs without arguments to
|
|
return the reducer identity. It then reduces over @var{lst} using the
|
|
identity as the seed.
|
|
|
|
If one of the transducers finishes early (such as @code{ttake} or
|
|
@code{tdrop}), it communicates this by returning a reduced value, which
|
|
in the guile implementation is just a value wrapped in a SRFI 9 record
|
|
type named ``reduced''. If such a value is returned by the transducer,
|
|
@code{list-transduce} must stop execution and return an unreduced value
|
|
immediately.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-transduce xform f vec
|
|
@deffnx {Scheme Procedure} vector-transduce xform f identity vec
|
|
@deffnx {Scheme Procedure} string-transduce xform f str
|
|
@deffnx {Scheme Procedure} string-transduce xform f identity str
|
|
@deffnx {Scheme Procedure} bytevector-u8-transduce xform f bv
|
|
@deffnx {Scheme Procedure} bytevector-u8-transduce xform f identity bv
|
|
@deffnx {Scheme Procedure} generator-transduce xform f gen
|
|
@deffnx {Scheme Procedure} generator-transduce xform f identity gen
|
|
|
|
Same as @code{list-transduce}, but for vectors, strings, u8-bytevectors
|
|
and SRFI-158-styled generators respectively.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} port-transduce xform f reader
|
|
@deffnx {Scheme Procedure} port-transduce xform f reader port
|
|
@deffnx {Scheme Procedure} port-transduce xform f identity reader port
|
|
|
|
Same as @code{list-transduce} but for ports. Called without a port, it
|
|
reduces over the results of applying @var{reader} until the EOF-object
|
|
is returned, presumably to read from @code{current-input-port}. With a
|
|
port @var{reader} is applied to @var{port} instead of without any
|
|
arguments. If @var{identity} is provided, that is used as the initial
|
|
identity in the reduction.
|
|
@end deffn
|
|
|
|
|
|
@node SRFI-171 Reducers
|
|
@subsubsection Reducers
|
|
@cindex transducers reducers
|
|
|
|
@deffn {Scheme Procedure} rcons
|
|
a simple consing reducer. When called without values, it returns its
|
|
identity, @code{'()}. With one value, which will be a list, it reverses
|
|
the list (using @code{reverse!}). When called with two values, it conses
|
|
the second value to the first.
|
|
|
|
@example
|
|
(list-transduce (tmap (lambda (x) (+ x 1)) rcons (list 0 1 2 3))
|
|
@result{} (1 2 3 4)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} reverse-rcons
|
|
same as rcons, but leaves the values in their reversed order.
|
|
@example
|
|
(list-transduce (tmap (lambda (x) (+ x 1))) reverse-rcons (list 0 1 2 3))
|
|
@result{} (4 3 2 1)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} rany pred?
|
|
The reducer version of any. Returns @code{(reduced (pred? value))} if
|
|
any @code{(pred? value)} returns non-#f. The identity is #f.
|
|
|
|
@example
|
|
(list-transduce (tmap (lambda (x) (+ x 1))) (rany odd?) (list 1 3 5))
|
|
@result{} #f
|
|
|
|
(list-transduce (tmap (lambda (x) (+ x 1))) (rany odd?) (list 1 3 4 5))
|
|
@result{} #t
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} revery pred?
|
|
The reducer version of every. Stops the transduction and returns
|
|
@code{(reduced #f)} if any @code{(pred? value)} returns #f. If every
|
|
@code{(pred? value)} returns true, it returns the result of the last
|
|
invocation of @code{(pred? value)}. The identity is #t.
|
|
|
|
@example
|
|
(list-transduce
|
|
(tmap (lambda (x) (+ x 1)))
|
|
(revery (lambda (v) (if (odd? v) v #f)))
|
|
(list 2 4 6))
|
|
@result{} 7
|
|
|
|
(list-transduce (tmap (lambda (x) (+ x 1)) (revery odd?) (list 2 4 5 6))
|
|
@result{} #f
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} rcount
|
|
A simple counting reducer. Counts the values that pass through the
|
|
transduction.
|
|
@example
|
|
(list-transduce (tfilter odd?) rcount (list 1 2 3 4)) @result{} 2.
|
|
@end example
|
|
@end deffn
|
|
|
|
|
|
@node SRFI-171 Transducers
|
|
@subsubsection Transducers
|
|
@cindex transducers transducers
|
|
|
|
@deffn {Scheme Procedure} tmap proc
|
|
Returns a transducer that applies @var{proc} to all values. Stateless.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tfilter pred?
|
|
Returns a transducer that removes values for which @var{pred?} returns #f.
|
|
|
|
Stateless.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tremove pred?
|
|
Returns a transducer that removes values for which @var{pred?} returns non-#f.
|
|
|
|
Stateless
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tfilter-map proc
|
|
The same as @code{(compose (tmap proc) (tfilter values))}. Stateless.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} treplace mapping
|
|
The argument @var{mapping} is an association list (using @code{equal?}
|
|
to compare keys), a hash-table, a one-argument procedure taking one
|
|
argument and either producing that same argument or a replacement value.
|
|
|
|
Returns a transducer which checks for the presence of any value passed
|
|
through it in mapping. If a mapping is found, the value of that mapping
|
|
is returned, otherwise it just returns the original value.
|
|
|
|
Does not keep internal state, but modifying the mapping while it's in
|
|
use by treplace is an error.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tdrop n
|
|
Returns a transducer that discards the first @var{n} values.
|
|
|
|
Stateful.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} ttake n
|
|
Returns a transducer that discards all values and stops the transduction
|
|
after the first @var{n} values have been let through. Any subsequent values
|
|
are ignored.
|
|
|
|
Stateful.
|
|
@end deffn
|
|
|
|
|
|
@deffn {Scheme Procedure} tdrop-while pred?
|
|
Returns a transducer that discards the first values for which
|
|
@var{pred?} returns true.
|
|
|
|
Stateful.
|
|
@end deffn
|
|
|
|
|
|
@deffn {Scheme Procedure} ttake-while pred?
|
|
@deffnx {Scheme Procedure} ttake-while pred? retf
|
|
Returns a transducer that stops the transduction after @var{pred?} has
|
|
returned #f. Any subsequent values are ignored and the last successful
|
|
value is returned. @var{retf} is a function that gets called whenever
|
|
@var{pred?} returns false. The arguments passed are the result so far
|
|
and the input for which pred? returns @code{#f}. The default function is
|
|
@code{(lambda (result input) result)}.
|
|
|
|
Stateful.
|
|
@end deffn
|
|
|
|
|
|
@deffn {Scheme Procedure} tconcatenate
|
|
tconcatenate @emph{is} a transducer that concatenates the content of
|
|
each value (that must be a list) into the reduction.
|
|
@example
|
|
(list-transduce tconcatenate rcons '((1 2) (3 4 5) (6 (7 8) 9)))
|
|
@result{} (1 2 3 4 5 6 (7 8) 9)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tappend-map proc
|
|
The same as @code{(compose (tmap proc) tconcatenate)}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tflatten
|
|
tflatten @emph{is} a transducer that flattens an input consisting of lists.
|
|
|
|
@example
|
|
(list-transduce tflatten rcons '((1 2) 3 (4 (5 6) 7 8) 9)
|
|
@result{} (1 2 3 4 5 6 7 8 9)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tdelete-neighbor-duplicates
|
|
@deffnx {Scheme Procedure} tdelete-neighbor-duplicates equality-predicate
|
|
Returns a transducer that removes any directly following duplicate
|
|
elements. The default @var{equality-predicate} is @code{equal?}.
|
|
|
|
Stateful.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tdelete-duplicates
|
|
@deffnx {Scheme Procedure} tdelete-duplicates equality-predicate
|
|
Returns a transducer that removes any subsequent duplicate elements
|
|
compared using @var{equality-predicate}. The default
|
|
@var{equality-predicate} is @code{equal?}.
|
|
|
|
Stateful.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tsegment n
|
|
Returns a transducer that groups inputs into lists of @var{n} elements.
|
|
When the transduction stops, it flushes any remaining collection, even
|
|
if it contains fewer than @var{n} elements.
|
|
|
|
Stateful.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tpartition pred?
|
|
Returns a transducer that groups inputs in lists by whenever
|
|
@code{(pred? input)} changes value.
|
|
|
|
Stateful.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tadd-between value
|
|
Returns a transducer which interposes @var{value} between each value
|
|
and the next. This does not compose gracefully with transducers like
|
|
@code{ttake}, as you might end up ending the transduction on
|
|
@code{value}.
|
|
|
|
Stateful.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tenumerate
|
|
@deffnx {Scheme Procedure} tenumerate start
|
|
Returns a transducer that indexes values passed through it, starting at
|
|
@var{start}, which defaults to 0. The indexing is done through cons
|
|
pairs like @code{(index . input)}.
|
|
|
|
@example
|
|
(list-transduce (tenumerate 1) rcons (list 'first 'second 'third))
|
|
@result{} ((1 . first) (2 . second) (3 . third))
|
|
@end example
|
|
|
|
Stateful.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tlog
|
|
@deffnx {Scheme Procedure} tlog logger
|
|
Returns a transducer that can be used to log or print values and
|
|
results. The result of the @var{logger} procedure is discarded. The
|
|
default @var{logger} is @code{(lambda (result input) (write input)
|
|
(newline))}.
|
|
|
|
Stateless.
|
|
@end deffn
|
|
|
|
@subheading Guile-specific transducers
|
|
These transducers are available in the @code{(srfi srfi-171 gnu)}
|
|
library, and are provided outside the standard described by the SRFI-171
|
|
document.
|
|
|
|
@deffn {Scheme Procedure} tbatch reducer
|
|
@deffnx {Scheme Procedure} tbatch transducer reducer
|
|
A batching transducer that accumulates results using @var{reducer} or
|
|
@code{((transducer) reducer)} until it returns a reduced value. This can
|
|
be used to generalize something like @code{tsegment}:
|
|
|
|
@example
|
|
;; This behaves exactly like (tsegment 4).
|
|
(list-transduce (tbatch (ttake 4) rcons) rcons (iota 10))
|
|
@result{} ((0 1 2 3) (4 5 6 7) (8 9))
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} tfold reducer
|
|
@deffnx {Scheme Procedure} tfold reducer seed
|
|
|
|
A folding transducer that yields the result of @code{(reducer seed
|
|
value)}, saving its result between iterations.
|
|
|
|
@example
|
|
(list-transduce (tfold +) rcons (iota 10))
|
|
@result{} (0 1 3 6 10 15 21 28 36 45)
|
|
@end example
|
|
@end deffn
|
|
|
|
|
|
@node SRFI-171 Helpers
|
|
@subsubsection Helper functions for writing transducers
|
|
@cindex transducers helpers
|
|
|
|
These functions are in the @code{(srfi srfi-171 meta)} module and are only
|
|
usable when you want to write your own transducers.
|
|
|
|
@deffn {Scheme Procedure} reduced value
|
|
Wraps a value in a @code{<reduced>} container, signalling that the
|
|
reduction should stop.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} reduced? value
|
|
Returns #t if value is a @code{<reduced>} record.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} unreduce reduced-container
|
|
Returns the value in reduced-container.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} ensure-reduced value
|
|
Wraps value in a @code{<reduced>} container if it is not already reduced.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} preserving-reduced reducer
|
|
Wraps @code{reducer} in another reducer that encapsulates any returned
|
|
reduced value in another reduced container. This is useful in places
|
|
where you re-use a reducer with [collection]-reduce. If the reducer
|
|
returns a reduced value, [collection]-reduce unwraps it. Unless handled,
|
|
this leads to the reduction continuing.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list-reduce f identity lst
|
|
The reducing function used internally by @code{list-transduce}. @var{f}
|
|
is a reducer as returned by a transducer. @var{identity} is the
|
|
identity (sometimes called "seed") of the reduction. @var{lst} is a
|
|
list. If @var{f} returns a reduced value, the reduction stops
|
|
immediately and the unreduced value is returned.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-reduce f identity vec
|
|
The vector version of list-reduce.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-reduce f identity str
|
|
The string version of list-reduce.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector-u8-reduce f identity bv
|
|
The bytevector-u8 version of list-reduce.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} port-reduce f identity reader port
|
|
The port version of list-reduce. It reduces over port using reader
|
|
until reader returns the EOF object.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} generator-reduce f identity gen
|
|
The generator version of list-reduce. It reduces over @code{gen} until
|
|
it returns the EOF object
|
|
@end deffn
|
|
|
|
@c srfi-modules.texi ends here
|
|
|
|
@c Local Variables:
|
|
@c TeX-master: "guile.texi"
|
|
@c End:
|