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>
10287 lines
370 KiB
Text
10287 lines
370 KiB
Text
@c -*-texinfo-*-
|
|
@c This is part of the GNU Guile Reference Manual.
|
|
@c Copyright (C) 1996, 1997, 2000-2004, 2006-2017, 2019-2020, 2022-2023
|
|
@c Free Software Foundation, Inc.
|
|
@c See the file guile.texi for copying conditions.
|
|
|
|
@node Data Types
|
|
@section Data Types
|
|
|
|
Guile's data types form a powerful built-in library of representations
|
|
and functionality that you can apply to your problem domain. This
|
|
chapter surveys the data types built-in to Guile, from the simple to the
|
|
complex.
|
|
|
|
@menu
|
|
* Booleans:: True/false values.
|
|
* Numbers:: Numerical data types.
|
|
* Characters:: Single characters.
|
|
* Character Sets:: Sets of characters.
|
|
* Strings:: Sequences of characters.
|
|
* Symbols:: Symbols.
|
|
* Keywords:: Self-quoting, customizable display keywords.
|
|
* Pairs:: Scheme's basic building block.
|
|
* Lists:: Special list functions supported by Guile.
|
|
* Vectors:: One-dimensional arrays of Scheme objects.
|
|
* Bit Vectors:: Vectors of bits.
|
|
* Bytevectors:: Sequences of bytes.
|
|
* Arrays:: Multidimensional matrices.
|
|
* VLists:: Vector-like lists.
|
|
* Record Overview:: Walking through the maze of record APIs.
|
|
* SRFI-9 Records:: The standard, recommended record API.
|
|
* Records:: Guile's historical record API.
|
|
* Structures:: Low-level record representation.
|
|
* Dictionary Types:: About dictionary types in general.
|
|
* Association Lists:: List-based dictionaries.
|
|
* VHashes:: VList-based dictionaries.
|
|
* Hash Tables:: Table-based dictionaries.
|
|
* Other Types:: Other sections describe data types too.
|
|
@end menu
|
|
|
|
|
|
@node Booleans
|
|
@subsection Booleans
|
|
@tpindex Booleans
|
|
|
|
The two boolean values are @code{#t} for true and @code{#f} for false.
|
|
They can also be written as @code{#true} and @code{#false}, as per R7RS.
|
|
|
|
Boolean values are returned by predicate procedures, such as the general
|
|
equality predicates @code{eq?}, @code{eqv?} and @code{equal?}
|
|
(@pxref{Equality}) and numerical and string comparison operators like
|
|
@code{string=?} (@pxref{String Comparison}) and @code{<=}
|
|
(@pxref{Comparison}).
|
|
|
|
@lisp
|
|
(<= 3 8)
|
|
@result{} #t
|
|
|
|
(<= 3 -3)
|
|
@result{} #f
|
|
|
|
(equal? "house" "houses")
|
|
@result{} #f
|
|
|
|
(eq? #f #f)
|
|
@result{}
|
|
#t
|
|
@end lisp
|
|
|
|
In test condition contexts like @code{if} and @code{cond}
|
|
(@pxref{Conditionals}), where a group of subexpressions will be
|
|
evaluated only if a @var{condition} expression evaluates to ``true'',
|
|
``true'' means any value at all except @code{#f}.
|
|
|
|
@lisp
|
|
(if #t "yes" "no")
|
|
@result{} "yes"
|
|
|
|
(if 0 "yes" "no")
|
|
@result{} "yes"
|
|
|
|
(if #f "yes" "no")
|
|
@result{} "no"
|
|
@end lisp
|
|
|
|
A result of this asymmetry is that typical Scheme source code more often
|
|
uses @code{#f} explicitly than @code{#t}: @code{#f} is necessary to
|
|
represent an @code{if} or @code{cond} false value, whereas @code{#t} is
|
|
not necessary to represent an @code{if} or @code{cond} true value.
|
|
|
|
It is important to note that @code{#f} is @strong{not} equivalent to any
|
|
other Scheme value. In particular, @code{#f} is not the same as the
|
|
number 0 (like in C and C++), and not the same as the ``empty list''
|
|
(like in some Lisp dialects).
|
|
|
|
In C, the two Scheme boolean values are available as the two constants
|
|
@code{SCM_BOOL_T} for @code{#t} and @code{SCM_BOOL_F} for @code{#f}.
|
|
Care must be taken with the false value @code{SCM_BOOL_F}: it is not
|
|
false when used in C conditionals. In order to test for it, use
|
|
@code{scm_is_false} or @code{scm_is_true}.
|
|
|
|
@rnindex not
|
|
@deffn {Scheme Procedure} not x
|
|
@deffnx {C Function} scm_not (x)
|
|
Return @code{#t} if @var{x} is @code{#f}, else return @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex boolean?
|
|
@deffn {Scheme Procedure} boolean? obj
|
|
@deffnx {C Function} scm_boolean_p (obj)
|
|
Return @code{#t} if @var{obj} is either @code{#t} or @code{#f}, else
|
|
return @code{#f}.
|
|
@end deffn
|
|
|
|
@deftypevr {C Macro} SCM SCM_BOOL_T
|
|
The @code{SCM} representation of the Scheme object @code{#t}.
|
|
@end deftypevr
|
|
|
|
@deftypevr {C Macro} SCM SCM_BOOL_F
|
|
The @code{SCM} representation of the Scheme object @code{#f}.
|
|
@end deftypevr
|
|
|
|
@deftypefn {C Function} int scm_is_true (SCM obj)
|
|
Return @code{0} if @var{obj} is @code{#f}, else return @code{1}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} int scm_is_false (SCM obj)
|
|
Return @code{1} if @var{obj} is @code{#f}, else return @code{0}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} int scm_is_bool (SCM obj)
|
|
Return @code{1} if @var{obj} is either @code{#t} or @code{#f}, else
|
|
return @code{0}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_from_bool (int val)
|
|
Return @code{#f} if @var{val} is @code{0}, else return @code{#t}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} int scm_to_bool (SCM val)
|
|
Return @code{1} if @var{val} is @code{SCM_BOOL_T}, return @code{0}
|
|
when @var{val} is @code{SCM_BOOL_F}, else signal a `wrong type' error.
|
|
|
|
You should probably use @code{scm_is_true} instead of this function
|
|
when you just want to test a @code{SCM} value for trueness.
|
|
@end deftypefn
|
|
|
|
@node Numbers
|
|
@subsection Numerical data types
|
|
@tpindex Numbers
|
|
|
|
Guile supports a rich ``tower'' of numerical types --- integer,
|
|
rational, real and complex --- and provides an extensive set of
|
|
mathematical and scientific functions for operating on numerical
|
|
data. This section of the manual documents those types and functions.
|
|
|
|
You may also find it illuminating to read R5RS's presentation of numbers
|
|
in Scheme, which is particularly clear and accessible: see
|
|
@ref{Numbers,,,r5rs,R5RS}.
|
|
|
|
@menu
|
|
* Numerical Tower:: Scheme's numerical "tower".
|
|
* Integers:: Whole numbers.
|
|
* Reals and Rationals:: Real and rational numbers.
|
|
* Complex Numbers:: Complex numbers.
|
|
* Exactness:: Exactness and inexactness.
|
|
* Number Syntax:: Read syntax for numerical data.
|
|
* Integer Operations:: Operations on integer values.
|
|
* Comparison:: Comparison predicates.
|
|
* Conversion:: Converting numbers to and from strings.
|
|
* Complex:: Complex number operations.
|
|
* Arithmetic:: Arithmetic functions.
|
|
* Scientific:: Scientific functions.
|
|
* Bitwise Operations:: Logical AND, OR, NOT, and so on.
|
|
* Random:: Random number generation.
|
|
@end menu
|
|
|
|
|
|
@node Numerical Tower
|
|
@subsubsection Scheme's Numerical ``Tower''
|
|
@rnindex number?
|
|
|
|
Scheme's numerical ``tower'' consists of the following categories of
|
|
numbers:
|
|
|
|
@table @dfn
|
|
@item integers
|
|
Whole numbers, positive or negative; e.g.@: --5, 0, 18.
|
|
|
|
@item rationals
|
|
The set of numbers that can be expressed as @math{@var{p}/@var{q}}
|
|
where @var{p} and @var{q} are integers; e.g.@: @math{9/16} works, but
|
|
pi (an irrational number) doesn't. These include integers
|
|
(@math{@var{n}/1}).
|
|
|
|
@item real numbers
|
|
The set of numbers that describes all possible positions along a
|
|
one-dimensional line. This includes rationals as well as irrational
|
|
numbers.
|
|
|
|
@item complex numbers
|
|
The set of numbers that describes all possible positions in a two
|
|
dimensional space. This includes real as well as imaginary numbers
|
|
(@math{@var{a}+@var{b}i}, where @var{a} is the @dfn{real part},
|
|
@var{b} is the @dfn{imaginary part}, and @math{i} is the square root of
|
|
@minus{}1.)
|
|
@end table
|
|
|
|
It is called a tower because each category ``sits on'' the one that
|
|
follows it, in the sense that every integer is also a rational, every
|
|
rational is also real, and every real number is also a complex number
|
|
(but with zero imaginary part).
|
|
|
|
In addition to the classification into integers, rationals, reals and
|
|
complex numbers, Scheme also distinguishes between whether a number is
|
|
represented exactly or not. For example, the result of
|
|
@m{2\sin(\pi/4),2*sin(pi/4)} is exactly @m{\sqrt{2},2^(1/2)}, but Guile
|
|
can represent neither @m{\pi/4,pi/4} nor @m{\sqrt{2},2^(1/2)} exactly.
|
|
Instead, it stores an inexact approximation, using the C type
|
|
@code{double}.
|
|
|
|
Guile can represent exact rationals of any magnitude, inexact
|
|
rationals that fit into a C @code{double}, and inexact complex numbers
|
|
with @code{double} real and imaginary parts.
|
|
|
|
The @code{number?} predicate may be applied to any Scheme value to
|
|
discover whether the value is any of the supported numerical types.
|
|
|
|
@deffn {Scheme Procedure} number? obj
|
|
@deffnx {C Function} scm_number_p (obj)
|
|
Return @code{#t} if @var{obj} is any kind of number, else @code{#f}.
|
|
@end deffn
|
|
|
|
For example:
|
|
|
|
@lisp
|
|
(number? 3)
|
|
@result{} #t
|
|
|
|
(number? "hello there!")
|
|
@result{} #f
|
|
|
|
(define pi 3.141592654)
|
|
(number? pi)
|
|
@result{} #t
|
|
@end lisp
|
|
|
|
@deftypefn {C Function} int scm_is_number (SCM obj)
|
|
This is equivalent to @code{scm_is_true (scm_number_p (obj))}.
|
|
@end deftypefn
|
|
|
|
The next few subsections document each of Guile's numerical data types
|
|
in detail.
|
|
|
|
@node Integers
|
|
@subsubsection Integers
|
|
|
|
@tpindex Integer numbers
|
|
|
|
@rnindex integer?
|
|
|
|
Integers are whole numbers, that is numbers with no fractional part,
|
|
such as 2, 83, and @minus{}3789.
|
|
|
|
Integers in Guile can be arbitrarily big, as shown by the following
|
|
example.
|
|
|
|
@lisp
|
|
(define (factorial n)
|
|
(let loop ((n n) (product 1))
|
|
(if (= n 0)
|
|
product
|
|
(loop (- n 1) (* product n)))))
|
|
|
|
(factorial 3)
|
|
@result{} 6
|
|
|
|
(factorial 20)
|
|
@result{} 2432902008176640000
|
|
|
|
(- (factorial 45))
|
|
@result{} -119622220865480194561963161495657715064383733760000000000
|
|
@end lisp
|
|
|
|
Readers whose background is in programming languages where integers are
|
|
limited by the need to fit into just 4 or 8 bytes of memory may find
|
|
this surprising, or suspect that Guile's representation of integers is
|
|
inefficient. In fact, Guile achieves a near optimal balance of
|
|
convenience and efficiency by using the host computer's native
|
|
representation of integers where possible, and a more general
|
|
representation where the required number does not fit in the native
|
|
form. Conversion between these two representations is automatic and
|
|
completely invisible to the Scheme level programmer.
|
|
|
|
C has a host of different integer types, and Guile offers a host of
|
|
functions to convert between them and the @code{SCM} representation.
|
|
For example, a C @code{int} can be handled with @code{scm_to_int} and
|
|
@code{scm_from_int}. Guile also defines a few C integer types of its
|
|
own, to help with differences between systems.
|
|
|
|
C integer types that are not covered can be handled with the generic
|
|
@code{scm_to_signed_integer} and @code{scm_from_signed_integer} for
|
|
signed types, or with @code{scm_to_unsigned_integer} and
|
|
@code{scm_from_unsigned_integer} for unsigned types.
|
|
|
|
Scheme integers can be exact and inexact. For example, a number
|
|
written as @code{3.0} with an explicit decimal-point is inexact, but
|
|
it is also an integer. The functions @code{integer?} and
|
|
@code{scm_is_integer} report true for such a number, but the functions
|
|
@code{exact-integer?}, @code{scm_is_exact_integer},
|
|
@code{scm_is_signed_integer}, and @code{scm_is_unsigned_integer} only
|
|
allow exact integers and thus report false. Likewise, the conversion
|
|
functions like @code{scm_to_signed_integer} only accept exact
|
|
integers.
|
|
|
|
The motivation for this behavior is that the inexactness of a number
|
|
should not be lost silently. If you want to allow inexact integers,
|
|
you can explicitly insert a call to @code{inexact->exact} or to its C
|
|
equivalent @code{scm_inexact_to_exact}. (Only inexact integers will
|
|
be converted by this call into exact integers; inexact non-integers
|
|
will become exact fractions.)
|
|
|
|
@deffn {Scheme Procedure} integer? x
|
|
@deffnx {C Function} scm_integer_p (x)
|
|
Return @code{#t} if @var{x} is an exact or inexact integer number, else
|
|
return @code{#f}.
|
|
|
|
@lisp
|
|
(integer? 487)
|
|
@result{} #t
|
|
|
|
(integer? 3.0)
|
|
@result{} #t
|
|
|
|
(integer? -3.4)
|
|
@result{} #f
|
|
|
|
(integer? +inf.0)
|
|
@result{} #f
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_integer (SCM x)
|
|
This is equivalent to @code{scm_is_true (scm_integer_p (x))}.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} exact-integer? x
|
|
@deffnx {C Function} scm_exact_integer_p (x)
|
|
Return @code{#t} if @var{x} is an exact integer number, else
|
|
return @code{#f}.
|
|
|
|
@lisp
|
|
(exact-integer? 37)
|
|
@result{} #t
|
|
|
|
(exact-integer? 3.0)
|
|
@result{} #f
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_exact_integer (SCM x)
|
|
This is equivalent to @code{scm_is_true (scm_exact_integer_p (x))}.
|
|
@end deftypefn
|
|
|
|
@defvr {C Type} scm_t_int8
|
|
@defvrx {C Type} scm_t_uint8
|
|
@defvrx {C Type} scm_t_int16
|
|
@defvrx {C Type} scm_t_uint16
|
|
@defvrx {C Type} scm_t_int32
|
|
@defvrx {C Type} scm_t_uint32
|
|
@defvrx {C Type} scm_t_int64
|
|
@defvrx {C Type} scm_t_uint64
|
|
@defvrx {C Type} scm_t_intmax
|
|
@defvrx {C Type} scm_t_uintmax
|
|
The C types are equivalent to the corresponding ISO C types but are
|
|
defined on all platforms, with the exception of @code{scm_t_int64} and
|
|
@code{scm_t_uint64}, which are only defined when a 64-bit type is
|
|
available. For example, @code{scm_t_int8} is equivalent to
|
|
@code{int8_t}.
|
|
|
|
You can regard these definitions as a stop-gap measure until all
|
|
platforms provide these types. If you know that all the platforms
|
|
that you are interested in already provide these types, it is better
|
|
to use them directly instead of the types provided by Guile.
|
|
@end defvr
|
|
|
|
@deftypefn {C Function} int scm_is_signed_integer (SCM x, scm_t_intmax min, scm_t_intmax max)
|
|
@deftypefnx {C Function} int scm_is_unsigned_integer (SCM x, scm_t_uintmax min, scm_t_uintmax max)
|
|
Return @code{1} when @var{x} represents an exact integer that is
|
|
between @var{min} and @var{max}, inclusive.
|
|
|
|
These functions can be used to check whether a @code{SCM} value will
|
|
fit into a given range, such as the range of a given C integer type.
|
|
If you just want to convert a @code{SCM} value to a given C integer
|
|
type, use one of the conversion functions directly.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} scm_t_intmax scm_to_signed_integer (SCM x, scm_t_intmax min, scm_t_intmax max)
|
|
@deftypefnx {C Function} scm_t_uintmax scm_to_unsigned_integer (SCM x, scm_t_uintmax min, scm_t_uintmax max)
|
|
When @var{x} represents an exact integer that is between @var{min} and
|
|
@var{max} inclusive, return that integer. Else signal an error,
|
|
either a `wrong-type' error when @var{x} is not an exact integer, or
|
|
an `out-of-range' error when it doesn't fit the given range.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_from_signed_integer (scm_t_intmax x)
|
|
@deftypefnx {C Function} SCM scm_from_unsigned_integer (scm_t_uintmax x)
|
|
Return the @code{SCM} value that represents the integer @var{x}. This
|
|
function will always succeed and will always return an exact number.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} char scm_to_char (SCM x)
|
|
@deftypefnx {C Function} {signed char} scm_to_schar (SCM x)
|
|
@deftypefnx {C Function} {unsigned char} scm_to_uchar (SCM x)
|
|
@deftypefnx {C Function} short scm_to_short (SCM x)
|
|
@deftypefnx {C Function} {unsigned short} scm_to_ushort (SCM x)
|
|
@deftypefnx {C Function} int scm_to_int (SCM x)
|
|
@deftypefnx {C Function} {unsigned int} scm_to_uint (SCM x)
|
|
@deftypefnx {C Function} long scm_to_long (SCM x)
|
|
@deftypefnx {C Function} {unsigned long} scm_to_ulong (SCM x)
|
|
@deftypefnx {C Function} {long long} scm_to_long_long (SCM x)
|
|
@deftypefnx {C Function} {unsigned long long} scm_to_ulong_long (SCM x)
|
|
@deftypefnx {C Function} size_t scm_to_size_t (SCM x)
|
|
@deftypefnx {C Function} ssize_t scm_to_ssize_t (SCM x)
|
|
@deftypefnx {C Function} scm_t_uintptr scm_to_uintptr_t (SCM x)
|
|
@deftypefnx {C Function} scm_t_ptrdiff scm_to_ptrdiff_t (SCM x)
|
|
@deftypefnx {C Function} scm_t_int8 scm_to_int8 (SCM x)
|
|
@deftypefnx {C Function} scm_t_uint8 scm_to_uint8 (SCM x)
|
|
@deftypefnx {C Function} scm_t_int16 scm_to_int16 (SCM x)
|
|
@deftypefnx {C Function} scm_t_uint16 scm_to_uint16 (SCM x)
|
|
@deftypefnx {C Function} scm_t_int32 scm_to_int32 (SCM x)
|
|
@deftypefnx {C Function} scm_t_uint32 scm_to_uint32 (SCM x)
|
|
@deftypefnx {C Function} scm_t_int64 scm_to_int64 (SCM x)
|
|
@deftypefnx {C Function} scm_t_uint64 scm_to_uint64 (SCM x)
|
|
@deftypefnx {C Function} scm_t_intmax scm_to_intmax (SCM x)
|
|
@deftypefnx {C Function} scm_t_uintmax scm_to_uintmax (SCM x)
|
|
@deftypefnx {C Function} scm_t_intptr scm_to_intptr_t (SCM x)
|
|
@deftypefnx {C Function} scm_t_uintptr scm_to_uintptr_t (SCM x)
|
|
When @var{x} represents an exact integer that fits into the indicated
|
|
C type, return that integer. Else signal an error, either a
|
|
`wrong-type' error when @var{x} is not an exact integer, or an
|
|
`out-of-range' error when it doesn't fit the given range.
|
|
|
|
The functions @code{scm_to_long_long}, @code{scm_to_ulong_long},
|
|
@code{scm_to_int64}, and @code{scm_to_uint64} are only available when
|
|
the corresponding types are.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_from_char (char x)
|
|
@deftypefnx {C Function} SCM scm_from_schar (signed char x)
|
|
@deftypefnx {C Function} SCM scm_from_uchar (unsigned char x)
|
|
@deftypefnx {C Function} SCM scm_from_short (short x)
|
|
@deftypefnx {C Function} SCM scm_from_ushort (unsigned short x)
|
|
@deftypefnx {C Function} SCM scm_from_int (int x)
|
|
@deftypefnx {C Function} SCM scm_from_uint (unsigned int x)
|
|
@deftypefnx {C Function} SCM scm_from_long (long x)
|
|
@deftypefnx {C Function} SCM scm_from_ulong (unsigned long x)
|
|
@deftypefnx {C Function} SCM scm_from_long_long (long long x)
|
|
@deftypefnx {C Function} SCM scm_from_ulong_long (unsigned long long x)
|
|
@deftypefnx {C Function} SCM scm_from_size_t (size_t x)
|
|
@deftypefnx {C Function} SCM scm_from_ssize_t (ssize_t x)
|
|
@deftypefnx {C Function} SCM scm_from_uintptr_t (uintptr_t x)
|
|
@deftypefnx {C Function} SCM scm_from_ptrdiff_t (scm_t_ptrdiff x)
|
|
@deftypefnx {C Function} SCM scm_from_int8 (scm_t_int8 x)
|
|
@deftypefnx {C Function} SCM scm_from_uint8 (scm_t_uint8 x)
|
|
@deftypefnx {C Function} SCM scm_from_int16 (scm_t_int16 x)
|
|
@deftypefnx {C Function} SCM scm_from_uint16 (scm_t_uint16 x)
|
|
@deftypefnx {C Function} SCM scm_from_int32 (scm_t_int32 x)
|
|
@deftypefnx {C Function} SCM scm_from_uint32 (scm_t_uint32 x)
|
|
@deftypefnx {C Function} SCM scm_from_int64 (scm_t_int64 x)
|
|
@deftypefnx {C Function} SCM scm_from_uint64 (scm_t_uint64 x)
|
|
@deftypefnx {C Function} SCM scm_from_intmax (scm_t_intmax x)
|
|
@deftypefnx {C Function} SCM scm_from_uintmax (scm_t_uintmax x)
|
|
@deftypefnx {C Function} SCM scm_from_intptr_t (scm_t_intptr x)
|
|
@deftypefnx {C Function} SCM scm_from_uintptr_t (scm_t_uintptr x)
|
|
Return the @code{SCM} value that represents the integer @var{x}.
|
|
These functions will always succeed and will always return an exact
|
|
number.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} void scm_to_mpz (SCM val, mpz_t rop)
|
|
Assign @var{val} to the multiple precision integer @var{rop}.
|
|
@var{val} must be an exact integer, otherwise an error will be
|
|
signaled. @var{rop} must have been initialized with @code{mpz_init}
|
|
before this function is called. When @var{rop} is no longer needed
|
|
the occupied space must be freed with @code{mpz_clear}.
|
|
@xref{Initializing Integers,,, gmp, GNU MP Manual}, for details.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_from_mpz (mpz_t val)
|
|
Return the @code{SCM} value that represents @var{val}.
|
|
@end deftypefn
|
|
|
|
@node Reals and Rationals
|
|
@subsubsection Real and Rational Numbers
|
|
@tpindex Real numbers
|
|
@tpindex Rational numbers
|
|
|
|
@rnindex real?
|
|
@rnindex rational?
|
|
|
|
Mathematically, the real numbers are the set of numbers that describe
|
|
all possible points along a continuous, infinite, one-dimensional line.
|
|
The rational numbers are the set of all numbers that can be written as
|
|
fractions @var{p}/@var{q}, where @var{p} and @var{q} are integers.
|
|
All rational numbers are also real, but there are real numbers that
|
|
are not rational, for example @m{\sqrt{2}, the square root of 2}, and
|
|
@m{\pi,pi}.
|
|
|
|
Guile can represent both exact and inexact rational numbers, but it
|
|
cannot represent precise finite irrational numbers. Exact rationals are
|
|
represented by storing the numerator and denominator as two exact
|
|
integers. Inexact rationals are stored as floating point numbers using
|
|
the C type @code{double}.
|
|
|
|
Exact rationals are written as a fraction of integers. There must be
|
|
no whitespace around the slash:
|
|
|
|
@lisp
|
|
1/2
|
|
-22/7
|
|
@end lisp
|
|
|
|
Even though the actual encoding of inexact rationals is in binary, it
|
|
may be helpful to think of it as a decimal number with a limited
|
|
number of significant figures and a decimal point somewhere, since
|
|
this corresponds to the standard notation for non-whole numbers. For
|
|
example:
|
|
|
|
@lisp
|
|
0.34
|
|
-0.00000142857931198
|
|
-5648394822220000000000.0
|
|
4.0
|
|
@end lisp
|
|
|
|
The limited precision of Guile's encoding means that any finite ``real''
|
|
number in Guile can be written in a rational form, by multiplying and
|
|
then dividing by sufficient powers of 10 (or in fact, 2). For example,
|
|
@samp{-0.00000142857931198} is the same as @minus{}142857931198 divided
|
|
by 100000000000000000. In Guile's current incarnation, therefore, the
|
|
@code{rational?} and @code{real?} predicates are equivalent for finite
|
|
numbers.
|
|
|
|
|
|
Dividing by an exact zero leads to a error message, as one might expect.
|
|
However, dividing by an inexact zero does not produce an error.
|
|
Instead, the result of the division is either plus or minus infinity,
|
|
depending on the sign of the divided number and the sign of the zero
|
|
divisor (some platforms support signed zeroes @samp{-0.0} and
|
|
@samp{+0.0}; @samp{0.0} is the same as @samp{+0.0}).
|
|
|
|
Dividing zero by an inexact zero yields a @acronym{NaN} (`not a number')
|
|
value, although they are actually considered numbers by Scheme.
|
|
Attempts to compare a @acronym{NaN} value with any number (including
|
|
itself) using @code{=}, @code{<}, @code{>}, @code{<=} or @code{>=}
|
|
always returns @code{#f}. Although a @acronym{NaN} value is not
|
|
@code{=} to itself, it is both @code{eqv?} and @code{equal?} to itself
|
|
and other @acronym{NaN} values. However, the preferred way to test for
|
|
them is by using @code{nan?}.
|
|
|
|
The real @acronym{NaN} values and infinities are written @samp{+nan.0},
|
|
@samp{+inf.0} and @samp{-inf.0}. This syntax is also recognized by
|
|
@code{read} as an extension to the usual Scheme syntax. These special
|
|
values are considered by Scheme to be inexact real numbers but not
|
|
rational. Note that non-real complex numbers may also contain
|
|
infinities or @acronym{NaN} values in their real or imaginary parts. To
|
|
test a real number to see if it is infinite, a @acronym{NaN} value, or
|
|
neither, use @code{inf?}, @code{nan?}, or @code{finite?}, respectively.
|
|
Every real number in Scheme belongs to precisely one of those three
|
|
classes.
|
|
|
|
On platforms that follow @acronym{IEEE} 754 for their floating point
|
|
arithmetic, the @samp{+inf.0}, @samp{-inf.0}, and @samp{+nan.0} values
|
|
are implemented using the corresponding @acronym{IEEE} 754 values.
|
|
They behave in arithmetic operations like @acronym{IEEE} 754 describes
|
|
it, i.e., @code{(= +nan.0 +nan.0)} @result{} @code{#f}.
|
|
|
|
@deffn {Scheme Procedure} real? obj
|
|
@deffnx {C Function} scm_real_p (obj)
|
|
Return @code{#t} if @var{obj} is a real number, else @code{#f}. Note
|
|
that the sets of integer and rational values form subsets of the set
|
|
of real numbers, so the predicate will also be fulfilled if @var{obj}
|
|
is an integer number or a rational number.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} rational? x
|
|
@deffnx {C Function} scm_rational_p (x)
|
|
Return @code{#t} if @var{x} is a rational number, @code{#f} otherwise.
|
|
Note that the set of integer values forms a subset of the set of
|
|
rational numbers, i.e.@: the predicate will also be fulfilled if
|
|
@var{x} is an integer number.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} rationalize x eps
|
|
@deffnx {C Function} scm_rationalize (x, eps)
|
|
Returns the @emph{simplest} rational number differing
|
|
from @var{x} by no more than @var{eps}.
|
|
|
|
As required by @acronym{R5RS}, @code{rationalize} only returns an
|
|
exact result when both its arguments are exact. Thus, you might need
|
|
to use @code{inexact->exact} on the arguments.
|
|
|
|
@lisp
|
|
(rationalize (inexact->exact 1.2) 1/100)
|
|
@result{} 6/5
|
|
@end lisp
|
|
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} inf? x
|
|
@deffnx {C Function} scm_inf_p (x)
|
|
Return @code{#t} if the real number @var{x} is @samp{+inf.0} or
|
|
@samp{-inf.0}. Otherwise return @code{#f}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} nan? x
|
|
@deffnx {C Function} scm_nan_p (x)
|
|
Return @code{#t} if the real number @var{x} is @samp{+nan.0}, or
|
|
@code{#f} otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} finite? x
|
|
@deffnx {C Function} scm_finite_p (x)
|
|
Return @code{#t} if the real number @var{x} is neither infinite nor a
|
|
NaN, @code{#f} otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} nan
|
|
@deffnx {C Function} scm_nan ()
|
|
Return @samp{+nan.0}, a @acronym{NaN} value.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} inf
|
|
@deffnx {C Function} scm_inf ()
|
|
Return @samp{+inf.0}, positive infinity.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} numerator x
|
|
@deffnx {C Function} scm_numerator (x)
|
|
Return the numerator of the rational number @var{x}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} denominator x
|
|
@deffnx {C Function} scm_denominator (x)
|
|
Return the denominator of the rational number @var{x}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_real (SCM val)
|
|
@deftypefnx {C Function} int scm_is_rational (SCM val)
|
|
Equivalent to @code{scm_is_true (scm_real_p (val))} and
|
|
@code{scm_is_true (scm_rational_p (val))}, respectively.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} double scm_to_double (SCM val)
|
|
Returns the number closest to @var{val} that is representable as a
|
|
@code{double}. Returns infinity for a @var{val} that is too large in
|
|
magnitude. The argument @var{val} must be a real number.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_from_double (double val)
|
|
Return the @code{SCM} value that represents @var{val}. The returned
|
|
value is inexact according to the predicate @code{inexact?}, but it
|
|
will be exactly equal to @var{val}.
|
|
@end deftypefn
|
|
|
|
@node Complex Numbers
|
|
@subsubsection Complex Numbers
|
|
@tpindex Complex numbers
|
|
|
|
@rnindex complex?
|
|
|
|
Complex numbers are the set of numbers that describe all possible points
|
|
in a two-dimensional space. The two coordinates of a particular point
|
|
in this space are known as the @dfn{real} and @dfn{imaginary} parts of
|
|
the complex number that describes that point.
|
|
|
|
In Guile, complex numbers are written in rectangular form as the sum of
|
|
their real and imaginary parts, using the symbol @code{i} to indicate
|
|
the imaginary part.
|
|
|
|
@lisp
|
|
3+4i
|
|
@result{}
|
|
3.0+4.0i
|
|
|
|
(* 3-8i 2.3+0.3i)
|
|
@result{}
|
|
9.3-17.5i
|
|
@end lisp
|
|
|
|
@cindex polar form
|
|
@noindent
|
|
Polar form can also be used, with an @samp{@@} between magnitude and
|
|
angle,
|
|
|
|
@lisp
|
|
1@@3.141592 @result{} -1.0 (approx)
|
|
-1@@1.57079 @result{} 0.0-1.0i (approx)
|
|
@end lisp
|
|
|
|
Guile represents a complex number as a pair of inexact reals, so the
|
|
real and imaginary parts of a complex number have the same properties of
|
|
inexactness and limited precision as single inexact real numbers.
|
|
|
|
Note that each part of a complex number may contain any inexact real
|
|
value, including the special values @samp{+nan.0}, @samp{+inf.0} and
|
|
@samp{-inf.0}, as well as either of the signed zeroes @samp{0.0} or
|
|
@samp{-0.0}.
|
|
|
|
|
|
@deffn {Scheme Procedure} complex? z
|
|
@deffnx {C Function} scm_complex_p (z)
|
|
Return @code{#t} if @var{z} is a complex number, @code{#f}
|
|
otherwise. Note that the sets of real, rational and integer
|
|
values form subsets of the set of complex numbers, i.e.@: the
|
|
predicate will also be fulfilled if @var{z} is a real,
|
|
rational or integer number.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_complex (SCM val)
|
|
Equivalent to @code{scm_is_true (scm_complex_p (val))}.
|
|
@end deftypefn
|
|
|
|
@node Exactness
|
|
@subsubsection Exact and Inexact Numbers
|
|
@tpindex Exact numbers
|
|
@tpindex Inexact numbers
|
|
|
|
@rnindex exact?
|
|
@rnindex inexact?
|
|
@rnindex exact->inexact
|
|
@rnindex inexact->exact
|
|
|
|
R5RS requires that, with few exceptions, a calculation involving inexact
|
|
numbers always produces an inexact result. To meet this requirement,
|
|
Guile distinguishes between an exact integer value such as @samp{5} and
|
|
the corresponding inexact integer value which, to the limited precision
|
|
available, has no fractional part, and is printed as @samp{5.0}. Guile
|
|
will only convert the latter value to the former when forced to do so by
|
|
an invocation of the @code{inexact->exact} procedure.
|
|
|
|
The only exception to the above requirement is when the values of the
|
|
inexact numbers do not affect the result. For example @code{(expt n 0)}
|
|
is @samp{1} for any value of @code{n}, therefore @code{(expt 5.0 0)} is
|
|
permitted to return an exact @samp{1}.
|
|
|
|
@deffn {Scheme Procedure} exact? z
|
|
@deffnx {C Function} scm_exact_p (z)
|
|
Return @code{#t} if the number @var{z} is exact, @code{#f}
|
|
otherwise.
|
|
|
|
@lisp
|
|
(exact? 2)
|
|
@result{} #t
|
|
|
|
(exact? 0.5)
|
|
@result{} #f
|
|
|
|
(exact? (/ 2))
|
|
@result{} #t
|
|
@end lisp
|
|
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_exact (SCM z)
|
|
Return a @code{1} if the number @var{z} is exact, and @code{0}
|
|
otherwise. This is equivalent to @code{scm_is_true (scm_exact_p (z))}.
|
|
|
|
An alternate approch to testing the exactness of a number is to
|
|
use @code{scm_is_signed_integer} or @code{scm_is_unsigned_integer}.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} inexact? z
|
|
@deffnx {C Function} scm_inexact_p (z)
|
|
Return @code{#t} if the number @var{z} is inexact, @code{#f}
|
|
else.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_inexact (SCM z)
|
|
Return a @code{1} if the number @var{z} is inexact, and @code{0}
|
|
otherwise. This is equivalent to @code{scm_is_true (scm_inexact_p (z))}.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} inexact->exact z
|
|
@deffnx {C Function} scm_inexact_to_exact (z)
|
|
Return an exact number that is numerically closest to @var{z}, when
|
|
there is one. For inexact rationals, Guile returns the exact rational
|
|
that is numerically equal to the inexact rational. Inexact complex
|
|
numbers with a non-zero imaginary part can not be made exact.
|
|
|
|
@lisp
|
|
(inexact->exact 0.5)
|
|
@result{} 1/2
|
|
@end lisp
|
|
|
|
The following happens because 12/10 is not exactly representable as a
|
|
@code{double} (on most platforms). However, when reading a decimal
|
|
number that has been marked exact with the ``#e'' prefix, Guile is
|
|
able to represent it correctly.
|
|
|
|
@lisp
|
|
(inexact->exact 1.2)
|
|
@result{} 5404319552844595/4503599627370496
|
|
|
|
#e1.2
|
|
@result{} 6/5
|
|
@end lisp
|
|
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "exact->inexact")
|
|
@deffn {Scheme Procedure} exact->inexact z
|
|
@deffnx {C Function} scm_exact_to_inexact (z)
|
|
Convert the number @var{z} to its inexact representation.
|
|
@end deffn
|
|
|
|
|
|
@node Number Syntax
|
|
@subsubsection Read Syntax for Numerical Data
|
|
|
|
The read syntax for integers is a string of digits, optionally
|
|
preceded by a minus or plus character, a code indicating the
|
|
base in which the integer is encoded, and a code indicating whether
|
|
the number is exact or inexact. The supported base codes are:
|
|
|
|
@table @code
|
|
@item #b
|
|
@itemx #B
|
|
the integer is written in binary (base 2)
|
|
|
|
@item #o
|
|
@itemx #O
|
|
the integer is written in octal (base 8)
|
|
|
|
@item #d
|
|
@itemx #D
|
|
the integer is written in decimal (base 10)
|
|
|
|
@item #x
|
|
@itemx #X
|
|
the integer is written in hexadecimal (base 16)
|
|
@end table
|
|
|
|
If the base code is omitted, the integer is assumed to be decimal. The
|
|
following examples show how these base codes are used.
|
|
|
|
@lisp
|
|
-13
|
|
@result{} -13
|
|
|
|
#d-13
|
|
@result{} -13
|
|
|
|
#x-13
|
|
@result{} -19
|
|
|
|
#b+1101
|
|
@result{} 13
|
|
|
|
#o377
|
|
@result{} 255
|
|
@end lisp
|
|
|
|
The codes for indicating exactness (which can, incidentally, be applied
|
|
to all numerical values) are:
|
|
|
|
@table @code
|
|
@item #e
|
|
@itemx #E
|
|
the number is exact
|
|
|
|
@item #i
|
|
@itemx #I
|
|
the number is inexact.
|
|
@end table
|
|
|
|
If the exactness indicator is omitted, the number is exact unless it
|
|
contains a radix point. Since Guile can not represent exact complex
|
|
numbers, an error is signaled when asking for them.
|
|
|
|
@lisp
|
|
(exact? 1.2)
|
|
@result{} #f
|
|
|
|
(exact? #e1.2)
|
|
@result{} #t
|
|
|
|
(exact? #e+1i)
|
|
ERROR: Wrong type argument
|
|
@end lisp
|
|
|
|
Guile also understands the syntax @samp{+inf.0} and @samp{-inf.0} for
|
|
plus and minus infinity, respectively. The value must be written
|
|
exactly as shown, that is, they always must have a sign and exactly
|
|
one zero digit after the decimal point. It also understands
|
|
@samp{+nan.0} and @samp{-nan.0} for the special `not-a-number' value.
|
|
The sign is ignored for `not-a-number' and the value is always printed
|
|
as @samp{+nan.0}.
|
|
|
|
@node Integer Operations
|
|
@subsubsection Operations on Integer Values
|
|
@rnindex odd?
|
|
@rnindex even?
|
|
@rnindex quotient
|
|
@rnindex remainder
|
|
@rnindex modulo
|
|
@rnindex gcd
|
|
@rnindex lcm
|
|
|
|
@deffn {Scheme Procedure} odd? n
|
|
@deffnx {C Function} scm_odd_p (n)
|
|
Return @code{#t} if @var{n} is an odd number, @code{#f}
|
|
otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} even? n
|
|
@deffnx {C Function} scm_even_p (n)
|
|
Return @code{#t} if @var{n} is an even number, @code{#f}
|
|
otherwise.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "quotient")
|
|
@c begin (texi-doc-string "guile" "remainder")
|
|
@deffn {Scheme Procedure} quotient n d
|
|
@deffnx {Scheme Procedure} remainder n d
|
|
@deffnx {C Function} scm_quotient (n, d)
|
|
@deffnx {C Function} scm_remainder (n, d)
|
|
Return the quotient or remainder from @var{n} divided by @var{d}. The
|
|
quotient is rounded towards zero, and the remainder will have the same
|
|
sign as @var{n}. In all cases quotient and remainder satisfy
|
|
@math{@var{n} = @var{q}*@var{d} + @var{r}}.
|
|
|
|
@lisp
|
|
(remainder 13 4) @result{} 1
|
|
(remainder -13 4) @result{} -1
|
|
@end lisp
|
|
|
|
See also @code{truncate-quotient}, @code{truncate-remainder} and
|
|
related operations in @ref{Arithmetic}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "modulo")
|
|
@deffn {Scheme Procedure} modulo n d
|
|
@deffnx {C Function} scm_modulo (n, d)
|
|
Return the remainder from @var{n} divided by @var{d}, with the same
|
|
sign as @var{d}.
|
|
|
|
@lisp
|
|
(modulo 13 4) @result{} 1
|
|
(modulo -13 4) @result{} 3
|
|
(modulo 13 -4) @result{} -3
|
|
(modulo -13 -4) @result{} -1
|
|
@end lisp
|
|
|
|
See also @code{floor-quotient}, @code{floor-remainder} and
|
|
related operations in @ref{Arithmetic}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "gcd")
|
|
@deffn {Scheme Procedure} gcd x@dots{}
|
|
@deffnx {C Function} scm_gcd (x, y)
|
|
Return the greatest common divisor of all arguments.
|
|
If called without arguments, 0 is returned.
|
|
|
|
The C function @code{scm_gcd} always takes two arguments, while the
|
|
Scheme function can take an arbitrary number.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "lcm")
|
|
@deffn {Scheme Procedure} lcm x@dots{}
|
|
@deffnx {C Function} scm_lcm (x, y)
|
|
Return the least common multiple of the arguments.
|
|
If called without arguments, 1 is returned.
|
|
|
|
The C function @code{scm_lcm} always takes two arguments, while the
|
|
Scheme function can take an arbitrary number.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} modulo-expt n k m
|
|
@deffnx {C Function} scm_modulo_expt (n, k, m)
|
|
Return @var{n} raised to the integer exponent
|
|
@var{k}, modulo @var{m}.
|
|
|
|
@lisp
|
|
(modulo-expt 2 3 5)
|
|
@result{} 3
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deftypefn {Scheme Procedure} {} exact-integer-sqrt @var{k}
|
|
@deftypefnx {C Function} void scm_exact_integer_sqrt (SCM @var{k}, SCM *@var{s}, SCM *@var{r})
|
|
Return two exact non-negative integers @var{s} and @var{r}
|
|
such that @math{@var{k} = @var{s}^2 + @var{r}} and
|
|
@math{@var{s}^2 <= @var{k} < (@var{s} + 1)^2}.
|
|
An error is raised if @var{k} is not an exact non-negative integer.
|
|
|
|
@lisp
|
|
(exact-integer-sqrt 10) @result{} 3 and 1
|
|
@end lisp
|
|
@end deftypefn
|
|
|
|
@node Comparison
|
|
@subsubsection Comparison Predicates
|
|
@rnindex zero?
|
|
@rnindex positive?
|
|
@rnindex negative?
|
|
|
|
The C comparison functions below always takes two arguments, while the
|
|
Scheme functions can take an arbitrary number. Also keep in mind that
|
|
the C functions return one of the Scheme boolean values
|
|
@code{SCM_BOOL_T} or @code{SCM_BOOL_F} which are both true as far as C
|
|
is concerned. Thus, always write @code{scm_is_true (scm_num_eq_p (x,
|
|
y))} when testing the two Scheme numbers @code{x} and @code{y} for
|
|
equality, for example.
|
|
|
|
@c begin (texi-doc-string "guile" "=")
|
|
@deffn {Scheme Procedure} =
|
|
@deffnx {C Function} scm_num_eq_p (x, y)
|
|
Return @code{#t} if all parameters are numerically equal.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "<")
|
|
@deffn {Scheme Procedure} <
|
|
@deffnx {C Function} scm_less_p (x, y)
|
|
Return @code{#t} if the list of parameters is monotonically
|
|
increasing.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" ">")
|
|
@deffn {Scheme Procedure} >
|
|
@deffnx {C Function} scm_gr_p (x, y)
|
|
Return @code{#t} if the list of parameters is monotonically
|
|
decreasing.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "<=")
|
|
@deffn {Scheme Procedure} <=
|
|
@deffnx {C Function} scm_leq_p (x, y)
|
|
Return @code{#t} if the list of parameters is monotonically
|
|
non-decreasing.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" ">=")
|
|
@deffn {Scheme Procedure} >=
|
|
@deffnx {C Function} scm_geq_p (x, y)
|
|
Return @code{#t} if the list of parameters is monotonically
|
|
non-increasing.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "zero?")
|
|
@deffn {Scheme Procedure} zero? z
|
|
@deffnx {C Function} scm_zero_p (z)
|
|
Return @code{#t} if @var{z} is an exact or inexact number equal to
|
|
zero.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "positive?")
|
|
@deffn {Scheme Procedure} positive? x
|
|
@deffnx {C Function} scm_positive_p (x)
|
|
Return @code{#t} if @var{x} is an exact or inexact number greater than
|
|
zero.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "negative?")
|
|
@deffn {Scheme Procedure} negative? x
|
|
@deffnx {C Function} scm_negative_p (x)
|
|
Return @code{#t} if @var{x} is an exact or inexact number less than
|
|
zero.
|
|
@end deffn
|
|
|
|
|
|
@node Conversion
|
|
@subsubsection Converting Numbers To and From Strings
|
|
@rnindex number->string
|
|
@rnindex string->number
|
|
|
|
The following procedures read and write numbers according to their
|
|
external representation as defined by R5RS (@pxref{Lexical structure,
|
|
R5RS Lexical Structure,, r5rs, The Revised^5 Report on the Algorithmic
|
|
Language Scheme}). @xref{Number Input and Output, the @code{(ice-9
|
|
i18n)} module}, for locale-dependent number parsing.
|
|
|
|
@deffn {Scheme Procedure} number->string n [radix]
|
|
@deffnx {C Function} scm_number_to_string (n, radix)
|
|
Return a string holding the external representation of the
|
|
number @var{n} in the given @var{radix}. If @var{n} is
|
|
inexact, a radix of 10 will be used.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string->number string [radix]
|
|
@deffnx {C Function} scm_string_to_number (string, radix)
|
|
Return a number of the maximally precise representation
|
|
expressed by the given @var{string}. @var{radix} must be an
|
|
exact integer, either 2, 8, 10, or 16. If supplied, @var{radix}
|
|
is a default radix that may be overridden by an explicit radix
|
|
prefix in @var{string} (e.g.@: "#o177"). If @var{radix} is not
|
|
supplied, then the default radix is 10. If string is not a
|
|
syntactically valid notation for a number, then
|
|
@code{string->number} returns @code{#f}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} SCM scm_c_locale_stringn_to_number (const char *string, size_t len, unsigned radix)
|
|
As per @code{string->number} above, but taking a C string, as pointer
|
|
and length. The string characters should be in the current locale
|
|
encoding (@code{locale} in the name refers only to that, there's no
|
|
locale-dependent parsing).
|
|
@end deftypefn
|
|
|
|
|
|
@node Complex
|
|
@subsubsection Complex Number Operations
|
|
@rnindex make-rectangular
|
|
@rnindex make-polar
|
|
@rnindex real-part
|
|
@rnindex imag-part
|
|
@rnindex magnitude
|
|
@rnindex angle
|
|
|
|
@deffn {Scheme Procedure} make-rectangular real_part imaginary_part
|
|
@deffnx {C Function} scm_make_rectangular (real_part, imaginary_part)
|
|
Return a complex number constructed of the given @var{real-part} and @var{imaginary-part} parts.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} make-polar mag ang
|
|
@deffnx {C Function} scm_make_polar (mag, ang)
|
|
@cindex polar form
|
|
Return the complex number @var{mag} * e^(i * @var{ang}).
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "real-part")
|
|
@deffn {Scheme Procedure} real-part z
|
|
@deffnx {C Function} scm_real_part (z)
|
|
Return the real part of the number @var{z}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "imag-part")
|
|
@deffn {Scheme Procedure} imag-part z
|
|
@deffnx {C Function} scm_imag_part (z)
|
|
Return the imaginary part of the number @var{z}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "magnitude")
|
|
@deffn {Scheme Procedure} magnitude z
|
|
@deffnx {C Function} scm_magnitude (z)
|
|
Return the magnitude of the number @var{z}. This is the same as
|
|
@code{abs} for real arguments, but also allows complex numbers.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "angle")
|
|
@deffn {Scheme Procedure} angle z
|
|
@deffnx {C Function} scm_angle (z)
|
|
Return the angle of the complex number @var{z}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} SCM scm_c_make_rectangular (double re, double im)
|
|
@deftypefnx {C Function} SCM scm_c_make_polar (double x, double y)
|
|
Like @code{scm_make_rectangular} or @code{scm_make_polar},
|
|
respectively, but these functions take @code{double}s as their
|
|
arguments.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} double scm_c_real_part (z)
|
|
@deftypefnx {C Function} double scm_c_imag_part (z)
|
|
Returns the real or imaginary part of @var{z} as a @code{double}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} double scm_c_magnitude (z)
|
|
@deftypefnx {C Function} double scm_c_angle (z)
|
|
Returns the magnitude or angle of @var{z} as a @code{double}.
|
|
@end deftypefn
|
|
|
|
|
|
@node Arithmetic
|
|
@subsubsection Arithmetic Functions
|
|
@rnindex max
|
|
@rnindex min
|
|
@rnindex +
|
|
@rnindex *
|
|
@rnindex -
|
|
@rnindex /
|
|
@findex 1+
|
|
@findex 1-
|
|
@rnindex abs
|
|
@rnindex floor
|
|
@rnindex ceiling
|
|
@rnindex truncate
|
|
@rnindex round
|
|
@rnindex euclidean/
|
|
@rnindex euclidean-quotient
|
|
@rnindex euclidean-remainder
|
|
@rnindex floor/
|
|
@rnindex floor-quotient
|
|
@rnindex floor-remainder
|
|
@rnindex ceiling/
|
|
@rnindex ceiling-quotient
|
|
@rnindex ceiling-remainder
|
|
@rnindex truncate/
|
|
@rnindex truncate-quotient
|
|
@rnindex truncate-remainder
|
|
@rnindex centered/
|
|
@rnindex centered-quotient
|
|
@rnindex centered-remainder
|
|
@rnindex round/
|
|
@rnindex round-quotient
|
|
@rnindex round-remainder
|
|
|
|
The C arithmetic functions below always takes two arguments, while the
|
|
Scheme functions can take an arbitrary number. When you need to
|
|
invoke them with just one argument, for example to compute the
|
|
equivalent of @code{(- x)}, pass @code{SCM_UNDEFINED} as the second
|
|
one: @code{scm_difference (x, SCM_UNDEFINED)}.
|
|
|
|
@c begin (texi-doc-string "guile" "+")
|
|
@deffn {Scheme Procedure} + z1 @dots{}
|
|
@deffnx {C Function} scm_sum (z1, z2)
|
|
Return the sum of all parameter values. Return 0 if called without any
|
|
parameters.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "-")
|
|
@deffn {Scheme Procedure} - z1 z2 @dots{}
|
|
@deffnx {C Function} scm_difference (z1, z2)
|
|
If called with one argument @var{z1}, -@var{z1} is returned. Otherwise
|
|
the sum of all but the first argument are subtracted from the first
|
|
argument.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "*")
|
|
@deffn {Scheme Procedure} * z1 @dots{}
|
|
@deffnx {C Function} scm_product (z1, z2)
|
|
Return the product of all arguments. If called without arguments, 1 is
|
|
returned.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "/")
|
|
@deffn {Scheme Procedure} / z1 z2 @dots{}
|
|
@deffnx {C Function} scm_divide (z1, z2)
|
|
Divide the first argument by the product of the remaining arguments. If
|
|
called with one argument @var{z1}, 1/@var{z1} is returned.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} 1+ z
|
|
@deffnx {C Function} scm_oneplus (z)
|
|
Return @math{@var{z} + 1}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} 1- z
|
|
@deffnx {C function} scm_oneminus (z)
|
|
Return @math{@var{z} - 1}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "abs")
|
|
@deffn {Scheme Procedure} abs x
|
|
@deffnx {C Function} scm_abs (x)
|
|
Return the absolute value of @var{x}.
|
|
|
|
@var{x} must be a number with zero imaginary part. To calculate the
|
|
magnitude of a complex number, use @code{magnitude} instead.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "max")
|
|
@deffn {Scheme Procedure} max x1 x2 @dots{}
|
|
@deffnx {C Function} scm_max (x1, x2)
|
|
Return the maximum of all parameter values.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "min")
|
|
@deffn {Scheme Procedure} min x1 x2 @dots{}
|
|
@deffnx {C Function} scm_min (x1, x2)
|
|
Return the minimum of all parameter values.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "truncate")
|
|
@deffn {Scheme Procedure} truncate x
|
|
@deffnx {C Function} scm_truncate_number (x)
|
|
Round the inexact number @var{x} towards zero.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "round")
|
|
@deffn {Scheme Procedure} round x
|
|
@deffnx {C Function} scm_round_number (x)
|
|
Round the inexact number @var{x} to the nearest integer. When exactly
|
|
halfway between two integers, round to the even one.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "floor")
|
|
@deffn {Scheme Procedure} floor x
|
|
@deffnx {C Function} scm_floor (x)
|
|
Round the number @var{x} towards minus infinity.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "ceiling")
|
|
@deffn {Scheme Procedure} ceiling x
|
|
@deffnx {C Function} scm_ceiling (x)
|
|
Round the number @var{x} towards infinity.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} double scm_c_truncate (double x)
|
|
@deftypefnx {C Function} double scm_c_round (double x)
|
|
Like @code{scm_truncate_number} or @code{scm_round_number},
|
|
respectively, but these functions take and return @code{double}
|
|
values.
|
|
@end deftypefn
|
|
|
|
@deftypefn {Scheme Procedure} {} euclidean/ @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} euclidean-quotient @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} euclidean-remainder @var{x} @var{y}
|
|
@deftypefnx {C Function} void scm_euclidean_divide (SCM @var{x}, SCM @var{y}, SCM *@var{q}, SCM *@var{r})
|
|
@deftypefnx {C Function} SCM scm_euclidean_quotient (SCM @var{x}, SCM @var{y})
|
|
@deftypefnx {C Function} SCM scm_euclidean_remainder (SCM @var{x}, SCM @var{y})
|
|
These procedures accept two real numbers @var{x} and @var{y}, where the
|
|
divisor @var{y} must be non-zero. @code{euclidean-quotient} returns the
|
|
integer @var{q} and @code{euclidean-remainder} returns the real number
|
|
@var{r} such that @math{@var{x} = @var{q}*@var{y} + @var{r}} and
|
|
@math{0 <= @var{r} < |@var{y}|}. @code{euclidean/} returns both @var{q} and
|
|
@var{r}, and is more efficient than computing each separately. Note
|
|
that when @math{@var{y} > 0}, @code{euclidean-quotient} returns
|
|
@math{floor(@var{x}/@var{y})}, otherwise it returns
|
|
@math{ceiling(@var{x}/@var{y})}.
|
|
|
|
Note that these operators are equivalent to the R6RS operators
|
|
@code{div}, @code{mod}, and @code{div-and-mod}.
|
|
|
|
@lisp
|
|
(euclidean-quotient 123 10) @result{} 12
|
|
(euclidean-remainder 123 10) @result{} 3
|
|
(euclidean/ 123 10) @result{} 12 and 3
|
|
(euclidean/ 123 -10) @result{} -12 and 3
|
|
(euclidean/ -123 10) @result{} -13 and 7
|
|
(euclidean/ -123 -10) @result{} 13 and 7
|
|
(euclidean/ -123.2 -63.5) @result{} 2.0 and 3.8
|
|
(euclidean/ 16/3 -10/7) @result{} -3 and 22/21
|
|
@end lisp
|
|
@end deftypefn
|
|
|
|
@deftypefn {Scheme Procedure} {} floor/ @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} floor-quotient @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} floor-remainder @var{x} @var{y}
|
|
@deftypefnx {C Function} void scm_floor_divide (SCM @var{x}, SCM @var{y}, SCM *@var{q}, SCM *@var{r})
|
|
@deftypefnx {C Function} SCM scm_floor_quotient (@var{x}, @var{y})
|
|
@deftypefnx {C Function} SCM scm_floor_remainder (@var{x}, @var{y})
|
|
These procedures accept two real numbers @var{x} and @var{y}, where the
|
|
divisor @var{y} must be non-zero. @code{floor-quotient} returns the
|
|
integer @var{q} and @code{floor-remainder} returns the real number
|
|
@var{r} such that @math{@var{q} = floor(@var{x}/@var{y})} and
|
|
@math{@var{x} = @var{q}*@var{y} + @var{r}}. @code{floor/} returns
|
|
both @var{q} and @var{r}, and is more efficient than computing each
|
|
separately. Note that @var{r}, if non-zero, will have the same sign
|
|
as @var{y}.
|
|
|
|
When @var{x} and @var{y} are integers, @code{floor-remainder} is
|
|
equivalent to the R5RS integer-only operator @code{modulo}.
|
|
|
|
@lisp
|
|
(floor-quotient 123 10) @result{} 12
|
|
(floor-remainder 123 10) @result{} 3
|
|
(floor/ 123 10) @result{} 12 and 3
|
|
(floor/ 123 -10) @result{} -13 and -7
|
|
(floor/ -123 10) @result{} -13 and 7
|
|
(floor/ -123 -10) @result{} 12 and -3
|
|
(floor/ -123.2 -63.5) @result{} 1.0 and -59.7
|
|
(floor/ 16/3 -10/7) @result{} -4 and -8/21
|
|
@end lisp
|
|
@end deftypefn
|
|
|
|
@deftypefn {Scheme Procedure} {} ceiling/ @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} ceiling-quotient @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} ceiling-remainder @var{x} @var{y}
|
|
@deftypefnx {C Function} void scm_ceiling_divide (SCM @var{x}, SCM @var{y}, SCM *@var{q}, SCM *@var{r})
|
|
@deftypefnx {C Function} SCM scm_ceiling_quotient (@var{x}, @var{y})
|
|
@deftypefnx {C Function} SCM scm_ceiling_remainder (@var{x}, @var{y})
|
|
These procedures accept two real numbers @var{x} and @var{y}, where the
|
|
divisor @var{y} must be non-zero. @code{ceiling-quotient} returns the
|
|
integer @var{q} and @code{ceiling-remainder} returns the real number
|
|
@var{r} such that @math{@var{q} = ceiling(@var{x}/@var{y})} and
|
|
@math{@var{x} = @var{q}*@var{y} + @var{r}}. @code{ceiling/} returns
|
|
both @var{q} and @var{r}, and is more efficient than computing each
|
|
separately. Note that @var{r}, if non-zero, will have the opposite sign
|
|
of @var{y}.
|
|
|
|
@lisp
|
|
(ceiling-quotient 123 10) @result{} 13
|
|
(ceiling-remainder 123 10) @result{} -7
|
|
(ceiling/ 123 10) @result{} 13 and -7
|
|
(ceiling/ 123 -10) @result{} -12 and 3
|
|
(ceiling/ -123 10) @result{} -12 and -3
|
|
(ceiling/ -123 -10) @result{} 13 and 7
|
|
(ceiling/ -123.2 -63.5) @result{} 2.0 and 3.8
|
|
(ceiling/ 16/3 -10/7) @result{} -3 and 22/21
|
|
@end lisp
|
|
@end deftypefn
|
|
|
|
@deftypefn {Scheme Procedure} {} truncate/ @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} truncate-quotient @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} truncate-remainder @var{x} @var{y}
|
|
@deftypefnx {C Function} void scm_truncate_divide (SCM @var{x}, SCM @var{y}, SCM *@var{q}, SCM *@var{r})
|
|
@deftypefnx {C Function} SCM scm_truncate_quotient (@var{x}, @var{y})
|
|
@deftypefnx {C Function} SCM scm_truncate_remainder (@var{x}, @var{y})
|
|
These procedures accept two real numbers @var{x} and @var{y}, where the
|
|
divisor @var{y} must be non-zero. @code{truncate-quotient} returns the
|
|
integer @var{q} and @code{truncate-remainder} returns the real number
|
|
@var{r} such that @var{q} is @math{@var{x}/@var{y}} rounded toward zero,
|
|
and @math{@var{x} = @var{q}*@var{y} + @var{r}}. @code{truncate/} returns
|
|
both @var{q} and @var{r}, and is more efficient than computing each
|
|
separately. Note that @var{r}, if non-zero, will have the same sign
|
|
as @var{x}.
|
|
|
|
When @var{x} and @var{y} are integers, these operators are
|
|
equivalent to the R5RS integer-only operators @code{quotient} and
|
|
@code{remainder}.
|
|
|
|
@lisp
|
|
(truncate-quotient 123 10) @result{} 12
|
|
(truncate-remainder 123 10) @result{} 3
|
|
(truncate/ 123 10) @result{} 12 and 3
|
|
(truncate/ 123 -10) @result{} -12 and 3
|
|
(truncate/ -123 10) @result{} -12 and -3
|
|
(truncate/ -123 -10) @result{} 12 and -3
|
|
(truncate/ -123.2 -63.5) @result{} 1.0 and -59.7
|
|
(truncate/ 16/3 -10/7) @result{} -3 and 22/21
|
|
@end lisp
|
|
@end deftypefn
|
|
|
|
@deftypefn {Scheme Procedure} {} centered/ @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} centered-quotient @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} centered-remainder @var{x} @var{y}
|
|
@deftypefnx {C Function} void scm_centered_divide (SCM @var{x}, SCM @var{y}, SCM *@var{q}, SCM *@var{r})
|
|
@deftypefnx {C Function} SCM scm_centered_quotient (SCM @var{x}, SCM @var{y})
|
|
@deftypefnx {C Function} SCM scm_centered_remainder (SCM @var{x}, SCM @var{y})
|
|
These procedures accept two real numbers @var{x} and @var{y}, where the
|
|
divisor @var{y} must be non-zero. @code{centered-quotient} returns the
|
|
integer @var{q} and @code{centered-remainder} returns the real number
|
|
@var{r} such that @math{@var{x} = @var{q}*@var{y} + @var{r}} and
|
|
@math{-|@var{y}/2| <= @var{r} < |@var{y}/2|}. @code{centered/}
|
|
returns both @var{q} and @var{r}, and is more efficient than computing
|
|
each separately.
|
|
|
|
Note that @code{centered-quotient} returns @math{@var{x}/@var{y}}
|
|
rounded to the nearest integer. When @math{@var{x}/@var{y}} lies
|
|
exactly half-way between two integers, the tie is broken according to
|
|
the sign of @var{y}. If @math{@var{y} > 0}, ties are rounded toward
|
|
positive infinity, otherwise they are rounded toward negative infinity.
|
|
This is a consequence of the requirement that
|
|
@math{-|@var{y}/2| <= @var{r} < |@var{y}/2|}.
|
|
|
|
Note that these operators are equivalent to the R6RS operators
|
|
@code{div0}, @code{mod0}, and @code{div0-and-mod0}.
|
|
|
|
@lisp
|
|
(centered-quotient 123 10) @result{} 12
|
|
(centered-remainder 123 10) @result{} 3
|
|
(centered/ 123 10) @result{} 12 and 3
|
|
(centered/ 123 -10) @result{} -12 and 3
|
|
(centered/ -123 10) @result{} -12 and -3
|
|
(centered/ -123 -10) @result{} 12 and -3
|
|
(centered/ 125 10) @result{} 13 and -5
|
|
(centered/ 127 10) @result{} 13 and -3
|
|
(centered/ 135 10) @result{} 14 and -5
|
|
(centered/ -123.2 -63.5) @result{} 2.0 and 3.8
|
|
(centered/ 16/3 -10/7) @result{} -4 and -8/21
|
|
@end lisp
|
|
@end deftypefn
|
|
|
|
@deftypefn {Scheme Procedure} {} round/ @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} round-quotient @var{x} @var{y}
|
|
@deftypefnx {Scheme Procedure} {} round-remainder @var{x} @var{y}
|
|
@deftypefnx {C Function} void scm_round_divide (SCM @var{x}, SCM @var{y}, SCM *@var{q}, SCM *@var{r})
|
|
@deftypefnx {C Function} SCM scm_round_quotient (@var{x}, @var{y})
|
|
@deftypefnx {C Function} SCM scm_round_remainder (@var{x}, @var{y})
|
|
These procedures accept two real numbers @var{x} and @var{y}, where the
|
|
divisor @var{y} must be non-zero. @code{round-quotient} returns the
|
|
integer @var{q} and @code{round-remainder} returns the real number
|
|
@var{r} such that @math{@var{x} = @var{q}*@var{y} + @var{r}} and
|
|
@var{q} is @math{@var{x}/@var{y}} rounded to the nearest integer,
|
|
with ties going to the nearest even integer. @code{round/}
|
|
returns both @var{q} and @var{r}, and is more efficient than computing
|
|
each separately.
|
|
|
|
Note that @code{round/} and @code{centered/} are almost equivalent, but
|
|
their behavior differs when @math{@var{x}/@var{y}} lies exactly half-way
|
|
between two integers. In this case, @code{round/} chooses the nearest
|
|
even integer, whereas @code{centered/} chooses in such a way to satisfy
|
|
the constraint @math{-|@var{y}/2| <= @var{r} < |@var{y}/2|}, which
|
|
is stronger than the corresponding constraint for @code{round/},
|
|
@math{-|@var{y}/2| <= @var{r} <= |@var{y}/2|}. In particular,
|
|
when @var{x} and @var{y} are integers, the number of possible remainders
|
|
returned by @code{centered/} is @math{|@var{y}|}, whereas the number of
|
|
possible remainders returned by @code{round/} is @math{|@var{y}|+1} when
|
|
@var{y} is even.
|
|
|
|
@lisp
|
|
(round-quotient 123 10) @result{} 12
|
|
(round-remainder 123 10) @result{} 3
|
|
(round/ 123 10) @result{} 12 and 3
|
|
(round/ 123 -10) @result{} -12 and 3
|
|
(round/ -123 10) @result{} -12 and -3
|
|
(round/ -123 -10) @result{} 12 and -3
|
|
(round/ 125 10) @result{} 12 and 5
|
|
(round/ 127 10) @result{} 13 and -3
|
|
(round/ 135 10) @result{} 14 and -5
|
|
(round/ -123.2 -63.5) @result{} 2.0 and 3.8
|
|
(round/ 16/3 -10/7) @result{} -4 and -8/21
|
|
@end lisp
|
|
@end deftypefn
|
|
|
|
@node Scientific
|
|
@subsubsection Scientific Functions
|
|
|
|
The following procedures accept any kind of number as arguments,
|
|
including complex numbers.
|
|
|
|
@rnindex sqrt
|
|
@c begin (texi-doc-string "guile" "sqrt")
|
|
@deffn {Scheme Procedure} sqrt z
|
|
Return the square root of @var{z}. Of the two possible roots
|
|
(positive and negative), the one with a positive real part is
|
|
returned, or if that's zero then a positive imaginary part. Thus,
|
|
|
|
@example
|
|
(sqrt 9.0) @result{} 3.0
|
|
(sqrt -9.0) @result{} 0.0+3.0i
|
|
(sqrt 1.0+1.0i) @result{} 1.09868411346781+0.455089860562227i
|
|
(sqrt -1.0-1.0i) @result{} 0.455089860562227-1.09868411346781i
|
|
@end example
|
|
@end deffn
|
|
|
|
@rnindex expt
|
|
@c begin (texi-doc-string "guile" "expt")
|
|
@deffn {Scheme Procedure} expt z1 z2
|
|
Return @var{z1} raised to the power of @var{z2}.
|
|
@end deffn
|
|
|
|
@rnindex sin
|
|
@c begin (texi-doc-string "guile" "sin")
|
|
@deffn {Scheme Procedure} sin z
|
|
Return the sine of @var{z}.
|
|
@end deffn
|
|
|
|
@rnindex cos
|
|
@c begin (texi-doc-string "guile" "cos")
|
|
@deffn {Scheme Procedure} cos z
|
|
Return the cosine of @var{z}.
|
|
@end deffn
|
|
|
|
@rnindex tan
|
|
@c begin (texi-doc-string "guile" "tan")
|
|
@deffn {Scheme Procedure} tan z
|
|
Return the tangent of @var{z}.
|
|
@end deffn
|
|
|
|
@rnindex asin
|
|
@c begin (texi-doc-string "guile" "asin")
|
|
@deffn {Scheme Procedure} asin z
|
|
Return the arcsine of @var{z}.
|
|
@end deffn
|
|
|
|
@rnindex acos
|
|
@c begin (texi-doc-string "guile" "acos")
|
|
@deffn {Scheme Procedure} acos z
|
|
Return the arccosine of @var{z}.
|
|
@end deffn
|
|
|
|
@rnindex atan
|
|
@c begin (texi-doc-string "guile" "atan")
|
|
@deffn {Scheme Procedure} atan z
|
|
@deffnx {Scheme Procedure} atan y x
|
|
Return the arctangent of @var{z}, or of @math{@var{y}/@var{x}}.
|
|
@end deffn
|
|
|
|
@rnindex exp
|
|
@c begin (texi-doc-string "guile" "exp")
|
|
@deffn {Scheme Procedure} exp z
|
|
Return e to the power of @var{z}, where e is the base of natural
|
|
logarithms (2.71828@dots{}).
|
|
@end deffn
|
|
|
|
@rnindex log
|
|
@c begin (texi-doc-string "guile" "log")
|
|
@deffn {Scheme Procedure} log z
|
|
Return the natural logarithm of @var{z}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "log10")
|
|
@deffn {Scheme Procedure} log10 z
|
|
Return the base 10 logarithm of @var{z}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "sinh")
|
|
@deffn {Scheme Procedure} sinh z
|
|
Return the hyperbolic sine of @var{z}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "cosh")
|
|
@deffn {Scheme Procedure} cosh z
|
|
Return the hyperbolic cosine of @var{z}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "tanh")
|
|
@deffn {Scheme Procedure} tanh z
|
|
Return the hyperbolic tangent of @var{z}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "asinh")
|
|
@deffn {Scheme Procedure} asinh z
|
|
Return the hyperbolic arcsine of @var{z}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "acosh")
|
|
@deffn {Scheme Procedure} acosh z
|
|
Return the hyperbolic arccosine of @var{z}.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "atanh")
|
|
@deffn {Scheme Procedure} atanh z
|
|
Return the hyperbolic arctangent of @var{z}.
|
|
@end deffn
|
|
|
|
|
|
@node Bitwise Operations
|
|
@subsubsection Bitwise Operations
|
|
|
|
For the following bitwise functions, negative numbers are treated as
|
|
infinite precision twos-complements. For instance @math{-6} is bits
|
|
@math{@dots{}111010}, with infinitely many ones on the left. It can
|
|
be seen that adding 6 (binary 110) to such a bit pattern gives all
|
|
zeros.
|
|
|
|
@deffn {Scheme Procedure} logand n1 n2 @dots{}
|
|
@deffnx {C Function} scm_logand (n1, n2)
|
|
Return the bitwise @sc{and} of the integer arguments.
|
|
|
|
@lisp
|
|
(logand) @result{} -1
|
|
(logand 7) @result{} 7
|
|
(logand #b111 #b011 #b001) @result{} 1
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} logior n1 n2 @dots{}
|
|
@deffnx {C Function} scm_logior (n1, n2)
|
|
Return the bitwise @sc{or} of the integer arguments.
|
|
|
|
@lisp
|
|
(logior) @result{} 0
|
|
(logior 7) @result{} 7
|
|
(logior #b000 #b001 #b011) @result{} 3
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} logxor n1 n2 @dots{}
|
|
@deffnx {C Function} scm_loxor (n1, n2)
|
|
Return the bitwise @sc{xor} of the integer arguments. A bit is
|
|
set in the result if it is set in an odd number of arguments.
|
|
|
|
@lisp
|
|
(logxor) @result{} 0
|
|
(logxor 7) @result{} 7
|
|
(logxor #b000 #b001 #b011) @result{} 2
|
|
(logxor #b000 #b001 #b011 #b011) @result{} 1
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} lognot n
|
|
@deffnx {C Function} scm_lognot (n)
|
|
Return the integer which is the ones-complement of the integer
|
|
argument, ie.@: each 0 bit is changed to 1 and each 1 bit to 0.
|
|
|
|
@lisp
|
|
(number->string (lognot #b10000000) 2)
|
|
@result{} "-10000001"
|
|
(number->string (lognot #b0) 2)
|
|
@result{} "-1"
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} logtest j k
|
|
@deffnx {C Function} scm_logtest (j, k)
|
|
Test whether @var{j} and @var{k} have any 1 bits in common. This is
|
|
equivalent to @code{(not (zero? (logand j k)))}, but without actually
|
|
calculating the @code{logand}, just testing for non-zero.
|
|
|
|
@lisp
|
|
(logtest #b0100 #b1011) @result{} #f
|
|
(logtest #b0100 #b0111) @result{} #t
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} logbit? index j
|
|
@deffnx {C Function} scm_logbit_p (index, j)
|
|
Test whether bit number @var{index} in @var{j} is set. @var{index}
|
|
starts from 0 for the least significant bit.
|
|
|
|
@lisp
|
|
(logbit? 0 #b1101) @result{} #t
|
|
(logbit? 1 #b1101) @result{} #f
|
|
(logbit? 2 #b1101) @result{} #t
|
|
(logbit? 3 #b1101) @result{} #t
|
|
(logbit? 4 #b1101) @result{} #f
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} ash n count
|
|
@deffnx {C Function} scm_ash (n, count)
|
|
Return @math{floor(n * 2^{count})}.
|
|
@var{n} and @var{count} must be exact integers.
|
|
|
|
With @var{n} viewed as an infinite-precision twos-complement
|
|
integer, @code{ash} means a left shift introducing zero bits
|
|
when @var{count} is positive, or a right shift dropping bits
|
|
when @var{count} is negative. This is an ``arithmetic'' shift.
|
|
|
|
@lisp
|
|
(number->string (ash #b1 3) 2) @result{} "1000"
|
|
(number->string (ash #b1010 -1) 2) @result{} "101"
|
|
|
|
;; -23 is bits ...11101001, -6 is bits ...111010
|
|
(ash -23 -2) @result{} -6
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} round-ash n count
|
|
@deffnx {C Function} scm_round_ash (n, count)
|
|
Return @math{round(n * 2^count)}.
|
|
@var{n} and @var{count} must be exact integers.
|
|
|
|
With @var{n} viewed as an infinite-precision twos-complement
|
|
integer, @code{round-ash} means a left shift introducing zero
|
|
bits when @var{count} is positive, or a right shift rounding
|
|
to the nearest integer (with ties going to the nearest even
|
|
integer) when @var{count} is negative. This is a rounded
|
|
``arithmetic'' shift.
|
|
|
|
@lisp
|
|
(number->string (round-ash #b1 3) 2) @result{} \"1000\"
|
|
(number->string (round-ash #b1010 -1) 2) @result{} \"101\"
|
|
(number->string (round-ash #b1010 -2) 2) @result{} \"10\"
|
|
(number->string (round-ash #b1011 -2) 2) @result{} \"11\"
|
|
(number->string (round-ash #b1101 -2) 2) @result{} \"11\"
|
|
(number->string (round-ash #b1110 -2) 2) @result{} \"100\"
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} logcount n
|
|
@deffnx {C Function} scm_logcount (n)
|
|
Return the number of bits in integer @var{n}. If @var{n} is
|
|
positive, the 1-bits in its binary representation are counted.
|
|
If negative, the 0-bits in its two's-complement binary
|
|
representation are counted. If zero, 0 is returned.
|
|
|
|
@lisp
|
|
(logcount #b10101010)
|
|
@result{} 4
|
|
(logcount 0)
|
|
@result{} 0
|
|
(logcount -2)
|
|
@result{} 1
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} integer-length n
|
|
@deffnx {C Function} scm_integer_length (n)
|
|
Return the number of bits necessary to represent @var{n}.
|
|
|
|
For positive @var{n} this is how many bits to the most significant one
|
|
bit. For negative @var{n} it's how many bits to the most significant
|
|
zero bit in twos complement form.
|
|
|
|
@lisp
|
|
(integer-length #b10101010) @result{} 8
|
|
(integer-length #b1111) @result{} 4
|
|
(integer-length 0) @result{} 0
|
|
(integer-length -1) @result{} 0
|
|
(integer-length -256) @result{} 8
|
|
(integer-length -257) @result{} 9
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} integer-expt n k
|
|
@deffnx {C Function} scm_integer_expt (n, k)
|
|
Return @var{n} raised to the power @var{k}. @var{k} must be an exact
|
|
integer, @var{n} can be any number.
|
|
|
|
Negative @var{k} is supported, and results in @m{1/n^|k|, 1/n^abs(k)}
|
|
in the usual way. @math{@var{n}^0} is 1, as usual, and that includes
|
|
@math{0^0} is 1.
|
|
|
|
@lisp
|
|
(integer-expt 2 5) @result{} 32
|
|
(integer-expt -3 3) @result{} -27
|
|
(integer-expt 5 -3) @result{} 1/125
|
|
(integer-expt 0 0) @result{} 1
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bit-extract n start end
|
|
@deffnx {C Function} scm_bit_extract (n, start, end)
|
|
Return the integer composed of the @var{start} (inclusive)
|
|
through @var{end} (exclusive) bits of @var{n}. The
|
|
@var{start}th bit becomes the 0-th bit in the result.
|
|
|
|
@lisp
|
|
(number->string (bit-extract #b1101101010 0 4) 2)
|
|
@result{} "1010"
|
|
(number->string (bit-extract #b1101101010 4 9) 2)
|
|
@result{} "10110"
|
|
@end lisp
|
|
@end deffn
|
|
|
|
|
|
@node Random
|
|
@subsubsection Random Number Generation
|
|
|
|
Pseudo-random numbers are generated from a random state object, which
|
|
can be created with @code{seed->random-state} or
|
|
@code{datum->random-state}. An external representation (i.e.@: one
|
|
which can written with @code{write} and read with @code{read}) of a
|
|
random state object can be obtained via
|
|
@code{random-state->datum}. The @var{state} parameter to the
|
|
various functions below is optional, it defaults to the state object
|
|
in the @code{*random-state*} variable.
|
|
|
|
@deffn {Scheme Procedure} copy-random-state [state]
|
|
@deffnx {C Function} scm_copy_random_state (state)
|
|
Return a copy of the random state @var{state}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} random n [state]
|
|
@deffnx {C Function} scm_random (n, state)
|
|
Return a number in [0, @var{n}).
|
|
|
|
Accepts a positive integer or real n and returns a
|
|
number of the same type between zero (inclusive) and
|
|
@var{n} (exclusive). The values returned have a uniform
|
|
distribution.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} random:exp [state]
|
|
@deffnx {C Function} scm_random_exp (state)
|
|
Return an inexact real in an exponential distribution with mean
|
|
1. For an exponential distribution with mean @var{u} use @code{(*
|
|
@var{u} (random:exp))}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} random:hollow-sphere! vect [state]
|
|
@deffnx {C Function} scm_random_hollow_sphere_x (vect, state)
|
|
Fills @var{vect} with inexact real random numbers the sum of whose
|
|
squares is equal to 1.0. Thinking of @var{vect} as coordinates in
|
|
space of dimension @var{n} @math{=} @code{(vector-length @var{vect})},
|
|
the coordinates are uniformly distributed over the surface of the unit
|
|
n-sphere.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} random:normal [state]
|
|
@deffnx {C Function} scm_random_normal (state)
|
|
Return an inexact real in a normal distribution. The distribution
|
|
used has mean 0 and standard deviation 1. For a normal distribution
|
|
with mean @var{m} and standard deviation @var{d} use @code{(+ @var{m}
|
|
(* @var{d} (random:normal)))}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} random:normal-vector! vect [state]
|
|
@deffnx {C Function} scm_random_normal_vector_x (vect, state)
|
|
Fills @var{vect} with inexact real random numbers that are
|
|
independent and standard normally distributed
|
|
(i.e., with mean 0 and variance 1).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} random:solid-sphere! vect [state]
|
|
@deffnx {C Function} scm_random_solid_sphere_x (vect, state)
|
|
Fills @var{vect} with inexact real random numbers the sum of whose
|
|
squares is less than 1.0. Thinking of @var{vect} as coordinates in
|
|
space of dimension @var{n} @math{=} @code{(vector-length @var{vect})},
|
|
the coordinates are uniformly distributed within the unit
|
|
@var{n}-sphere.
|
|
@c FIXME: What does this mean, particularly the n-sphere part?
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} random:uniform [state]
|
|
@deffnx {C Function} scm_random_uniform (state)
|
|
Return a uniformly distributed inexact real random number in
|
|
[0,1).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} seed->random-state seed
|
|
@deffnx {C Function} scm_seed_to_random_state (seed)
|
|
Return a new random state using @var{seed}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} datum->random-state datum
|
|
@deffnx {C Function} scm_datum_to_random_state (datum)
|
|
Return a new random state from @var{datum}, which should have been
|
|
obtained by @code{random-state->datum}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} random-state->datum state
|
|
@deffnx {C Function} scm_random_state_to_datum (state)
|
|
Return a datum representation of @var{state} that may be written out and
|
|
read back with the Scheme reader.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} random-state-from-platform
|
|
@deffnx {C Function} scm_random_state_from_platform ()
|
|
Construct a new random state seeded from a platform-specific source of
|
|
entropy, appropriate for use in non-security-critical applications.
|
|
Currently @file{/dev/urandom} is tried first, or else the seed is based
|
|
on the time, date, process ID, an address from a freshly allocated heap
|
|
cell, an address from the local stack frame, and a high-resolution timer
|
|
if available.
|
|
@end deffn
|
|
|
|
@defvar *random-state*
|
|
The global random state used by the above functions when the
|
|
@var{state} parameter is not given.
|
|
@end defvar
|
|
|
|
Note that the initial value of @code{*random-state*} is the same every
|
|
time Guile starts up. Therefore, if you don't pass a @var{state}
|
|
parameter to the above procedures, and you don't set
|
|
@code{*random-state*} to @code{(seed->random-state your-seed)}, where
|
|
@code{your-seed} is something that @emph{isn't} the same every time,
|
|
you'll get the same sequence of ``random'' numbers on every run.
|
|
|
|
For example, unless the relevant source code has changed, @code{(map
|
|
random (cdr (iota 30)))}, if the first use of random numbers since
|
|
Guile started up, will always give:
|
|
|
|
@lisp
|
|
(map random (cdr (iota 19)))
|
|
@result{}
|
|
(0 1 1 2 2 2 1 2 6 7 10 0 5 3 12 5 5 12)
|
|
@end lisp
|
|
|
|
To seed the random state in a sensible way for non-security-critical
|
|
applications, do this during initialization of your program:
|
|
|
|
@lisp
|
|
(set! *random-state* (random-state-from-platform))
|
|
@end lisp
|
|
|
|
|
|
@node Characters
|
|
@subsection Characters
|
|
@tpindex Characters
|
|
|
|
In Scheme, there is a data type to describe a single character.
|
|
|
|
Defining what exactly a character @emph{is} can be more complicated
|
|
than it seems. Guile follows the advice of R6RS and uses The Unicode
|
|
Standard to help define what a character is. So, for Guile, a
|
|
character is anything in the Unicode Character Database.
|
|
|
|
@cindex code point
|
|
@cindex Unicode code point
|
|
|
|
The Unicode Character Database is basically a table of characters
|
|
indexed using integers called 'code points'. Valid code points are in
|
|
the ranges 0 to @code{#xD7FF} inclusive or @code{#xE000} to
|
|
@code{#x10FFFF} inclusive, which is about 1.1 million code points.
|
|
|
|
@cindex designated code point
|
|
@cindex code point, designated
|
|
|
|
Any code point that has been assigned to a character or that has
|
|
otherwise been given a meaning by Unicode is called a 'designated code
|
|
point'. Most of the designated code points, about 200,000 of them,
|
|
indicate characters, accents or other combining marks that modify
|
|
other characters, symbols, whitespace, and control characters. Some
|
|
are not characters but indicators that suggest how to format or
|
|
display neighboring characters.
|
|
|
|
@cindex reserved code point
|
|
@cindex code point, reserved
|
|
|
|
If a code point is not a designated code point -- if it has not been
|
|
assigned to a character by The Unicode Standard -- it is a 'reserved
|
|
code point', meaning that they are reserved for future use. Most of
|
|
the code points, about 800,000, are 'reserved code points'.
|
|
|
|
By convention, a Unicode code point is written as
|
|
``U+XXXX'' where ``XXXX'' is a hexadecimal number. Please note that
|
|
this convenient notation is not valid code. Guile does not interpret
|
|
``U+XXXX'' as a character.
|
|
|
|
In Scheme, a character literal is written as @code{#\@var{name}} where
|
|
@var{name} is the name of the character that you want. Printable
|
|
characters have their usual single character name; for example,
|
|
@code{#\a} is a lower case @code{a}.
|
|
|
|
Some of the code points are 'combining characters' that are not meant
|
|
to be printed by themselves but are instead meant to modify the
|
|
appearance of the previous character. For combining characters, an
|
|
alternate form of the character literal is @code{#\} followed by
|
|
U+25CC (a small, dotted circle), followed by the combining character.
|
|
This allows the combining character to be drawn on the circle, not on
|
|
the backslash of @code{#\}.
|
|
|
|
Many of the non-printing characters, such as whitespace characters and
|
|
control characters, also have names.
|
|
|
|
The most commonly used non-printing characters have long character
|
|
names, described in the table below.
|
|
|
|
@multitable {@code{#\backspace}} {Preferred}
|
|
@item Character Name @tab Codepoint
|
|
@item @code{#\nul} @tab U+0000
|
|
@item @code{#\alarm} @tab U+0007
|
|
@item @code{#\backspace} @tab U+0008
|
|
@item @code{#\tab} @tab U+0009
|
|
@item @code{#\linefeed} @tab U+000A
|
|
@item @code{#\newline} @tab U+000A
|
|
@item @code{#\vtab} @tab U+000B
|
|
@item @code{#\page} @tab U+000C
|
|
@item @code{#\return} @tab U+000D
|
|
@item @code{#\esc} @tab U+001B
|
|
@item @code{#\space} @tab U+0020
|
|
@item @code{#\delete} @tab U+007F
|
|
@end multitable
|
|
|
|
There are also short names for all of the ``C0 control characters''
|
|
(those with code points below 32). The following table lists the short
|
|
name for each character.
|
|
|
|
@multitable @columnfractions .25 .25 .25 .25
|
|
@item 0 = @code{#\nul}
|
|
@tab 1 = @code{#\soh}
|
|
@tab 2 = @code{#\stx}
|
|
@tab 3 = @code{#\etx}
|
|
@item 4 = @code{#\eot}
|
|
@tab 5 = @code{#\enq}
|
|
@tab 6 = @code{#\ack}
|
|
@tab 7 = @code{#\bel}
|
|
@item 8 = @code{#\bs}
|
|
@tab 9 = @code{#\ht}
|
|
@tab 10 = @code{#\lf}
|
|
@tab 11 = @code{#\vt}
|
|
@item 12 = @code{#\ff}
|
|
@tab 13 = @code{#\cr}
|
|
@tab 14 = @code{#\so}
|
|
@tab 15 = @code{#\si}
|
|
@item 16 = @code{#\dle}
|
|
@tab 17 = @code{#\dc1}
|
|
@tab 18 = @code{#\dc2}
|
|
@tab 19 = @code{#\dc3}
|
|
@item 20 = @code{#\dc4}
|
|
@tab 21 = @code{#\nak}
|
|
@tab 22 = @code{#\syn}
|
|
@tab 23 = @code{#\etb}
|
|
@item 24 = @code{#\can}
|
|
@tab 25 = @code{#\em}
|
|
@tab 26 = @code{#\sub}
|
|
@tab 27 = @code{#\esc}
|
|
@item 28 = @code{#\fs}
|
|
@tab 29 = @code{#\gs}
|
|
@tab 30 = @code{#\rs}
|
|
@tab 31 = @code{#\us}
|
|
@item 32 = @code{#\sp}
|
|
@end multitable
|
|
|
|
The short name for the ``delete'' character (code point U+007F) is
|
|
@code{#\del}.
|
|
|
|
The R7RS name for the ``escape'' character (code point U+001B) is
|
|
@code{#\escape}.
|
|
|
|
There are also a few alternative names left over for compatibility with
|
|
previous versions of Guile.
|
|
|
|
@multitable {@code{#\backspace}} {Preferred}
|
|
@item Alternate @tab Standard
|
|
@item @code{#\nl} @tab @code{#\newline}
|
|
@item @code{#\np} @tab @code{#\page}
|
|
@item @code{#\null} @tab @code{#\nul}
|
|
@end multitable
|
|
|
|
Characters may also be written using their code point values. They can
|
|
be written with as an octal number, such as @code{#\10} for
|
|
@code{#\bs} or @code{#\177} for @code{#\del}.
|
|
|
|
If one prefers hex to octal, there is an additional syntax for character
|
|
escapes: @code{#\xHHHH} -- the letter 'x' followed by a hexadecimal
|
|
number of one to eight digits.
|
|
|
|
@rnindex char?
|
|
@deffn {Scheme Procedure} char? x
|
|
@deffnx {C Function} scm_char_p (x)
|
|
Return @code{#t} if @var{x} is a character, else @code{#f}.
|
|
@end deffn
|
|
|
|
Fundamentally, the character comparison operations below are
|
|
numeric comparisons of the character's code points.
|
|
|
|
@rnindex char=?
|
|
@deffn {Scheme Procedure} char=? x y
|
|
Return @code{#t} if code point of @var{x} is equal to the code point
|
|
of @var{y}, else @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char<?
|
|
@deffn {Scheme Procedure} char<? x y
|
|
Return @code{#t} if the code point of @var{x} is less than the code
|
|
point of @var{y}, else @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char<=?
|
|
@deffn {Scheme Procedure} char<=? x y
|
|
Return @code{#t} if the code point of @var{x} is less than or equal
|
|
to the code point of @var{y}, else @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char>?
|
|
@deffn {Scheme Procedure} char>? x y
|
|
Return @code{#t} if the code point of @var{x} is greater than the
|
|
code point of @var{y}, else @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char>=?
|
|
@deffn {Scheme Procedure} char>=? x y
|
|
Return @code{#t} if the code point of @var{x} is greater than or
|
|
equal to the code point of @var{y}, else @code{#f}.
|
|
@end deffn
|
|
|
|
@cindex case folding
|
|
|
|
Case-insensitive character comparisons use @emph{Unicode case
|
|
folding}. In case folding comparisons, if a character is lowercase
|
|
and has an uppercase form that can be expressed as a single character,
|
|
it is converted to uppercase before comparison. All other characters
|
|
undergo no conversion before the comparison occurs. This includes the
|
|
German sharp S (Eszett) which is not uppercased before conversion
|
|
because its uppercase form has two characters. Unicode case folding
|
|
is language independent: it uses rules that are generally true, but,
|
|
it cannot cover all cases for all languages.
|
|
|
|
@rnindex char-ci=?
|
|
@deffn {Scheme Procedure} char-ci=? x y
|
|
Return @code{#t} if the case-folded code point of @var{x} is the same
|
|
as the case-folded code point of @var{y}, else @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char-ci<?
|
|
@deffn {Scheme Procedure} char-ci<? x y
|
|
Return @code{#t} if the case-folded code point of @var{x} is less
|
|
than the case-folded code point of @var{y}, else @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char-ci<=?
|
|
@deffn {Scheme Procedure} char-ci<=? x y
|
|
Return @code{#t} if the case-folded code point of @var{x} is less
|
|
than or equal to the case-folded code point of @var{y}, else
|
|
@code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char-ci>?
|
|
@deffn {Scheme Procedure} char-ci>? x y
|
|
Return @code{#t} if the case-folded code point of @var{x} is greater
|
|
than the case-folded code point of @var{y}, else @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char-ci>=?
|
|
@deffn {Scheme Procedure} char-ci>=? x y
|
|
Return @code{#t} if the case-folded code point of @var{x} is greater
|
|
than or equal to the case-folded code point of @var{y}, else
|
|
@code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char-alphabetic?
|
|
@deffn {Scheme Procedure} char-alphabetic? chr
|
|
@deffnx {C Function} scm_char_alphabetic_p (chr)
|
|
Return @code{#t} if @var{chr} is alphabetic, else @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char-numeric?
|
|
@deffn {Scheme Procedure} char-numeric? chr
|
|
@deffnx {C Function} scm_char_numeric_p (chr)
|
|
Return @code{#t} if @var{chr} is numeric, else @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char-whitespace?
|
|
@deffn {Scheme Procedure} char-whitespace? chr
|
|
@deffnx {C Function} scm_char_whitespace_p (chr)
|
|
Return @code{#t} if @var{chr} is whitespace, else @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char-upper-case?
|
|
@deffn {Scheme Procedure} char-upper-case? chr
|
|
@deffnx {C Function} scm_char_upper_case_p (chr)
|
|
Return @code{#t} if @var{chr} is uppercase, else @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex char-lower-case?
|
|
@deffn {Scheme Procedure} char-lower-case? chr
|
|
@deffnx {C Function} scm_char_lower_case_p (chr)
|
|
Return @code{#t} if @var{chr} is lowercase, else @code{#f}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-is-both? chr
|
|
@deffnx {C Function} scm_char_is_both_p (chr)
|
|
Return @code{#t} if @var{chr} is either uppercase or lowercase, else
|
|
@code{#f}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-general-category chr
|
|
@deffnx {C Function} scm_char_general_category (chr)
|
|
Return a symbol giving the two-letter name of the Unicode general
|
|
category assigned to @var{chr} or @code{#f} if no named category is
|
|
assigned. The following table provides a list of category names along
|
|
with their meanings.
|
|
|
|
@multitable @columnfractions .1 .4 .1 .4
|
|
@item Lu
|
|
@tab Uppercase letter
|
|
@tab Pf
|
|
@tab Final quote punctuation
|
|
@item Ll
|
|
@tab Lowercase letter
|
|
@tab Po
|
|
@tab Other punctuation
|
|
@item Lt
|
|
@tab Titlecase letter
|
|
@tab Sm
|
|
@tab Math symbol
|
|
@item Lm
|
|
@tab Modifier letter
|
|
@tab Sc
|
|
@tab Currency symbol
|
|
@item Lo
|
|
@tab Other letter
|
|
@tab Sk
|
|
@tab Modifier symbol
|
|
@item Mn
|
|
@tab Non-spacing mark
|
|
@tab So
|
|
@tab Other symbol
|
|
@item Mc
|
|
@tab Combining spacing mark
|
|
@tab Zs
|
|
@tab Space separator
|
|
@item Me
|
|
@tab Enclosing mark
|
|
@tab Zl
|
|
@tab Line separator
|
|
@item Nd
|
|
@tab Decimal digit number
|
|
@tab Zp
|
|
@tab Paragraph separator
|
|
@item Nl
|
|
@tab Letter number
|
|
@tab Cc
|
|
@tab Control
|
|
@item No
|
|
@tab Other number
|
|
@tab Cf
|
|
@tab Format
|
|
@item Pc
|
|
@tab Connector punctuation
|
|
@tab Cs
|
|
@tab Surrogate
|
|
@item Pd
|
|
@tab Dash punctuation
|
|
@tab Co
|
|
@tab Private use
|
|
@item Ps
|
|
@tab Open punctuation
|
|
@tab Cn
|
|
@tab Unassigned
|
|
@item Pe
|
|
@tab Close punctuation
|
|
@tab
|
|
@tab
|
|
@item Pi
|
|
@tab Initial quote punctuation
|
|
@tab
|
|
@tab
|
|
@end multitable
|
|
@end deffn
|
|
|
|
@rnindex char->integer
|
|
@deffn {Scheme Procedure} char->integer chr
|
|
@deffnx {C Function} scm_char_to_integer (chr)
|
|
Return the code point of @var{chr}.
|
|
@end deffn
|
|
|
|
@rnindex integer->char
|
|
@deffn {Scheme Procedure} integer->char n
|
|
@deffnx {C Function} scm_integer_to_char (n)
|
|
Return the character that has code point @var{n}. The integer @var{n}
|
|
must be a valid code point. Valid code points are in the ranges 0 to
|
|
@code{#xD7FF} inclusive or @code{#xE000} to @code{#x10FFFF} inclusive.
|
|
@end deffn
|
|
|
|
@rnindex char-upcase
|
|
@deffn {Scheme Procedure} char-upcase chr
|
|
@deffnx {C Function} scm_char_upcase (chr)
|
|
Return the uppercase character version of @var{chr}.
|
|
@end deffn
|
|
|
|
@rnindex char-downcase
|
|
@deffn {Scheme Procedure} char-downcase chr
|
|
@deffnx {C Function} scm_char_downcase (chr)
|
|
Return the lowercase character version of @var{chr}.
|
|
@end deffn
|
|
|
|
@rnindex char-titlecase
|
|
@deffn {Scheme Procedure} char-titlecase chr
|
|
@deffnx {C Function} scm_char_titlecase (chr)
|
|
Return the titlecase character version of @var{chr} if one exists;
|
|
otherwise return the uppercase version.
|
|
|
|
For most characters these will be the same, but the Unicode Standard
|
|
includes certain digraph compatibility characters, such as @code{U+01F3}
|
|
``dz'', for which the uppercase and titlecase characters are different
|
|
(@code{U+01F1} ``DZ'' and @code{U+01F2} ``Dz'' in this case,
|
|
respectively).
|
|
@end deffn
|
|
|
|
@tindex scm_t_wchar
|
|
@deftypefn {C Function} scm_t_wchar scm_c_upcase (scm_t_wchar @var{c})
|
|
@deftypefnx {C Function} scm_t_wchar scm_c_downcase (scm_t_wchar @var{c})
|
|
@deftypefnx {C Function} scm_t_wchar scm_c_titlecase (scm_t_wchar @var{c})
|
|
|
|
These C functions take an integer representation of a Unicode
|
|
codepoint and return the codepoint corresponding to its uppercase,
|
|
lowercase, and titlecase forms respectively. The type
|
|
@code{scm_t_wchar} is a signed, 32-bit integer.
|
|
@end deftypefn
|
|
|
|
Characters also have ``formal names'', which are defined by Unicode.
|
|
These names can be accessed in Guile from the @code{(ice-9 unicode)}
|
|
module:
|
|
|
|
@example
|
|
(use-modules (ice-9 unicode))
|
|
@end example
|
|
|
|
@deffn {Scheme Procedure} char->formal-name chr
|
|
Return the formal all-upper-case Unicode name of @var{ch},
|
|
as a string, or @code{#f} if the character has no name.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} formal-name->char name
|
|
Return the character whose formal all-upper-case Unicode name is
|
|
@var{name}, or @code{#f} if no such character is known.
|
|
@end deffn
|
|
|
|
@node Character Sets
|
|
@subsection Character Sets
|
|
|
|
The features described in this section correspond directly to SRFI-14.
|
|
|
|
The data type @dfn{charset} implements sets of characters
|
|
(@pxref{Characters}). Because the internal representation of
|
|
character sets is not visible to the user, a lot of procedures for
|
|
handling them are provided.
|
|
|
|
Character sets can be created, extended, tested for the membership of a
|
|
characters and be compared to other character sets.
|
|
|
|
@menu
|
|
* Character Set Predicates/Comparison::
|
|
* Iterating Over Character Sets:: Enumerate charset elements.
|
|
* Creating Character Sets:: Making new charsets.
|
|
* Querying Character Sets:: Test charsets for membership etc.
|
|
* Character-Set Algebra:: Calculating new charsets.
|
|
* Standard Character Sets:: Variables containing predefined charsets.
|
|
@end menu
|
|
|
|
@node Character Set Predicates/Comparison
|
|
@subsubsection Character Set Predicates/Comparison
|
|
|
|
Use these procedures for testing whether an object is a character set,
|
|
or whether several character sets are equal or subsets of each other.
|
|
@code{char-set-hash} can be used for calculating a hash value, maybe for
|
|
usage in fast lookup procedures.
|
|
|
|
@deffn {Scheme Procedure} char-set? obj
|
|
@deffnx {C Function} scm_char_set_p (obj)
|
|
Return @code{#t} if @var{obj} is a character set, @code{#f}
|
|
otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set= char_set @dots{}
|
|
@deffnx {C Function} scm_char_set_eq (char_sets)
|
|
Return @code{#t} if all given character sets are equal.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set<= char_set @dots{}
|
|
@deffnx {C Function} scm_char_set_leq (char_sets)
|
|
Return @code{#t} if every character set @var{char_set}i is a subset
|
|
of character set @var{char_set}i+1.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-hash cs [bound]
|
|
@deffnx {C Function} scm_char_set_hash (cs, bound)
|
|
Compute a hash value for the character set @var{cs}. If
|
|
@var{bound} is given and non-zero, it restricts the
|
|
returned value to the range 0 @dots{} @var{bound} - 1.
|
|
@end deffn
|
|
|
|
@c ===================================================================
|
|
|
|
@node Iterating Over Character Sets
|
|
@subsubsection Iterating Over Character Sets
|
|
|
|
Character set cursors are a means for iterating over the members of a
|
|
character sets. After creating a character set cursor with
|
|
@code{char-set-cursor}, a cursor can be dereferenced with
|
|
@code{char-set-ref}, advanced to the next member with
|
|
@code{char-set-cursor-next}. Whether a cursor has passed past the last
|
|
element of the set can be checked with @code{end-of-char-set?}.
|
|
|
|
Additionally, mapping and (un-)folding procedures for character sets are
|
|
provided.
|
|
|
|
@deffn {Scheme Procedure} char-set-cursor cs
|
|
@deffnx {C Function} scm_char_set_cursor (cs)
|
|
Return a cursor into the character set @var{cs}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-ref cs cursor
|
|
@deffnx {C Function} scm_char_set_ref (cs, cursor)
|
|
Return the character at the current cursor position
|
|
@var{cursor} in the character set @var{cs}. It is an error to
|
|
pass a cursor for which @code{end-of-char-set?} returns true.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-cursor-next cs cursor
|
|
@deffnx {C Function} scm_char_set_cursor_next (cs, cursor)
|
|
Advance the character set cursor @var{cursor} to the next
|
|
character in the character set @var{cs}. It is an error if the
|
|
cursor given satisfies @code{end-of-char-set?}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} end-of-char-set? cursor
|
|
@deffnx {C Function} scm_end_of_char_set_p (cursor)
|
|
Return @code{#t} if @var{cursor} has reached the end of a
|
|
character set, @code{#f} otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-fold kons knil cs
|
|
@deffnx {C Function} scm_char_set_fold (kons, knil, cs)
|
|
Fold the procedure @var{kons} over the character set @var{cs},
|
|
initializing it with @var{knil}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-unfold p f g seed [base_cs]
|
|
@deffnx {C Function} scm_char_set_unfold (p, f, g, seed, base_cs)
|
|
This is a fundamental constructor for character sets.
|
|
@itemize @bullet
|
|
@item @var{g} is used to generate a series of ``seed'' values
|
|
from the initial seed: @var{seed}, (@var{g} @var{seed}),
|
|
(@var{g}^2 @var{seed}), (@var{g}^3 @var{seed}), @dots{}
|
|
@item @var{p} tells us when to stop -- when it returns true
|
|
when applied to one of the seed values.
|
|
@item @var{f} maps each seed value to a character. These
|
|
characters are added to the base character set @var{base_cs} to
|
|
form the result; @var{base_cs} defaults to the empty set.
|
|
@end itemize
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-unfold! p f g seed base_cs
|
|
@deffnx {C Function} scm_char_set_unfold_x (p, f, g, seed, base_cs)
|
|
This is a fundamental constructor for character sets.
|
|
@itemize @bullet
|
|
@item @var{g} is used to generate a series of ``seed'' values
|
|
from the initial seed: @var{seed}, (@var{g} @var{seed}),
|
|
(@var{g}^2 @var{seed}), (@var{g}^3 @var{seed}), @dots{}
|
|
@item @var{p} tells us when to stop -- when it returns true
|
|
when applied to one of the seed values.
|
|
@item @var{f} maps each seed value to a character. These
|
|
characters are added to the base character set @var{base_cs} to
|
|
form the result; @var{base_cs} defaults to the empty set.
|
|
@end itemize
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-for-each proc cs
|
|
@deffnx {C Function} scm_char_set_for_each (proc, cs)
|
|
Apply @var{proc} to every character in the character set
|
|
@var{cs}. The return value is not specified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-map proc cs
|
|
@deffnx {C Function} scm_char_set_map (proc, cs)
|
|
Map the procedure @var{proc} over every character in @var{cs}.
|
|
@var{proc} must be a character -> character procedure.
|
|
@end deffn
|
|
|
|
@c ===================================================================
|
|
|
|
@node Creating Character Sets
|
|
@subsubsection Creating Character Sets
|
|
|
|
New character sets are produced with these procedures.
|
|
|
|
@deffn {Scheme Procedure} char-set-copy cs
|
|
@deffnx {C Function} scm_char_set_copy (cs)
|
|
Return a newly allocated character set containing all
|
|
characters in @var{cs}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set chr @dots{}
|
|
@deffnx {C Function} scm_char_set (chrs)
|
|
Return a character set containing all given characters.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list->char-set list [base_cs]
|
|
@deffnx {C Function} scm_list_to_char_set (list, base_cs)
|
|
Convert the character list @var{list} to a character set. If
|
|
the character set @var{base_cs} is given, the character in this
|
|
set are also included in the result.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list->char-set! list base_cs
|
|
@deffnx {C Function} scm_list_to_char_set_x (list, base_cs)
|
|
Convert the character list @var{list} to a character set. The
|
|
characters are added to @var{base_cs} and @var{base_cs} is
|
|
returned.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string->char-set str [base_cs]
|
|
@deffnx {C Function} scm_string_to_char_set (str, base_cs)
|
|
Convert the string @var{str} to a character set. If the
|
|
character set @var{base_cs} is given, the characters in this
|
|
set are also included in the result.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string->char-set! str base_cs
|
|
@deffnx {C Function} scm_string_to_char_set_x (str, base_cs)
|
|
Convert the string @var{str} to a character set. The
|
|
characters from the string are added to @var{base_cs}, and
|
|
@var{base_cs} is returned.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-filter pred cs [base_cs]
|
|
@deffnx {C Function} scm_char_set_filter (pred, cs, base_cs)
|
|
Return a character set containing every character from @var{cs}
|
|
so that it satisfies @var{pred}. If provided, the characters
|
|
from @var{base_cs} are added to the result.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-filter! pred cs base_cs
|
|
@deffnx {C Function} scm_char_set_filter_x (pred, cs, base_cs)
|
|
Return a character set containing every character from @var{cs}
|
|
so that it satisfies @var{pred}. The characters are added to
|
|
@var{base_cs} and @var{base_cs} is returned.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} ucs-range->char-set lower upper [error [base_cs]]
|
|
@deffnx {C Function} scm_ucs_range_to_char_set (lower, upper, error, base_cs)
|
|
Return a character set containing all characters whose
|
|
character codes lie in the half-open range
|
|
[@var{lower},@var{upper}).
|
|
|
|
If @var{error} is a true value, an error is signaled if the
|
|
specified range contains characters which are not contained in
|
|
the implemented character range. If @var{error} is @code{#f},
|
|
these characters are silently left out of the resulting
|
|
character set.
|
|
|
|
The characters in @var{base_cs} are added to the result, if
|
|
given.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} ucs-range->char-set! lower upper error base_cs
|
|
@deffnx {C Function} scm_ucs_range_to_char_set_x (lower, upper, error, base_cs)
|
|
Return a character set containing all characters whose
|
|
character codes lie in the half-open range
|
|
[@var{lower},@var{upper}).
|
|
|
|
If @var{error} is a true value, an error is signaled if the
|
|
specified range contains characters which are not contained in
|
|
the implemented character range. If @var{error} is @code{#f},
|
|
these characters are silently left out of the resulting
|
|
character set.
|
|
|
|
The characters are added to @var{base_cs} and @var{base_cs} is
|
|
returned.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} ->char-set x
|
|
@deffnx {C Function} scm_to_char_set (x)
|
|
Coerces x into a char-set. @var{x} may be a string, character or
|
|
char-set. A string is converted to the set of its constituent
|
|
characters; a character is converted to a singleton set; a char-set is
|
|
returned as-is.
|
|
@end deffn
|
|
|
|
@c ===================================================================
|
|
|
|
@node Querying Character Sets
|
|
@subsubsection Querying Character Sets
|
|
|
|
Access the elements and other information of a character set with these
|
|
procedures.
|
|
|
|
@deffn {Scheme Procedure} %char-set-dump cs
|
|
Returns an association list containing debugging information
|
|
for @var{cs}. The association list has the following entries.
|
|
@table @code
|
|
@item char-set
|
|
The char-set itself
|
|
@item len
|
|
The number of groups of contiguous code points the char-set
|
|
contains
|
|
@item ranges
|
|
A list of lists where each sublist is a range of code points
|
|
and their associated characters
|
|
@end table
|
|
The return value of this function cannot be relied upon to be
|
|
consistent between versions of Guile and should not be used in code.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-size cs
|
|
@deffnx {C Function} scm_char_set_size (cs)
|
|
Return the number of elements in character set @var{cs}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-count pred cs
|
|
@deffnx {C Function} scm_char_set_count (pred, cs)
|
|
Return the number of the elements int the character set
|
|
@var{cs} which satisfy the predicate @var{pred}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set->list cs
|
|
@deffnx {C Function} scm_char_set_to_list (cs)
|
|
Return a list containing the elements of the character set
|
|
@var{cs}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set->string cs
|
|
@deffnx {C Function} scm_char_set_to_string (cs)
|
|
Return a string containing the elements of the character set
|
|
@var{cs}. The order in which the characters are placed in the
|
|
string is not defined.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-contains? cs ch
|
|
@deffnx {C Function} scm_char_set_contains_p (cs, ch)
|
|
Return @code{#t} if the character @var{ch} is contained in the
|
|
character set @var{cs}, or @code{#f} otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-every pred cs
|
|
@deffnx {C Function} scm_char_set_every (pred, cs)
|
|
Return a true value if every character in the character set
|
|
@var{cs} satisfies the predicate @var{pred}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-any pred cs
|
|
@deffnx {C Function} scm_char_set_any (pred, cs)
|
|
Return a true value if any character in the character set
|
|
@var{cs} satisfies the predicate @var{pred}.
|
|
@end deffn
|
|
|
|
@c ===================================================================
|
|
|
|
@node Character-Set Algebra
|
|
@subsubsection Character-Set Algebra
|
|
|
|
Character sets can be manipulated with the common set algebra operation,
|
|
such as union, complement, intersection etc. All of these procedures
|
|
provide side-effecting variants, which modify their character set
|
|
argument(s).
|
|
|
|
@deffn {Scheme Procedure} char-set-adjoin cs chr @dots{}
|
|
@deffnx {C Function} scm_char_set_adjoin (cs, chrs)
|
|
Add all character arguments to the first argument, which must
|
|
be a character set.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-delete cs chr @dots{}
|
|
@deffnx {C Function} scm_char_set_delete (cs, chrs)
|
|
Delete all character arguments from the first argument, which
|
|
must be a character set.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-adjoin! cs chr @dots{}
|
|
@deffnx {C Function} scm_char_set_adjoin_x (cs, chrs)
|
|
Add all character arguments to the first argument, which must
|
|
be a character set.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-delete! cs chr @dots{}
|
|
@deffnx {C Function} scm_char_set_delete_x (cs, chrs)
|
|
Delete all character arguments from the first argument, which
|
|
must be a character set.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-complement cs
|
|
@deffnx {C Function} scm_char_set_complement (cs)
|
|
Return the complement of the character set @var{cs}.
|
|
@end deffn
|
|
|
|
Note that the complement of a character set is likely to contain many
|
|
reserved code points (code points that are not associated with
|
|
characters). It may be helpful to modify the output of
|
|
@code{char-set-complement} by computing its intersection with the set
|
|
of designated code points, @code{char-set:designated}.
|
|
|
|
@deffn {Scheme Procedure} char-set-union cs @dots{}
|
|
@deffnx {C Function} scm_char_set_union (char_sets)
|
|
Return the union of all argument character sets.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-intersection cs @dots{}
|
|
@deffnx {C Function} scm_char_set_intersection (char_sets)
|
|
Return the intersection of all argument character sets.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-difference cs1 cs @dots{}
|
|
@deffnx {C Function} scm_char_set_difference (cs1, char_sets)
|
|
Return the difference of all argument character sets.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-xor cs @dots{}
|
|
@deffnx {C Function} scm_char_set_xor (char_sets)
|
|
Return the exclusive-or of all argument character sets.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-diff+intersection cs1 cs @dots{}
|
|
@deffnx {C Function} scm_char_set_diff_plus_intersection (cs1, char_sets)
|
|
Return the difference and the intersection of all argument
|
|
character sets.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-complement! cs
|
|
@deffnx {C Function} scm_char_set_complement_x (cs)
|
|
Return the complement of the character set @var{cs}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-union! cs1 cs @dots{}
|
|
@deffnx {C Function} scm_char_set_union_x (cs1, char_sets)
|
|
Return the union of all argument character sets.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-intersection! cs1 cs @dots{}
|
|
@deffnx {C Function} scm_char_set_intersection_x (cs1, char_sets)
|
|
Return the intersection of all argument character sets.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-difference! cs1 cs @dots{}
|
|
@deffnx {C Function} scm_char_set_difference_x (cs1, char_sets)
|
|
Return the difference of all argument character sets.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-xor! cs1 cs @dots{}
|
|
@deffnx {C Function} scm_char_set_xor_x (cs1, char_sets)
|
|
Return the exclusive-or of all argument character sets.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} char-set-diff+intersection! cs1 cs2 cs @dots{}
|
|
@deffnx {C Function} scm_char_set_diff_plus_intersection_x (cs1, cs2, char_sets)
|
|
Return the difference and the intersection of all argument
|
|
character sets.
|
|
@end deffn
|
|
|
|
@c ===================================================================
|
|
|
|
@node Standard Character Sets
|
|
@subsubsection Standard Character Sets
|
|
|
|
In order to make the use of the character set data type and procedures
|
|
useful, several predefined character set variables exist.
|
|
|
|
@cindex codeset
|
|
@cindex charset
|
|
@cindex locale
|
|
|
|
These character sets are locale independent and are not recomputed
|
|
upon a @code{setlocale} call. They contain characters from the whole
|
|
range of Unicode code points. For instance, @code{char-set:letter}
|
|
contains about 100,000 characters.
|
|
|
|
@defvr {Scheme Variable} char-set:lower-case
|
|
@defvrx {C Variable} scm_char_set_lower_case
|
|
All lower-case characters.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:upper-case
|
|
@defvrx {C Variable} scm_char_set_upper_case
|
|
All upper-case characters.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:title-case
|
|
@defvrx {C Variable} scm_char_set_title_case
|
|
All single characters that function as if they were an upper-case
|
|
letter followed by a lower-case letter.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:letter
|
|
@defvrx {C Variable} scm_char_set_letter
|
|
All letters. This includes @code{char-set:lower-case},
|
|
@code{char-set:upper-case}, @code{char-set:title-case}, and many
|
|
letters that have no case at all. For example, Chinese and Japanese
|
|
characters typically have no concept of case.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:digit
|
|
@defvrx {C Variable} scm_char_set_digit
|
|
All digits.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:letter+digit
|
|
@defvrx {C Variable} scm_char_set_letter_and_digit
|
|
The union of @code{char-set:letter} and @code{char-set:digit}.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:graphic
|
|
@defvrx {C Variable} scm_char_set_graphic
|
|
All characters which would put ink on the paper.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:printing
|
|
@defvrx {C Variable} scm_char_set_printing
|
|
The union of @code{char-set:graphic} and @code{char-set:whitespace}.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:whitespace
|
|
@defvrx {C Variable} scm_char_set_whitespace
|
|
All whitespace characters.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:blank
|
|
@defvrx {C Variable} scm_char_set_blank
|
|
All horizontal whitespace characters, which notably includes
|
|
@code{#\space} and @code{#\tab}.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:iso-control
|
|
@defvrx {C Variable} scm_char_set_iso_control
|
|
The ISO control characters are the C0 control characters (U+0000 to
|
|
U+001F), delete (U+007F), and the C1 control characters (U+0080 to
|
|
U+009F).
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:punctuation
|
|
@defvrx {C Variable} scm_char_set_punctuation
|
|
All punctuation characters, such as the characters
|
|
@code{!"#%&'()*,-./:;?@@[\\]_@{@}}
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:symbol
|
|
@defvrx {C Variable} scm_char_set_symbol
|
|
All symbol characters, such as the characters @code{$+<=>^`|~}.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:hex-digit
|
|
@defvrx {C Variable} scm_char_set_hex_digit
|
|
The hexadecimal digits @code{0123456789abcdefABCDEF}.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:ascii
|
|
@defvrx {C Variable} scm_char_set_ascii
|
|
All ASCII characters.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:empty
|
|
@defvrx {C Variable} scm_char_set_empty
|
|
The empty character set.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:designated
|
|
@defvrx {C Variable} scm_char_set_designated
|
|
This character set contains all designated code points. This includes
|
|
all the code points to which Unicode has assigned a character or other
|
|
meaning.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} char-set:full
|
|
@defvrx {C Variable} scm_char_set_full
|
|
This character set contains all possible code points. This includes
|
|
both designated and reserved code points.
|
|
@end defvr
|
|
|
|
@node Strings
|
|
@subsection Strings
|
|
@tpindex Strings
|
|
|
|
Strings are fixed-length sequences of characters. They can be created
|
|
by calling constructor procedures, but they can also literally get
|
|
entered at the @acronym{REPL} or in Scheme source files.
|
|
|
|
@c Guile provides a rich set of string processing procedures, because text
|
|
@c handling is very important when Guile is used as a scripting language.
|
|
|
|
Strings always carry the information about how many characters they are
|
|
composed of with them, so there is no special end-of-string character,
|
|
like in C. That means that Scheme strings can contain any character,
|
|
even the @samp{#\nul} character @samp{\0}.
|
|
|
|
To use strings efficiently, you need to know a bit about how Guile
|
|
implements them. In Guile, a string consists of two parts, a head and
|
|
the actual memory where the characters are stored. When a string (or
|
|
a substring of it) is copied, only a new head gets created, the memory
|
|
is usually not copied. The two heads start out pointing to the same
|
|
memory.
|
|
|
|
When one of these two strings is modified, as with @code{string-set!},
|
|
their common memory does get copied so that each string has its own
|
|
memory and modifying one does not accidentally modify the other as well.
|
|
Thus, Guile's strings are `copy on write'; the actual copying of their
|
|
memory is delayed until one string is written to.
|
|
|
|
This implementation makes functions like @code{substring} very
|
|
efficient in the common case that no modifications are done to the
|
|
involved strings.
|
|
|
|
If you do know that your strings are getting modified right away, you
|
|
can use @code{substring/copy} instead of @code{substring}. This
|
|
function performs the copy immediately at the time of creation. This
|
|
is more efficient, especially in a multi-threaded program. Also,
|
|
@code{substring/copy} can avoid the problem that a short substring
|
|
holds on to the memory of a very large original string that could
|
|
otherwise be recycled.
|
|
|
|
If you want to avoid the copy altogether, so that modifications of one
|
|
string show up in the other, you can use @code{substring/shared}. The
|
|
strings created by this procedure are called @dfn{mutation sharing
|
|
substrings} since the substring and the original string share
|
|
modifications to each other.
|
|
|
|
If you want to prevent modifications, use @code{substring/read-only}.
|
|
|
|
Guile provides all procedures of SRFI-13 and a few more.
|
|
|
|
@menu
|
|
* String Syntax:: Read syntax for strings.
|
|
* String Predicates:: Testing strings for certain properties.
|
|
* String Constructors:: Creating new string objects.
|
|
* List/String Conversion:: Converting from/to lists of characters.
|
|
* String Selection:: Select portions from strings.
|
|
* String Modification:: Modify parts or whole strings.
|
|
* String Comparison:: Lexicographic ordering predicates.
|
|
* String Searching:: Searching in strings.
|
|
* Alphabetic Case Mapping:: Convert the alphabetic case of strings.
|
|
* Reversing and Appending Strings:: Appending strings to form a new string.
|
|
* Mapping Folding and Unfolding:: Iterating over strings.
|
|
* Miscellaneous String Operations:: Replicating, insertion, parsing, ...
|
|
* Representing Strings as Bytes:: Encoding and decoding strings.
|
|
* Conversion to/from C::
|
|
* String Internals:: The storage strategy for strings.
|
|
@end menu
|
|
|
|
@node String Syntax
|
|
@subsubsection String Read Syntax
|
|
|
|
@c In the following @code is used to get a good font in TeX etc, but
|
|
@c is omitted for Info format, so as not to risk any confusion over
|
|
@c whether surrounding ` ' quotes are part of the escape or are
|
|
@c special in a string (they're not).
|
|
|
|
The read syntax for strings is an arbitrarily long sequence of
|
|
characters enclosed in double quotes (@nicode{"}).
|
|
|
|
Backslash is an escape character and can be used to insert the following
|
|
special characters. @nicode{\"} and @nicode{\\} are R5RS standard,
|
|
@nicode{\|} is R7RS standard, the next seven are R6RS standard ---
|
|
notice they follow C syntax --- and the remaining four are Guile
|
|
extensions.
|
|
|
|
@table @asis
|
|
@item @nicode{\\}
|
|
Backslash character.
|
|
|
|
@item @nicode{\"}
|
|
Double quote character (an unescaped @nicode{"} is otherwise the end
|
|
of the string).
|
|
|
|
@item @nicode{\|}
|
|
Vertical bar character.
|
|
|
|
@item @nicode{\a}
|
|
Bell character (ASCII 7).
|
|
|
|
@item @nicode{\f}
|
|
Formfeed character (ASCII 12).
|
|
|
|
@item @nicode{\n}
|
|
Newline character (ASCII 10).
|
|
|
|
@item @nicode{\r}
|
|
Carriage return character (ASCII 13).
|
|
|
|
@item @nicode{\t}
|
|
Tab character (ASCII 9).
|
|
|
|
@item @nicode{\v}
|
|
Vertical tab character (ASCII 11).
|
|
|
|
@item @nicode{\b}
|
|
Backspace character (ASCII 8).
|
|
|
|
@item @nicode{\0}
|
|
NUL character (ASCII 0).
|
|
|
|
@item @nicode{\(}
|
|
Open parenthesis. This is intended for use at the beginning of lines in
|
|
multiline strings to avoid confusing Emacs lisp modes.
|
|
|
|
@item @nicode{\} followed by newline (ASCII 10)
|
|
Nothing. This way if @nicode{\} is the last character in a line, the
|
|
string will continue with the first character from the next line,
|
|
without a line break.
|
|
|
|
If the @code{hungry-eol-escapes} reader option is enabled, which is not
|
|
the case by default, leading whitespace on the next line is discarded.
|
|
|
|
@lisp
|
|
"foo\
|
|
bar"
|
|
@result{} "foo bar"
|
|
(read-enable 'hungry-eol-escapes)
|
|
"foo\
|
|
bar"
|
|
@result{} "foobar"
|
|
@end lisp
|
|
@item @nicode{\xHH}
|
|
Character code given by two hexadecimal digits. For example
|
|
@nicode{\x7f} for an ASCII DEL (127).
|
|
|
|
@item @nicode{\uHHHH}
|
|
Character code given by four hexadecimal digits. For example
|
|
@nicode{\u0100} for a capital A with macron (U+0100).
|
|
|
|
@item @nicode{\UHHHHHH}
|
|
Character code given by six hexadecimal digits. For example
|
|
@nicode{\U010402}.
|
|
@end table
|
|
|
|
@noindent
|
|
The following are examples of string literals:
|
|
|
|
@lisp
|
|
"foo"
|
|
"bar plonk"
|
|
"Hello World"
|
|
"\"Hi\", he said."
|
|
@end lisp
|
|
|
|
The three escape sequences @code{\xHH}, @code{\uHHHH} and @code{\UHHHHHH} were
|
|
chosen to not break compatibility with code written for previous versions of
|
|
Guile. The R6RS specification suggests a different, incompatible syntax for hex
|
|
escapes: @code{\xHHHH;} -- a character code followed by one to eight hexadecimal
|
|
digits terminated with a semicolon. If this escape format is desired instead,
|
|
it can be enabled with the reader option @code{r6rs-hex-escapes}.
|
|
|
|
@lisp
|
|
(read-enable 'r6rs-hex-escapes)
|
|
@end lisp
|
|
|
|
For more on reader options, @xref{Scheme Read}.
|
|
|
|
@node String Predicates
|
|
@subsubsection String Predicates
|
|
|
|
The following procedures can be used to check whether a given string
|
|
fulfills some specified property.
|
|
|
|
@rnindex string?
|
|
@deffn {Scheme Procedure} string? obj
|
|
@deffnx {C Function} scm_string_p (obj)
|
|
Return @code{#t} if @var{obj} is a string, else @code{#f}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_string (SCM obj)
|
|
Returns @code{1} if @var{obj} is a string, @code{0} otherwise.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} string-null? str
|
|
@deffnx {C Function} scm_string_null_p (str)
|
|
Return @code{#t} if @var{str}'s length is zero, and
|
|
@code{#f} otherwise.
|
|
@lisp
|
|
(string-null? "") @result{} #t
|
|
y @result{} "foo"
|
|
(string-null? y) @result{} #f
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-any char_pred s [start [end]]
|
|
@deffnx {C Function} scm_string_any (char_pred, s, start, end)
|
|
Check if @var{char_pred} is true for any character in string @var{s}.
|
|
|
|
@var{char_pred} can be a character to check for any equal to that, or
|
|
a character set (@pxref{Character Sets}) to check for any in that set,
|
|
or a predicate procedure to call.
|
|
|
|
For a procedure, calls @code{(@var{char_pred} c)} are made
|
|
successively on the characters from @var{start} to @var{end}. If
|
|
@var{char_pred} returns true (ie.@: non-@code{#f}), @code{string-any}
|
|
stops and that return value is the return from @code{string-any}. The
|
|
call on the last character (ie.@: at @math{@var{end}-1}), if that
|
|
point is reached, is a tail call.
|
|
|
|
If there are no characters in @var{s} (ie.@: @var{start} equals
|
|
@var{end}) then the return is @code{#f}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-every char_pred s [start [end]]
|
|
@deffnx {C Function} scm_string_every (char_pred, s, start, end)
|
|
Check if @var{char_pred} is true for every character in string
|
|
@var{s}.
|
|
|
|
@var{char_pred} can be a character to check for every character equal
|
|
to that, or a character set (@pxref{Character Sets}) to check for
|
|
every character being in that set, or a predicate procedure to call.
|
|
|
|
For a procedure, calls @code{(@var{char_pred} c)} are made
|
|
successively on the characters from @var{start} to @var{end}. If
|
|
@var{char_pred} returns @code{#f}, @code{string-every} stops and
|
|
returns @code{#f}. The call on the last character (ie.@: at
|
|
@math{@var{end}-1}), if that point is reached, is a tail call and the
|
|
return from that call is the return from @code{string-every}.
|
|
|
|
If there are no characters in @var{s} (ie.@: @var{start} equals
|
|
@var{end}) then the return is @code{#t}.
|
|
@end deffn
|
|
|
|
@node String Constructors
|
|
@subsubsection String Constructors
|
|
|
|
The string constructor procedures create new string objects, possibly
|
|
initializing them with some specified character data. See also
|
|
@xref{String Selection}, for ways to create strings from existing
|
|
strings.
|
|
|
|
@c FIXME::martin: list->string belongs into `List/String Conversion'
|
|
|
|
@deffn {Scheme Procedure} string char@dots{}
|
|
@rnindex string
|
|
Return a newly allocated string made from the given character
|
|
arguments.
|
|
|
|
@example
|
|
(string #\x #\y #\z) @result{} "xyz"
|
|
(string) @result{} ""
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list->string lst
|
|
@deffnx {C Function} scm_string (lst)
|
|
@rnindex list->string
|
|
Return a newly allocated string made from a list of characters.
|
|
|
|
@example
|
|
(list->string '(#\a #\b #\c)) @result{} "abc"
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} reverse-list->string lst
|
|
@deffnx {C Function} scm_reverse_list_to_string (lst)
|
|
Return a newly allocated string made from a list of characters, in
|
|
reverse order.
|
|
|
|
@example
|
|
(reverse-list->string '(#\a #\B #\c)) @result{} "cBa"
|
|
@end example
|
|
@end deffn
|
|
|
|
@rnindex make-string
|
|
@deffn {Scheme Procedure} make-string k [chr]
|
|
@deffnx {C Function} scm_make_string (k, chr)
|
|
Return a newly allocated string of
|
|
length @var{k}. If @var{chr} is given, then all elements of
|
|
the string are initialized to @var{chr}, otherwise the contents
|
|
of the string are unspecified.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} SCM scm_c_make_string (size_t len, SCM chr)
|
|
Like @code{scm_make_string}, but expects the length as a
|
|
@code{size_t}.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} string-tabulate proc len
|
|
@deffnx {C Function} scm_string_tabulate (proc, len)
|
|
@var{proc} is an integer->char procedure. Construct a string
|
|
of size @var{len} by applying @var{proc} to each index to
|
|
produce the corresponding string element. The order in which
|
|
@var{proc} is applied to the indices is not specified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-join ls [delimiter [grammar]]
|
|
@deffnx {C Function} scm_string_join (ls, delimiter, grammar)
|
|
Append the string in the string list @var{ls}, using the string
|
|
@var{delimiter} as a delimiter between the elements of @var{ls}.
|
|
@var{delimiter} defaults to @w{@samp{ }}, that is, strings in @var{ls}
|
|
are appended with the space character in between them. @var{grammar} is
|
|
a symbol which specifies how the delimiter is placed between the
|
|
strings, and defaults to the symbol @code{infix}.
|
|
|
|
@table @code
|
|
@item infix
|
|
Insert the separator between list elements. An empty string
|
|
will produce an empty list.
|
|
@item strict-infix
|
|
Like @code{infix}, but will raise an error if given the empty
|
|
list.
|
|
@item suffix
|
|
Insert the separator after every list element.
|
|
@item prefix
|
|
Insert the separator before each list element.
|
|
@end table
|
|
@end deffn
|
|
|
|
@node List/String Conversion
|
|
@subsubsection List/String conversion
|
|
|
|
When processing strings, it is often convenient to first convert them
|
|
into a list representation by using the procedure @code{string->list},
|
|
work with the resulting list, and then convert it back into a string.
|
|
These procedures are useful for similar tasks.
|
|
|
|
@rnindex string->list
|
|
@deffn {Scheme Procedure} string->list str [start [end]]
|
|
@deffnx {C Function} scm_substring_to_list (str, start, end)
|
|
@deffnx {C Function} scm_string_to_list (str)
|
|
Convert the string @var{str} into a list of characters.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-split str char_pred
|
|
@deffnx {C Function} scm_string_split (str, char_pred)
|
|
Split the string @var{str} into a list of substrings delimited
|
|
by appearances of characters that
|
|
|
|
@itemize @bullet
|
|
@item
|
|
equal @var{char_pred}, if it is a character,
|
|
|
|
@item
|
|
satisfy the predicate @var{char_pred}, if it is a procedure,
|
|
|
|
@item
|
|
are in the set @var{char_pred}, if it is a character set.
|
|
@end itemize
|
|
|
|
Note that an empty substring between separator characters will result in
|
|
an empty string in the result list.
|
|
|
|
@lisp
|
|
(string-split "root:x:0:0:root:/root:/bin/bash" #\:)
|
|
@result{}
|
|
("root" "x" "0" "0" "root" "/root" "/bin/bash")
|
|
|
|
(string-split "::" #\:)
|
|
@result{}
|
|
("" "" "")
|
|
|
|
(string-split "" #\:)
|
|
@result{}
|
|
("")
|
|
@end lisp
|
|
@end deffn
|
|
|
|
|
|
@node String Selection
|
|
@subsubsection String Selection
|
|
|
|
Portions of strings can be extracted by these procedures.
|
|
@code{string-ref} delivers individual characters whereas
|
|
@code{substring} can be used to extract substrings from longer strings.
|
|
|
|
@rnindex string-length
|
|
@deffn {Scheme Procedure} string-length string
|
|
@deffnx {C Function} scm_string_length (string)
|
|
Return the number of characters in @var{string}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} size_t scm_c_string_length (SCM str)
|
|
Return the number of characters in @var{str} as a @code{size_t}.
|
|
@end deftypefn
|
|
|
|
@rnindex string-ref
|
|
@deffn {Scheme Procedure} string-ref str k
|
|
@deffnx {C Function} scm_string_ref (str, k)
|
|
Return character @var{k} of @var{str} using zero-origin
|
|
indexing. @var{k} must be a valid index of @var{str}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} SCM scm_c_string_ref (SCM str, size_t k)
|
|
Return character @var{k} of @var{str} using zero-origin
|
|
indexing. @var{k} must be a valid index of @var{str}.
|
|
@end deftypefn
|
|
|
|
@rnindex string-copy
|
|
@deffn {Scheme Procedure} string-copy str [start [end]]
|
|
@deffnx {C Function} scm_substring_copy (str, start, end)
|
|
@deffnx {C Function} scm_string_copy (str)
|
|
Return a copy of the given string @var{str}.
|
|
|
|
The returned string shares storage with @var{str} initially, but it is
|
|
copied as soon as one of the two strings is modified.
|
|
@end deffn
|
|
|
|
@rnindex substring
|
|
@deffn {Scheme Procedure} substring str start [end]
|
|
@deffnx {C Function} scm_substring (str, start, end)
|
|
Return a new string formed from the characters
|
|
of @var{str} beginning with index @var{start} (inclusive) and
|
|
ending with index @var{end} (exclusive).
|
|
@var{str} must be a string, @var{start} and @var{end} must be
|
|
exact integers satisfying:
|
|
|
|
0 <= @var{start} <= @var{end} <= @code{(string-length @var{str})}.
|
|
|
|
The returned string shares storage with @var{str} initially, but it is
|
|
copied as soon as one of the two strings is modified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} substring/shared str start [end]
|
|
@deffnx {C Function} scm_substring_shared (str, start, end)
|
|
Like @code{substring}, but the strings continue to share their storage
|
|
even if they are modified. Thus, modifications to @var{str} show up
|
|
in the new string, and vice versa.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} substring/copy str start [end]
|
|
@deffnx {C Function} scm_substring_copy (str, start, end)
|
|
Like @code{substring}, but the storage for the new string is copied
|
|
immediately.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} substring/read-only str start [end]
|
|
@deffnx {C Function} scm_substring_read_only (str, start, end)
|
|
Like @code{substring}, but the resulting string can not be modified.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} SCM scm_c_substring (SCM str, size_t start, size_t end)
|
|
@deftypefnx {C Function} SCM scm_c_substring_shared (SCM str, size_t start, size_t end)
|
|
@deftypefnx {C Function} SCM scm_c_substring_copy (SCM str, size_t start, size_t end)
|
|
@deftypefnx {C Function} SCM scm_c_substring_read_only (SCM str, size_t start, size_t end)
|
|
Like @code{scm_substring}, etc. but the bounds are given as a @code{size_t}.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} string-take s n
|
|
@deffnx {C Function} scm_string_take (s, n)
|
|
Return the @var{n} first characters of @var{s}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-drop s n
|
|
@deffnx {C Function} scm_string_drop (s, n)
|
|
Return all but the first @var{n} characters of @var{s}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-take-right s n
|
|
@deffnx {C Function} scm_string_take_right (s, n)
|
|
Return the @var{n} last characters of @var{s}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-drop-right s n
|
|
@deffnx {C Function} scm_string_drop_right (s, n)
|
|
Return all but the last @var{n} characters of @var{s}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-pad s len [chr [start [end]]]
|
|
@deffnx {Scheme Procedure} string-pad-right s len [chr [start [end]]]
|
|
@deffnx {C Function} scm_string_pad (s, len, chr, start, end)
|
|
@deffnx {C Function} scm_string_pad_right (s, len, chr, start, end)
|
|
Take characters @var{start} to @var{end} from the string @var{s} and
|
|
either pad with @var{chr} or truncate them to give @var{len}
|
|
characters.
|
|
|
|
@code{string-pad} pads or truncates on the left, so for example
|
|
|
|
@example
|
|
(string-pad "x" 3) @result{} " x"
|
|
(string-pad "abcde" 3) @result{} "cde"
|
|
@end example
|
|
|
|
@code{string-pad-right} pads or truncates on the right, so for example
|
|
|
|
@example
|
|
(string-pad-right "x" 3) @result{} "x "
|
|
(string-pad-right "abcde" 3) @result{} "abc"
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-trim s [char_pred [start [end]]]
|
|
@deffnx {Scheme Procedure} string-trim-right s [char_pred [start [end]]]
|
|
@deffnx {Scheme Procedure} string-trim-both s [char_pred [start [end]]]
|
|
@deffnx {C Function} scm_string_trim (s, char_pred, start, end)
|
|
@deffnx {C Function} scm_string_trim_right (s, char_pred, start, end)
|
|
@deffnx {C Function} scm_string_trim_both (s, char_pred, start, end)
|
|
Trim occurrences of @var{char_pred} from the ends of @var{s}.
|
|
|
|
@code{string-trim} trims @var{char_pred} characters from the left
|
|
(start) of the string, @code{string-trim-right} trims them from the
|
|
right (end) of the string, @code{string-trim-both} trims from both
|
|
ends.
|
|
|
|
@var{char_pred} can be a character, a character set, or a predicate
|
|
procedure to call on each character. If @var{char_pred} is not given
|
|
the default is whitespace as per @code{char-set:whitespace}
|
|
(@pxref{Standard Character Sets}).
|
|
|
|
@example
|
|
(string-trim " x ") @result{} "x "
|
|
(string-trim-right "banana" #\a) @result{} "banan"
|
|
(string-trim-both ".,xy:;" char-set:punctuation)
|
|
@result{} "xy"
|
|
(string-trim-both "xyzzy" (lambda (c)
|
|
(or (eqv? c #\x)
|
|
(eqv? c #\y))))
|
|
@result{} "zz"
|
|
@end example
|
|
@end deffn
|
|
|
|
@node String Modification
|
|
@subsubsection String Modification
|
|
|
|
These procedures are for modifying strings in-place. This means that the
|
|
result of the operation is not a new string; instead, the original string's
|
|
memory representation is modified.
|
|
|
|
@rnindex string-set!
|
|
@deffn {Scheme Procedure} string-set! str k chr
|
|
@deffnx {C Function} scm_string_set_x (str, k, chr)
|
|
Store @var{chr} in element @var{k} of @var{str} and return
|
|
an unspecified value. @var{k} must be a valid index of
|
|
@var{str}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} void scm_c_string_set_x (SCM str, size_t k, SCM chr)
|
|
Like @code{scm_string_set_x}, but the index is given as a @code{size_t}.
|
|
@end deftypefn
|
|
|
|
@rnindex string-fill!
|
|
@anchor{x-string-fill!}
|
|
@deffn {Scheme Procedure} string-fill! str chr [start [end]]
|
|
@deffnx {C Function} scm_substring_fill_x (str, chr, start, end)
|
|
@deffnx {C Function} scm_string_fill_x (str, chr)
|
|
Stores @var{chr} in every element of the given @var{str} and
|
|
returns an unspecified value.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} substring-fill! str start end fill
|
|
@deffnx {C Function} scm_substring_fill_x (str, start, end, fill)
|
|
Change every character in @var{str} between @var{start} and
|
|
@var{end} to @var{fill}.
|
|
|
|
@lisp
|
|
(define y (string-copy "abcdefg"))
|
|
(substring-fill! y 1 3 #\r)
|
|
y
|
|
@result{} "arrdefg"
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} substring-move! str1 start1 end1 str2 start2
|
|
@deffnx {C Function} scm_substring_move_x (str1, start1, end1, str2, start2)
|
|
Copy the substring of @var{str1} bounded by @var{start1} and @var{end1}
|
|
into @var{str2} beginning at position @var{start2}.
|
|
@var{str1} and @var{str2} can be the same string.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-copy! target tstart s [start [end]]
|
|
@deffnx {C Function} scm_string_copy_x (target, tstart, s, start, end)
|
|
Copy the sequence of characters from index range [@var{start},
|
|
@var{end}) in string @var{s} to string @var{target}, beginning
|
|
at index @var{tstart}. The characters are copied left-to-right
|
|
or right-to-left as needed -- the copy is guaranteed to work,
|
|
even if @var{target} and @var{s} are the same string. It is an
|
|
error if the copy operation runs off the end of the target
|
|
string.
|
|
@end deffn
|
|
|
|
|
|
@node String Comparison
|
|
@subsubsection String Comparison
|
|
|
|
The procedures in this section are similar to the character ordering
|
|
predicates (@pxref{Characters}), but are defined on character sequences.
|
|
|
|
The first set is specified in R5RS and has names that end in @code{?}.
|
|
The second set is specified in SRFI-13 and the names have not ending
|
|
@code{?}.
|
|
|
|
The predicates ending in @code{-ci} ignore the character case
|
|
when comparing strings. For now, case-insensitive comparison is done
|
|
using the R5RS rules, where every lower-case character that has a
|
|
single character upper-case form is converted to uppercase before
|
|
comparison. See @xref{Text Collation, the @code{(ice-9
|
|
i18n)} module}, for locale-dependent string comparison.
|
|
|
|
@rnindex string=?
|
|
@deffn {Scheme Procedure} string=? s1 s2 s3 @dots{}
|
|
Lexicographic equality predicate; return @code{#t} if all strings are
|
|
the same length and contain the same characters in the same positions,
|
|
otherwise return @code{#f}.
|
|
|
|
The procedure @code{string-ci=?} treats upper and lower case
|
|
letters as though they were the same character, but
|
|
@code{string=?} treats upper and lower case as distinct
|
|
characters.
|
|
@end deffn
|
|
|
|
@rnindex string<?
|
|
@deffn {Scheme Procedure} string<? s1 s2 s3 @dots{}
|
|
Lexicographic ordering predicate; return @code{#t} if, for every pair of
|
|
consecutive string arguments @var{str_i} and @var{str_i+1}, @var{str_i} is
|
|
lexicographically less than @var{str_i+1}.
|
|
@end deffn
|
|
|
|
@rnindex string<=?
|
|
@deffn {Scheme Procedure} string<=? s1 s2 s3 @dots{}
|
|
Lexicographic ordering predicate; return @code{#t} if, for every pair of
|
|
consecutive string arguments @var{str_i} and @var{str_i+1}, @var{str_i} is
|
|
lexicographically less than or equal to @var{str_i+1}.
|
|
@end deffn
|
|
|
|
@rnindex string>?
|
|
@deffn {Scheme Procedure} string>? s1 s2 s3 @dots{}
|
|
Lexicographic ordering predicate; return @code{#t} if, for every pair of
|
|
consecutive string arguments @var{str_i} and @var{str_i+1}, @var{str_i} is
|
|
lexicographically greater than @var{str_i+1}.
|
|
@end deffn
|
|
|
|
@rnindex string>=?
|
|
@deffn {Scheme Procedure} string>=? s1 s2 s3 @dots{}
|
|
Lexicographic ordering predicate; return @code{#t} if, for every pair of
|
|
consecutive string arguments @var{str_i} and @var{str_i+1}, @var{str_i} is
|
|
lexicographically greater than or equal to @var{str_i+1}.
|
|
@end deffn
|
|
|
|
@rnindex string-ci=?
|
|
@deffn {Scheme Procedure} string-ci=? s1 s2 s3 @dots{}
|
|
Case-insensitive string equality predicate; return @code{#t} if
|
|
all strings are the same length and their component
|
|
characters match (ignoring case) at each position; otherwise
|
|
return @code{#f}.
|
|
@end deffn
|
|
|
|
@rnindex string-ci<?
|
|
@deffn {Scheme Procedure} string-ci<? s1 s2 s3 @dots{}
|
|
Case insensitive lexicographic ordering predicate; return @code{#t} if,
|
|
for every pair of consecutive string arguments @var{str_i} and
|
|
@var{str_i+1}, @var{str_i} is lexicographically less than @var{str_i+1}
|
|
regardless of case.
|
|
@end deffn
|
|
|
|
@rnindex string<=?
|
|
@deffn {Scheme Procedure} string-ci<=? s1 s2 s3 @dots{}
|
|
Case insensitive lexicographic ordering predicate; return @code{#t} if,
|
|
for every pair of consecutive string arguments @var{str_i} and
|
|
@var{str_i+1}, @var{str_i} is lexicographically less than or equal to
|
|
@var{str_i+1} regardless of case.
|
|
@end deffn
|
|
|
|
@rnindex string-ci>?
|
|
@deffn {Scheme Procedure} string-ci>? s1 s2 s3 @dots{}
|
|
Case insensitive lexicographic ordering predicate; return @code{#t} if,
|
|
for every pair of consecutive string arguments @var{str_i} and
|
|
@var{str_i+1}, @var{str_i} is lexicographically greater than
|
|
@var{str_i+1} regardless of case.
|
|
@end deffn
|
|
|
|
@rnindex string-ci>=?
|
|
@deffn {Scheme Procedure} string-ci>=? s1 s2 s3 @dots{}
|
|
Case insensitive lexicographic ordering predicate; return @code{#t} if,
|
|
for every pair of consecutive string arguments @var{str_i} and
|
|
@var{str_i+1}, @var{str_i} is lexicographically greater than or equal to
|
|
@var{str_i+1} regardless of case.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-compare s1 s2 proc_lt proc_eq proc_gt [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_compare (s1, s2, proc_lt, proc_eq, proc_gt, start1, end1, start2, end2)
|
|
Apply @var{proc_lt}, @var{proc_eq}, @var{proc_gt} to the
|
|
mismatch index, depending upon whether @var{s1} is less than,
|
|
equal to, or greater than @var{s2}. The mismatch index is the
|
|
largest index @var{i} such that for every 0 <= @var{j} <
|
|
@var{i}, @var{s1}[@var{j}] = @var{s2}[@var{j}] -- that is,
|
|
@var{i} is the first position that does not match.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-compare-ci s1 s2 proc_lt proc_eq proc_gt [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_compare_ci (s1, s2, proc_lt, proc_eq, proc_gt, start1, end1, start2, end2)
|
|
Apply @var{proc_lt}, @var{proc_eq}, @var{proc_gt} to the
|
|
mismatch index, depending upon whether @var{s1} is less than,
|
|
equal to, or greater than @var{s2}. The mismatch index is the
|
|
largest index @var{i} such that for every 0 <= @var{j} <
|
|
@var{i}, @var{s1}[@var{j}] = @var{s2}[@var{j}] -- that is,
|
|
@var{i} is the first position where the lowercased letters
|
|
do not match.
|
|
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string= s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_eq (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} and @var{s2} are not equal, a true
|
|
value otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string<> s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_neq (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} and @var{s2} are equal, a true
|
|
value otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string< s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_lt (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} is greater or equal to @var{s2}, a
|
|
true value otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string> s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_gt (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} is less or equal to @var{s2}, a
|
|
true value otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string<= s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_le (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} is greater to @var{s2}, a true
|
|
value otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string>= s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_ge (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} is less to @var{s2}, a true value
|
|
otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-ci= s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_ci_eq (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} and @var{s2} are not equal, a true
|
|
value otherwise. The character comparison is done
|
|
case-insensitively.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-ci<> s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_ci_neq (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} and @var{s2} are equal, a true
|
|
value otherwise. The character comparison is done
|
|
case-insensitively.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-ci< s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_ci_lt (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} is greater or equal to @var{s2}, a
|
|
true value otherwise. The character comparison is done
|
|
case-insensitively.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-ci> s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_ci_gt (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} is less or equal to @var{s2}, a
|
|
true value otherwise. The character comparison is done
|
|
case-insensitively.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-ci<= s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_ci_le (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} is greater to @var{s2}, a true
|
|
value otherwise. The character comparison is done
|
|
case-insensitively.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-ci>= s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_ci_ge (s1, s2, start1, end1, start2, end2)
|
|
Return @code{#f} if @var{s1} is less to @var{s2}, a true value
|
|
otherwise. The character comparison is done
|
|
case-insensitively.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-hash s [bound [start [end]]]
|
|
@deffnx {C Function} scm_substring_hash (s, bound, start, end)
|
|
Compute a hash value for @var{s}. The optional argument @var{bound} is a non-negative exact integer specifying the range of the hash function. A positive value restricts the return value to the range [0,bound).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-hash-ci s [bound [start [end]]]
|
|
@deffnx {C Function} scm_substring_hash_ci (s, bound, start, end)
|
|
Compute a hash value for @var{s}. The optional argument @var{bound} is a non-negative exact integer specifying the range of the hash function. A positive value restricts the return value to the range [0,bound).
|
|
@end deffn
|
|
|
|
Because the same visual appearance of an abstract Unicode character can
|
|
be obtained via multiple sequences of Unicode characters, even the
|
|
case-insensitive string comparison functions described above may return
|
|
@code{#f} when presented with strings containing different
|
|
representations of the same character. For example, the Unicode
|
|
character ``LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE'' can be
|
|
represented with a single character (U+1E69) or by the character ``LATIN
|
|
SMALL LETTER S'' (U+0073) followed by the combining marks ``COMBINING
|
|
DOT BELOW'' (U+0323) and ``COMBINING DOT ABOVE'' (U+0307).
|
|
|
|
For this reason, it is often desirable to ensure that the strings
|
|
to be compared are using a mutually consistent representation for every
|
|
character. The Unicode standard defines two methods of normalizing the
|
|
contents of strings: Decomposition, which breaks composite characters
|
|
into a set of constituent characters with an ordering defined by the
|
|
Unicode Standard; and composition, which performs the converse.
|
|
|
|
There are two decomposition operations. ``Canonical decomposition''
|
|
produces character sequences that share the same visual appearance as
|
|
the original characters, while ``compatibility decomposition'' produces
|
|
ones whose visual appearances may differ from the originals but which
|
|
represent the same abstract character.
|
|
|
|
These operations are encapsulated in the following set of normalization
|
|
forms:
|
|
|
|
@table @dfn
|
|
@item NFD
|
|
Characters are decomposed to their canonical forms.
|
|
|
|
@item NFKD
|
|
Characters are decomposed to their compatibility forms.
|
|
|
|
@item NFC
|
|
Characters are decomposed to their canonical forms, then composed.
|
|
|
|
@item NFKC
|
|
Characters are decomposed to their compatibility forms, then composed.
|
|
|
|
@end table
|
|
|
|
The functions below put their arguments into one of the forms described
|
|
above.
|
|
|
|
@deffn {Scheme Procedure} string-normalize-nfd s
|
|
@deffnx {C Function} scm_string_normalize_nfd (s)
|
|
Return the @code{NFD} normalized form of @var{s}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-normalize-nfkd s
|
|
@deffnx {C Function} scm_string_normalize_nfkd (s)
|
|
Return the @code{NFKD} normalized form of @var{s}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-normalize-nfc s
|
|
@deffnx {C Function} scm_string_normalize_nfc (s)
|
|
Return the @code{NFC} normalized form of @var{s}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-normalize-nfkc s
|
|
@deffnx {C Function} scm_string_normalize_nfkc (s)
|
|
Return the @code{NFKC} normalized form of @var{s}.
|
|
@end deffn
|
|
|
|
@node String Searching
|
|
@subsubsection String Searching
|
|
|
|
@deffn {Scheme Procedure} string-index s char_pred [start [end]]
|
|
@deffnx {C Function} scm_string_index (s, char_pred, start, end)
|
|
Search through the string @var{s} from left to right, returning
|
|
the index of the first occurrence of a character which
|
|
|
|
@itemize @bullet
|
|
@item
|
|
equals @var{char_pred}, if it is character,
|
|
|
|
@item
|
|
satisfies the predicate @var{char_pred}, if it is a procedure,
|
|
|
|
@item
|
|
is in the set @var{char_pred}, if it is a character set.
|
|
@end itemize
|
|
|
|
Return @code{#f} if no match is found.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-rindex s char_pred [start [end]]
|
|
@deffnx {C Function} scm_string_rindex (s, char_pred, start, end)
|
|
Search through the string @var{s} from right to left, returning
|
|
the index of the last occurrence of a character which
|
|
|
|
@itemize @bullet
|
|
@item
|
|
equals @var{char_pred}, if it is character,
|
|
|
|
@item
|
|
satisfies the predicate @var{char_pred}, if it is a procedure,
|
|
|
|
@item
|
|
is in the set if @var{char_pred} is a character set.
|
|
@end itemize
|
|
|
|
Return @code{#f} if no match is found.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-prefix-length s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_prefix_length (s1, s2, start1, end1, start2, end2)
|
|
Return the length of the longest common prefix of the two
|
|
strings.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-prefix-length-ci s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_prefix_length_ci (s1, s2, start1, end1, start2, end2)
|
|
Return the length of the longest common prefix of the two
|
|
strings, ignoring character case.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-suffix-length s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_suffix_length (s1, s2, start1, end1, start2, end2)
|
|
Return the length of the longest common suffix of the two
|
|
strings.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-suffix-length-ci s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_suffix_length_ci (s1, s2, start1, end1, start2, end2)
|
|
Return the length of the longest common suffix of the two
|
|
strings, ignoring character case.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-prefix? s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_prefix_p (s1, s2, start1, end1, start2, end2)
|
|
Is @var{s1} a prefix of @var{s2}?
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-prefix-ci? s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_prefix_ci_p (s1, s2, start1, end1, start2, end2)
|
|
Is @var{s1} a prefix of @var{s2}, ignoring character case?
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-suffix? s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_suffix_p (s1, s2, start1, end1, start2, end2)
|
|
Is @var{s1} a suffix of @var{s2}?
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-suffix-ci? s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_suffix_ci_p (s1, s2, start1, end1, start2, end2)
|
|
Is @var{s1} a suffix of @var{s2}, ignoring character case?
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-index-right s char_pred [start [end]]
|
|
@deffnx {C Function} scm_string_index_right (s, char_pred, start, end)
|
|
Search through the string @var{s} from right to left, returning
|
|
the index of the last occurrence of a character which
|
|
|
|
@itemize @bullet
|
|
@item
|
|
equals @var{char_pred}, if it is character,
|
|
|
|
@item
|
|
satisfies the predicate @var{char_pred}, if it is a procedure,
|
|
|
|
@item
|
|
is in the set if @var{char_pred} is a character set.
|
|
@end itemize
|
|
|
|
Return @code{#f} if no match is found.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-skip s char_pred [start [end]]
|
|
@deffnx {C Function} scm_string_skip (s, char_pred, start, end)
|
|
Search through the string @var{s} from left to right, returning
|
|
the index of the first occurrence of a character which
|
|
|
|
@itemize @bullet
|
|
@item
|
|
does not equal @var{char_pred}, if it is character,
|
|
|
|
@item
|
|
does not satisfy the predicate @var{char_pred}, if it is a
|
|
procedure,
|
|
|
|
@item
|
|
is not in the set if @var{char_pred} is a character set.
|
|
@end itemize
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-skip-right s char_pred [start [end]]
|
|
@deffnx {C Function} scm_string_skip_right (s, char_pred, start, end)
|
|
Search through the string @var{s} from right to left, returning
|
|
the index of the last occurrence of a character which
|
|
|
|
@itemize @bullet
|
|
@item
|
|
does not equal @var{char_pred}, if it is character,
|
|
|
|
@item
|
|
does not satisfy the predicate @var{char_pred}, if it is a
|
|
procedure,
|
|
|
|
@item
|
|
is not in the set if @var{char_pred} is a character set.
|
|
@end itemize
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-count s char_pred [start [end]]
|
|
@deffnx {C Function} scm_string_count (s, char_pred, start, end)
|
|
Return the count of the number of characters in the string
|
|
@var{s} which
|
|
|
|
@itemize @bullet
|
|
@item
|
|
equals @var{char_pred}, if it is character,
|
|
|
|
@item
|
|
satisfies the predicate @var{char_pred}, if it is a procedure.
|
|
|
|
@item
|
|
is in the set @var{char_pred}, if it is a character set.
|
|
@end itemize
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-contains s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_contains (s1, s2, start1, end1, start2, end2)
|
|
Does string @var{s1} contain string @var{s2}? Return the index
|
|
in @var{s1} where @var{s2} occurs as a substring, or false.
|
|
The optional start/end indices restrict the operation to the
|
|
indicated substrings.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-contains-ci s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_contains_ci (s1, s2, start1, end1, start2, end2)
|
|
Does string @var{s1} contain string @var{s2}? Return the index
|
|
in @var{s1} where @var{s2} occurs as a substring, or false.
|
|
The optional start/end indices restrict the operation to the
|
|
indicated substrings. Character comparison is done
|
|
case-insensitively.
|
|
@end deffn
|
|
|
|
@node Alphabetic Case Mapping
|
|
@subsubsection Alphabetic Case Mapping
|
|
|
|
These are procedures for mapping strings to their upper- or lower-case
|
|
equivalents, respectively, or for capitalizing strings.
|
|
|
|
They use the basic case mapping rules for Unicode characters. No
|
|
special language or context rules are considered. The resulting strings
|
|
are guaranteed to be the same length as the input strings.
|
|
|
|
@xref{Character Case Mapping, the @code{(ice-9
|
|
i18n)} module}, for locale-dependent case conversions.
|
|
|
|
@deffn {Scheme Procedure} string-upcase str [start [end]]
|
|
@deffnx {C Function} scm_substring_upcase (str, start, end)
|
|
@deffnx {C Function} scm_string_upcase (str)
|
|
Upcase every character in @code{str}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-upcase! str [start [end]]
|
|
@deffnx {C Function} scm_substring_upcase_x (str, start, end)
|
|
@deffnx {C Function} scm_string_upcase_x (str)
|
|
Destructively upcase every character in @code{str}.
|
|
|
|
@lisp
|
|
(string-upcase! y)
|
|
@result{} "ARRDEFG"
|
|
y
|
|
@result{} "ARRDEFG"
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-downcase str [start [end]]
|
|
@deffnx {C Function} scm_substring_downcase (str, start, end)
|
|
@deffnx {C Function} scm_string_downcase (str)
|
|
Downcase every character in @var{str}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-downcase! str [start [end]]
|
|
@deffnx {C Function} scm_substring_downcase_x (str, start, end)
|
|
@deffnx {C Function} scm_string_downcase_x (str)
|
|
Destructively downcase every character in @var{str}.
|
|
|
|
@lisp
|
|
y
|
|
@result{} "ARRDEFG"
|
|
(string-downcase! y)
|
|
@result{} "arrdefg"
|
|
y
|
|
@result{} "arrdefg"
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-capitalize str
|
|
@deffnx {C Function} scm_string_capitalize (str)
|
|
Return a freshly allocated string with the characters in
|
|
@var{str}, where the first character of every word is
|
|
capitalized.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-capitalize! str
|
|
@deffnx {C Function} scm_string_capitalize_x (str)
|
|
Upcase the first character of every word in @var{str}
|
|
destructively and return @var{str}.
|
|
|
|
@lisp
|
|
y @result{} "hello world"
|
|
(string-capitalize! y) @result{} "Hello World"
|
|
y @result{} "Hello World"
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-titlecase str [start [end]]
|
|
@deffnx {C Function} scm_string_titlecase (str, start, end)
|
|
Titlecase every first character in a word in @var{str}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-titlecase! str [start [end]]
|
|
@deffnx {C Function} scm_string_titlecase_x (str, start, end)
|
|
Destructively titlecase every first character in a word in
|
|
@var{str}.
|
|
@end deffn
|
|
|
|
@node Reversing and Appending Strings
|
|
@subsubsection Reversing and Appending Strings
|
|
|
|
@deffn {Scheme Procedure} string-reverse str [start [end]]
|
|
@deffnx {C Function} scm_string_reverse (str, start, end)
|
|
Reverse the string @var{str}. The optional arguments
|
|
@var{start} and @var{end} delimit the region of @var{str} to
|
|
operate on.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-reverse! str [start [end]]
|
|
@deffnx {C Function} scm_string_reverse_x (str, start, end)
|
|
Reverse the string @var{str} in-place. The optional arguments
|
|
@var{start} and @var{end} delimit the region of @var{str} to
|
|
operate on. The return value is unspecified.
|
|
@end deffn
|
|
|
|
@rnindex string-append
|
|
@deffn {Scheme Procedure} string-append arg @dots{}
|
|
@deffnx {C Function} scm_string_append (args)
|
|
Return a newly allocated string whose characters form the
|
|
concatenation of the given strings, @var{arg} @enddots{}.
|
|
|
|
@example
|
|
(let ((h "hello "))
|
|
(string-append h "world"))
|
|
@result{} "hello world"
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-append/shared arg @dots{}
|
|
@deffnx {C Function} scm_string_append_shared (args)
|
|
Like @code{string-append}, but the result may share memory
|
|
with the argument strings.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-concatenate ls
|
|
@deffnx {C Function} scm_string_concatenate (ls)
|
|
Append the elements (which must be strings) of @var{ls} together into a
|
|
single string. Guaranteed to return a freshly allocated string.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-concatenate-reverse ls [final_string [end]]
|
|
@deffnx {C Function} scm_string_concatenate_reverse (ls, final_string, end)
|
|
Without optional arguments, this procedure is equivalent to
|
|
|
|
@lisp
|
|
(string-concatenate (reverse ls))
|
|
@end lisp
|
|
|
|
If the optional argument @var{final_string} is specified, it is
|
|
consed onto the beginning to @var{ls} before performing the
|
|
list-reverse and string-concatenate operations. If @var{end}
|
|
is given, only the characters of @var{final_string} up to index
|
|
@var{end} are used.
|
|
|
|
Guaranteed to return a freshly allocated string.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-concatenate/shared ls
|
|
@deffnx {C Function} scm_string_concatenate_shared (ls)
|
|
Like @code{string-concatenate}, but the result may share memory
|
|
with the strings in the list @var{ls}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-concatenate-reverse/shared ls [final_string [end]]
|
|
@deffnx {C Function} scm_string_concatenate_reverse_shared (ls, final_string, end)
|
|
Like @code{string-concatenate-reverse}, but the result may
|
|
share memory with the strings in the @var{ls} arguments.
|
|
@end deffn
|
|
|
|
@node Mapping Folding and Unfolding
|
|
@subsubsection Mapping, Folding, and Unfolding
|
|
|
|
@deffn {Scheme Procedure} string-map proc s [start [end]]
|
|
@deffnx {C Function} scm_string_map (proc, s, start, end)
|
|
@var{proc} is a char->char procedure, it is mapped over
|
|
@var{s}. The order in which the procedure is applied to the
|
|
string elements is not specified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-map! proc s [start [end]]
|
|
@deffnx {C Function} scm_string_map_x (proc, s, start, end)
|
|
@var{proc} is a char->char procedure, it is mapped over
|
|
@var{s}. The order in which the procedure is applied to the
|
|
string elements is not specified. The string @var{s} is
|
|
modified in-place, the return value is not specified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-for-each proc s [start [end]]
|
|
@deffnx {C Function} scm_string_for_each (proc, s, start, end)
|
|
@var{proc} is mapped over @var{s} in left-to-right order. The
|
|
return value is not specified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-for-each-index proc s [start [end]]
|
|
@deffnx {C Function} scm_string_for_each_index (proc, s, start, end)
|
|
Call @code{(@var{proc} i)} for each index i in @var{s}, from left to
|
|
right.
|
|
|
|
For example, to change characters to alternately upper and lower case,
|
|
|
|
@example
|
|
(define str (string-copy "studly"))
|
|
(string-for-each-index
|
|
(lambda (i)
|
|
(string-set! str i
|
|
((if (even? i) char-upcase char-downcase)
|
|
(string-ref str i))))
|
|
str)
|
|
str @result{} "StUdLy"
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-fold kons knil s [start [end]]
|
|
@deffnx {C Function} scm_string_fold (kons, knil, s, start, end)
|
|
Fold @var{kons} over the characters of @var{s}, with @var{knil}
|
|
as the terminating element, from left to right. @var{kons}
|
|
must expect two arguments: The actual character and the last
|
|
result of @var{kons}' application.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-fold-right kons knil s [start [end]]
|
|
@deffnx {C Function} scm_string_fold_right (kons, knil, s, start, end)
|
|
Fold @var{kons} over the characters of @var{s}, with @var{knil}
|
|
as the terminating element, from right to left. @var{kons}
|
|
must expect two arguments: The actual character and the last
|
|
result of @var{kons}' application.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-unfold p f g seed [base [make_final]]
|
|
@deffnx {C Function} scm_string_unfold (p, f, g, seed, base, make_final)
|
|
@itemize @bullet
|
|
@item @var{g} is used to generate a series of @emph{seed}
|
|
values from the initial @var{seed}: @var{seed}, (@var{g}
|
|
@var{seed}), (@var{g}^2 @var{seed}), (@var{g}^3 @var{seed}),
|
|
@dots{}
|
|
@item @var{p} tells us when to stop -- when it returns true
|
|
when applied to one of these seed values.
|
|
@item @var{f} maps each seed value to the corresponding
|
|
character in the result string. These chars are assembled
|
|
into the string in a left-to-right order.
|
|
@item @var{base} is the optional initial/leftmost portion
|
|
of the constructed string; it default to the empty
|
|
string.
|
|
@item @var{make_final} is applied to the terminal seed
|
|
value (on which @var{p} returns true) to produce
|
|
the final/rightmost portion of the constructed string.
|
|
The default is nothing extra.
|
|
@end itemize
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-unfold-right p f g seed [base [make_final]]
|
|
@deffnx {C Function} scm_string_unfold_right (p, f, g, seed, base, make_final)
|
|
@itemize @bullet
|
|
@item @var{g} is used to generate a series of @emph{seed}
|
|
values from the initial @var{seed}: @var{seed}, (@var{g}
|
|
@var{seed}), (@var{g}^2 @var{seed}), (@var{g}^3 @var{seed}),
|
|
@dots{}
|
|
@item @var{p} tells us when to stop -- when it returns true
|
|
when applied to one of these seed values.
|
|
@item @var{f} maps each seed value to the corresponding
|
|
character in the result string. These chars are assembled
|
|
into the string in a right-to-left order.
|
|
@item @var{base} is the optional initial/rightmost portion
|
|
of the constructed string; it default to the empty
|
|
string.
|
|
@item @var{make_final} is applied to the terminal seed
|
|
value (on which @var{p} returns true) to produce
|
|
the final/leftmost portion of the constructed string.
|
|
It defaults to @code{(lambda (x) )}.
|
|
@end itemize
|
|
@end deffn
|
|
|
|
@node Miscellaneous String Operations
|
|
@subsubsection Miscellaneous String Operations
|
|
|
|
@deffn {Scheme Procedure} xsubstring s from [to [start [end]]]
|
|
@deffnx {C Function} scm_xsubstring (s, from, to, start, end)
|
|
This is the @emph{extended substring} procedure that implements
|
|
replicated copying of a substring of some string.
|
|
|
|
@var{s} is a string, @var{start} and @var{end} are optional
|
|
arguments that demarcate a substring of @var{s}, defaulting to
|
|
0 and the length of @var{s}. Replicate this substring up and
|
|
down index space, in both the positive and negative directions.
|
|
@code{xsubstring} returns the substring of this string
|
|
beginning at index @var{from}, and ending at @var{to}, which
|
|
defaults to @var{from} + (@var{end} - @var{start}).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-xcopy! target tstart s sfrom [sto [start [end]]]
|
|
@deffnx {C Function} scm_string_xcopy_x (target, tstart, s, sfrom, sto, start, end)
|
|
Exactly the same as @code{xsubstring}, but the extracted text
|
|
is written into the string @var{target} starting at index
|
|
@var{tstart}. The operation is not defined if @code{(eq?
|
|
@var{target} @var{s})} or these arguments share storage -- you
|
|
cannot copy a string on top of itself.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-replace s1 s2 [start1 [end1 [start2 [end2]]]]
|
|
@deffnx {C Function} scm_string_replace (s1, s2, start1, end1, start2, end2)
|
|
Return the string @var{s1}, but with the characters
|
|
@var{start1} @dots{} @var{end1} replaced by the characters
|
|
@var{start2} @dots{} @var{end2} from @var{s2}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-tokenize s [token_set [start [end]]]
|
|
@deffnx {C Function} scm_string_tokenize (s, token_set, start, end)
|
|
Split the string @var{s} into a list of substrings, where each
|
|
substring is a maximal non-empty contiguous sequence of
|
|
characters from the character set @var{token_set}, which
|
|
defaults to @code{char-set:graphic}.
|
|
If @var{start} or @var{end} indices are provided, they restrict
|
|
@code{string-tokenize} to operating on the indicated substring
|
|
of @var{s}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-filter char_pred s [start [end]]
|
|
@deffnx {C Function} scm_string_filter (char_pred, s, start, end)
|
|
Filter the string @var{s}, retaining only those characters which
|
|
satisfy @var{char_pred}.
|
|
|
|
If @var{char_pred} is a procedure, it is applied to each character as
|
|
a predicate, if it is a character, it is tested for equality and if it
|
|
is a character set, it is tested for membership.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-delete char_pred s [start [end]]
|
|
@deffnx {C Function} scm_string_delete (char_pred, s, start, end)
|
|
Delete characters satisfying @var{char_pred} from @var{s}.
|
|
|
|
If @var{char_pred} is a procedure, it is applied to each character as
|
|
a predicate, if it is a character, it is tested for equality and if it
|
|
is a character set, it is tested for membership.
|
|
@end deffn
|
|
|
|
The following additional functions are available in the module @code{(ice-9 string-fun)}. They can be used with:
|
|
|
|
@example
|
|
(use-modules (ice-9 string-fun))
|
|
@end example
|
|
|
|
@deffn {Scheme Procedure} string-replace-substring str substring replacement
|
|
Return a new string where every instance of @var{substring} in string
|
|
@var{str} has been replaced by @var{replacement}. For example:
|
|
|
|
@lisp
|
|
(string-replace-substring "a ring of strings" "ring" "rut")
|
|
@result{} "a rut of struts"
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@node Representing Strings as Bytes
|
|
@subsubsection Representing Strings as Bytes
|
|
|
|
Out in the cold world outside of Guile, not all strings are treated in
|
|
the same way. Out there there are only bytes, and there are many ways
|
|
of representing a strings (sequences of characters) as binary data
|
|
(sequences of bytes).
|
|
|
|
As a user, usually you don't have to think about this very much. When
|
|
you type on your keyboard, your system encodes your keystrokes as bytes
|
|
according to the locale that you have configured on your computer.
|
|
Guile uses the locale to decode those bytes back into characters --
|
|
hopefully the same characters that you typed in.
|
|
|
|
All is not so clear when dealing with a system with multiple users, such
|
|
as a web server. Your web server might get a request from one user for
|
|
data encoded in the ISO-8859-1 character set, and then another request
|
|
from a different user for UTF-8 data.
|
|
|
|
@cindex iconv
|
|
@cindex character encoding
|
|
Guile provides an @dfn{iconv} module for converting between strings and
|
|
sequences of bytes. @xref{Bytevectors}, for more on how Guile
|
|
represents raw byte sequences. This module gets its name from the
|
|
common @sc{unix} command of the same name.
|
|
|
|
Note that often it is sufficient to just read and write strings from
|
|
ports instead of using these functions. To do this, specify the port
|
|
encoding using @code{set-port-encoding!}. @xref{Ports}, for more on
|
|
ports and character encodings.
|
|
|
|
Unlike the rest of the procedures in this section, you have to load the
|
|
@code{iconv} module before having access to these procedures:
|
|
|
|
@example
|
|
(use-modules (ice-9 iconv))
|
|
@end example
|
|
|
|
@deffn {Scheme Procedure} string->bytevector string encoding [conversion-strategy]
|
|
Encode @var{string} as a sequence of bytes.
|
|
|
|
The string will be encoded in the character set specified by the
|
|
@var{encoding} string. If the string has characters that cannot be
|
|
represented in the encoding, by default this procedure raises an
|
|
@code{encoding-error}. Pass a @var{conversion-strategy} argument to
|
|
specify other behaviors.
|
|
|
|
The return value is a bytevector. @xref{Bytevectors}, for more on
|
|
bytevectors. @xref{Ports}, for more on character encodings and
|
|
conversion strategies.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector->string bytevector encoding [conversion-strategy]
|
|
Decode @var{bytevector} into a string.
|
|
|
|
The bytes will be decoded from the character set by the @var{encoding}
|
|
string. If the bytes do not form a valid encoding, by default this
|
|
procedure raises an @code{decoding-error}. As with
|
|
@code{string->bytevector}, pass the optional @var{conversion-strategy}
|
|
argument to modify this behavior. @xref{Ports}, for more on character
|
|
encodings and conversion strategies.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} call-with-output-encoded-string encoding proc [conversion-strategy]
|
|
Like @code{call-with-output-string}, but instead of returning a string,
|
|
returns a encoding of the string according to @var{encoding}, as a
|
|
bytevector. This procedure can be more efficient than collecting a
|
|
string and then converting it via @code{string->bytevector}.
|
|
@end deffn
|
|
|
|
@node Conversion to/from C
|
|
@subsubsection Conversion to/from C
|
|
|
|
When creating a Scheme string from a C string or when converting a
|
|
Scheme string to a C string, the concept of character encoding becomes
|
|
important.
|
|
|
|
In C, a string is just a sequence of bytes, and the character encoding
|
|
describes the relation between these bytes and the actual characters
|
|
that make up the string. For Scheme strings, character encoding is not
|
|
an issue (most of the time), since in Scheme you usually treat strings
|
|
as character sequences, not byte sequences.
|
|
|
|
Converting to C and converting from C each have their own challenges.
|
|
|
|
When converting from C to Scheme, it is important that the sequence of
|
|
bytes in the C string be valid with respect to its encoding. ASCII
|
|
strings, for example, can't have any bytes greater than 127. An ASCII
|
|
byte greater than 127 is considered @emph{ill-formed} and cannot be
|
|
converted into a Scheme character.
|
|
|
|
Problems can occur in the reverse operation as well. Not all character
|
|
encodings can hold all possible Scheme characters. Some encodings, like
|
|
ASCII for example, can only describe a small subset of all possible
|
|
characters. So, when converting to C, one must first decide what to do
|
|
with Scheme characters that can't be represented in the C string.
|
|
|
|
Converting a Scheme string to a C string will often allocate fresh
|
|
memory to hold the result. You must take care that this memory is
|
|
properly freed eventually. In many cases, this can be achieved by
|
|
using @code{scm_dynwind_free} inside an appropriate dynwind context,
|
|
@xref{Dynamic Wind}.
|
|
|
|
@deftypefn {C Function} SCM scm_from_locale_string (const char *str)
|
|
@deftypefnx {C Function} SCM scm_from_locale_stringn (const char *str, size_t len)
|
|
Creates a new Scheme string that has the same contents as @var{str} when
|
|
interpreted in the character encoding of the current locale.
|
|
|
|
For @code{scm_from_locale_string}, @var{str} must be null-terminated.
|
|
|
|
For @code{scm_from_locale_stringn}, @var{len} specifies the length of
|
|
@var{str} in bytes, and @var{str} does not need to be null-terminated.
|
|
If @var{len} is @code{(size_t)-1}, then @var{str} does need to be
|
|
null-terminated and the real length will be found with @code{strlen}.
|
|
|
|
If the C string is ill-formed, an error will be raised.
|
|
|
|
Note that these functions should @emph{not} be used to convert C string
|
|
constants, because there is no guarantee that the current locale will
|
|
match that of the execution character set, used for string and character
|
|
constants. Most modern C compilers use UTF-8 by default, so to convert
|
|
C string constants we recommend @code{scm_from_utf8_string}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_take_locale_string (char *str)
|
|
@deftypefnx {C Function} SCM scm_take_locale_stringn (char *str, size_t len)
|
|
Like @code{scm_from_locale_string} and @code{scm_from_locale_stringn},
|
|
respectively, but also frees @var{str} with @code{free} eventually.
|
|
Thus, you can use this function when you would free @var{str} anyway
|
|
immediately after creating the Scheme string. In certain cases, Guile
|
|
can then use @var{str} directly as its internal representation.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {char *} scm_to_locale_string (SCM str)
|
|
@deftypefnx {C Function} {char *} scm_to_locale_stringn (SCM str, size_t *lenp)
|
|
Returns a C string with the same contents as @var{str} in the character
|
|
encoding of the current locale. The C string must be freed with
|
|
@code{free} eventually, maybe by using @code{scm_dynwind_free},
|
|
@xref{Dynamic Wind}.
|
|
|
|
For @code{scm_to_locale_string}, the returned string is
|
|
null-terminated and an error is signaled when @var{str} contains
|
|
@code{#\nul} characters.
|
|
|
|
For @code{scm_to_locale_stringn} and @var{lenp} not @code{NULL},
|
|
@var{str} might contain @code{#\nul} characters and the length of the
|
|
returned string in bytes is stored in @code{*@var{lenp}}. The
|
|
returned string will not be null-terminated in this case. If
|
|
@var{lenp} is @code{NULL}, @code{scm_to_locale_stringn} behaves like
|
|
@code{scm_to_locale_string}.
|
|
|
|
If a character in @var{str} cannot be represented in the character
|
|
encoding of the current locale, the default port conversion strategy is
|
|
used. @xref{Ports}, for more on conversion strategies.
|
|
|
|
If the conversion strategy is @code{error}, an error will be raised. If
|
|
it is @code{substitute}, a replacement character, such as a question
|
|
mark, will be inserted in its place. If it is @code{escape}, a hex
|
|
escape will be inserted in its place.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} size_t scm_to_locale_stringbuf (SCM str, char *buf, size_t max_len)
|
|
Puts @var{str} as a C string in the current locale encoding into the
|
|
memory pointed to by @var{buf}. The buffer at @var{buf} has room for
|
|
@var{max_len} bytes and @code{scm_to_local_stringbuf} will never store
|
|
more than that. No terminating @code{'\0'} will be stored.
|
|
|
|
The return value of @code{scm_to_locale_stringbuf} is the number of
|
|
bytes that are needed for all of @var{str}, regardless of whether
|
|
@var{buf} was large enough to hold them. Thus, when the return value
|
|
is larger than @var{max_len}, only @var{max_len} bytes have been
|
|
stored and you probably need to try again with a larger buffer.
|
|
@end deftypefn
|
|
|
|
For most situations, string conversion should occur using the current
|
|
locale, such as with the functions above. But there may be cases where
|
|
one wants to convert strings from a character encoding other than the
|
|
locale's character encoding. For these cases, the lower-level functions
|
|
@code{scm_to_stringn} and @code{scm_from_stringn} are provided. These
|
|
functions should seldom be necessary if one is properly using locales.
|
|
|
|
@deftp {C Type} scm_t_string_failed_conversion_handler
|
|
This is an enumerated type that can take one of three values:
|
|
@code{SCM_FAILED_CONVERSION_ERROR},
|
|
@code{SCM_FAILED_CONVERSION_QUESTION_MARK}, and
|
|
@code{SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE}. They are used to indicate
|
|
a strategy for handling characters that cannot be converted to or from a
|
|
given character encoding. @code{SCM_FAILED_CONVERSION_ERROR} indicates
|
|
that a conversion should throw an error if some characters cannot be
|
|
converted. @code{SCM_FAILED_CONVERSION_QUESTION_MARK} indicates that a
|
|
conversion should replace unconvertable characters with the question
|
|
mark character. And, @code{SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE}
|
|
requests that a conversion should replace an unconvertable character
|
|
with an escape sequence.
|
|
|
|
While all three strategies apply when converting Scheme strings to C,
|
|
only @code{SCM_FAILED_CONVERSION_ERROR} and
|
|
@code{SCM_FAILED_CONVERSION_QUESTION_MARK} can be used when converting C
|
|
strings to Scheme.
|
|
@end deftp
|
|
|
|
@deftypefn {C Function} char *scm_to_stringn (SCM str, size_t *lenp, const char *encoding, scm_t_string_failed_conversion_handler handler)
|
|
This function returns a newly allocated C string from the Guile string
|
|
@var{str}. The length of the returned string in bytes will be returned in
|
|
@var{lenp}. The character encoding of the C string is passed as the ASCII,
|
|
null-terminated C string @var{encoding}. The @var{handler} parameter
|
|
gives a strategy for dealing with characters that cannot be converted
|
|
into @var{encoding}.
|
|
|
|
If @var{lenp} is @code{NULL}, this function will return a null-terminated C
|
|
string. It will throw an error if the string contains a null
|
|
character.
|
|
|
|
The Scheme interface to this function is @code{string->bytevector}, from the
|
|
@code{ice-9 iconv} module. @xref{Representing Strings as Bytes}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_from_stringn (const char *str, size_t len, const char *encoding, scm_t_string_failed_conversion_handler handler)
|
|
This function returns a scheme string from the C string @var{str}. The
|
|
length in bytes of the C string is input as @var{len}. The encoding of the C
|
|
string is passed as the ASCII, null-terminated C string @code{encoding}.
|
|
The @var{handler} parameters suggests a strategy for dealing with
|
|
unconvertable characters.
|
|
|
|
The Scheme interface to this function is @code{bytevector->string}.
|
|
@xref{Representing Strings as Bytes}.
|
|
@end deftypefn
|
|
|
|
The following conversion functions are provided as a convenience for the
|
|
most commonly used encodings.
|
|
|
|
@deftypefn {C Function} SCM scm_from_latin1_string (const char *str)
|
|
@deftypefnx {C Function} SCM scm_from_utf8_string (const char *str)
|
|
@deftypefnx {C Function} SCM scm_from_utf32_string (const scm_t_wchar *str)
|
|
Return a scheme string from the null-terminated C string @var{str},
|
|
which is ISO-8859-1-, UTF-8-, or UTF-32-encoded. These functions should
|
|
be used to convert hard-coded C string constants into Scheme strings.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_from_latin1_stringn (const char *str, size_t len)
|
|
@deftypefnx {C Function} SCM scm_from_utf8_stringn (const char *str, size_t len)
|
|
@deftypefnx {C Function} SCM scm_from_utf32_stringn (const scm_t_wchar *str, size_t len)
|
|
Return a scheme string from C string @var{str}, which is ISO-8859-1-,
|
|
UTF-8-, or UTF-32-encoded, of length @var{len}. @var{len} is the number
|
|
of bytes pointed to by @var{str} for @code{scm_from_latin1_stringn} and
|
|
@code{scm_from_utf8_stringn}; it is the number of elements (code points)
|
|
in @var{str} in the case of @code{scm_from_utf32_stringn}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C function} char *scm_to_latin1_stringn (SCM str, size_t *lenp)
|
|
@deftypefnx {C function} char *scm_to_utf8_stringn (SCM str, size_t *lenp)
|
|
@deftypefnx {C function} scm_t_wchar *scm_to_utf32_stringn (SCM str, size_t *lenp)
|
|
Return a newly allocated, ISO-8859-1-, UTF-8-, or UTF-32-encoded C string
|
|
from Scheme string @var{str}. An error is thrown when @var{str}
|
|
cannot be converted to the specified encoding. If @var{lenp} is
|
|
@code{NULL}, the returned C string will be null terminated, and an error
|
|
will be thrown if the C string would otherwise contain null
|
|
characters. If @var{lenp} is not @code{NULL}, the string is not null terminated,
|
|
and the length of the returned string is returned in @var{lenp}. The length
|
|
returned is the number of bytes for @code{scm_to_latin1_stringn} and
|
|
@code{scm_to_utf8_stringn}; it is the number of elements (code points)
|
|
for @code{scm_to_utf32_stringn}.
|
|
@end deftypefn
|
|
|
|
It is not often the case, but sometimes when you are dealing with the
|
|
implementation details of a port, you need to encode and decode strings
|
|
according to the encoding and conversion strategy of the port. There
|
|
are some convenience functions for that purpose as well.
|
|
|
|
@deftypefn {C Function} SCM scm_from_port_string (const char *str, SCM port)
|
|
@deftypefnx {C Function} SCM scm_from_port_stringn (const char *str, size_t len, SCM port)
|
|
@deftypefnx {C Function} char* scm_to_port_string (SCM str, SCM port)
|
|
@deftypefnx {C Function} char* scm_to_port_stringn (SCM str, size_t *lenp, SCM port)
|
|
Like @code{scm_from_stringn} and friends, except they take their
|
|
encoding and conversion strategy from a given port object.
|
|
@end deftypefn
|
|
|
|
@node String Internals
|
|
@subsubsection String Internals
|
|
|
|
Guile stores each string in memory as a contiguous array of Unicode code
|
|
points along with an associated set of attributes. If all of the code
|
|
points of a string have an integer range between 0 and 255 inclusive,
|
|
the code point array is stored as one byte per code point: it is stored
|
|
as an ISO-8859-1 (aka Latin-1) string. If any of the code points of the
|
|
string has an integer value greater that 255, the code point array is
|
|
stored as four bytes per code point: it is stored as a UTF-32 string.
|
|
|
|
Conversion between the one-byte-per-code-point and
|
|
four-bytes-per-code-point representations happens automatically as
|
|
necessary.
|
|
|
|
No API is provided to set the internal representation of strings;
|
|
however, there are pair of procedures available to query it. These are
|
|
debugging procedures. Using them in production code is discouraged,
|
|
since the details of Guile's internal representation of strings may
|
|
change from release to release.
|
|
|
|
@deffn {Scheme Procedure} string-bytes-per-char str
|
|
@deffnx {C Function} scm_string_bytes_per_char (str)
|
|
Return the number of bytes used to encode a Unicode code point in string
|
|
@var{str}. The result is one or four.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} %string-dump str
|
|
@deffnx {C Function} scm_sys_string_dump (str)
|
|
Returns an association list containing debugging information for
|
|
@var{str}. The association list has the following entries.
|
|
@table @code
|
|
|
|
@item string
|
|
The string itself.
|
|
|
|
@item start
|
|
The start index of the string into its stringbuf
|
|
|
|
@item length
|
|
The length of the string
|
|
|
|
@item shared
|
|
If this string is a substring, it returns its
|
|
parent string. Otherwise, it returns @code{#f}
|
|
|
|
@item read-only
|
|
@code{#t} if the string is read-only
|
|
|
|
@item stringbuf-chars
|
|
A new string containing this string's stringbuf's characters
|
|
|
|
@item stringbuf-length
|
|
The number of characters in this stringbuf
|
|
|
|
@item stringbuf-shared
|
|
@code{#t} if this stringbuf is shared
|
|
|
|
@item stringbuf-wide
|
|
@code{#t} if this stringbuf's characters are stored in a 32-bit buffer,
|
|
or @code{#f} if they are stored in an 8-bit buffer
|
|
@end table
|
|
@end deffn
|
|
|
|
|
|
@node Symbols
|
|
@subsection Symbols
|
|
@tpindex Symbols
|
|
|
|
Symbols in Scheme are widely used in three ways: as items of discrete
|
|
data, as lookup keys for alists and hash tables, and to denote variable
|
|
references.
|
|
|
|
A @dfn{symbol} is similar to a string in that it is defined by a
|
|
sequence of characters. The sequence of characters is known as the
|
|
symbol's @dfn{name}. In the usual case --- that is, where the symbol's
|
|
name doesn't include any characters that could be confused with other
|
|
elements of Scheme syntax --- a symbol is written in a Scheme program by
|
|
writing the sequence of characters that make up the name, @emph{without}
|
|
any quotation marks or other special syntax. For example, the symbol
|
|
whose name is ``multiply-by-2'' is written, simply:
|
|
|
|
@lisp
|
|
multiply-by-2
|
|
@end lisp
|
|
|
|
Notice how this differs from a @emph{string} with contents
|
|
``multiply-by-2'', which is written with double quotation marks, like
|
|
this:
|
|
|
|
@lisp
|
|
"multiply-by-2"
|
|
@end lisp
|
|
|
|
Looking beyond how they are written, symbols are different from strings
|
|
in two important respects.
|
|
|
|
The first important difference is uniqueness. If the same-looking
|
|
string is read twice from two different places in a program, the result
|
|
is two @emph{different} string objects whose contents just happen to be
|
|
the same. If, on the other hand, the same-looking symbol is read twice
|
|
from two different places in a program, the result is the @emph{same}
|
|
symbol object both times.
|
|
|
|
Given two read symbols, you can use @code{eq?} to test whether they are
|
|
the same (that is, have the same name). @code{eq?} is the most
|
|
efficient comparison operator in Scheme, and comparing two symbols like
|
|
this is as fast as comparing, for example, two numbers. Given two
|
|
strings, on the other hand, you must use @code{equal?} or
|
|
@code{string=?}, which are much slower comparison operators, to
|
|
determine whether the strings have the same contents.
|
|
|
|
@lisp
|
|
(define sym1 (quote hello))
|
|
(define sym2 (quote hello))
|
|
(eq? sym1 sym2) @result{} #t
|
|
|
|
(define str1 "hello")
|
|
(define str2 "hello")
|
|
(eq? str1 str2) @result{} #f
|
|
(equal? str1 str2) @result{} #t
|
|
@end lisp
|
|
|
|
The second important difference is that symbols, unlike strings, are not
|
|
self-evaluating. This is why we need the @code{(quote @dots{})}s in the
|
|
example above: @code{(quote hello)} evaluates to the symbol named
|
|
"hello" itself, whereas an unquoted @code{hello} is @emph{read} as the
|
|
symbol named "hello" and evaluated as a variable reference @dots{} about
|
|
which more below (@pxref{Symbol Variables}).
|
|
|
|
@menu
|
|
* Symbol Data:: Symbols as discrete data.
|
|
* Symbol Keys:: Symbols as lookup keys.
|
|
* Symbol Variables:: Symbols as denoting variables.
|
|
* Symbol Primitives:: Operations related to symbols.
|
|
* Symbol Read Syntax:: Extended read syntax for symbols.
|
|
* Symbol Uninterned:: Uninterned symbols.
|
|
@end menu
|
|
|
|
|
|
@node Symbol Data
|
|
@subsubsection Symbols as Discrete Data
|
|
|
|
Numbers and symbols are similar to the extent that they both lend
|
|
themselves to @code{eq?} comparison. But symbols are more descriptive
|
|
than numbers, because a symbol's name can be used directly to describe
|
|
the concept for which that symbol stands.
|
|
|
|
For example, imagine that you need to represent some colours in a
|
|
computer program. Using numbers, you would have to choose arbitrarily
|
|
some mapping between numbers and colours, and then take care to use that
|
|
mapping consistently:
|
|
|
|
@lisp
|
|
;; 1=red, 2=green, 3=purple
|
|
|
|
(if (eq? (colour-of vehicle) 1)
|
|
...)
|
|
@end lisp
|
|
|
|
@noindent
|
|
You can make the mapping more explicit and the code more readable by
|
|
defining constants:
|
|
|
|
@lisp
|
|
(define red 1)
|
|
(define green 2)
|
|
(define purple 3)
|
|
|
|
(if (eq? (colour-of vehicle) red)
|
|
...)
|
|
@end lisp
|
|
|
|
@noindent
|
|
But the simplest and clearest approach is not to use numbers at all, but
|
|
symbols whose names specify the colours that they refer to:
|
|
|
|
@lisp
|
|
(if (eq? (colour-of vehicle) 'red)
|
|
...)
|
|
@end lisp
|
|
|
|
The descriptive advantages of symbols over numbers increase as the set
|
|
of concepts that you want to describe grows. Suppose that a car object
|
|
can have other properties as well, such as whether it has or uses:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
automatic or manual transmission
|
|
@item
|
|
leaded or unleaded fuel
|
|
@item
|
|
power steering (or not).
|
|
@end itemize
|
|
|
|
@noindent
|
|
Then a car's combined property set could be naturally represented and
|
|
manipulated as a list of symbols:
|
|
|
|
@lisp
|
|
(properties-of vehicle1)
|
|
@result{}
|
|
(red manual unleaded power-steering)
|
|
|
|
(if (memq 'power-steering (properties-of vehicle1))
|
|
(display "Unfit people can drive this vehicle.\n")
|
|
(display "You'll need strong arms to drive this vehicle!\n"))
|
|
@print{}
|
|
Unfit people can drive this vehicle.
|
|
@end lisp
|
|
|
|
Remember, the fundamental property of symbols that we are relying on
|
|
here is that an occurrence of @code{'red} in one part of a program is an
|
|
@emph{indistinguishable} symbol from an occurrence of @code{'red} in
|
|
another part of a program; this means that symbols can usefully be
|
|
compared using @code{eq?}. At the same time, symbols have naturally
|
|
descriptive names. This combination of efficiency and descriptive power
|
|
makes them ideal for use as discrete data.
|
|
|
|
|
|
@node Symbol Keys
|
|
@subsubsection Symbols as Lookup Keys
|
|
|
|
Given their efficiency and descriptive power, it is natural to use
|
|
symbols as the keys in an association list or hash table.
|
|
|
|
To illustrate this, consider a more structured representation of the car
|
|
properties example from the preceding subsection. Rather than
|
|
mixing all the properties up together in a flat list, we could use an
|
|
association list like this:
|
|
|
|
@lisp
|
|
(define car1-properties '((colour . red)
|
|
(transmission . manual)
|
|
(fuel . unleaded)
|
|
(steering . power-assisted)))
|
|
@end lisp
|
|
|
|
Notice how this structure is more explicit and extensible than the flat
|
|
list. For example it makes clear that @code{manual} refers to the
|
|
transmission rather than, say, the windows or the locking of the car.
|
|
It also allows further properties to use the same symbols among their
|
|
possible values without becoming ambiguous:
|
|
|
|
@lisp
|
|
(define car1-properties '((colour . red)
|
|
(transmission . manual)
|
|
(fuel . unleaded)
|
|
(steering . power-assisted)
|
|
(seat-colour . red)
|
|
(locking . manual)))
|
|
@end lisp
|
|
|
|
With a representation like this, it is easy to use the efficient
|
|
@code{assq-XXX} family of procedures (@pxref{Association Lists}) to
|
|
extract or change individual pieces of information:
|
|
|
|
@lisp
|
|
(assq-ref car1-properties 'fuel) @result{} unleaded
|
|
(assq-ref car1-properties 'transmission) @result{} manual
|
|
|
|
(assq-set! car1-properties 'seat-colour 'black)
|
|
@result{}
|
|
((colour . red)
|
|
(transmission . manual)
|
|
(fuel . unleaded)
|
|
(steering . power-assisted)
|
|
(seat-colour . black)
|
|
(locking . manual)))
|
|
@end lisp
|
|
|
|
Hash tables also have keys, and exactly the same arguments apply to the
|
|
use of symbols in hash tables as in association lists. The hash value
|
|
that Guile uses to decide where to add a symbol-keyed entry to a hash
|
|
table can be obtained by calling the @code{symbol-hash} procedure:
|
|
|
|
@deffn {Scheme Procedure} symbol-hash symbol
|
|
@deffnx {C Function} scm_symbol_hash (symbol)
|
|
Return a hash value for @var{symbol}.
|
|
@end deffn
|
|
|
|
See @ref{Hash Tables} for information about hash tables in general, and
|
|
for why you might choose to use a hash table rather than an association
|
|
list.
|
|
|
|
|
|
@node Symbol Variables
|
|
@subsubsection Symbols as Denoting Variables
|
|
|
|
When an unquoted symbol in a Scheme program is evaluated, it is
|
|
interpreted as a variable reference, and the result of the evaluation is
|
|
the appropriate variable's value.
|
|
|
|
For example, when the expression @code{(string-length "abcd")} is read
|
|
and evaluated, the sequence of characters @code{string-length} is read
|
|
as the symbol whose name is "string-length". This symbol is associated
|
|
with a variable whose value is the procedure that implements string
|
|
length calculation. Therefore evaluation of the @code{string-length}
|
|
symbol results in that procedure.
|
|
|
|
The details of the connection between an unquoted symbol and the
|
|
variable to which it refers are explained elsewhere. See @ref{Binding
|
|
Constructs}, for how associations between symbols and variables are
|
|
created, and @ref{Modules}, for how those associations are affected by
|
|
Guile's module system.
|
|
|
|
|
|
@node Symbol Primitives
|
|
@subsubsection Operations Related to Symbols
|
|
|
|
Given any Scheme value, you can determine whether it is a symbol using
|
|
the @code{symbol?} primitive:
|
|
|
|
@rnindex symbol?
|
|
@deffn {Scheme Procedure} symbol? obj
|
|
@deffnx {C Function} scm_symbol_p (obj)
|
|
Return @code{#t} if @var{obj} is a symbol, otherwise return
|
|
@code{#f}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_symbol (SCM val)
|
|
Equivalent to @code{scm_is_true (scm_symbol_p (val))}.
|
|
@end deftypefn
|
|
|
|
Once you know that you have a symbol, you can obtain its name as a
|
|
string by calling @code{symbol->string}. Note that Guile differs by
|
|
default from R5RS on the details of @code{symbol->string} as regards
|
|
case-sensitivity:
|
|
|
|
@rnindex symbol->string
|
|
@deffn {Scheme Procedure} symbol->string s
|
|
@deffnx {C Function} scm_symbol_to_string (s)
|
|
Return the name of symbol @var{s} as a string. By default, Guile reads
|
|
symbols case-sensitively, so the string returned will have the same case
|
|
variation as the sequence of characters that caused @var{s} to be
|
|
created.
|
|
|
|
If Guile is set to read symbols case-insensitively (as specified by
|
|
R5RS), and @var{s} comes into being as part of a literal expression
|
|
(@pxref{Literal expressions,,,r5rs, The Revised^5 Report on Scheme}) or
|
|
by a call to the @code{read} or @code{string-ci->symbol} procedures,
|
|
Guile converts any alphabetic characters in the symbol's name to
|
|
lower case before creating the symbol object, so the string returned
|
|
here will be in lower case.
|
|
|
|
If @var{s} was created by @code{string->symbol}, the case of characters
|
|
in the string returned will be the same as that in the string that was
|
|
passed to @code{string->symbol}, regardless of Guile's case-sensitivity
|
|
setting at the time @var{s} was created.
|
|
|
|
It is an error to apply mutation procedures like @code{string-set!} to
|
|
strings returned by this procedure.
|
|
@end deffn
|
|
|
|
Most symbols are created by writing them literally in code. However it
|
|
is also possible to create symbols programmatically using the following
|
|
procedures:
|
|
|
|
@deffn {Scheme Procedure} symbol char@dots{}
|
|
@rnindex symbol
|
|
Return a newly allocated symbol made from the given character arguments.
|
|
|
|
@example
|
|
(symbol #\x #\y #\z) @result{} xyz
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list->symbol lst
|
|
@rnindex list->symbol
|
|
Return a newly allocated symbol made from a list of characters.
|
|
|
|
@example
|
|
(list->symbol '(#\a #\b #\c)) @result{} abc
|
|
@end example
|
|
@end deffn
|
|
|
|
@rnindex symbol-append
|
|
@deffn {Scheme Procedure} symbol-append arg @dots{}
|
|
Return a newly allocated symbol whose characters form the
|
|
concatenation of the given symbols, @var{arg} @enddots{}.
|
|
|
|
@example
|
|
(let ((h 'hello))
|
|
(symbol-append h 'world))
|
|
@result{} helloworld
|
|
@end example
|
|
@end deffn
|
|
|
|
@rnindex string->symbol
|
|
@deffn {Scheme Procedure} string->symbol string
|
|
@deffnx {C Function} scm_string_to_symbol (string)
|
|
Return the symbol whose name is @var{string}. This procedure can create
|
|
symbols with names containing special characters or letters in the
|
|
non-standard case, but it is usually a bad idea to create such symbols
|
|
because in some implementations of Scheme they cannot be read as
|
|
themselves.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} string-ci->symbol str
|
|
@deffnx {C Function} scm_string_ci_to_symbol (str)
|
|
Return the symbol whose name is @var{str}. If Guile is currently
|
|
reading symbols case-insensitively, @var{str} is converted to lowercase
|
|
before the returned symbol is looked up or created.
|
|
@end deffn
|
|
|
|
The following examples illustrate Guile's detailed behaviour as regards
|
|
the case-sensitivity of symbols:
|
|
|
|
@lisp
|
|
(read-enable 'case-insensitive) ; R5RS compliant behaviour
|
|
|
|
(symbol->string 'flying-fish) @result{} "flying-fish"
|
|
(symbol->string 'Martin) @result{} "martin"
|
|
(symbol->string
|
|
(string->symbol "Malvina")) @result{} "Malvina"
|
|
|
|
(eq? 'mISSISSIppi 'mississippi) @result{} #t
|
|
(string->symbol "mISSISSIppi") @result{} mISSISSIppi
|
|
(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #f
|
|
(eq? 'LolliPop
|
|
(string->symbol (symbol->string 'LolliPop))) @result{} #t
|
|
(string=? "K. Harper, M.D."
|
|
(symbol->string
|
|
(string->symbol "K. Harper, M.D."))) @result{} #t
|
|
|
|
(read-disable 'case-insensitive) ; Guile default behaviour
|
|
|
|
(symbol->string 'flying-fish) @result{} "flying-fish"
|
|
(symbol->string 'Martin) @result{} "Martin"
|
|
(symbol->string
|
|
(string->symbol "Malvina")) @result{} "Malvina"
|
|
|
|
(eq? 'mISSISSIppi 'mississippi) @result{} #f
|
|
(string->symbol "mISSISSIppi") @result{} mISSISSIppi
|
|
(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #t
|
|
(eq? 'LolliPop
|
|
(string->symbol (symbol->string 'LolliPop))) @result{} #t
|
|
(string=? "K. Harper, M.D."
|
|
(symbol->string
|
|
(string->symbol "K. Harper, M.D."))) @result{} #t
|
|
@end lisp
|
|
|
|
From C, there are lower level functions that construct a Scheme symbol
|
|
from a C string in the current locale encoding.
|
|
|
|
When you want to do more from C, you should convert between symbols
|
|
and strings using @code{scm_symbol_to_string} and
|
|
@code{scm_string_to_symbol} and work with the strings.
|
|
|
|
@deftypefn {C Function} SCM scm_from_latin1_symbol (const char *name)
|
|
@deftypefnx {C Function} SCM scm_from_utf8_symbol (const char *name)
|
|
Construct and return a Scheme symbol whose name is specified by the
|
|
null-terminated C string @var{name}. These are appropriate when
|
|
the C string is hard-coded in the source code.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_from_locale_symbol (const char *name)
|
|
@deftypefnx {C Function} SCM scm_from_locale_symboln (const char *name, size_t len)
|
|
Construct and return a Scheme symbol whose name is specified by
|
|
@var{name}. For @code{scm_from_locale_symbol}, @var{name} must be null
|
|
terminated; for @code{scm_from_locale_symboln} the length of @var{name} is
|
|
specified explicitly by @var{len}.
|
|
|
|
Note that these functions should @emph{not} be used when @var{name} is a
|
|
C string constant, because there is no guarantee that the current locale
|
|
will match that of the execution character set, used for string and
|
|
character constants. Most modern C compilers use UTF-8 by default, so
|
|
in such cases we recommend @code{scm_from_utf8_symbol}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_take_locale_symbol (char *str)
|
|
@deftypefnx {C Function} SCM scm_take_locale_symboln (char *str, size_t len)
|
|
Like @code{scm_from_locale_symbol} and @code{scm_from_locale_symboln},
|
|
respectively, but also frees @var{str} with @code{free} eventually.
|
|
Thus, you can use this function when you would free @var{str} anyway
|
|
immediately after creating the Scheme string. In certain cases, Guile
|
|
can then use @var{str} directly as its internal representation.
|
|
@end deftypefn
|
|
|
|
The size of a symbol can also be obtained from C:
|
|
|
|
@deftypefn {C Function} size_t scm_c_symbol_length (SCM sym)
|
|
Return the number of characters in @var{sym}.
|
|
@end deftypefn
|
|
|
|
Finally, some applications, especially those that generate new Scheme
|
|
code dynamically, need to generate symbols for use in the generated
|
|
code. The @code{gensym} primitive meets this need:
|
|
|
|
@deffn {Scheme Procedure} gensym [prefix]
|
|
@deffnx {C Function} scm_gensym (prefix)
|
|
Create a new symbol with a name constructed from a prefix and a counter
|
|
value. The string @var{prefix} can be specified as an optional
|
|
argument. Default prefix is @samp{@w{ g}}. The counter is increased by 1
|
|
at each call. There is no provision for resetting the counter.
|
|
@end deffn
|
|
|
|
The symbols generated by @code{gensym} are @emph{likely} to be unique,
|
|
since their names begin with a space and it is only otherwise possible
|
|
to generate such symbols if a programmer goes out of their way to do
|
|
so. Uniqueness can be guaranteed by instead using uninterned symbols
|
|
(@pxref{Symbol Uninterned}), though they can't be usefully written out
|
|
and read back in.
|
|
|
|
|
|
@node Symbol Read Syntax
|
|
@subsubsection Extended Read Syntax for Symbols
|
|
|
|
@cindex r7rs-symbols
|
|
|
|
The read syntax for a symbol is a sequence of letters, digits, and
|
|
@dfn{extended alphabetic characters}, beginning with a character that
|
|
cannot begin a number. In addition, the special cases of @code{+},
|
|
@code{-}, and @code{...} are read as symbols even though numbers can
|
|
begin with @code{+}, @code{-} or @code{.}.
|
|
|
|
Extended alphabetic characters may be used within identifiers as if
|
|
they were letters. The set of extended alphabetic characters is:
|
|
|
|
@example
|
|
! $ % & * + - . / : < = > ? @@ ^ _ ~
|
|
@end example
|
|
|
|
In addition to the standard read syntax defined above (which is taken
|
|
from R5RS (@pxref{Formal syntax,,,r5rs,The Revised^5 Report on
|
|
Scheme})), Guile provides an extended symbol read syntax that allows the
|
|
inclusion of unusual characters such as space characters, newlines and
|
|
parentheses. If (for whatever reason) you need to write a symbol
|
|
containing characters not mentioned above, you can do so as follows.
|
|
|
|
@itemize @bullet
|
|
@item
|
|
Begin the symbol with the characters @code{#@{},
|
|
|
|
@item
|
|
write the characters of the symbol and
|
|
|
|
@item
|
|
finish the symbol with the characters @code{@}#}.
|
|
@end itemize
|
|
|
|
Here are a few examples of this form of read syntax. The first symbol
|
|
needs to use extended syntax because it contains a space character, the
|
|
second because it contains a line break, and the last because it looks
|
|
like a number.
|
|
|
|
@lisp
|
|
#@{foo bar@}#
|
|
|
|
#@{what
|
|
ever@}#
|
|
|
|
#@{4242@}#
|
|
@end lisp
|
|
|
|
Although Guile provides this extended read syntax for symbols,
|
|
widespread usage of it is discouraged because it is not portable and not
|
|
very readable.
|
|
|
|
Alternatively, if you enable the @code{r7rs-symbols} read option (see
|
|
@pxref{Scheme Read}), you can write arbitrary symbols using the same
|
|
notation used for strings, except delimited by vertical bars instead of
|
|
double quotes.
|
|
|
|
@example
|
|
|foo bar|
|
|
|\x3BB; is a greek lambda|
|
|
|\| is a vertical bar|
|
|
@end example
|
|
|
|
Note that there's also an @code{r7rs-symbols} print option
|
|
(@pxref{Scheme Write}). To enable the use of this notation, evaluate
|
|
one or both of the following expressions:
|
|
|
|
@example
|
|
(read-enable 'r7rs-symbols)
|
|
(print-enable 'r7rs-symbols)
|
|
@end example
|
|
|
|
|
|
@node Symbol Uninterned
|
|
@subsubsection Uninterned Symbols
|
|
|
|
What makes symbols useful is that they are automatically kept unique.
|
|
There are no two symbols that are distinct objects but have the same
|
|
name. But of course, there is no rule without exception. In addition
|
|
to the normal symbols that have been discussed up to now, you can also
|
|
create special @dfn{uninterned} symbols that behave slightly
|
|
differently.
|
|
|
|
To understand what is different about them and why they might be useful,
|
|
we look at how normal symbols are actually kept unique.
|
|
|
|
Whenever Guile wants to find the symbol with a specific name, for
|
|
example during @code{read} or when executing @code{string->symbol}, it
|
|
first looks into a table of all existing symbols to find out whether a
|
|
symbol with the given name already exists. When this is the case, Guile
|
|
just returns that symbol. When not, a new symbol with the name is
|
|
created and entered into the table so that it can be found later.
|
|
|
|
Sometimes you might want to create a symbol that is guaranteed `fresh',
|
|
i.e.@: a symbol that did not exist previously. You might also want to
|
|
somehow guarantee that no one else will ever unintentionally stumble
|
|
across your symbol in the future. These properties of a symbol are
|
|
often needed when generating code during macro expansion. When
|
|
introducing new temporary variables, you want to guarantee that they
|
|
don't conflict with variables in other people's code.
|
|
|
|
The simplest way to arrange for this is to create a new symbol but
|
|
not enter it into the global table of all symbols. That way, no one
|
|
will ever get access to your symbol by chance. Symbols that are not in
|
|
the table are called @dfn{uninterned}. Of course, symbols that
|
|
@emph{are} in the table are called @dfn{interned}.
|
|
|
|
You create new uninterned symbols with the function @code{make-symbol}.
|
|
You can test whether a symbol is interned or not with
|
|
@code{symbol-interned?}.
|
|
|
|
Uninterned symbols break the rule that the name of a symbol uniquely
|
|
identifies the symbol object. Because of this, they can not be written
|
|
out and read back in like interned symbols. Currently, Guile has no
|
|
support for reading uninterned symbols. Note that the function
|
|
@code{gensym} does not return uninterned symbols for this reason.
|
|
|
|
@deffn {Scheme Procedure} make-symbol name
|
|
@deffnx {C Function} scm_make_symbol (name)
|
|
Return a new uninterned symbol with the name @var{name}. The returned
|
|
symbol is guaranteed to be unique and future calls to
|
|
@code{string->symbol} will not return it.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} symbol-interned? symbol
|
|
@deffnx {C Function} scm_symbol_interned_p (symbol)
|
|
Return @code{#t} if @var{symbol} is interned, otherwise return
|
|
@code{#f}.
|
|
@end deffn
|
|
|
|
For example:
|
|
|
|
@lisp
|
|
(define foo-1 (string->symbol "foo"))
|
|
(define foo-2 (string->symbol "foo"))
|
|
(define foo-3 (make-symbol "foo"))
|
|
(define foo-4 (make-symbol "foo"))
|
|
|
|
(eq? foo-1 foo-2)
|
|
@result{} #t
|
|
; Two interned symbols with the same name are the same object,
|
|
|
|
(eq? foo-1 foo-3)
|
|
@result{} #f
|
|
; but a call to make-symbol with the same name returns a
|
|
; distinct object.
|
|
|
|
(eq? foo-3 foo-4)
|
|
@result{} #f
|
|
; A call to make-symbol always returns a new object, even for
|
|
; the same name.
|
|
|
|
foo-3
|
|
@result{} #<uninterned-symbol foo 8085290>
|
|
; Uninterned symbols print differently from interned symbols,
|
|
|
|
(symbol? foo-3)
|
|
@result{} #t
|
|
; but they are still symbols,
|
|
|
|
(symbol-interned? foo-3)
|
|
@result{} #f
|
|
; just not interned.
|
|
@end lisp
|
|
|
|
|
|
@node Keywords
|
|
@subsection Keywords
|
|
@tpindex Keywords
|
|
|
|
Keywords are self-evaluating objects with a convenient read syntax that
|
|
makes them easy to type.
|
|
|
|
Guile's keyword support conforms to R5RS, and adds a (switchable) read
|
|
syntax extension to permit keywords to begin with @code{:} as well as
|
|
@code{#:}, or to end with @code{:}.
|
|
|
|
@menu
|
|
* Why Use Keywords?:: Motivation for keyword usage.
|
|
* Coding With Keywords:: How to use keywords.
|
|
* Keyword Read Syntax:: Read syntax for keywords.
|
|
* Keyword Procedures:: Procedures for dealing with keywords.
|
|
@end menu
|
|
|
|
@node Why Use Keywords?
|
|
@subsubsection Why Use Keywords?
|
|
|
|
Keywords are useful in contexts where a program or procedure wants to be
|
|
able to accept a large number of optional arguments without making its
|
|
interface unmanageable.
|
|
|
|
To illustrate this, consider a hypothetical @code{make-window}
|
|
procedure, which creates a new window on the screen for drawing into
|
|
using some graphical toolkit. There are many parameters that the caller
|
|
might like to specify, but which could also be sensibly defaulted, for
|
|
example:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
color depth -- Default: the color depth for the screen
|
|
|
|
@item
|
|
background color -- Default: white
|
|
|
|
@item
|
|
width -- Default: 600
|
|
|
|
@item
|
|
height -- Default: 400
|
|
@end itemize
|
|
|
|
If @code{make-window} did not use keywords, the caller would have to
|
|
pass in a value for each possible argument, remembering the correct
|
|
argument order and using a special value to indicate the default value
|
|
for that argument:
|
|
|
|
@lisp
|
|
(make-window 'default ;; Color depth
|
|
'default ;; Background color
|
|
800 ;; Width
|
|
100 ;; Height
|
|
@dots{}) ;; More make-window arguments
|
|
@end lisp
|
|
|
|
With keywords, on the other hand, defaulted arguments are omitted, and
|
|
non-default arguments are clearly tagged by the appropriate keyword. As
|
|
a result, the invocation becomes much clearer:
|
|
|
|
@lisp
|
|
(make-window #:width 800 #:height 100)
|
|
@end lisp
|
|
|
|
On the other hand, for a simpler procedure with few arguments, the use
|
|
of keywords would be a hindrance rather than a help. The primitive
|
|
procedure @code{cons}, for example, would not be improved if it had to
|
|
be invoked as
|
|
|
|
@lisp
|
|
(cons #:car x #:cdr y)
|
|
@end lisp
|
|
|
|
So the decision whether to use keywords or not is purely pragmatic: use
|
|
them if they will clarify the procedure invocation at point of call.
|
|
|
|
@node Coding With Keywords
|
|
@subsubsection Coding With Keywords
|
|
|
|
If a procedure wants to support keywords, it should take a rest argument
|
|
and then use whatever means is convenient to extract keywords and their
|
|
corresponding arguments from the contents of that rest argument.
|
|
|
|
The following example illustrates the principle: the code for
|
|
@code{make-window} uses a helper procedure called
|
|
@code{get-keyword-value} to extract individual keyword arguments from
|
|
the rest argument.
|
|
|
|
@lisp
|
|
(define (get-keyword-value args keyword default)
|
|
(let ((kv (memq keyword args)))
|
|
(if (and kv (>= (length kv) 2))
|
|
(cadr kv)
|
|
default)))
|
|
|
|
(define (make-window . args)
|
|
(let ((depth (get-keyword-value args #:depth screen-depth))
|
|
(bg (get-keyword-value args #:bg "white"))
|
|
(width (get-keyword-value args #:width 800))
|
|
(height (get-keyword-value args #:height 100))
|
|
@dots{})
|
|
@dots{}))
|
|
@end lisp
|
|
|
|
But you don't need to write @code{get-keyword-value}. The @code{(ice-9
|
|
optargs)} module provides a set of powerful macros that you can use to
|
|
implement keyword-supporting procedures like this:
|
|
|
|
@lisp
|
|
(use-modules (ice-9 optargs))
|
|
|
|
(define (make-window . args)
|
|
(let-keywords args #f ((depth screen-depth)
|
|
(bg "white")
|
|
(width 800)
|
|
(height 100))
|
|
...))
|
|
@end lisp
|
|
|
|
@noindent
|
|
Or, even more economically, like this:
|
|
|
|
@lisp
|
|
(use-modules (ice-9 optargs))
|
|
|
|
(define* (make-window #:key (depth screen-depth)
|
|
(bg "white")
|
|
(width 800)
|
|
(height 100))
|
|
...)
|
|
@end lisp
|
|
|
|
For further details on @code{let-keywords}, @code{define*} and other
|
|
facilities provided by the @code{(ice-9 optargs)} module, see
|
|
@ref{Optional Arguments}.
|
|
|
|
To handle keyword arguments from procedures implemented in C,
|
|
use @code{scm_c_bind_keyword_arguments} (@pxref{Keyword Procedures}).
|
|
|
|
@node Keyword Read Syntax
|
|
@subsubsection Keyword Read Syntax
|
|
|
|
Guile, by default, only recognizes a keyword syntax that is compatible
|
|
with R5RS. A token of the form @code{#:NAME}, where @code{NAME} has the
|
|
same syntax as a Scheme symbol (@pxref{Symbol Read Syntax}), is the
|
|
external representation of the keyword named @code{NAME}. Keyword
|
|
objects print using this syntax as well, so values containing keyword
|
|
objects can be read back into Guile. When used in an expression,
|
|
keywords are self-quoting objects.
|
|
|
|
If the @code{keywords} read option is set to @code{'prefix}, Guile also
|
|
recognizes the alternative read syntax @code{:NAME}. Otherwise, tokens
|
|
of the form @code{:NAME} are read as symbols, as required by R5RS.
|
|
|
|
@cindex SRFI-88 keyword syntax
|
|
|
|
If the @code{keywords} read option is set to @code{'postfix}, Guile
|
|
recognizes the SRFI-88 read syntax @code{NAME:} (@pxref{SRFI-88}).
|
|
Otherwise, tokens of this form are read as symbols.
|
|
|
|
To enable and disable the alternative non-R5RS keyword syntax, you use
|
|
the @code{read-set!} procedure documented @ref{Scheme Read}. Note that
|
|
the @code{prefix} and @code{postfix} syntax are mutually exclusive.
|
|
|
|
@lisp
|
|
(read-set! keywords 'prefix)
|
|
|
|
#:type
|
|
@result{}
|
|
#:type
|
|
|
|
:type
|
|
@result{}
|
|
#:type
|
|
|
|
(read-set! keywords 'postfix)
|
|
|
|
type:
|
|
@result{}
|
|
#:type
|
|
|
|
:type
|
|
@result{}
|
|
:type
|
|
|
|
(read-set! keywords #f)
|
|
|
|
#:type
|
|
@result{}
|
|
#:type
|
|
|
|
:type
|
|
@print{}
|
|
ERROR: In expression :type:
|
|
ERROR: Unbound variable: :type
|
|
ABORT: (unbound-variable)
|
|
@end lisp
|
|
|
|
@node Keyword Procedures
|
|
@subsubsection Keyword Procedures
|
|
|
|
@deffn {Scheme Procedure} keyword? obj
|
|
@deffnx {C Function} scm_keyword_p (obj)
|
|
Return @code{#t} if the argument @var{obj} is a keyword, else
|
|
@code{#f}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} keyword->symbol keyword
|
|
@deffnx {C Function} scm_keyword_to_symbol (keyword)
|
|
Return the symbol with the same name as @var{keyword}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} symbol->keyword symbol
|
|
@deffnx {C Function} scm_symbol_to_keyword (symbol)
|
|
Return the keyword with the same name as @var{symbol}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_keyword (SCM obj)
|
|
Equivalent to @code{scm_is_true (scm_keyword_p (@var{obj}))}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_from_locale_keyword (const char *name)
|
|
@deftypefnx {C Function} SCM scm_from_locale_keywordn (const char *name, size_t len)
|
|
Equivalent to @code{scm_symbol_to_keyword (scm_from_locale_symbol
|
|
(@var{name}))} and @code{scm_symbol_to_keyword (scm_from_locale_symboln
|
|
(@var{name}, @var{len}))}, respectively.
|
|
|
|
Note that these functions should @emph{not} be used when @var{name} is a
|
|
C string constant, because there is no guarantee that the current locale
|
|
will match that of the execution character set, used for string and
|
|
character constants. Most modern C compilers use UTF-8 by default, so
|
|
in such cases we recommend @code{scm_from_utf8_keyword}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_from_latin1_keyword (const char *name)
|
|
@deftypefnx {C Function} SCM scm_from_utf8_keyword (const char *name)
|
|
Equivalent to @code{scm_symbol_to_keyword (scm_from_latin1_symbol
|
|
(@var{name}))} and @code{scm_symbol_to_keyword (scm_from_utf8_symbol
|
|
(@var{name}))}, respectively.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} void scm_c_bind_keyword_arguments (const char *subr, @
|
|
SCM rest, scm_t_keyword_arguments_flags flags, @
|
|
SCM keyword1, SCM *argp1, @
|
|
@dots{}, @
|
|
SCM keywordN, SCM *argpN, @
|
|
@nicode{SCM_UNDEFINED})
|
|
|
|
Extract the specified keyword arguments from @var{rest}, which is not
|
|
modified. If the keyword argument @var{keyword1} is present in
|
|
@var{rest} with an associated value, that value is stored in the
|
|
variable pointed to by @var{argp1}, otherwise the variable is left
|
|
unchanged. Similarly for the other keywords and argument pointers up to
|
|
@var{keywordN} and @var{argpN}. The argument list to
|
|
@code{scm_c_bind_keyword_arguments} must be terminated by
|
|
@code{SCM_UNDEFINED}.
|
|
|
|
Note that since the variables pointed to by @var{argp1} through
|
|
@var{argpN} are left unchanged if the associated keyword argument is not
|
|
present, they should be initialized to their default values before
|
|
calling @code{scm_c_bind_keyword_arguments}. Alternatively, you can
|
|
initialize them to @code{SCM_UNDEFINED} before the call, and then use
|
|
@code{SCM_UNBNDP} after the call to see which ones were provided.
|
|
|
|
If an unrecognized keyword argument is present in @var{rest} and
|
|
@var{flags} does not contain @code{SCM_ALLOW_OTHER_KEYS}, or if
|
|
non-keyword arguments are present and @var{flags} does not contain
|
|
@code{SCM_ALLOW_NON_KEYWORD_ARGUMENTS}, an exception is raised.
|
|
@var{subr} should be the name of the procedure receiving the keyword
|
|
arguments, for purposes of error reporting.
|
|
|
|
For example:
|
|
|
|
@example
|
|
SCM k_delimiter;
|
|
SCM k_grammar;
|
|
SCM sym_infix;
|
|
|
|
SCM my_string_join (SCM strings, SCM rest)
|
|
@{
|
|
SCM delimiter = SCM_UNDEFINED;
|
|
SCM grammar = sym_infix;
|
|
|
|
scm_c_bind_keyword_arguments ("my-string-join", rest, 0,
|
|
k_delimiter, &delimiter,
|
|
k_grammar, &grammar,
|
|
SCM_UNDEFINED);
|
|
|
|
if (SCM_UNBNDP (delimiter))
|
|
delimiter = scm_from_utf8_string (" ");
|
|
|
|
return scm_string_join (strings, delimiter, grammar);
|
|
@}
|
|
|
|
void my_init ()
|
|
@{
|
|
k_delimiter = scm_from_utf8_keyword ("delimiter");
|
|
k_grammar = scm_from_utf8_keyword ("grammar");
|
|
sym_infix = scm_from_utf8_symbol ("infix");
|
|
scm_c_define_gsubr ("my-string-join", 1, 0, 1, my_string_join);
|
|
@}
|
|
@end example
|
|
@end deftypefn
|
|
|
|
|
|
@node Pairs
|
|
@subsection Pairs
|
|
@tpindex Pairs
|
|
|
|
Pairs are used to combine two Scheme objects into one compound object.
|
|
Hence the name: A pair stores a pair of objects.
|
|
|
|
The data type @dfn{pair} is extremely important in Scheme, just like in
|
|
any other Lisp dialect. The reason is that pairs are not only used to
|
|
make two values available as one object, but that pairs are used for
|
|
constructing lists of values. Because lists are so important in Scheme,
|
|
they are described in a section of their own (@pxref{Lists}).
|
|
|
|
Pairs can literally get entered in source code or at the REPL, in the
|
|
so-called @dfn{dotted list} syntax. This syntax consists of an opening
|
|
parentheses, the first element of the pair, a dot, the second element
|
|
and a closing parentheses. The following example shows how a pair
|
|
consisting of the two numbers 1 and 2, and a pair containing the symbols
|
|
@code{foo} and @code{bar} can be entered. It is very important to write
|
|
the whitespace before and after the dot, because otherwise the Scheme
|
|
parser would not be able to figure out where to split the tokens.
|
|
|
|
@lisp
|
|
(1 . 2)
|
|
(foo . bar)
|
|
@end lisp
|
|
|
|
But beware, if you want to try out these examples, you have to
|
|
@dfn{quote} the expressions. More information about quotation is
|
|
available in the section @ref{Expression Syntax}. The correct way
|
|
to try these examples is as follows.
|
|
|
|
@lisp
|
|
'(1 . 2)
|
|
@result{}
|
|
(1 . 2)
|
|
'(foo . bar)
|
|
@result{}
|
|
(foo . bar)
|
|
@end lisp
|
|
|
|
A new pair is made by calling the procedure @code{cons} with two
|
|
arguments. Then the argument values are stored into a newly allocated
|
|
pair, and the pair is returned. The name @code{cons} stands for
|
|
"construct". Use the procedure @code{pair?} to test whether a
|
|
given Scheme object is a pair or not.
|
|
|
|
@rnindex cons
|
|
@deffn {Scheme Procedure} cons x y
|
|
@deffnx {C Function} scm_cons (x, y)
|
|
Return a newly allocated pair whose car is @var{x} and whose
|
|
cdr is @var{y}. The pair is guaranteed to be different (in the
|
|
sense of @code{eq?}) from every previously existing object.
|
|
@end deffn
|
|
|
|
@rnindex pair?
|
|
@deffn {Scheme Procedure} pair? x
|
|
@deffnx {C Function} scm_pair_p (x)
|
|
Return @code{#t} if @var{x} is a pair; otherwise return
|
|
@code{#f}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_pair (SCM x)
|
|
Return 1 when @var{x} is a pair; otherwise return 0.
|
|
@end deftypefn
|
|
|
|
The two parts of a pair are traditionally called @dfn{car} and
|
|
@dfn{cdr}. They can be retrieved with procedures of the same name
|
|
(@code{car} and @code{cdr}), and can be modified with the procedures
|
|
@code{set-car!} and @code{set-cdr!}.
|
|
|
|
Since a very common operation in Scheme programs is to access the car of
|
|
a car of a pair, or the car of the cdr of a pair, etc., the procedures
|
|
called @code{caar}, @code{cadr} and so on are also predefined. However,
|
|
using these procedures is often detrimental to readability, and
|
|
error-prone. Thus, accessing the contents of a list is usually better
|
|
achieved using pattern matching techniques (@pxref{Pattern Matching}).
|
|
|
|
@rnindex car
|
|
@rnindex cdr
|
|
@deffn {Scheme Procedure} car pair
|
|
@deffnx {Scheme Procedure} cdr pair
|
|
@deffnx {C Function} scm_car (pair)
|
|
@deffnx {C Function} scm_cdr (pair)
|
|
Return the car or the cdr of @var{pair}, respectively.
|
|
@end deffn
|
|
|
|
@deftypefn {C Macro} SCM SCM_CAR (SCM pair)
|
|
@deftypefnx {C Macro} SCM SCM_CDR (SCM pair)
|
|
These two macros are the fastest way to access the car or cdr of a
|
|
pair; they can be thought of as compiling into a single memory
|
|
reference.
|
|
|
|
These macros do no checking at all. The argument @var{pair} must be a
|
|
valid pair.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} cddr pair
|
|
@deffnx {Scheme Procedure} cdar pair
|
|
@deffnx {Scheme Procedure} cadr pair
|
|
@deffnx {Scheme Procedure} caar pair
|
|
@deffnx {Scheme Procedure} cdddr pair
|
|
@deffnx {Scheme Procedure} cddar pair
|
|
@deffnx {Scheme Procedure} cdadr pair
|
|
@deffnx {Scheme Procedure} cdaar pair
|
|
@deffnx {Scheme Procedure} caddr pair
|
|
@deffnx {Scheme Procedure} cadar pair
|
|
@deffnx {Scheme Procedure} caadr pair
|
|
@deffnx {Scheme Procedure} caaar pair
|
|
@deffnx {Scheme Procedure} cddddr pair
|
|
@deffnx {Scheme Procedure} cdddar pair
|
|
@deffnx {Scheme Procedure} cddadr pair
|
|
@deffnx {Scheme Procedure} cddaar pair
|
|
@deffnx {Scheme Procedure} cdaddr pair
|
|
@deffnx {Scheme Procedure} cdadar pair
|
|
@deffnx {Scheme Procedure} cdaadr pair
|
|
@deffnx {Scheme Procedure} cdaaar pair
|
|
@deffnx {Scheme Procedure} cadddr pair
|
|
@deffnx {Scheme Procedure} caddar pair
|
|
@deffnx {Scheme Procedure} cadadr pair
|
|
@deffnx {Scheme Procedure} cadaar pair
|
|
@deffnx {Scheme Procedure} caaddr pair
|
|
@deffnx {Scheme Procedure} caadar pair
|
|
@deffnx {Scheme Procedure} caaadr pair
|
|
@deffnx {Scheme Procedure} caaaar pair
|
|
@deffnx {C Function} scm_cddr (pair)
|
|
@deffnx {C Function} scm_cdar (pair)
|
|
@deffnx {C Function} scm_cadr (pair)
|
|
@deffnx {C Function} scm_caar (pair)
|
|
@deffnx {C Function} scm_cdddr (pair)
|
|
@deffnx {C Function} scm_cddar (pair)
|
|
@deffnx {C Function} scm_cdadr (pair)
|
|
@deffnx {C Function} scm_cdaar (pair)
|
|
@deffnx {C Function} scm_caddr (pair)
|
|
@deffnx {C Function} scm_cadar (pair)
|
|
@deffnx {C Function} scm_caadr (pair)
|
|
@deffnx {C Function} scm_caaar (pair)
|
|
@deffnx {C Function} scm_cddddr (pair)
|
|
@deffnx {C Function} scm_cdddar (pair)
|
|
@deffnx {C Function} scm_cddadr (pair)
|
|
@deffnx {C Function} scm_cddaar (pair)
|
|
@deffnx {C Function} scm_cdaddr (pair)
|
|
@deffnx {C Function} scm_cdadar (pair)
|
|
@deffnx {C Function} scm_cdaadr (pair)
|
|
@deffnx {C Function} scm_cdaaar (pair)
|
|
@deffnx {C Function} scm_cadddr (pair)
|
|
@deffnx {C Function} scm_caddar (pair)
|
|
@deffnx {C Function} scm_cadadr (pair)
|
|
@deffnx {C Function} scm_cadaar (pair)
|
|
@deffnx {C Function} scm_caaddr (pair)
|
|
@deffnx {C Function} scm_caadar (pair)
|
|
@deffnx {C Function} scm_caaadr (pair)
|
|
@deffnx {C Function} scm_caaaar (pair)
|
|
These procedures are compositions of @code{car} and @code{cdr}, where
|
|
for example @code{caddr} could be defined by
|
|
|
|
@lisp
|
|
(define caddr (lambda (x) (car (cdr (cdr x)))))
|
|
@end lisp
|
|
|
|
@code{cadr}, @code{caddr} and @code{cadddr} pick out the second, third
|
|
or fourth elements of a list, respectively. SRFI-1 provides the same
|
|
under the names @code{second}, @code{third} and @code{fourth}
|
|
(@pxref{SRFI-1 Selectors}).
|
|
@end deffn
|
|
|
|
@rnindex set-car!
|
|
@deffn {Scheme Procedure} set-car! pair value
|
|
@deffnx {C Function} scm_set_car_x (pair, value)
|
|
Stores @var{value} in the car field of @var{pair}. The value returned
|
|
by @code{set-car!} is unspecified.
|
|
@end deffn
|
|
|
|
@rnindex set-cdr!
|
|
@deffn {Scheme Procedure} set-cdr! pair value
|
|
@deffnx {C Function} scm_set_cdr_x (pair, value)
|
|
Stores @var{value} in the cdr field of @var{pair}. The value returned
|
|
by @code{set-cdr!} is unspecified.
|
|
@end deffn
|
|
|
|
|
|
@node Lists
|
|
@subsection Lists
|
|
@tpindex Lists
|
|
|
|
A very important data type in Scheme---as well as in all other Lisp
|
|
dialects---is the data type @dfn{list}.@footnote{Strictly speaking,
|
|
Scheme does not have a real datatype @dfn{list}. Lists are made up of
|
|
@dfn{chained pairs}, and only exist by definition---a list is a chain
|
|
of pairs which looks like a list.}
|
|
|
|
This is the short definition of what a list is:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
Either the empty list @code{()},
|
|
|
|
@item
|
|
or a pair which has a list in its cdr.
|
|
@end itemize
|
|
|
|
@c FIXME::martin: Describe the pair chaining in more detail.
|
|
|
|
@c FIXME::martin: What is a proper, what an improper list?
|
|
@c What is a circular list?
|
|
|
|
@c FIXME::martin: Maybe steal some graphics from the Elisp reference
|
|
@c manual?
|
|
|
|
@menu
|
|
* List Syntax:: Writing literal lists.
|
|
* List Predicates:: Testing lists.
|
|
* List Constructors:: Creating new lists.
|
|
* List Selection:: Selecting from lists, getting their length.
|
|
* Append/Reverse:: Appending and reversing lists.
|
|
* List Modification:: Modifying existing lists.
|
|
* List Searching:: Searching for list elements
|
|
* List Mapping:: Applying procedures to lists.
|
|
@end menu
|
|
|
|
@node List Syntax
|
|
@subsubsection List Read Syntax
|
|
|
|
The syntax for lists is an opening parentheses, then all the elements of
|
|
the list (separated by whitespace) and finally a closing
|
|
parentheses.@footnote{Note that there is no separation character between
|
|
the list elements, like a comma or a semicolon.}.
|
|
|
|
@lisp
|
|
(1 2 3) ; @r{a list of the numbers 1, 2 and 3}
|
|
("foo" bar 3.1415) ; @r{a string, a symbol and a real number}
|
|
() ; @r{the empty list}
|
|
@end lisp
|
|
|
|
The last example needs a bit more explanation. A list with no elements,
|
|
called the @dfn{empty list}, is special in some ways. It is used for
|
|
terminating lists by storing it into the cdr of the last pair that makes
|
|
up a list. An example will clear that up:
|
|
|
|
@lisp
|
|
(car '(1))
|
|
@result{}
|
|
1
|
|
(cdr '(1))
|
|
@result{}
|
|
()
|
|
@end lisp
|
|
|
|
This example also shows that lists have to be quoted when written
|
|
(@pxref{Expression Syntax}), because they would otherwise be
|
|
mistakingly taken as procedure applications (@pxref{Simple
|
|
Invocation}).
|
|
|
|
|
|
@node List Predicates
|
|
@subsubsection List Predicates
|
|
|
|
Often it is useful to test whether a given Scheme object is a list or
|
|
not. List-processing procedures could use this information to test
|
|
whether their input is valid, or they could do different things
|
|
depending on the datatype of their arguments.
|
|
|
|
@rnindex list?
|
|
@deffn {Scheme Procedure} list? x
|
|
@deffnx {C Function} scm_list_p (x)
|
|
Return @code{#t} if @var{x} is a proper list, else @code{#f}.
|
|
@end deffn
|
|
|
|
The predicate @code{null?} is often used in list-processing code to
|
|
tell whether a given list has run out of elements. That is, a loop
|
|
somehow deals with the elements of a list until the list satisfies
|
|
@code{null?}. Then, the algorithm terminates.
|
|
|
|
@rnindex null?
|
|
@deffn {Scheme Procedure} null? x
|
|
@deffnx {C Function} scm_null_p (x)
|
|
Return @code{#t} if @var{x} is the empty list, else @code{#f}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_null (SCM x)
|
|
Return 1 when @var{x} is the empty list; otherwise return 0.
|
|
@end deftypefn
|
|
|
|
|
|
@node List Constructors
|
|
@subsubsection List Constructors
|
|
|
|
This section describes the procedures for constructing new lists.
|
|
@code{list} simply returns a list where the elements are the arguments,
|
|
@code{cons*} is similar, but the last argument is stored in the cdr of
|
|
the last pair of the list.
|
|
|
|
@c C Function scm_list(rest) used to be documented here, but it's a
|
|
@c no-op since it does nothing but return the list the caller must
|
|
@c have already created.
|
|
@c
|
|
@deffn {Scheme Procedure} list elem @dots{}
|
|
@deffnx {C Function} scm_list_1 (elem1)
|
|
@deffnx {C Function} scm_list_2 (elem1, elem2)
|
|
@deffnx {C Function} scm_list_3 (elem1, elem2, elem3)
|
|
@deffnx {C Function} scm_list_4 (elem1, elem2, elem3, elem4)
|
|
@deffnx {C Function} scm_list_5 (elem1, elem2, elem3, elem4, elem5)
|
|
@deffnx {C Function} scm_list_n (elem1, @dots{}, elemN, @nicode{SCM_UNDEFINED})
|
|
@rnindex list
|
|
Return a new list containing elements @var{elem} @enddots{}.
|
|
|
|
@code{scm_list_n} takes a variable number of arguments, terminated by
|
|
the special @code{SCM_UNDEFINED}. That final @code{SCM_UNDEFINED} is
|
|
not included in the list. None of @var{elem} @dots{} can
|
|
themselves be @code{SCM_UNDEFINED}, or @code{scm_list_n} will
|
|
terminate at that point.
|
|
@end deffn
|
|
|
|
@c C Function scm_cons_star(arg1,rest) used to be documented here,
|
|
@c but it's not really a useful interface, since it expects the
|
|
@c caller to have already consed up all but the first argument
|
|
@c already.
|
|
@c
|
|
@deffn {Scheme Procedure} cons* arg1 arg2 @dots{}
|
|
Like @code{list}, but the last arg provides the tail of the
|
|
constructed list, returning @code{(cons @var{arg1} (cons
|
|
@var{arg2} (cons @dots{} @var{argn})))}. Requires at least one
|
|
argument. If given one argument, that argument is returned as
|
|
result. This function is called @code{list*} in some other
|
|
Schemes and in Common LISP.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list-copy lst
|
|
@deffnx {C Function} scm_list_copy (lst)
|
|
Return a (newly-created) copy of @var{lst}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} make-list n [init]
|
|
Create a list containing of @var{n} elements, where each element is
|
|
initialized to @var{init}. @var{init} defaults to the empty list
|
|
@code{()} if not given.
|
|
@end deffn
|
|
|
|
Note that @code{list-copy} only makes a copy of the pairs which make up
|
|
the spine of the lists. The list elements are not copied, which means
|
|
that modifying the elements of the new list also modifies the elements
|
|
of the old list. On the other hand, applying procedures like
|
|
@code{set-cdr!} or @code{delv!} to the new list will not alter the old
|
|
list. If you also need to copy the list elements (making a deep copy),
|
|
use the procedure @code{copy-tree} from @code{(ice-9 copy-tree)}
|
|
(@pxref{Copying}).
|
|
|
|
@node List Selection
|
|
@subsubsection List Selection
|
|
|
|
These procedures are used to get some information about a list, or to
|
|
retrieve one or more elements of a list.
|
|
|
|
@rnindex length
|
|
@deffn {Scheme Procedure} length lst
|
|
@deffnx {C Function} scm_length (lst)
|
|
Return the number of elements in list @var{lst}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} last-pair lst
|
|
@deffnx {C Function} scm_last_pair (lst)
|
|
Return the last pair in @var{lst}, signalling an error if
|
|
@var{lst} is circular.
|
|
@end deffn
|
|
|
|
@rnindex list-ref
|
|
@deffn {Scheme Procedure} list-ref list k
|
|
@deffnx {C Function} scm_list_ref (list, k)
|
|
Return the @var{k}th element from @var{list}.
|
|
@end deffn
|
|
|
|
@rnindex list-tail
|
|
@deffn {Scheme Procedure} list-tail lst k
|
|
@deffnx {Scheme Procedure} list-cdr-ref lst k
|
|
@deffnx {C Function} scm_list_tail (lst, k)
|
|
Return the "tail" of @var{lst} beginning with its @var{k}th element.
|
|
The first element of the list is considered to be element 0.
|
|
|
|
@code{list-tail} and @code{list-cdr-ref} are identical. It may help to
|
|
think of @code{list-cdr-ref} as accessing the @var{k}th cdr of the list,
|
|
or returning the results of cdring @var{k} times down @var{lst}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list-head lst k
|
|
@deffnx {C Function} scm_list_head (lst, k)
|
|
Copy the first @var{k} elements from @var{lst} into a new list, and
|
|
return it.
|
|
@end deffn
|
|
|
|
@node Append/Reverse
|
|
@subsubsection Append and Reverse
|
|
|
|
@code{append} and @code{append!} are used to concatenate two or more
|
|
lists in order to form a new list. @code{reverse} and @code{reverse!}
|
|
return lists with the same elements as their arguments, but in reverse
|
|
order. The procedure variants with an @code{!} directly modify the
|
|
pairs which form the list, whereas the other procedures create new
|
|
pairs. This is why you should be careful when using the side-effecting
|
|
variants.
|
|
|
|
@rnindex append
|
|
@deffn {Scheme Procedure} append lst @dots{} obj
|
|
@deffnx {Scheme Procedure} append
|
|
@deffnx {Scheme Procedure} append! lst @dots{} obj
|
|
@deffnx {Scheme Procedure} append!
|
|
@deffnx {C Function} scm_append (lstlst)
|
|
@deffnx {C Function} scm_append_x (lstlst)
|
|
Return a list comprising all the elements of lists @var{lst} @dots{}
|
|
@var{obj}. If called with no arguments, return the empty list.
|
|
|
|
@lisp
|
|
(append '(x) '(y)) @result{} (x y)
|
|
(append '(a) '(b c d)) @result{} (a b c d)
|
|
(append '(a (b)) '((c))) @result{} (a (b) (c))
|
|
@end lisp
|
|
|
|
The last argument @var{obj} may actually be any object; an improper
|
|
list results if the last argument is not a proper list.
|
|
|
|
@lisp
|
|
(append '(a b) '(c . d)) @result{} (a b c . d)
|
|
(append '() 'a) @result{} a
|
|
@end lisp
|
|
|
|
@code{append} doesn't modify the given lists, but the return may share
|
|
structure with the final @var{obj}. @code{append!} is permitted, but
|
|
not required, to modify the given lists to form its return.
|
|
|
|
For @code{scm_append} and @code{scm_append_x}, @var{lstlst} is a list
|
|
of the list operands @var{lst} @dots{} @var{obj}. That @var{lstlst}
|
|
itself is not modified or used in the return.
|
|
@end deffn
|
|
|
|
@rnindex reverse
|
|
@deffn {Scheme Procedure} reverse lst
|
|
@deffnx {Scheme Procedure} reverse! lst [newtail]
|
|
@deffnx {C Function} scm_reverse (lst)
|
|
@deffnx {C Function} scm_reverse_x (lst, newtail)
|
|
Return a list comprising the elements of @var{lst}, in reverse order.
|
|
|
|
@code{reverse} constructs a new list. @code{reverse!} is permitted, but
|
|
not required, to modify @var{lst} in constructing its return.
|
|
|
|
For @code{reverse!}, the optional @var{newtail} is appended to the
|
|
result. @var{newtail} isn't reversed, it simply becomes the list
|
|
tail. For @code{scm_reverse_x}, the @var{newtail} parameter is
|
|
mandatory, but can be @code{SCM_EOL} if no further tail is required.
|
|
@end deffn
|
|
|
|
@node List Modification
|
|
@subsubsection List Modification
|
|
|
|
The following procedures modify an existing list, either by changing
|
|
elements of the list, or by changing the list structure itself.
|
|
|
|
@deffn {Scheme Procedure} list-set! list k val
|
|
@deffnx {C Function} scm_list_set_x (list, k, val)
|
|
Set the @var{k}th element of @var{list} to @var{val}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list-cdr-set! list k val
|
|
@deffnx {C Function} scm_list_cdr_set_x (list, k, val)
|
|
Set the @var{k}th cdr of @var{list} to @var{val}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} delq item lst
|
|
@deffnx {C Function} scm_delq (item, lst)
|
|
Return a newly-created copy of @var{lst} with elements
|
|
@code{eq?} to @var{item} removed. This procedure mirrors
|
|
@code{memq}: @code{delq} compares elements of @var{lst} against
|
|
@var{item} with @code{eq?}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} delv item lst
|
|
@deffnx {C Function} scm_delv (item, lst)
|
|
Return a newly-created copy of @var{lst} with elements
|
|
@code{eqv?} to @var{item} removed. This procedure mirrors
|
|
@code{memv}: @code{delv} compares elements of @var{lst} against
|
|
@var{item} with @code{eqv?}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} delete item lst
|
|
@deffnx {C Function} scm_delete (item, lst)
|
|
Return a newly-created copy of @var{lst} with elements
|
|
@code{equal?} to @var{item} removed. This procedure mirrors
|
|
@code{member}: @code{delete} compares elements of @var{lst}
|
|
against @var{item} with @code{equal?}.
|
|
|
|
See also SRFI-1 which has an extended @code{delete} (@ref{SRFI-1
|
|
Deleting}), and also an @code{lset-difference} which can delete
|
|
multiple @var{item}s in one call (@ref{SRFI-1 Set Operations}).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} delq! item lst
|
|
@deffnx {Scheme Procedure} delv! item lst
|
|
@deffnx {Scheme Procedure} delete! item lst
|
|
@deffnx {C Function} scm_delq_x (item, lst)
|
|
@deffnx {C Function} scm_delv_x (item, lst)
|
|
@deffnx {C Function} scm_delete_x (item, lst)
|
|
These procedures are destructive versions of @code{delq}, @code{delv}
|
|
and @code{delete}: they modify the pointers in the existing @var{lst}
|
|
rather than creating a new list. Caveat evaluator: Like other
|
|
destructive list functions, these functions cannot modify the binding of
|
|
@var{lst}, and so cannot be used to delete the first element of
|
|
@var{lst} destructively.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} delq1! item lst
|
|
@deffnx {C Function} scm_delq1_x (item, lst)
|
|
Like @code{delq!}, but only deletes the first occurrence of
|
|
@var{item} from @var{lst}. Tests for equality using
|
|
@code{eq?}. See also @code{delv1!} and @code{delete1!}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} delv1! item lst
|
|
@deffnx {C Function} scm_delv1_x (item, lst)
|
|
Like @code{delv!}, but only deletes the first occurrence of
|
|
@var{item} from @var{lst}. Tests for equality using
|
|
@code{eqv?}. See also @code{delq1!} and @code{delete1!}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} delete1! item lst
|
|
@deffnx {C Function} scm_delete1_x (item, lst)
|
|
Like @code{delete!}, but only deletes the first occurrence of
|
|
@var{item} from @var{lst}. Tests for equality using
|
|
@code{equal?}. See also @code{delq1!} and @code{delv1!}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} filter pred lst
|
|
@deffnx {Scheme Procedure} filter! pred lst
|
|
Return a list containing all elements from @var{lst} which 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{filter} does not change @var{lst}, but the result may share a
|
|
tail with it. @code{filter!} may modify @var{lst} to construct its
|
|
return.
|
|
@end deffn
|
|
|
|
@node List Searching
|
|
@subsubsection List Searching
|
|
|
|
The following procedures search lists for particular elements. They use
|
|
different comparison predicates for comparing list elements with the
|
|
object to be searched. When they fail, they return @code{#f}, otherwise
|
|
they return the sublist whose car is equal to the search object, where
|
|
equality depends on the equality predicate used.
|
|
|
|
@rnindex memq
|
|
@deffn {Scheme Procedure} memq x lst
|
|
@deffnx {C Function} scm_memq (x, lst)
|
|
Return the first sublist of @var{lst} whose car is @code{eq?}
|
|
to @var{x} where the sublists of @var{lst} are the non-empty
|
|
lists returned by @code{(list-tail @var{lst} @var{k})} for
|
|
@var{k} less than the length of @var{lst}. If @var{x} does not
|
|
occur in @var{lst}, then @code{#f} (not the empty list) is
|
|
returned.
|
|
@end deffn
|
|
|
|
@rnindex memv
|
|
@deffn {Scheme Procedure} memv x lst
|
|
@deffnx {C Function} scm_memv (x, lst)
|
|
Return the first sublist of @var{lst} whose car is @code{eqv?}
|
|
to @var{x} where the sublists of @var{lst} are the non-empty
|
|
lists returned by @code{(list-tail @var{lst} @var{k})} for
|
|
@var{k} less than the length of @var{lst}. If @var{x} does not
|
|
occur in @var{lst}, then @code{#f} (not the empty list) is
|
|
returned.
|
|
@end deffn
|
|
|
|
@rnindex member
|
|
@deffn {Scheme Procedure} member x lst
|
|
@deffnx {C Function} scm_member (x, lst)
|
|
Return the first sublist of @var{lst} whose car is
|
|
@code{equal?} to @var{x} where the sublists of @var{lst} are
|
|
the non-empty lists returned by @code{(list-tail @var{lst}
|
|
@var{k})} for @var{k} less than the length of @var{lst}. If
|
|
@var{x} does not occur in @var{lst}, then @code{#f} (not the
|
|
empty list) is returned.
|
|
|
|
See also SRFI-1 which has an extended @code{member} function
|
|
(@ref{SRFI-1 Searching}).
|
|
@end deffn
|
|
|
|
|
|
@node List Mapping
|
|
@subsubsection List Mapping
|
|
|
|
List processing is very convenient in Scheme because the process of
|
|
iterating over the elements of a list can be highly abstracted. The
|
|
procedures in this section are the most basic iterating procedures for
|
|
lists. They take a procedure and one or more lists as arguments, and
|
|
apply the procedure to each element of the list. They differ in their
|
|
return value.
|
|
|
|
@rnindex map
|
|
@c begin (texi-doc-string "guile" "map")
|
|
@deffn {Scheme Procedure} map proc arg1 arg2 @dots{}
|
|
@deffnx {Scheme Procedure} map-in-order proc arg1 arg2 @dots{}
|
|
@deffnx {C Function} scm_map (proc, arg1, args)
|
|
Apply @var{proc} to each element of the list @var{arg1} (if only two
|
|
arguments are given), or to the corresponding elements of the argument
|
|
lists (if more than two arguments are given). The result(s) of the
|
|
procedure applications are saved and returned in a list. For
|
|
@code{map}, the order of procedure applications is not specified,
|
|
@code{map-in-order} applies the procedure from left to right to the list
|
|
elements.
|
|
@end deffn
|
|
|
|
@rnindex for-each
|
|
@c begin (texi-doc-string "guile" "for-each")
|
|
@deffn {Scheme Procedure} for-each proc arg1 arg2 @dots{}
|
|
Like @code{map}, but the procedure is always applied from left to right,
|
|
and the result(s) of the procedure applications are thrown away. The
|
|
return value is not specified.
|
|
@end deffn
|
|
|
|
See also SRFI-1 which extends these functions to take lists of unequal
|
|
lengths (@ref{SRFI-1 Fold and Map}).
|
|
|
|
@node Vectors
|
|
@subsection Vectors
|
|
@tpindex Vectors
|
|
|
|
Vectors are sequences of Scheme objects. Unlike lists, the length of a
|
|
vector, once the vector is created, cannot be changed. The advantage of
|
|
vectors over lists is that the time required to access one element of a vector
|
|
given its @dfn{position} (synonymous with @dfn{index}), a zero-origin number,
|
|
is constant, whereas lists have an access time linear to the position of the
|
|
accessed element in the list.
|
|
|
|
Vectors can contain any kind of Scheme object; it is even possible to
|
|
have different types of objects in the same vector. For vectors
|
|
containing vectors, you may wish to use @ref{Arrays} instead.
|
|
Note, too, that vectors are a special case of one dimensional
|
|
non-uniform arrays and that array procedures operate happily on vectors.
|
|
|
|
Also see @ref{SRFI-43}, @ref{R6RS Support}, or @ref{R7RS Support}, for
|
|
more comprehensive vector libraries.
|
|
|
|
@menu
|
|
* Vector Syntax:: Read syntax for vectors.
|
|
* Vector Creation:: Dynamic vector creation and validation.
|
|
* Vector Accessors:: Accessing and modifying vector contents.
|
|
* Vector Accessing from C:: Ways to work with vectors from C.
|
|
* Uniform Numeric Vectors:: Vectors of unboxed numeric values.
|
|
@end menu
|
|
|
|
|
|
@node Vector Syntax
|
|
@subsubsection Read Syntax for Vectors
|
|
|
|
Vectors can literally be entered in source code, just like strings,
|
|
characters or some of the other data types. The read syntax for vectors
|
|
is as follows: A sharp sign (@code{#}), followed by an opening
|
|
parentheses, all elements of the vector in their respective read syntax,
|
|
and finally a closing parentheses. Like strings, vectors do not have to
|
|
be quoted.
|
|
|
|
The following are examples of the read syntax for vectors; where the
|
|
first vector only contains numbers and the second three different object
|
|
types: a string, a symbol and a number in hexadecimal notation.
|
|
|
|
@lisp
|
|
#(1 2 3)
|
|
#("Hello" foo #xdeadbeef)
|
|
@end lisp
|
|
|
|
@node Vector Creation
|
|
@subsubsection Dynamic Vector Creation and Validation
|
|
|
|
Instead of creating a vector implicitly by using the read syntax just
|
|
described, you can create a vector dynamically by calling one of the
|
|
@code{vector} and @code{list->vector} primitives with the list of Scheme
|
|
values that you want to place into a vector. The size of the vector
|
|
thus created is determined implicitly by the number of arguments given.
|
|
|
|
@rnindex vector
|
|
@rnindex list->vector
|
|
@deffn {Scheme Procedure} vector arg @dots{}
|
|
@deffnx {Scheme Procedure} list->vector l
|
|
@deffnx {C Function} scm_vector (l)
|
|
Return a newly allocated vector composed of the
|
|
given arguments. Analogous to @code{list}.
|
|
|
|
@lisp
|
|
(vector 'a 'b 'c) @result{} #(a b c)
|
|
@end lisp
|
|
@end deffn
|
|
|
|
The inverse operation is @code{vector->list}:
|
|
|
|
@rnindex vector->list
|
|
@deffn {Scheme Procedure} vector->list v
|
|
@deffnx {C Function} scm_vector_to_list (v)
|
|
Return a newly allocated list composed of the elements of @var{v}.
|
|
|
|
@lisp
|
|
(vector->list #(dah dah didah)) @result{} (dah dah didah)
|
|
(list->vector '(dididit dah)) @result{} #(dididit dah)
|
|
@end lisp
|
|
@end deffn
|
|
|
|
To allocate a vector with an explicitly specified size, use
|
|
@code{make-vector}. With this primitive you can also specify an initial
|
|
value for the vector elements (the same value for all elements, that
|
|
is):
|
|
|
|
@rnindex make-vector
|
|
@deffn {Scheme Procedure} make-vector len [fill]
|
|
@deffnx {C Function} scm_make_vector (len, fill)
|
|
Return a newly allocated vector of @var{len} elements. If a
|
|
second argument is given, then each position is initialized to
|
|
@var{fill}. Otherwise the initial contents of each position is
|
|
unspecified.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} SCM scm_c_make_vector (size_t k, SCM fill)
|
|
Like @code{scm_make_vector}, but the length is given as a @code{size_t}.
|
|
@end deftypefn
|
|
|
|
To check whether an arbitrary Scheme value @emph{is} a vector, use the
|
|
@code{vector?} primitive:
|
|
|
|
@rnindex vector?
|
|
@deffn {Scheme Procedure} vector? obj
|
|
@deffnx {C Function} scm_vector_p (obj)
|
|
Return @code{#t} if @var{obj} is a vector, otherwise return
|
|
@code{#f}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_vector (SCM obj)
|
|
Return non-zero when @var{obj} is a vector, otherwise return
|
|
@code{zero}.
|
|
@end deftypefn
|
|
|
|
@node Vector Accessors
|
|
@subsubsection Accessing and Modifying Vector Contents
|
|
|
|
@code{vector-length} and @code{vector-ref} return information about a
|
|
given vector, respectively its size and the elements that are contained
|
|
in the vector.
|
|
|
|
@rnindex vector-length
|
|
@deffn {Scheme Procedure} vector-length vector
|
|
@deffnx {C Function} scm_vector_length (vector)
|
|
Return the number of elements in @var{vector} as an exact integer.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} size_t scm_c_vector_length (SCM vec)
|
|
Return the number of elements in @var{vec} as a @code{size_t}.
|
|
@end deftypefn
|
|
|
|
@rnindex vector-ref
|
|
@deffn {Scheme Procedure} vector-ref vec k
|
|
@deffnx {C Function} scm_vector_ref (vec, k)
|
|
Return the contents of position @var{k} of @var{vec}.
|
|
@var{k} must be a valid index of @var{vec}.
|
|
@lisp
|
|
(vector-ref #(1 1 2 3 5 8 13 21) 5) @result{} 8
|
|
(vector-ref #(1 1 2 3 5 8 13 21)
|
|
(let ((i (round (* 2 (acos -1)))))
|
|
(if (inexact? i)
|
|
(inexact->exact i)
|
|
i))) @result{} 13
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@anchor{x-scm_c_vector_ref}
|
|
@deftypefn {C Function} SCM scm_c_vector_ref (SCM vec, size_t k)
|
|
Return the contents of position @var{k} (a @code{size_t}) of
|
|
@var{vec}.
|
|
@end deftypefn
|
|
|
|
A vector created by one of the dynamic vector constructor procedures
|
|
(@pxref{Vector Creation}) can be modified using the following
|
|
procedures.
|
|
|
|
@emph{NOTE:} According to R5RS, it is an error to use any of these
|
|
procedures on a literally read vector, because such vectors should be
|
|
considered as constants. Currently, however, Guile does not detect this
|
|
error.
|
|
|
|
@rnindex vector-set!
|
|
@deffn {Scheme Procedure} vector-set! vec k obj
|
|
@deffnx {C Function} scm_vector_set_x (vec, k, obj)
|
|
Store @var{obj} in position @var{k} of @var{vec}.
|
|
@var{k} must be a valid index of @var{vec}.
|
|
The value returned by @samp{vector-set!} is unspecified.
|
|
@lisp
|
|
(let ((vec (vector 0 '(2 2 2 2) "Anna")))
|
|
(vector-set! vec 1 '("Sue" "Sue"))
|
|
vec) @result{} #(0 ("Sue" "Sue") "Anna")
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@anchor{x-scm_c_vector_set_x}
|
|
@deftypefn {C Function} void scm_c_vector_set_x (SCM vec, size_t k, SCM obj)
|
|
Store @var{obj} in position @var{k} (a @code{size_t}) of @var{vec}.
|
|
@end deftypefn
|
|
|
|
@rnindex vector-fill!
|
|
@anchor{x-vector-fill!}
|
|
@deffn {Scheme Procedure} vector-fill! vec fill [start [end]]
|
|
@deffnx {C Function} scm_vector_fill_x (vec, fill)
|
|
Store @var{fill} in every position of @var{vec} in the range
|
|
[@var{start} ... @var{end}). @var{start} defaults to 0 and @var{end}
|
|
defaults to the length of @var{vec}.
|
|
|
|
The value returned by @code{vector-fill!} is unspecified.
|
|
@end deffn
|
|
|
|
@rnindex vector-copy
|
|
@anchor{x-vector-copy}
|
|
@deffn {Scheme Procedure} vector-copy vec [start [end]]
|
|
@deffnx {C Function} scm_vector_copy (vec)
|
|
Returns a freshly allocated vector containing the elements of @var{vec}
|
|
in the range [@var{start} ... @var{end}). @var{start} defaults to 0 and
|
|
@var{end} defaults to the length of @var{vec}.
|
|
@end deffn
|
|
|
|
@rnindex vector-copy!
|
|
@anchor{x-vector-copy!}
|
|
@deffn {Scheme Procedure} vector-copy! dst at src [start [end]]
|
|
Copy the block of elements from vector @var{src} in the range
|
|
[@var{start} ... @var{end}) into vector @var{dst}, starting at position
|
|
@var{at}. @var{at} and @var{start} default to 0 and @var{end} defaults
|
|
to the length of @var{src}.
|
|
|
|
It is an error for @var{dst} to have a length less than @var{at} +
|
|
(@var{end} - @var{start}).
|
|
|
|
The order in which elements are copied is unspecified, except that if the
|
|
source and destination overlap, copying takes place as if the source is
|
|
first copied into a temporary vector and then into the destination.
|
|
|
|
The value returned by @code{vector-copy!} is unspecified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-move-left! vec1 start1 end1 vec2 start2
|
|
@deffnx {C Function} scm_vector_move_left_x (vec1, start1, end1, vec2, start2)
|
|
Copy elements from @var{vec1}, positions @var{start1} to @var{end1},
|
|
to @var{vec2} starting at position @var{start2}. @var{start1} and
|
|
@var{start2} are inclusive indices; @var{end1} is exclusive.
|
|
|
|
@code{vector-move-left!} copies elements in leftmost order.
|
|
Therefore, in the case where @var{vec1} and @var{vec2} refer to the
|
|
same vector, @code{vector-move-left!} is usually appropriate when
|
|
@var{start1} is greater than @var{start2}.
|
|
|
|
The value returned by @code{vector-move-left!} is unspecified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vector-move-right! vec1 start1 end1 vec2 start2
|
|
@deffnx {C Function} scm_vector_move_right_x (vec1, start1, end1, vec2, start2)
|
|
Copy elements from @var{vec1}, positions @var{start1} to @var{end1},
|
|
to @var{vec2} starting at position @var{start2}. @var{start1} and
|
|
@var{start2} are inclusive indices; @var{end1} is exclusive.
|
|
|
|
@code{vector-move-right!} copies elements in rightmost order.
|
|
Therefore, in the case where @var{vec1} and @var{vec2} refer to the
|
|
same vector, @code{vector-move-right!} is usually appropriate when
|
|
@var{start1} is less than @var{start2}.
|
|
|
|
The value returned by @code{vector-move-right!} is unspecified.
|
|
@end deffn
|
|
|
|
@node Vector Accessing from C
|
|
@subsubsection Vector Accessing from C
|
|
|
|
A vector can be read and modified from C with the functions
|
|
@ref{x-scm_c_vector_ref,@code{scm_c_vector_ref}} and
|
|
@ref{x-scm_c_vector_set_x,@code{scm_c_vector_set_x}}. In addition to
|
|
these functions, there are two other ways to access vectors from C that
|
|
might be more efficient in certain situations: you can use the unsafe
|
|
@emph{vector macros}; or you can use the general framework for accessing
|
|
all kinds of arrays (@pxref{Accessing Arrays from C}), which is more
|
|
verbose, but can deal efficiently with all kinds of vectors (and
|
|
arrays). For arrays of rank 1 whose backing store is a vector, you can
|
|
use the @code{scm_vector_elements} and
|
|
@code{scm_vector_writable_elements} functions as shortcuts.
|
|
|
|
@deftypefn {C Macro} size_t SCM_SIMPLE_VECTOR_LENGTH (SCM vec)
|
|
Evaluates to the length of the vector @var{vec}. No type
|
|
checking is done.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Macro} SCM SCM_SIMPLE_VECTOR_REF (SCM vec, size_t idx)
|
|
Evaluates to the element at position @var{idx} in the vector @var{vec}.
|
|
No type or range checking is done.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Macro} void SCM_SIMPLE_VECTOR_SET (SCM vec, size_t idx, SCM val)
|
|
Sets the element at position @var{idx} in the vector @var{vec} to
|
|
@var{val}. No type or range checking is done.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {const SCM *} scm_vector_elements (SCM array, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
|
|
Acquire a @ref{Accessing Arrays from C,handle} for @var{array} and
|
|
return a read-only pointer to its elements. @var{array} must be either
|
|
a vector, or an array of rank 1 whose backing store is a vector;
|
|
otherwise an error is signaled. The handle must eventually be released
|
|
with @ref{x-scm_array_handle_release,@code{scm_array_handle_release}}.
|
|
|
|
The variables pointed to by @var{lenp} and @var{incp} are filled with
|
|
the number of elements of the array and the increment (number of
|
|
elements) between successive elements, respectively. Successive
|
|
elements of @var{array} need not be contiguous in their underlying
|
|
``root vector'' returned here; hence the increment is not necessarily
|
|
equal to 1 and may well be negative too (@pxref{Shared Arrays}).
|
|
|
|
The following example shows the typical way to use this function. It
|
|
creates a list of all elements of @var{array} (in reverse order).
|
|
|
|
@example
|
|
scm_t_array_handle handle;
|
|
size_t i, len;
|
|
ssize_t inc;
|
|
const SCM *elt;
|
|
SCM list;
|
|
|
|
elt = scm_vector_elements (array, &handle, &len, &inc);
|
|
list = SCM_EOL;
|
|
for (i = 0; i < len; i++, elt += inc)
|
|
list = scm_cons (*elt, list);
|
|
scm_array_handle_release (&handle);
|
|
@end example
|
|
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {SCM *} scm_vector_writable_elements (SCM array, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
|
|
Like @code{scm_vector_elements} but the pointer can be used to modify
|
|
the array.
|
|
|
|
The following example shows the typical way to use this function. It
|
|
fills an array with @code{#t}.
|
|
|
|
@example
|
|
scm_t_array_handle handle;
|
|
size_t i, len;
|
|
ssize_t inc;
|
|
SCM *elt;
|
|
|
|
elt = scm_vector_writable_elements (array, &handle, &len, &inc);
|
|
for (i = 0; i < len; i++, elt += inc)
|
|
*elt = SCM_BOOL_T;
|
|
scm_array_handle_release (&handle);
|
|
@end example
|
|
|
|
@end deftypefn
|
|
|
|
@node Uniform Numeric Vectors
|
|
@subsubsection Uniform Numeric Vectors
|
|
|
|
A uniform numeric vector is a vector 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 complex floating-point numbers of these two
|
|
sizes. @xref{SRFI-4}, for more information.
|
|
|
|
For many purposes, bytevectors work just as well as uniform vectors, and have
|
|
the advantage that they integrate well with binary input and output.
|
|
@xref{Bytevectors}, for more information on bytevectors.
|
|
|
|
@node Bit Vectors
|
|
@subsection Bit Vectors
|
|
|
|
@noindent
|
|
Bit vectors are zero-origin, one-dimensional arrays of booleans. They
|
|
are displayed as a sequence of @code{0}s and @code{1}s prefixed by
|
|
@code{#*}, e.g.,
|
|
|
|
@example
|
|
(make-bitvector 8 #f) @result{}
|
|
#*00000000
|
|
@end example
|
|
|
|
Bit vectors are the special case of one dimensional bit arrays, and can
|
|
thus be used with the array procedures, @xref{Arrays}.
|
|
|
|
@deffn {Scheme Procedure} bitvector? obj
|
|
Return @code{#t} when @var{obj} is a bitvector, else
|
|
return @code{#f}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} make-bitvector len [fill]
|
|
Create a new bitvector of length @var{len} and
|
|
optionally initialize all elements to @var{fill}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector bit @dots{}
|
|
Create a new bitvector with the arguments as elements.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector-length vec
|
|
Return the length of the bitvector @var{vec}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector-bit-set? vec idx
|
|
@deffnx {Scheme Procedure} bitvector-bit-clear? vec idx
|
|
Return @code{#t} if the bit at index @var{idx} of the bitvector
|
|
@var{vec} is set (for @code{bitvector-bit-set?}) or clear (for
|
|
@code{bitvector-bit-clear?}).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector-set-bit! vec idx
|
|
@deffnx {Scheme Procedure} bitvector-clear-bit! vec idx
|
|
Set (for @code{bitvector-set-bit!}) or clear (for
|
|
@code{bitvector-clear-bit!}) the bit at index @var{idx} of the bitvector
|
|
@var{vec}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector-set-all-bits! vec
|
|
@deffnx {Scheme Procedure} bitvector-clear-all-bits! vec
|
|
@deffnx {Scheme Procedure} bitvector-flip-all-bits! vec
|
|
Set, clear, or flip all bits of @var{vec}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list->bitvector list
|
|
@deffnx {C Function} scm_list_to_bitvector (list)
|
|
Return a new bitvector initialized with the elements
|
|
of @var{list}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector->list vec
|
|
@deffnx {C Function} scm_bitvector_to_list (vec)
|
|
Return a new list initialized with the elements
|
|
of the bitvector @var{vec}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector-copy bitvector [start [end]]
|
|
@deffnx {C Function} scm_bitvector_copy (bitvector, start, end)
|
|
Returns a freshly allocated bitvector containing the elements of @var{bitvector}
|
|
in the range [@var{start} ... @var{end}). @var{start} defaults to 0 and
|
|
@var{end} defaults to the length of @var{bitvector}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector-count bitvector
|
|
Return a count of how many entries in @var{bitvector} are set.
|
|
|
|
@example
|
|
(bitvector-count #*000111000) @result{} 3
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector-count-bits bitvector bits
|
|
Return a count of how many entries in @var{bitvector} are set, with the
|
|
bitvector @var{bits} selecting the entries to consider. @var{bitvector}
|
|
must be at least as long as @var{bits}.
|
|
|
|
For example,
|
|
|
|
@example
|
|
(bitvector-count-bits #*01110111 #*11001101) @result{} 3
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector-position bitvector bool start
|
|
@deffnx {C Function} scm_bitvector_position (bitvector, bool, start)
|
|
Return the index of the first occurrence of @var{bool} in
|
|
@var{bitvector}, starting from @var{start}. If there is no @var{bool}
|
|
entry between @var{start} and the end of @var{bitvector}, then return
|
|
@code{#f}. For example,
|
|
|
|
@example
|
|
(bitvector-position #*000101 #t 0) @result{} 3
|
|
(bitvector-position #*0001111 #f 3) @result{} #f
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector-set-bits! bitvector bits
|
|
Set entries of @var{bitvector} to @code{#t}, with @var{bits} selecting
|
|
the bits to set. The return value is unspecified. @var{bitvector} must
|
|
be at least as long as @var{bits}.
|
|
|
|
@example
|
|
(define bv (bitvector-copy #*11000010))
|
|
(bitvector-set-bits! bv #*10010001)
|
|
bv
|
|
@result{} #*11010011
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bitvector-clear-bits! bitvector bits
|
|
Set entries of @var{bitvector} to @code{#f}, with @var{bits} selecting
|
|
the bits to clear. The return value is unspecified. @var{bitvector}
|
|
must be at least as long as @var{bits}.
|
|
|
|
@example
|
|
(define bv (bitvector-copy #*11000010))
|
|
(bitvector-clear-bits! bv #*10010001)
|
|
bv
|
|
@result{} #*01000010
|
|
@end example
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_bitvector (SCM obj)
|
|
@deftypefnx {C Function} SCM scm_c_make_bitvector (size_t len, SCM fill)
|
|
@deftypefnx {C Function} int scm_bitvector_bit_is_set (SCM vec, size_t idx)
|
|
@deftypefnx {C Function} int scm_bitvector_bit_is_clear (SCM vec, size_t idx)
|
|
@deftypefnx {C Function} void scm_c_bitvector_set_bit_x (SCM vec, size_t idx)
|
|
@deftypefnx {C Function} void scm_c_bitvector_clear_bit_x (SCM vec, size_t idx)
|
|
@deftypefnx {C Function} void scm_c_bitvector_set_bits_x (SCM vec, SCM bits)
|
|
@deftypefnx {C Function} void scm_c_bitvector_clear_bits_x (SCM vec, SCM bits)
|
|
@deftypefnx {C Function} void scm_c_bitvector_set_all_bits_x (SCM vec)
|
|
@deftypefnx {C Function} void scm_c_bitvector_clear_all_bits_x (SCM vec)
|
|
@deftypefnx {C Function} void scm_c_bitvector_flip_all_bits_x (SCM vec)
|
|
@deftypefnx {C Function} size_t scm_c_bitvector_length (SCM bitvector)
|
|
@deftypefnx {C Function} size_t scm_c_bitvector_count (SCM bitvector)
|
|
@deftypefnx {C Function} size_t scm_c_bitvector_count_bits (SCM bitvector, SCM bits)
|
|
C API for the corresponding Scheme bitvector interfaces.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {const scm_t_uint32 *} scm_bitvector_elements (SCM vec, scm_t_array_handle *handle, size_t *offp, size_t *lenp, ssize_t *incp)
|
|
Like @code{scm_vector_elements} (@pxref{Vector Accessing from C}), but
|
|
for bitvectors. The variable pointed to by @var{offp} is set to the
|
|
value returned by @code{scm_array_handle_bit_elements_offset}. See
|
|
@code{scm_array_handle_bit_elements} for how to use the returned
|
|
pointer and the offset.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {scm_t_uint32 *} scm_bitvector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *offp, size_t *lenp, ssize_t *incp)
|
|
Like @code{scm_bitvector_elements}, but the pointer is good for reading
|
|
and writing.
|
|
@end deftypefn
|
|
|
|
@node Bytevectors
|
|
@subsection Bytevectors
|
|
|
|
@cindex bytevector
|
|
@cindex R6RS
|
|
|
|
A @dfn{bytevector} is a raw byte string. The @code{(rnrs bytevectors)}
|
|
module provides the programming interface specified by the
|
|
@uref{http://www.r6rs.org/, Revised^6 Report on the Algorithmic Language
|
|
Scheme (R6RS)}. It contains procedures to manipulate bytevectors and
|
|
interpret their contents in a number of ways: as signed or unsigned
|
|
integer of various sizes and endianness, as IEEE-754 floating point
|
|
numbers, or as strings. It is a useful tool to encode and decode binary
|
|
data. The @ref{R7RS Support,R7RS} offers its own set of bytevector
|
|
procedures (@pxref{Bytevector Procedures in R7RS}).
|
|
|
|
The R6RS (Section 4.3.4) specifies an external representation for
|
|
bytevectors, whereby the octets (integers in the range 0--255) contained
|
|
in the bytevector are represented as a list prefixed by @code{#vu8}:
|
|
|
|
@lisp
|
|
#vu8(1 53 204)
|
|
@end lisp
|
|
|
|
denotes a 3-byte bytevector containing the octets 1, 53, and 204. Like
|
|
string literals, booleans, etc., bytevectors are ``self-quoting'', i.e.,
|
|
they do not need to be quoted:
|
|
|
|
@lisp
|
|
#vu8(1 53 204)
|
|
@result{} #vu8(1 53 204)
|
|
@end lisp
|
|
|
|
Bytevectors can be used with the binary input/output primitives
|
|
(@pxref{Binary I/O}).
|
|
|
|
@menu
|
|
* Bytevector Endianness:: Dealing with byte order.
|
|
* Bytevector Manipulation:: Creating, copying, manipulating bytevectors.
|
|
* Bytevectors as Integers:: Interpreting bytes as integers.
|
|
* Bytevectors and Integer Lists:: Converting to/from an integer list.
|
|
* Bytevectors as Floats:: Interpreting bytes as real numbers.
|
|
* Bytevectors as Strings:: Interpreting bytes as Unicode strings.
|
|
* Bytevectors as Arrays:: Guile extension to the bytevector API.
|
|
* Bytevectors as Uniform Vectors:: Bytevectors and SRFI-4.
|
|
* Bytevector Procedures in R7RS:: R7RS interface for bytevectors.
|
|
* Bytevector Slices:: Aliases for parts of a bytevector.
|
|
@end menu
|
|
|
|
@node Bytevector Endianness
|
|
@subsubsection Endianness
|
|
|
|
@cindex endianness
|
|
@cindex byte order
|
|
@cindex word order
|
|
|
|
Some of the following procedures take an @var{endianness} parameter.
|
|
The @dfn{endianness} is defined as the order of bytes in multi-byte
|
|
numbers: numbers encoded in @dfn{big endian} have their most
|
|
significant bytes written first, whereas numbers encoded in
|
|
@dfn{little endian} have their least significant bytes
|
|
first@footnote{Big-endian and little-endian are the most common
|
|
``endiannesses'', but others do exist. For instance, the GNU MP
|
|
library allows @dfn{word order} to be specified independently of
|
|
@dfn{byte order} (@pxref{Integer Import and Export,,, gmp, The GNU
|
|
Multiple Precision Arithmetic Library Manual}).}.
|
|
|
|
Little-endian is the native endianness of the IA32 architecture and
|
|
its derivatives, while big-endian is native to SPARC and PowerPC,
|
|
among others. The @code{native-endianness} procedure returns the
|
|
native endianness of the machine it runs on.
|
|
|
|
@deffn {Scheme Procedure} native-endianness
|
|
@deffnx {C Function} scm_native_endianness ()
|
|
Return a value denoting the native endianness of the host machine.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Macro} endianness symbol
|
|
Return an object denoting the endianness specified by @var{symbol}. If
|
|
@var{symbol} is neither @code{big} nor @code{little} then an error is
|
|
raised at expand-time.
|
|
@end deffn
|
|
|
|
@defvr {C Variable} scm_endianness_big
|
|
@defvrx {C Variable} scm_endianness_little
|
|
The objects denoting big- and little-endianness, respectively.
|
|
@end defvr
|
|
|
|
|
|
@node Bytevector Manipulation
|
|
@subsubsection Manipulating Bytevectors
|
|
|
|
Bytevectors can be created, copied, and analyzed with the following
|
|
procedures and C functions.
|
|
|
|
@anchor{x-make-bytevector}
|
|
@deffn {Scheme Procedure} make-bytevector len [fill]
|
|
@deffnx {C Function} scm_make_bytevector (len, fill)
|
|
@deffnx {C Function} scm_c_make_bytevector (size_t len)
|
|
Return a new bytevector of @var{len} bytes. Optionally, if @var{fill}
|
|
is given, fill it with @var{fill}; @var{fill} must be in the range
|
|
[-128,255].
|
|
@end deffn
|
|
|
|
@anchor{x-bytevector?}
|
|
@deffn {Scheme Procedure} bytevector? obj
|
|
@deffnx {C Function} scm_bytevector_p (obj)
|
|
Return true if @var{obj} is a bytevector.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_bytevector (SCM obj)
|
|
Equivalent to @code{scm_is_true (scm_bytevector_p (obj))}.
|
|
@end deftypefn
|
|
|
|
@anchor{x-bytevector-length}
|
|
@deffn {Scheme Procedure} bytevector-length bv
|
|
@deffnx {C Function} scm_bytevector_length (bv)
|
|
Return the length in bytes of bytevector @var{bv}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} size_t scm_c_bytevector_length (SCM bv)
|
|
Likewise, return the length in bytes of bytevector @var{bv}.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} bytevector=? bv1 bv2
|
|
@deffnx {C Function} scm_bytevector_eq_p (bv1, bv2)
|
|
Return @code{#t} if @var{bv1} equals @var{bv2}---i.e., if they have the same
|
|
length and contents.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector-fill! bv fill [start [end]]
|
|
@deffnx {C Function} scm_bytevector_fill_x (bv, fill)
|
|
Fill positions [@var{start} ... @var{end}) of bytevector @var{bv} with
|
|
byte @var{fill}. @var{start} defaults to 0 and @var{end} defaults to the
|
|
length of @var{bv}.@footnote{R6RS only defines @code{(bytevector-fill! bv
|
|
fill)}. Arguments @var{start} and @var{end} are a Guile extension
|
|
(cf. @ref{x-vector-fill!,@code{vector-fill!}},
|
|
@ref{x-string-fill!,@code{string-fill!}}).}
|
|
@end deffn
|
|
|
|
@anchor{x-r6:bytevector-copy!}
|
|
@deffn {Scheme Procedure} bytevector-copy! source source-start target target-start len
|
|
@deffnx {C Function} scm_bytevector_copy_x (source, source_start, target, target_start, len)
|
|
Copy @var{len} bytes from @var{source} into @var{target}, starting
|
|
reading from @var{source-start} (an index index within @var{source})
|
|
and writing at @var{target-start}.
|
|
|
|
It is permitted for the @var{source} and @var{target} regions to
|
|
overlap. In that case, copying takes place as if the source is first
|
|
copied into a temporary bytevector and then into the destination.
|
|
@end deffn
|
|
|
|
@anchor{x-r6:bytevector-copy}
|
|
@deffn {Scheme Procedure} bytevector-copy bv
|
|
@deffnx {C Function} scm_bytevector_copy (bv)
|
|
Return a newly allocated copy of @var{bv}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} scm_t_uint8 scm_c_bytevector_ref (SCM bv, size_t index)
|
|
Return the byte at @var{index} in bytevector @var{bv}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} void scm_c_bytevector_set_x (SCM bv, size_t index, scm_t_uint8 value)
|
|
Set the byte at @var{index} in @var{bv} to @var{value}.
|
|
@end deftypefn
|
|
|
|
Low-level C macros are available. They do not perform any
|
|
type-checking; as such they should be used with care.
|
|
|
|
@deftypefn {C Macro} size_t SCM_BYTEVECTOR_LENGTH (bv)
|
|
Return the length in bytes of bytevector @var{bv}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Macro} {signed char *} SCM_BYTEVECTOR_CONTENTS (bv)
|
|
Return a pointer to the contents of bytevector @var{bv}.
|
|
@end deftypefn
|
|
|
|
|
|
@node Bytevectors as Integers
|
|
@subsubsection Interpreting Bytevector Contents as Integers
|
|
|
|
The contents of a bytevector can be interpreted as a sequence of
|
|
integers of any given size, sign, and endianness.
|
|
|
|
@lisp
|
|
(let ((bv (make-bytevector 4)))
|
|
(bytevector-u8-set! bv 0 #x12)
|
|
(bytevector-u8-set! bv 1 #x34)
|
|
(bytevector-u8-set! bv 2 #x56)
|
|
(bytevector-u8-set! bv 3 #x78)
|
|
|
|
(map (lambda (number)
|
|
(number->string number 16))
|
|
(list (bytevector-u8-ref bv 0)
|
|
(bytevector-u16-ref bv 0 (endianness big))
|
|
(bytevector-u32-ref bv 0 (endianness little)))))
|
|
|
|
@result{} ("12" "1234" "78563412")
|
|
@end lisp
|
|
|
|
The most generic procedures to interpret bytevector contents as integers
|
|
are described below.
|
|
|
|
@deffn {Scheme Procedure} bytevector-uint-ref bv index endianness size
|
|
@deffnx {C Function} scm_bytevector_uint_ref (bv, index, endianness, size)
|
|
Return the @var{size}-byte long unsigned integer at index @var{index} in
|
|
@var{bv}, decoded according to @var{endianness}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector-sint-ref bv index endianness size
|
|
@deffnx {C Function} scm_bytevector_sint_ref (bv, index, endianness, size)
|
|
Return the @var{size}-byte long signed integer at index @var{index} in
|
|
@var{bv}, decoded according to @var{endianness}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector-uint-set! bv index value endianness size
|
|
@deffnx {C Function} scm_bytevector_uint_set_x (bv, index, value, endianness, size)
|
|
Set the @var{size}-byte long unsigned integer at @var{index} to
|
|
@var{value}, encoded according to @var{endianness}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector-sint-set! bv index value endianness size
|
|
@deffnx {C Function} scm_bytevector_sint_set_x (bv, index, value, endianness, size)
|
|
Set the @var{size}-byte long signed integer at @var{index} to
|
|
@var{value}, encoded according to @var{endianness}.
|
|
@end deffn
|
|
|
|
The following procedures are similar to the ones above, but specialized
|
|
to a given integer size:
|
|
|
|
@anchor{x-bytevector-u8-ref}
|
|
@deffn {Scheme Procedure} bytevector-u8-ref bv index
|
|
@deffnx {Scheme Procedure} bytevector-s8-ref bv index
|
|
@deffnx {Scheme Procedure} bytevector-u16-ref bv index endianness
|
|
@deffnx {Scheme Procedure} bytevector-s16-ref bv index endianness
|
|
@deffnx {Scheme Procedure} bytevector-u32-ref bv index endianness
|
|
@deffnx {Scheme Procedure} bytevector-s32-ref bv index endianness
|
|
@deffnx {Scheme Procedure} bytevector-u64-ref bv index endianness
|
|
@deffnx {Scheme Procedure} bytevector-s64-ref bv index endianness
|
|
@deffnx {C Function} scm_bytevector_u8_ref (bv, index)
|
|
@deffnx {C Function} scm_bytevector_s8_ref (bv, index)
|
|
@deffnx {C Function} scm_bytevector_u16_ref (bv, index, endianness)
|
|
@deffnx {C Function} scm_bytevector_s16_ref (bv, index, endianness)
|
|
@deffnx {C Function} scm_bytevector_u32_ref (bv, index, endianness)
|
|
@deffnx {C Function} scm_bytevector_s32_ref (bv, index, endianness)
|
|
@deffnx {C Function} scm_bytevector_u64_ref (bv, index, endianness)
|
|
@deffnx {C Function} scm_bytevector_s64_ref (bv, index, endianness)
|
|
Return the unsigned @var{n}-bit (signed) integer (where @var{n} is 8,
|
|
16, 32 or 64) from @var{bv} at @var{index}, decoded according to
|
|
@var{endianness}.
|
|
@end deffn
|
|
|
|
@anchor{x-bytevector-u8-set!}
|
|
@deffn {Scheme Procedure} bytevector-u8-set! bv index value
|
|
@deffnx {Scheme Procedure} bytevector-s8-set! bv index value
|
|
@deffnx {Scheme Procedure} bytevector-u16-set! bv index value endianness
|
|
@deffnx {Scheme Procedure} bytevector-s16-set! bv index value endianness
|
|
@deffnx {Scheme Procedure} bytevector-u32-set! bv index value endianness
|
|
@deffnx {Scheme Procedure} bytevector-s32-set! bv index value endianness
|
|
@deffnx {Scheme Procedure} bytevector-u64-set! bv index value endianness
|
|
@deffnx {Scheme Procedure} bytevector-s64-set! bv index value endianness
|
|
@deffnx {C Function} scm_bytevector_u8_set_x (bv, index, value)
|
|
@deffnx {C Function} scm_bytevector_s8_set_x (bv, index, value)
|
|
@deffnx {C Function} scm_bytevector_u16_set_x (bv, index, value, endianness)
|
|
@deffnx {C Function} scm_bytevector_s16_set_x (bv, index, value, endianness)
|
|
@deffnx {C Function} scm_bytevector_u32_set_x (bv, index, value, endianness)
|
|
@deffnx {C Function} scm_bytevector_s32_set_x (bv, index, value, endianness)
|
|
@deffnx {C Function} scm_bytevector_u64_set_x (bv, index, value, endianness)
|
|
@deffnx {C Function} scm_bytevector_s64_set_x (bv, index, value, endianness)
|
|
Store @var{value} as an @var{n}-bit (signed) integer (where @var{n} is
|
|
8, 16, 32 or 64) in @var{bv} at @var{index}, encoded according to
|
|
@var{endianness}.
|
|
@end deffn
|
|
|
|
Finally, a variant specialized for the host's endianness is available
|
|
for each of these functions (with the exception of the @code{u8} and
|
|
@code{s8} accessors, as endianness is about byte order and there is only
|
|
1 byte):
|
|
|
|
@deffn {Scheme Procedure} bytevector-u16-native-ref bv index
|
|
@deffnx {Scheme Procedure} bytevector-s16-native-ref bv index
|
|
@deffnx {Scheme Procedure} bytevector-u32-native-ref bv index
|
|
@deffnx {Scheme Procedure} bytevector-s32-native-ref bv index
|
|
@deffnx {Scheme Procedure} bytevector-u64-native-ref bv index
|
|
@deffnx {Scheme Procedure} bytevector-s64-native-ref bv index
|
|
@deffnx {C Function} scm_bytevector_u16_native_ref (bv, index)
|
|
@deffnx {C Function} scm_bytevector_s16_native_ref (bv, index)
|
|
@deffnx {C Function} scm_bytevector_u32_native_ref (bv, index)
|
|
@deffnx {C Function} scm_bytevector_s32_native_ref (bv, index)
|
|
@deffnx {C Function} scm_bytevector_u64_native_ref (bv, index)
|
|
@deffnx {C Function} scm_bytevector_s64_native_ref (bv, index)
|
|
Return the unsigned @var{n}-bit (signed) integer (where @var{n} is 8,
|
|
16, 32 or 64) from @var{bv} at @var{index}, decoded according to the
|
|
host's native endianness.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector-u16-native-set! bv index value
|
|
@deffnx {Scheme Procedure} bytevector-s16-native-set! bv index value
|
|
@deffnx {Scheme Procedure} bytevector-u32-native-set! bv index value
|
|
@deffnx {Scheme Procedure} bytevector-s32-native-set! bv index value
|
|
@deffnx {Scheme Procedure} bytevector-u64-native-set! bv index value
|
|
@deffnx {Scheme Procedure} bytevector-s64-native-set! bv index value
|
|
@deffnx {C Function} scm_bytevector_u16_native_set_x (bv, index, value)
|
|
@deffnx {C Function} scm_bytevector_s16_native_set_x (bv, index, value)
|
|
@deffnx {C Function} scm_bytevector_u32_native_set_x (bv, index, value)
|
|
@deffnx {C Function} scm_bytevector_s32_native_set_x (bv, index, value)
|
|
@deffnx {C Function} scm_bytevector_u64_native_set_x (bv, index, value)
|
|
@deffnx {C Function} scm_bytevector_s64_native_set_x (bv, index, value)
|
|
Store @var{value} as an @var{n}-bit (signed) integer (where @var{n} is
|
|
8, 16, 32 or 64) in @var{bv} at @var{index}, encoded according to the
|
|
host's native endianness.
|
|
@end deffn
|
|
|
|
|
|
@node Bytevectors and Integer Lists
|
|
@subsubsection Converting Bytevectors to/from Integer Lists
|
|
|
|
Bytevector contents can readily be converted to/from lists of signed or
|
|
unsigned integers:
|
|
|
|
@lisp
|
|
(bytevector->sint-list (u8-list->bytevector (make-list 4 255))
|
|
(endianness little) 2)
|
|
@result{} (-1 -1)
|
|
@end lisp
|
|
|
|
@deffn {Scheme Procedure} bytevector->u8-list bv
|
|
@deffnx {C Function} scm_bytevector_to_u8_list (bv)
|
|
Return a newly allocated list of unsigned 8-bit integers from the
|
|
contents of @var{bv}.
|
|
@end deffn
|
|
|
|
@anchor{x-u8-list->bytevector}
|
|
@deffn {Scheme Procedure} u8-list->bytevector lst
|
|
@deffnx {C Function} scm_u8_list_to_bytevector (lst)
|
|
Return a newly allocated bytevector consisting of the unsigned 8-bit
|
|
integers listed in @var{lst}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector->uint-list bv endianness size
|
|
@deffnx {C Function} scm_bytevector_to_uint_list (bv, endianness, size)
|
|
Return a list of unsigned integers of @var{size} bytes representing the
|
|
contents of @var{bv}, decoded according to @var{endianness}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector->sint-list bv endianness size
|
|
@deffnx {C Function} scm_bytevector_to_sint_list (bv, endianness, size)
|
|
Return a list of signed integers of @var{size} bytes representing the
|
|
contents of @var{bv}, decoded according to @var{endianness}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} uint-list->bytevector lst endianness size
|
|
@deffnx {C Function} scm_uint_list_to_bytevector (lst, endianness, size)
|
|
Return a new bytevector containing the unsigned integers listed in
|
|
@var{lst} and encoded on @var{size} bytes according to @var{endianness}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} sint-list->bytevector lst endianness size
|
|
@deffnx {C Function} scm_sint_list_to_bytevector (lst, endianness, size)
|
|
Return a new bytevector containing the signed integers listed in
|
|
@var{lst} and encoded on @var{size} bytes according to @var{endianness}.
|
|
@end deffn
|
|
|
|
@node Bytevectors as Floats
|
|
@subsubsection Interpreting Bytevector Contents as Floating Point Numbers
|
|
|
|
@cindex IEEE-754 floating point numbers
|
|
|
|
Bytevector contents can also be accessed as IEEE-754 single- or
|
|
double-precision floating point numbers (respectively 32 and 64-bit
|
|
long) using the procedures described here.
|
|
|
|
@deffn {Scheme Procedure} bytevector-ieee-single-ref bv index endianness
|
|
@deffnx {Scheme Procedure} bytevector-ieee-double-ref bv index endianness
|
|
@deffnx {C Function} scm_bytevector_ieee_single_ref (bv, index, endianness)
|
|
@deffnx {C Function} scm_bytevector_ieee_double_ref (bv, index, endianness)
|
|
Return the IEEE-754 single-precision floating point number from @var{bv}
|
|
at @var{index} according to @var{endianness}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector-ieee-single-set! bv index value endianness
|
|
@deffnx {Scheme Procedure} bytevector-ieee-double-set! bv index value endianness
|
|
@deffnx {C Function} scm_bytevector_ieee_single_set_x (bv, index, value, endianness)
|
|
@deffnx {C Function} scm_bytevector_ieee_double_set_x (bv, index, value, endianness)
|
|
Store real number @var{value} in @var{bv} at @var{index} according to
|
|
@var{endianness}.
|
|
@end deffn
|
|
|
|
Specialized procedures are also available:
|
|
|
|
@deffn {Scheme Procedure} bytevector-ieee-single-native-ref bv index
|
|
@deffnx {Scheme Procedure} bytevector-ieee-double-native-ref bv index
|
|
@deffnx {C Function} scm_bytevector_ieee_single_native_ref (bv, index)
|
|
@deffnx {C Function} scm_bytevector_ieee_double_native_ref (bv, index)
|
|
Return the IEEE-754 single-precision floating point number from @var{bv}
|
|
at @var{index} according to the host's native endianness.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} bytevector-ieee-single-native-set! bv index value
|
|
@deffnx {Scheme Procedure} bytevector-ieee-double-native-set! bv index value
|
|
@deffnx {C Function} scm_bytevector_ieee_single_native_set_x (bv, index, value)
|
|
@deffnx {C Function} scm_bytevector_ieee_double_native_set_x (bv, index, value)
|
|
Store real number @var{value} in @var{bv} at @var{index} according to
|
|
the host's native endianness.
|
|
@end deffn
|
|
|
|
|
|
@node Bytevectors as Strings
|
|
@subsubsection Interpreting Bytevector Contents as Unicode Strings
|
|
|
|
@cindex Unicode string encoding
|
|
|
|
Bytevector contents can also be interpreted as Unicode strings encoded
|
|
in one of the most commonly available encoding formats.
|
|
@xref{Representing Strings as Bytes}, for a more generic interface.
|
|
|
|
@lisp
|
|
(utf8->string (u8-list->bytevector '(99 97 102 101)))
|
|
@result{} "cafe"
|
|
|
|
(string->utf8 "caf@'e") ;; SMALL LATIN LETTER E WITH ACUTE ACCENT
|
|
@result{} #vu8(99 97 102 195 169)
|
|
@end lisp
|
|
|
|
@deftypefn {Scheme Procedure} {} string-utf8-length str
|
|
@deftypefnx {C function} SCM scm_string_utf8_length (str)
|
|
@deftypefnx {C function} size_t scm_c_string_utf8_length (str)
|
|
Return the number of bytes in the UTF-8 representation of @var{str}.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} string->utf8 str
|
|
@deffnx {Scheme Procedure} string->utf16 str [endianness]
|
|
@deffnx {Scheme Procedure} string->utf32 str [endianness]
|
|
@deffnx {C Function} scm_string_to_utf8 (str)
|
|
@deffnx {C Function} scm_string_to_utf16 (str, endianness)
|
|
@deffnx {C Function} scm_string_to_utf32 (str, endianness)
|
|
Return a newly allocated bytevector that contains the UTF-8, UTF-16, or
|
|
UTF-32 (aka. UCS-4) encoding of @var{str}. For UTF-16 and UTF-32,
|
|
@var{endianness} should be the symbol @code{big} or @code{little}; when omitted,
|
|
it defaults to big endian.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} utf8->string utf
|
|
@deffnx {Scheme Procedure} utf16->string utf [endianness]
|
|
@deffnx {Scheme Procedure} utf32->string utf [endianness]
|
|
@deffnx {C Function} scm_utf8_to_string (utf)
|
|
@deffnx {C Function} scm_utf16_to_string (utf, endianness)
|
|
@deffnx {C Function} scm_utf32_to_string (utf, endianness)
|
|
Return a newly allocated string that contains from the UTF-8-, UTF-16-,
|
|
or UTF-32-decoded contents of bytevector @var{utf}. For UTF-16 and UTF-32,
|
|
@var{endianness} should be the symbol @code{big} or @code{little}; when omitted,
|
|
it defaults to big endian.
|
|
@end deffn
|
|
|
|
@node Bytevectors as Arrays
|
|
@subsubsection Accessing Bytevectors with the Array API
|
|
|
|
As an extension to the R6RS, Guile allows bytevectors to be manipulated
|
|
with the @dfn{array} procedures (@pxref{Arrays}). When using these
|
|
APIs, bytes are accessed one at a time as 8-bit unsigned integers:
|
|
|
|
@example
|
|
(define bv #vu8(0 1 2 3))
|
|
|
|
(array? bv)
|
|
@result{} #t
|
|
|
|
(array-rank bv)
|
|
@result{} 1
|
|
|
|
(array-ref bv 2)
|
|
@result{} 2
|
|
|
|
;; Note the different argument order on array-set!.
|
|
(array-set! bv 77 2)
|
|
(array-ref bv 2)
|
|
@result{} 77
|
|
|
|
(array-type bv)
|
|
@result{} vu8
|
|
@end example
|
|
|
|
|
|
@node Bytevectors as Uniform Vectors
|
|
@subsubsection Accessing Bytevectors with the SRFI-4 API
|
|
|
|
Bytevectors may also be accessed with the SRFI-4 API. @xref{SRFI-4 and
|
|
Bytevectors}, for more information.
|
|
|
|
|
|
@node Bytevector Procedures in R7RS
|
|
@subsubsection Bytevector Procedures in R7RS
|
|
|
|
The @ref{R7RS Support,R7RS} (Section 6.9) defines a set of
|
|
bytevector manipulation procedures, accessible with
|
|
|
|
@example
|
|
(use-modules (scheme base))
|
|
@end example
|
|
|
|
Of these, @ref{x-make-bytevector,@code{make-bytevector}},
|
|
@ref{x-bytevector?,@code{bytevector?}},
|
|
@ref{x-bytevector-length,@code{bytevector-length}},
|
|
@ref{x-bytevector-u8-ref,@code{bytevector-u8-ref}} and
|
|
@ref{x-bytevector-u8-set!,@code{bytevector-u8-set!}} have the same
|
|
definition as in R6RS. The procedures listed below either have a
|
|
different definition in R7RS and R6RS, or are not defined in R6RS.
|
|
|
|
@deffn {Scheme Procedure} bytevector arg @dots{}
|
|
Return a newly allocated bytevector composed of the given arguments.
|
|
Analogous to @code{list}.
|
|
|
|
@lisp
|
|
(bytevector 2 3 4) @result{} #vu8(2 3 4)
|
|
@end lisp
|
|
|
|
See also @ref{x-u8-list->bytevector,@code{u8-list->bytevector}}.
|
|
@end deffn
|
|
|
|
@anchor{x-r7:bytevector-copy}
|
|
@deffn {Scheme Procedure} bytevector-copy bv [start [end]]
|
|
Returns a newly allocated bytevector containing the elements of @var{bv}
|
|
in the range [@var{start} ... @var{end}). @var{start} defaults to 0 and
|
|
@var{end} defaults to the length of @var{bv}.
|
|
|
|
@lisp
|
|
(define bv #vu8(0 1 2 3 4 5))
|
|
(bytevector-copy bv) @result{} #vu8(0 1 2 3 4 5)
|
|
(bytevector-copy bv 2) @result{} #vu8(2 3 4 5)
|
|
(bytevector-copy bv 2 4) @result{} #vu8(2 3)
|
|
@end lisp
|
|
|
|
See also @ref{x-r6:bytevector-copy,the R6RS version}.
|
|
@end deffn
|
|
|
|
@anchor{x-r7:bytevector-copy!}
|
|
@deffn {Scheme Procedure} bytevector-copy! dst at src [start [end]]
|
|
Copy the block of elements from bytevector @var{src} in the range
|
|
[@var{start} ... @var{end}) into bytevector @var{dst}, starting at
|
|
position @var{at}. @var{start} defaults to 0 and @var{end} defaults to
|
|
the length of @var{src}. It is an error for @var{dst}
|
|
to have a length less than @var{at} + (@var{end} - @var{start}).
|
|
|
|
See also @ref{x-r6:bytevector-copy!,the R6RS version}. With
|
|
|
|
@lisp
|
|
(use-modules ((rnrs bytevectors) #:prefix r6:)
|
|
((scheme base) #:prefix r7:))
|
|
@end lisp
|
|
|
|
the following calls are equivalent:
|
|
|
|
@lisp
|
|
(r6:bytevector-copy! source source-start target target-start len)
|
|
(r7:bytevector-copy! target target-start source source-start (+ source-start len))
|
|
@end lisp
|
|
|
|
@end deffn
|
|
|
|
@rnindex bytevector-append
|
|
@deffn {Scheme Procedure} bytevector-append arg @dots{}
|
|
Return a newly allocated bytevector whose characters form the
|
|
concatenation of the given bytevectors @var{arg} @enddots{}
|
|
|
|
@lisp
|
|
(bytevector-append #vu8(0 1 2) #vu8(3 4 5))
|
|
@result{} #vu8(0 1 2 3 4 5)
|
|
@end lisp
|
|
@end deffn
|
|
|
|
|
|
@node Bytevector Slices
|
|
@subsubsection Bytevector Slices
|
|
|
|
@cindex subset, of a bytevector
|
|
@cindex slice, of a bytevector
|
|
@cindex slice, of a uniform vector
|
|
As an extension to the R6RS specification, the @code{(rnrs bytevectors
|
|
gnu)} module provides the @code{bytevector-slice} procedure, which
|
|
returns a bytevector aliasing part of an existing bytevector.
|
|
|
|
@deffn {Scheme Procedure} bytevector-slice @var{bv} @var{offset} [@var{size}]
|
|
@deffnx {C Function} scm_bytevector_slice (@var{bv}, @var{offset}, @var{size})
|
|
Return the slice of @var{bv} starting at @var{offset} and counting
|
|
@var{size} bytes. When @var{size} is omitted, the slice covers all
|
|
of @var{bv} starting from @var{offset}. The returned slice shares
|
|
storage with @var{bv}: changes to the slice are visible in @var{bv}
|
|
and vice-versa.
|
|
|
|
When @var{bv} is actually a SRFI-4 uniform vector, its element
|
|
type is preserved unless @var{offset} and @var{size} are not aligned
|
|
on its element type size.
|
|
@end deffn
|
|
|
|
Here is an example showing how to use it:
|
|
|
|
@lisp
|
|
(use-modules (rnrs bytevectors)
|
|
(rnrs bytevectors gnu))
|
|
|
|
(define bv (u8-list->bytevector (iota 10)))
|
|
(define slice (bytevector-slice bv 2 3))
|
|
|
|
slice
|
|
@result{} #vu8(2 3 4)
|
|
|
|
(bytevector-u8-set! slice 0 77)
|
|
slice
|
|
@result{} #vu8(77 3 4)
|
|
|
|
bv
|
|
@result{} #vu8(0 1 77 3 4 5 6 7 8 9)
|
|
@end lisp
|
|
|
|
|
|
@node Arrays
|
|
@subsection Arrays
|
|
@tpindex Arrays
|
|
|
|
@dfn{Arrays} are a collection of cells organized into an arbitrary
|
|
number of dimensions. Each cell can be accessed in constant time by
|
|
supplying an index for each dimension.
|
|
|
|
In the current implementation, an array uses a vector of some kind for
|
|
the actual storage of its elements. Any kind of vector will do, so you
|
|
can have arrays of uniform numeric values, arrays of characters, arrays
|
|
of bits, and of course, arrays of arbitrary Scheme values. For example,
|
|
arrays with an underlying @code{c64vector} might be nice for digital
|
|
signal processing, while arrays made from a @code{u8vector} might be
|
|
used to hold gray-scale images.
|
|
|
|
The number of dimensions of an array is called its @dfn{rank}. Thus,
|
|
a matrix is an array of rank 2, while a vector has rank 1. When
|
|
accessing an array element, you have to specify one exact integer for
|
|
each dimension. These integers are called the @dfn{indices} of the
|
|
element. An array specifies the allowed range of indices for each
|
|
dimension via an inclusive lower and upper bound. These bounds can
|
|
well be negative, but the upper bound must be greater than or equal to
|
|
the lower bound minus one. When all lower bounds of an array are
|
|
zero, it is called a @dfn{zero-origin} array.
|
|
|
|
Arrays can be of rank 0, which could be interpreted as a scalar.
|
|
Thus, a zero-rank array can store exactly one object and the list of
|
|
indices of this element is the empty list.
|
|
|
|
Arrays contain zero elements when one of their dimensions has a zero
|
|
length. These empty arrays maintain information about their shape: a
|
|
matrix with zero columns and 3 rows is different from a matrix with 3
|
|
columns and zero rows, which again is different from a vector of
|
|
length zero.
|
|
|
|
The array procedures are all polymorphic, treating strings, uniform
|
|
numeric vectors, bytevectors, bit vectors and ordinary vectors as one
|
|
dimensional arrays.
|
|
|
|
@menu
|
|
* Array Syntax::
|
|
* Array Procedures::
|
|
* Shared Arrays::
|
|
* Arrays as arrays of arrays::
|
|
* Accessing Arrays from C::
|
|
@end menu
|
|
|
|
@node Array Syntax
|
|
@subsubsection Array Syntax
|
|
|
|
An array is displayed as @code{#} followed by its rank, followed by a
|
|
tag that describes the underlying vector, optionally followed by
|
|
information about its shape, and finally followed by the cells,
|
|
organized into dimensions using parentheses.
|
|
|
|
In more words, the array tag is of the form
|
|
|
|
@example
|
|
#<rank><vectag><@@lower><:len><@@lower><:len>...
|
|
@end example
|
|
|
|
where @code{<rank>} is a positive integer in decimal giving the rank of
|
|
the array. It is omitted when the rank is 1 and the array is non-shared
|
|
and has zero-origin (see below). For shared arrays and for a non-zero
|
|
origin, the rank is always printed even when it is 1 to distinguish
|
|
them from ordinary vectors.
|
|
|
|
The @code{<vectag>} part is the tag for a uniform numeric vector, like
|
|
@code{u8}, @code{s16}, etc, @code{b} for bitvectors, or @code{a} for
|
|
strings. It is empty for ordinary vectors.
|
|
|
|
The @code{<@@lower>} part is a @samp{@@} character followed by a signed
|
|
integer in decimal giving the lower bound of a dimension. There is one
|
|
@code{<@@lower>} for each dimension. When all lower bounds are zero,
|
|
all @code{<@@lower>} parts are omitted.
|
|
|
|
The @code{<:len>} part is a @samp{:} character followed by an unsigned
|
|
integer in decimal giving the length of a dimension. Like for the lower
|
|
bounds, there is one @code{<:len>} for each dimension, and the
|
|
@code{<:len>} part always follows the @code{<@@lower>} part for a
|
|
dimension. Lengths are only then printed when they can't be deduced
|
|
from the nested lists of elements of the array literal, which can happen
|
|
when at least one length is zero.
|
|
|
|
As a special case, an array of rank 0 is printed as
|
|
@code{#0<vectag>(<scalar>)}, where @code{<scalar>} is the result of
|
|
printing the single element of the array.
|
|
|
|
Thus,
|
|
|
|
@table @code
|
|
@item #(1 2 3)
|
|
is an ordinary array of rank 1 with lower bound 0 in dimension 0.
|
|
(I.e., a regular vector.)
|
|
|
|
@item #@@2(1 2 3)
|
|
is an ordinary array of rank 1 with lower bound 2 in dimension 0.
|
|
|
|
@item #2((1 2 3) (4 5 6))
|
|
is a non-uniform array of rank 2; a 2@cross{}3 matrix with index ranges 0..1
|
|
and 0..2.
|
|
|
|
@item #u8(0 1 2)
|
|
is a uniform u8 array of rank 1.
|
|
|
|
@item #2u32@@2@@3((1 2) (2 3))
|
|
is a uniform u32 array of rank 2 with index ranges 2..3 and 3..4.
|
|
|
|
@item #2()
|
|
is a two-dimensional array with index ranges 0..-1 and 0..-1, i.e.@:
|
|
both dimensions have length zero.
|
|
|
|
@item #2:0:2()
|
|
is a two-dimensional array with index ranges 0..-1 and 0..1, i.e.@: the
|
|
first dimension has length zero, but the second has length 2.
|
|
|
|
@item #0(12)
|
|
is a rank-zero array with contents 12.
|
|
|
|
@end table
|
|
|
|
In addition, bytevectors are also arrays, but use a different syntax
|
|
(@pxref{Bytevectors}):
|
|
|
|
@table @code
|
|
|
|
@item #vu8(1 2 3)
|
|
is a 3-byte long bytevector, with contents 1, 2, 3.
|
|
|
|
@end table
|
|
|
|
@node Array Procedures
|
|
@subsubsection Array Procedures
|
|
|
|
When an array is created, the range of each dimension must be
|
|
specified, e.g., to create a 2@cross{}3 array with a zero-based index:
|
|
|
|
@example
|
|
(make-array 'ho 2 3) @result{} #2((ho ho ho) (ho ho ho))
|
|
@end example
|
|
|
|
The range of each dimension can also be given explicitly, e.g., another
|
|
way to create the same array:
|
|
|
|
@example
|
|
(make-array 'ho '(0 1) '(0 2)) @result{} #2((ho ho ho) (ho ho ho))
|
|
@end example
|
|
|
|
The following procedures can be used with arrays (or vectors). An
|
|
argument shown as @var{idx}@dots{} means one parameter for each
|
|
dimension in the array. A @var{idxlist} argument means a list of such
|
|
values, one for each dimension.
|
|
|
|
|
|
@deffn {Scheme Procedure} array? obj
|
|
@deffnx {C Function} scm_array_p (obj, unused)
|
|
Return @code{#t} if the @var{obj} is an array, and @code{#f} if
|
|
not.
|
|
|
|
The second argument to scm_array_p is there for historical reasons,
|
|
but it is not used. You should always pass @code{SCM_UNDEFINED} as
|
|
its value.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} typed-array? obj type
|
|
@deffnx {C Function} scm_typed_array_p (obj, type)
|
|
Return @code{#t} if the @var{obj} is an array of type @var{type}, and
|
|
@code{#f} if not.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} int scm_is_array (SCM obj)
|
|
Return @code{1} if the @var{obj} is an array and @code{0} if not.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} int scm_is_typed_array (SCM obj, SCM type)
|
|
Return @code{0} if the @var{obj} is an array of type @var{type}, and
|
|
@code{1} if not.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} make-array fill bound @dots{}
|
|
@deffnx {C Function} scm_make_array (fill, bounds)
|
|
Equivalent to @code{(make-typed-array #t @var{fill} @var{bound} ...)}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} make-typed-array type fill bound @dots{}
|
|
@deffnx {C Function} scm_make_typed_array (type, fill, bounds)
|
|
Create and return an array that has as many dimensions as there are
|
|
@var{bound}s and (maybe) fill it with @var{fill}.
|
|
|
|
The underlying storage vector is created according to @var{type},
|
|
which must be a symbol whose name is the `vectag' of the array as
|
|
explained above, or @code{#t} for ordinary, non-specialized arrays.
|
|
|
|
For example, using the symbol @code{f64} for @var{type} will create an
|
|
array that uses a @code{f64vector} for storing its elements, and
|
|
@code{a} will use a string.
|
|
|
|
When @var{fill} is not the special @emph{unspecified} value, the new
|
|
array is filled with @var{fill}. Otherwise, the initial contents of
|
|
the array is unspecified. The special @emph{unspecified} value is
|
|
stored in the variable @code{*unspecified*} so that for example
|
|
@code{(make-typed-array 'u32 *unspecified* 4)} creates a uninitialized
|
|
@code{u32} vector of length 4.
|
|
|
|
Each @var{bound} may be a positive non-zero integer @var{n}, in which
|
|
case the index for that dimension can range from 0 through @var{n}-1; or
|
|
an explicit index range specifier in the form @code{(LOWER UPPER)},
|
|
where both @var{lower} and @var{upper} are integers, possibly less than
|
|
zero, and possibly the same number (however, @var{lower} cannot be
|
|
greater than @var{upper}).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list->array dimspec list
|
|
Equivalent to @code{(list->typed-array #t @var{dimspec}
|
|
@var{list})}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list->typed-array type dimspec list
|
|
@deffnx {C Function} scm_list_to_typed_array (type, dimspec, list)
|
|
Return an array of the type indicated by @var{type} with elements the
|
|
same as those of @var{list}.
|
|
|
|
The argument @var{dimspec} determines the number of dimensions of the
|
|
array and their lower bounds. When @var{dimspec} is an exact integer,
|
|
it gives the number of dimensions directly and all lower bounds are
|
|
zero. When it is a list of exact integers, then each element is the
|
|
lower index bound of a dimension, and there will be as many dimensions
|
|
as elements in the list.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-type array
|
|
@deffnx {C Function} scm_array_type (array)
|
|
Return the type of @var{array}. This is the `vectag' used for
|
|
printing @var{array} (or @code{#t} for ordinary arrays) and can be
|
|
used with @code{make-typed-array} to create an array of the same kind
|
|
as @var{array}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-ref array idx @dots{}
|
|
@deffnx {C Function} scm_array_ref (array, idxlist)
|
|
Return the element at @code{(idx @dots{})} in @var{array}.
|
|
|
|
@example
|
|
(define a (make-array 999 '(1 2) '(3 4)))
|
|
(array-ref a 2 4) @result{} 999
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-in-bounds? array idx @dots{}
|
|
@deffnx {C Function} scm_array_in_bounds_p (array, idxlist)
|
|
Return @code{#t} if the given indices would be acceptable to
|
|
@code{array-ref}.
|
|
|
|
@example
|
|
(define a (make-array #f '(1 2) '(3 4)))
|
|
(array-in-bounds? a 2 3) @result{} #t
|
|
(array-in-bounds? a 0 0) @result{} #f
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-set! array obj idx @dots{}
|
|
@deffnx {C Function} scm_array_set_x (array, obj, idxlist)
|
|
Set the element at @code{(idx @dots{})} in @var{array} to @var{obj}.
|
|
The return value is unspecified.
|
|
|
|
@example
|
|
(define a (make-array #f '(0 1) '(0 1)))
|
|
(array-set! a #t 1 1)
|
|
a @result{} #2((#f #f) (#f #t))
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-shape array
|
|
@deffnx {Scheme Procedure} array-dimensions array
|
|
@deffnx {C Function} scm_array_dimensions (array)
|
|
Return a list of the bounds for each dimension of @var{array}.
|
|
|
|
@code{array-shape} gives @code{(@var{lower} @var{upper})} for each
|
|
dimension. @code{array-dimensions} instead returns just
|
|
@math{@var{upper}+1} for dimensions with a 0 lower bound. Both are
|
|
suitable as input to @code{make-array}.
|
|
|
|
For example,
|
|
|
|
@example
|
|
(define a (make-array 'foo '(-1 3) 5))
|
|
(array-shape a) @result{} ((-1 3) (0 4))
|
|
(array-dimensions a) @result{} ((-1 3) 5)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-length array
|
|
@deffnx {C Function} scm_array_length (array)
|
|
@deffnx {C Function} size_t scm_c_array_length (array)
|
|
Return the length of an array: its first dimension. It is an error to
|
|
ask for the length of an array of rank 0.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-rank array
|
|
@deffnx {C Function} scm_array_rank (array)
|
|
Return the rank of @var{array}.
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} size_t scm_c_array_rank (SCM array)
|
|
Return the rank of @var{array} as a @code{size_t}.
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} array->list array
|
|
@deffnx {C Function} scm_array_to_list (array)
|
|
Return a list consisting of all the elements, in order, of
|
|
@var{array}.
|
|
@end deffn
|
|
|
|
@c FIXME: Describe how the order affects the copying (it matters for
|
|
@c shared arrays with the same underlying root vector, presumably).
|
|
@c
|
|
@deffn {Scheme Procedure} array-copy! src dst
|
|
@deffnx {Scheme Procedure} array-copy-in-order! src dst
|
|
@deffnx {C Function} scm_array_copy_x (src, dst)
|
|
Copy every element from vector or array @var{src} to the corresponding
|
|
element of @var{dst}. @var{dst} must have the same rank as @var{src},
|
|
and be at least as large in each dimension. The return value is
|
|
unspecified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-fill! array fill
|
|
@deffnx {C Function} scm_array_fill_x (array, fill)
|
|
Store @var{fill} in every element of @var{array}. The value returned
|
|
is unspecified.
|
|
@end deffn
|
|
|
|
@c begin (texi-doc-string "guile" "array-equal?")
|
|
@deffn {Scheme Procedure} array-equal? array @dots{}
|
|
Return @code{#t} if all arguments are arrays with the same shape, the
|
|
same type, and have corresponding elements which are either
|
|
@code{equal?} or @code{array-equal?}. This function differs from
|
|
@code{equal?} (@pxref{Equality}) in that all arguments must be arrays.
|
|
@end deffn
|
|
|
|
@c FIXME: array-for-each doesn't say what happens if the sources have
|
|
@c different index ranges. The code currently iterates over the
|
|
@c indices of the first and expects the others to cover those. That
|
|
@c at least vaguely matches array-map!, but is it meant to be a
|
|
@c documented feature?
|
|
|
|
@deffn {Scheme Procedure} array-map! dst proc src @dots{}
|
|
@deffnx {Scheme Procedure} array-map-in-order! dst proc src @dots{}
|
|
@deffnx {C Function} scm_array_map_x (dst, proc, srclist)
|
|
Set each element of the @var{dst} array to values obtained from calls to
|
|
@var{proc}. The list of @var{src} arguments may be empty. The value
|
|
returned is unspecified.
|
|
|
|
Each call is @code{(@var{proc} @var{elem} @dots{})}, where each
|
|
@var{elem} is from the corresponding @var{src} array, at the
|
|
@var{dst} index. @code{array-map-in-order!} makes the calls in
|
|
row-major order, @code{array-map!} makes them in an unspecified order.
|
|
|
|
The @var{src} arrays must have the same number of dimensions as
|
|
@var{dst}, and must have a range for each dimension which covers the
|
|
range in @var{dst}. This ensures all @var{dst} indices are valid in
|
|
each @var{src}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-for-each proc src1 src2 @dots{}
|
|
@deffnx {C Function} scm_array_for_each (proc, src1, srclist)
|
|
Apply @var{proc} to each tuple of elements of @var{src1} @var{src2}
|
|
@dots{}, in row-major order. The value returned is unspecified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-index-map! dst proc
|
|
@deffnx {C Function} scm_array_index_map_x (dst, proc)
|
|
Set each element of the @var{dst} array to values returned by calls to
|
|
@var{proc}. The value returned is unspecified.
|
|
|
|
Each call is @code{(@var{proc} @var{i1} @dots{} @var{iN})}, where
|
|
@var{i1}@dots{}@var{iN} is the destination index, one parameter for
|
|
each dimension. The order in which the calls are made is unspecified.
|
|
|
|
For example, to create a @m{4\times4, 4x4} matrix representing a
|
|
cyclic group,
|
|
|
|
@tex
|
|
\advance\leftskip by 2\lispnarrowing {
|
|
$\left(\matrix{%
|
|
0 & 1 & 2 & 3 \cr
|
|
1 & 2 & 3 & 0 \cr
|
|
2 & 3 & 0 & 1 \cr
|
|
3 & 0 & 1 & 2 \cr
|
|
}\right)$} \par
|
|
@end tex
|
|
@ifnottex
|
|
@example
|
|
/ 0 1 2 3 \
|
|
| 1 2 3 0 |
|
|
| 2 3 0 1 |
|
|
\ 3 0 1 2 /
|
|
@end example
|
|
@end ifnottex
|
|
|
|
@example
|
|
(define a (make-array #f 4 4))
|
|
(array-index-map! a (lambda (i j)
|
|
(modulo (+ i j) 4)))
|
|
@end example
|
|
@end deffn
|
|
|
|
An additional array function is available in the module
|
|
@code{(ice-9 arrays)}. It can be used with:
|
|
|
|
@example
|
|
(use-modules (ice-9 arrays))
|
|
@end example
|
|
|
|
@deffn {Scheme Procedure} array-copy src
|
|
Return a new array with the same elements, type and shape as
|
|
@var{src}. However, the array increments may not be the same as those of
|
|
@var{src}. In the current implementation, the returned array will be in
|
|
row-major order, but that might change in the future. Use
|
|
@code{array-copy!} on an array of known order if that is a concern.
|
|
@end deffn
|
|
|
|
@node Shared Arrays
|
|
@subsubsection Shared Arrays
|
|
|
|
@deffn {Scheme Procedure} make-shared-array oldarray mapfunc bound @dots{}
|
|
@deffnx {C Function} scm_make_shared_array (oldarray, mapfunc, boundlist)
|
|
Return a new array which shares the storage of @var{oldarray}.
|
|
Changes made through either affect the same underlying storage. The
|
|
@var{bound} @dots{} arguments are the shape of the new array, the same
|
|
as @code{make-array} (@pxref{Array Procedures}).
|
|
|
|
@var{mapfunc} translates coordinates from the new array to the
|
|
@var{oldarray}. It's called as @code{(@var{mapfunc} newidx1 @dots{})}
|
|
with one parameter for each dimension of the new array, and should
|
|
return a list of indices for @var{oldarray}, one for each dimension of
|
|
@var{oldarray}.
|
|
|
|
@var{mapfunc} must be affine linear, meaning that each @var{oldarray}
|
|
index must be formed by adding integer multiples (possibly negative)
|
|
of some or all of @var{newidx1} etc, plus a possible integer offset.
|
|
The multiples and offset must be the same in each call.
|
|
|
|
@sp 1
|
|
One good use for a shared array is to restrict the range of some
|
|
dimensions, so as to apply say @code{array-for-each} or
|
|
@code{array-fill!} to only part of an array. The plain @code{list}
|
|
function can be used for @var{mapfunc} in this case, making no changes
|
|
to the index values. For example,
|
|
|
|
@example
|
|
(make-shared-array #2((a b c) (d e f) (g h i)) list 3 2)
|
|
@result{} #2((a b) (d e) (g h))
|
|
@end example
|
|
|
|
The new array can have fewer dimensions than @var{oldarray}, for
|
|
example to take a column from an array.
|
|
|
|
@example
|
|
(make-shared-array #2((a b c) (d e f) (g h i))
|
|
(lambda (i) (list i 2))
|
|
'(0 2))
|
|
@result{} #1(c f i)
|
|
@end example
|
|
|
|
A diagonal can be taken by using the single new array index for both
|
|
row and column in the old array. For example,
|
|
|
|
@example
|
|
(make-shared-array #2((a b c) (d e f) (g h i))
|
|
(lambda (i) (list i i))
|
|
'(0 2))
|
|
@result{} #1(a e i)
|
|
@end example
|
|
|
|
Dimensions can be increased by for instance considering portions of a
|
|
one dimensional array as rows in a two dimensional array.
|
|
(@code{array-contents} below can do the opposite, flattening an
|
|
array.)
|
|
|
|
@example
|
|
(make-shared-array #1(a b c d e f g h i j k l)
|
|
(lambda (i j) (list (+ (* i 3) j)))
|
|
4 3)
|
|
@result{} #2((a b c) (d e f) (g h i) (j k l))
|
|
@end example
|
|
|
|
By negating an index the order that elements appear can be reversed.
|
|
The following just reverses the column order,
|
|
|
|
@example
|
|
(make-shared-array #2((a b c) (d e f) (g h i))
|
|
(lambda (i j) (list i (- 2 j)))
|
|
3 3)
|
|
@result{} #2((c b a) (f e d) (i h g))
|
|
@end example
|
|
|
|
A fixed offset on indexes allows for instance a change from a 0 based
|
|
to a 1 based array,
|
|
|
|
@example
|
|
(define x #2((a b c) (d e f) (g h i)))
|
|
(define y (make-shared-array x
|
|
(lambda (i j) (list (1- i) (1- j)))
|
|
'(1 3) '(1 3)))
|
|
(array-ref x 0 0) @result{} a
|
|
(array-ref y 1 1) @result{} a
|
|
@end example
|
|
|
|
A multiple on an index allows every Nth element of an array to be
|
|
taken. The following is every third element,
|
|
|
|
@example
|
|
(make-shared-array #1(a b c d e f g h i j k l)
|
|
(lambda (i) (list (* i 3)))
|
|
4)
|
|
@result{} #1(a d g j)
|
|
@end example
|
|
|
|
The above examples can be combined to make weird and wonderful
|
|
selections from an array, but it's important to note that because
|
|
@var{mapfunc} must be affine linear, arbitrary permutations are not
|
|
possible.
|
|
|
|
In the current implementation, @var{mapfunc} is not called for every
|
|
access to the new array but only on some sample points to establish a
|
|
base and stride for new array indices in @var{oldarray} data. A few
|
|
sample points are enough because @var{mapfunc} is linear.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} shared-array-increments array
|
|
@deffnx {C Function} scm_shared_array_increments (array)
|
|
For each dimension, return the distance between elements in the root vector.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} shared-array-offset array
|
|
@deffnx {C Function} scm_shared_array_offset (array)
|
|
Return the root vector index of the first element in the array.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} shared-array-root array
|
|
@deffnx {C Function} scm_shared_array_root (array)
|
|
Return the root vector of a shared array.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-contents array [strict]
|
|
@deffnx {C Function} scm_array_contents (array, strict)
|
|
If @var{array} may be @dfn{unrolled} into a one dimensional shared array
|
|
without changing their order (last subscript changing fastest), then
|
|
@code{array-contents} returns that shared array, otherwise it returns
|
|
@code{#f}. All arrays made by @code{make-array} and
|
|
@code{make-typed-array} may be unrolled, some arrays made by
|
|
@code{make-shared-array} may not be.
|
|
|
|
If the optional argument @var{strict} is provided, a shared array will
|
|
be returned only if its elements are stored internally contiguous in
|
|
memory.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} transpose-array array dim1 dim2 @dots{}
|
|
@deffnx {C Function} scm_transpose_array (array, dimlist)
|
|
Return an array sharing contents with @var{array}, but with
|
|
dimensions arranged in a different order. There must be one
|
|
@var{dim} argument for each dimension of @var{array}.
|
|
@var{dim1}, @var{dim2}, @dots{} should be integers between 0
|
|
and the rank of the array to be returned. Each integer in that
|
|
range must appear at least once in the argument list.
|
|
|
|
The values of @var{dim1}, @var{dim2}, @dots{} correspond to
|
|
dimensions in the array to be returned, and their positions in the
|
|
argument list to dimensions of @var{array}. Several @var{dim}s
|
|
may have the same value, in which case the returned array will
|
|
have smaller rank than @var{array}.
|
|
|
|
@lisp
|
|
(transpose-array '#2((a b) (c d)) 1 0) @result{} #2((a c) (b d))
|
|
(transpose-array '#2((a b) (c d)) 0 0) @result{} #1(a d)
|
|
(transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) @result{}
|
|
#2((a 4) (b 5) (c 6))
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@node Arrays as arrays of arrays
|
|
@subsubsection Arrays as arrays of arrays
|
|
|
|
@cindex array cell
|
|
|
|
One can see an array of rank @math{n} (an
|
|
@math{n}-array) as an array of lower rank where the elements are
|
|
themselves arrays (`cells').
|
|
|
|
@cindex array frame
|
|
@cindex frame rank
|
|
|
|
We speak of the first @math{n-k} dimensions of the array as the
|
|
@math{n-k}-`frame' of the array, while the last @math{k} dimensions are
|
|
the dimensions of the @math{k}-`cells'. For example, a 3-array can be
|
|
seen as a 2-array of vectors (1-arrays) or as a 1-array of matrices
|
|
(2-arrays). In each case, the vectors or matrices are the 1-cells or
|
|
2-cells of the array. This terminology originates in the J language.
|
|
|
|
@cindex array slice
|
|
@cindex prefix slice
|
|
|
|
The more vague concept of a `slice' refers to a subset of the array
|
|
where some indices are fixed and others are left free. As a Guile data
|
|
object, a cell is the same as a `prefix slice' (the first @math{n-k}
|
|
indices into the original array are fixed), except that a 0-cell is not
|
|
a shared array of the original array, but a 0-slice (where all the
|
|
indices into the original array are fixed) is.
|
|
|
|
@cindex enclosed array
|
|
|
|
Before @w{version 2.0}, Guile had a feature called `enclosed arrays' to
|
|
create special `array of arrays' objects. The functions in this section
|
|
do not need special types; instead, the frame rank is stated in each
|
|
function call, either implicitly or explicitly.
|
|
|
|
@deffn {Scheme Procedure} array-cell-ref array idx @dots{}
|
|
@deffnx {C Function} scm_array_cell_ref (array, idxlist)
|
|
If the length of @var{idxlist} equals the rank @math{n} of @var{array},
|
|
return the element at @code{(idx @dots{})}, just like @code{(array-ref
|
|
array idx @dots{})}. If, however, the length @math{k} of @var{idxlist}
|
|
is smaller than @math{n}, then return the @math{(n-k)}-cell of
|
|
@var{array} given by @var{idxlist}, as a shared array.
|
|
|
|
For example:
|
|
|
|
@lisp
|
|
(array-cell-ref #2((a b) (c d)) 0) @result{} #(a b)
|
|
(array-cell-ref #2((a b) (c d)) 1) @result{} #(c d)
|
|
(array-cell-ref #2((a b) (c d)) 1 1) @result{} d
|
|
(array-cell-ref #2((a b) (c d))) @result{} #2((a b) (c d))
|
|
@end lisp
|
|
|
|
@code{(apply array-cell-ref array indices)} is equivalent to
|
|
|
|
@lisp
|
|
(let ((len (length indices)))
|
|
(if (= (array-rank a) len)
|
|
(apply array-ref a indices)
|
|
(apply make-shared-array a
|
|
(lambda t (append indices t))
|
|
(drop (array-dimensions a) len))))
|
|
@end lisp
|
|
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-slice array idx @dots{}
|
|
@deffnx {C Function} scm_array_slice (array, idxlist)
|
|
Like @code{(array-cell-ref array idx @dots{})}, but return a 0-rank
|
|
shared array into @var{ARRAY} if the length of @var{idxlist} matches the
|
|
rank of @var{array}. This can be useful when using @var{ARRAY} as a
|
|
place to write to.
|
|
|
|
Compare:
|
|
|
|
@lisp
|
|
(array-cell-ref #2((a b) (c d)) 1 1) @result{} d
|
|
(array-slice #2((a b) (c d)) 1 1) @result{} #0(d)
|
|
(define a (make-array 'a 2 2))
|
|
(array-fill! (array-slice a 1 1) 'b)
|
|
a @result{} #2((a a) (a b)).
|
|
(array-fill! (array-cell-ref a 1 1) 'b) @result{} error: not an array
|
|
@end lisp
|
|
|
|
@code{(apply array-slice array indices)} is equivalent to
|
|
|
|
@lisp
|
|
(apply make-shared-array a
|
|
(lambda t (append indices t))
|
|
(drop (array-dimensions a) (length indices)))
|
|
@end lisp
|
|
@end deffn
|
|
|
|
|
|
@deffn {Scheme Procedure} array-cell-set! array x idx @dots{}
|
|
@deffnx {C Function} scm_array_cell_set_x (array, x, idxlist)
|
|
If the length of @var{idxlist} equals the rank @math{n} of
|
|
@var{array}, set the element at @code{(idx @dots{})} of @var{array} to
|
|
@var{x}, just like @code{(array-set! array x idx @dots{})}. If,
|
|
however, the length @math{k} of @var{idxlist} is smaller than
|
|
@math{n}, then copy the @math{(n-k)}-rank array @var{x}
|
|
into the @math{(n-k)}-cell of @var{array} given by
|
|
@var{idxlist}. In this case, the last @math{(n-k)} dimensions of
|
|
@var{array} and the dimensions of @var{x} must match exactly.
|
|
|
|
This function returns the modified @var{array}.
|
|
|
|
For example:
|
|
|
|
@lisp
|
|
(array-cell-set! (make-array 'a 2 2) b 1 1)
|
|
@result{} #2((a a) (a b))
|
|
(array-cell-set! (make-array 'a 2 2) #(x y) 1)
|
|
@result{} #2((a a) (x y))
|
|
@end lisp
|
|
|
|
Note that @code{array-cell-set!} will expect elements, not arrays, when
|
|
the destination has rank 0. Use @code{array-slice} for the opposite
|
|
behavior.
|
|
|
|
@lisp
|
|
(array-cell-set! (make-array 'a 2 2) #0(b) 1 1)
|
|
@result{} #2((a a) (a #0(b)))
|
|
(let ((a (make-array 'a 2 2)))
|
|
(array-copy! #0(b) (array-slice a 1 1)) a)
|
|
@result{} #2((a a) (a b))
|
|
@end lisp
|
|
|
|
@code{(apply array-cell-set! array x indices)} is equivalent to
|
|
|
|
@lisp
|
|
(let ((len (length indices)))
|
|
(if (= (array-rank array) len)
|
|
(apply array-set! array x indices)
|
|
(array-copy! x (apply array-cell-ref array indices)))
|
|
array)
|
|
@end lisp
|
|
|
|
@end deffn
|
|
|
|
|
|
@deffn {Scheme Procedure} array-slice-for-each frame-rank op x @dots{}
|
|
@deffnx {C Function} scm_array_slice_for_each (array, frame_rank, op, xlist)
|
|
Each @var{x} must be an array of rank ≥ @var{frame-rank}, and
|
|
the first @var{frame-rank} dimensions of each @var{x} must all be the
|
|
same. @var{array-slice-for-each} calls @var{op} with each set of
|
|
(rank(@var{x}) - @var{frame-rank})-cells from @var{x}, in unspecified order.
|
|
|
|
@var{array-slice-for-each} allows you to loop over cells of any rank
|
|
without having to carry an index list or construct shared arrays
|
|
manually. The slices passed to @var{op} are always shared arrays of
|
|
@var{X}, even if they are of rank 0, so it is possible to write to them.
|
|
|
|
This function returns an unspecified value.
|
|
|
|
For example, to sort the rows of rank-2 array @code{a}:
|
|
|
|
@lisp
|
|
(array-slice-for-each 1 (lambda (x) (sort! x <)) a)
|
|
@end lisp
|
|
|
|
As another example, let @code{a} be a rank-2 array where each row is a
|
|
2-element vector @math{(x,y)}. Let's compute the arguments of these
|
|
vectors and store them in rank-1 array @code{b}.
|
|
@lisp
|
|
(array-slice-for-each 1
|
|
(lambda (a b)
|
|
(array-set! b (atan (array-ref a 1) (array-ref a 0))))
|
|
a b)
|
|
@end lisp
|
|
|
|
@code{(apply array-slice-for-each frame-rank op x)} is equivalent to
|
|
|
|
@lisp
|
|
(let ((frame (take (array-dimensions (car x)) frank)))
|
|
(unless (every (lambda (x)
|
|
(equal? frame (take (array-dimensions x) frank)))
|
|
(cdr x))
|
|
(error))
|
|
(array-index-map!
|
|
(apply make-shared-array (make-array #t) (const '()) frame)
|
|
(lambda i (apply op (map (lambda (x) (apply array-slice x i)) x)))))
|
|
@end lisp
|
|
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} array-slice-for-each-in-order frame-rank op x @dots{}
|
|
@deffnx {C Function} scm_array_slice_for_each_in_order (array, frame_rank, op, xlist)
|
|
Same as @code{array-slice-for-each}, but the arguments are traversed
|
|
sequentially and in row-major order.
|
|
@end deffn
|
|
|
|
@node Accessing Arrays from C
|
|
@subsubsection Accessing Arrays from C
|
|
|
|
For interworking with external C code, Guile provides an API to allow C
|
|
code to access the elements of a Scheme array. In particular, for
|
|
uniform numeric arrays, the API exposes the underlying uniform data as a
|
|
C array of numbers of the relevant type.
|
|
|
|
While pointers to the elements of an array are in use, the array itself
|
|
must be protected so that the pointer remains valid. Such a protected
|
|
array is said to be @dfn{reserved}. A reserved array can be read but
|
|
modifications to it that would cause the pointer to its elements to
|
|
become invalid are prevented. When you attempt such a modification, an
|
|
error is signaled.
|
|
|
|
(This is similar to locking the array while it is in use, but without
|
|
the danger of a deadlock. In a multi-threaded program, you will need
|
|
additional synchronization to avoid modifying reserved arrays.)
|
|
|
|
You must take care to always unreserve an array after reserving it,
|
|
even in the presence of non-local exits. If a non-local exit can
|
|
happen between these two calls, you should install a dynwind context
|
|
that releases the array when it is left (@pxref{Dynamic Wind}).
|
|
|
|
In addition, array reserving and unreserving must be properly
|
|
paired. For instance, when reserving two or more arrays in a certain
|
|
order, you need to unreserve them in the opposite order.
|
|
|
|
Once you have reserved an array and have retrieved the pointer to its
|
|
elements, you must figure out the layout of the elements in memory.
|
|
Guile allows slices to be taken out of arrays without actually making a
|
|
copy, such as making an alias for the diagonal of a matrix that can be
|
|
treated as a vector. Arrays that result from such an operation are not
|
|
stored contiguously in memory and when working with their elements
|
|
directly, you need to take this into account.
|
|
|
|
The layout of array elements in memory can be defined via a
|
|
@emph{mapping function} that computes a scalar position from a vector of
|
|
indices. The scalar position then is the offset of the element with the
|
|
given indices from the start of the storage block of the array.
|
|
|
|
In Guile, this mapping function is restricted to be @dfn{affine}: all
|
|
mapping functions of Guile arrays can be written as @code{p = b +
|
|
c[0]*i[0] + c[1]*i[1] + ... + c[n-1]*i[n-1]} where @code{i[k]} is the
|
|
@nicode{k}th index and @code{n} is the rank of the array. For
|
|
example, a matrix of size 3x3 would have @code{b == 0}, @code{c[0] ==
|
|
3} and @code{c[1] == 1}. When you transpose this matrix (with
|
|
@code{transpose-array}, say), you will get an array whose mapping
|
|
function has @code{b == 0}, @code{c[0] == 1} and @code{c[1] == 3}.
|
|
|
|
The function @code{scm_array_handle_dims} gives you (indirect) access to
|
|
the coefficients @code{c[k]}.
|
|
|
|
@c XXX
|
|
Note that there are no functions for accessing the elements of a
|
|
character array yet. Once the string implementation of Guile has been
|
|
changed to use Unicode, we will provide them.
|
|
|
|
@deftp {C Type} scm_t_array_handle
|
|
This is a structure type that holds all information necessary to manage
|
|
the reservation of arrays as explained above. Structures of this type
|
|
must be allocated on the stack and must only be accessed by the
|
|
functions listed below.
|
|
@end deftp
|
|
|
|
@deftypefn {C Function} void scm_array_get_handle (SCM array, scm_t_array_handle *handle)
|
|
Reserve @var{array}, which must be an array, and prepare @var{handle} to
|
|
be used with the functions below. You must eventually call
|
|
@code{scm_array_handle_release} on @var{handle}, and do this in a
|
|
properly nested fashion, as explained above. The structure pointed to
|
|
by @var{handle} does not need to be initialized before calling this
|
|
function.
|
|
@end deftypefn
|
|
|
|
@anchor{x-scm_array_handle_release}
|
|
@deftypefn {C Function} void scm_array_handle_release (scm_t_array_handle *handle)
|
|
End the array reservation represented by @var{handle}. After a call to
|
|
this function, @var{handle} might be used for another reservation.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} size_t scm_array_handle_rank (scm_t_array_handle *handle)
|
|
Return the rank of the array represented by @var{handle}.
|
|
@end deftypefn
|
|
|
|
@deftp {C Type} scm_t_array_dim
|
|
This structure type holds information about the layout of one dimension
|
|
of an array. It includes the following fields:
|
|
|
|
@table @code
|
|
@item ssize_t lbnd
|
|
@itemx ssize_t ubnd
|
|
The lower and upper bounds (both inclusive) of the permissible index
|
|
range for the given dimension. Both values can be negative, but
|
|
@var{lbnd} is always less than or equal to @var{ubnd}.
|
|
|
|
@item ssize_t inc
|
|
The distance from one element of this dimension to the next. Note, too,
|
|
that this can be negative.
|
|
@end table
|
|
@end deftp
|
|
|
|
@deftypefn {C Function} {const scm_t_array_dim *} scm_array_handle_dims (scm_t_array_handle *handle)
|
|
Return a pointer to a C vector of information about the dimensions of
|
|
the array represented by @var{handle}. This pointer is valid as long as
|
|
the array remains reserved. As explained above, the
|
|
@code{scm_t_array_dim} structures returned by this function can be used
|
|
calculate the position of an element in the storage block of the array
|
|
from its indices.
|
|
|
|
This position can then be used as an index into the C array pointer
|
|
returned by the various @code{scm_array_handle_<foo>_elements}
|
|
functions, or with @code{scm_array_handle_ref} and
|
|
@code{scm_array_handle_set}.
|
|
|
|
Here is how one can compute the position @var{pos} of an element given
|
|
its indices in the vector @var{indices}:
|
|
|
|
@example
|
|
ssize_t indices[RANK];
|
|
scm_t_array_dim *dims;
|
|
ssize_t pos;
|
|
size_t i;
|
|
|
|
pos = 0;
|
|
for (i = 0; i < RANK; i++)
|
|
@{
|
|
if (indices[i] < dims[i].lbnd || indices[i] > dims[i].ubnd)
|
|
out_of_range ();
|
|
pos += (indices[i] - dims[i].lbnd) * dims[i].inc;
|
|
@}
|
|
@end example
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} ssize_t scm_array_handle_pos (scm_t_array_handle *handle, SCM indices)
|
|
Compute the position corresponding to @var{indices}, a list of
|
|
indices. The position is computed as described above for
|
|
@code{scm_array_handle_dims}. The number of the indices and their
|
|
range is checked and an appropriate error is signaled for invalid
|
|
indices.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} SCM scm_array_handle_ref (scm_t_array_handle *handle, ssize_t pos)
|
|
Return the element at position @var{pos} in the storage block of the
|
|
array represented by @var{handle}. Any kind of array is acceptable. No
|
|
range checking is done on @var{pos}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} void scm_array_handle_set (scm_t_array_handle *handle, ssize_t pos, SCM val)
|
|
Set the element at position @var{pos} in the storage block of the array
|
|
represented by @var{handle} to @var{val}. Any kind of array is
|
|
acceptable. No range checking is done on @var{pos}. An error is
|
|
signaled when the array can not store @var{val}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {const SCM *} scm_array_handle_elements (scm_t_array_handle *handle)
|
|
Return a pointer to the elements of a ordinary array of general Scheme
|
|
values (i.e., a non-uniform array) for reading. This pointer is valid
|
|
as long as the array remains reserved.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {SCM *} scm_array_handle_writable_elements (scm_t_array_handle *handle)
|
|
Like @code{scm_array_handle_elements}, but the pointer is good for
|
|
reading and writing.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {const void *} scm_array_handle_uniform_elements (scm_t_array_handle *handle)
|
|
Return a pointer to the elements of a uniform numeric array for reading.
|
|
This pointer is valid as long as the array remains reserved. The size
|
|
of each element is given by @code{scm_array_handle_uniform_element_size}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {void *} scm_array_handle_uniform_writable_elements (scm_t_array_handle *handle)
|
|
Like @code{scm_array_handle_uniform_elements}, but the pointer is good
|
|
reading and writing.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} size_t scm_array_handle_uniform_element_size (scm_t_array_handle *handle)
|
|
Return the size of one element of the uniform numeric array represented
|
|
by @var{handle}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {const scm_t_uint8 *} scm_array_handle_u8_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {const scm_t_int8 *} scm_array_handle_s8_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {const scm_t_uint16 *} scm_array_handle_u16_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {const scm_t_int16 *} scm_array_handle_s16_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {const scm_t_uint32 *} scm_array_handle_u32_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {const scm_t_int32 *} scm_array_handle_s32_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {const scm_t_uint64 *} scm_array_handle_u64_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {const scm_t_int64 *} scm_array_handle_s64_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {const float *} scm_array_handle_f32_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {const double *} scm_array_handle_f64_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {const float *} scm_array_handle_c32_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {const double *} scm_array_handle_c64_elements (scm_t_array_handle *handle)
|
|
Return a pointer to the elements of a uniform numeric array of the
|
|
indicated kind for reading. This pointer is valid as long as the array
|
|
remains reserved.
|
|
|
|
The pointers for @code{c32} and @code{c64} uniform numeric arrays point
|
|
to pairs of floating point numbers. The even index holds the real part,
|
|
the odd index the imaginary part of the complex number.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {scm_t_uint8 *} scm_array_handle_u8_writable_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {scm_t_int8 *} scm_array_handle_s8_writable_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {scm_t_uint16 *} scm_array_handle_u16_writable_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {scm_t_int16 *} scm_array_handle_s16_writable_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {scm_t_uint32 *} scm_array_handle_u32_writable_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {scm_t_int32 *} scm_array_handle_s32_writable_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {scm_t_uint64 *} scm_array_handle_u64_writable_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {scm_t_int64 *} scm_array_handle_s64_writable_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {float *} scm_array_handle_f32_writable_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {double *} scm_array_handle_f64_writable_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {float *} scm_array_handle_c32_writable_elements (scm_t_array_handle *handle)
|
|
@deftypefnx {C Function} {double *} scm_array_handle_c64_writable_elements (scm_t_array_handle *handle)
|
|
Like @code{scm_array_handle_<kind>_elements}, but the pointer is good
|
|
for reading and writing.
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {const scm_t_uint32 *} scm_array_handle_bit_elements (scm_t_array_handle *handle)
|
|
Return a pointer to the words that store the bits of the represented
|
|
array, which must be a bit array.
|
|
|
|
Unlike other arrays, bit arrays have an additional offset that must be
|
|
figured into index calculations. That offset is returned by
|
|
@code{scm_array_handle_bit_elements_offset}.
|
|
|
|
To find a certain bit you first need to calculate its position as
|
|
explained above for @code{scm_array_handle_dims} and then add the
|
|
offset. This gives the absolute position of the bit, which is always a
|
|
non-negative integer.
|
|
|
|
Each word of the bit array storage block contains exactly 32 bits, with
|
|
the least significant bit in that word having the lowest absolute
|
|
position number. The next word contains the next 32 bits.
|
|
|
|
Thus, the following code can be used to access a bit whose position
|
|
according to @code{scm_array_handle_dims} is given in @var{pos}:
|
|
|
|
@example
|
|
SCM bit_array;
|
|
scm_t_array_handle handle;
|
|
scm_t_uint32 *bits;
|
|
ssize_t pos;
|
|
size_t abs_pos;
|
|
size_t word_pos, mask;
|
|
|
|
scm_array_get_handle (&bit_array, &handle);
|
|
bits = scm_array_handle_bit_elements (&handle);
|
|
|
|
pos = ...
|
|
abs_pos = pos + scm_array_handle_bit_elements_offset (&handle);
|
|
word_pos = abs_pos / 32;
|
|
mask = 1L << (abs_pos % 32);
|
|
|
|
if (bits[word_pos] & mask)
|
|
/* bit is set. */
|
|
|
|
scm_array_handle_release (&handle);
|
|
@end example
|
|
|
|
@end deftypefn
|
|
|
|
@deftypefn {C Function} {scm_t_uint32 *} scm_array_handle_bit_writable_elements (scm_t_array_handle *handle)
|
|
Like @code{scm_array_handle_bit_elements} but the pointer is good for
|
|
reading and writing. You must take care not to modify bits outside of
|
|
the allowed index range of the array, even for contiguous arrays.
|
|
@end deftypefn
|
|
|
|
@node VLists
|
|
@subsection VLists
|
|
|
|
@cindex vlist
|
|
|
|
The @code{(ice-9 vlist)} module provides an implementation of the @dfn{VList}
|
|
data structure designed by Phil Bagwell in 2002. VLists are immutable lists,
|
|
which can contain any Scheme object. They improve on standard Scheme linked
|
|
lists in several areas:
|
|
|
|
@itemize
|
|
@item
|
|
Random access has typically constant-time complexity.
|
|
|
|
@item
|
|
Computing the length of a VList has time complexity logarithmic in the number of
|
|
elements.
|
|
|
|
@item
|
|
VLists use less storage space than standard lists.
|
|
|
|
@item
|
|
VList elements are stored in contiguous regions, which improves memory locality
|
|
and leads to more efficient use of hardware caches.
|
|
@end itemize
|
|
|
|
The idea behind VLists is to store vlist elements in increasingly large
|
|
contiguous blocks (implemented as vectors here). These blocks are linked to one
|
|
another using a pointer to the next block and an offset within that block. The
|
|
size of these blocks form a geometric series with ratio
|
|
@code{block-growth-factor} (2 by default).
|
|
|
|
The VList structure also serves as the basis for the @dfn{VList-based hash
|
|
lists} or ``vhashes'', an immutable dictionary type (@pxref{VHashes}).
|
|
|
|
However, the current implementation in @code{(ice-9 vlist)} has several
|
|
noteworthy shortcomings:
|
|
|
|
@itemize
|
|
|
|
@item
|
|
It is @emph{not} thread-safe. Although operations on vlists are all
|
|
@dfn{referentially transparent} (i.e., purely functional), adding elements to a
|
|
vlist with @code{vlist-cons} mutates part of its internal structure, which makes
|
|
it non-thread-safe. This could be fixed, but it would slow down
|
|
@code{vlist-cons}.
|
|
|
|
@item
|
|
@code{vlist-cons} always allocates at least as much memory as @code{cons}.
|
|
Again, Phil Bagwell describes how to fix it, but that would require tuning the
|
|
garbage collector in a way that may not be generally beneficial.
|
|
|
|
@item
|
|
@code{vlist-cons} is a Scheme procedure compiled to bytecode, and it does not
|
|
compete with the straightforward C implementation of @code{cons}, and with the
|
|
fact that the VM has a special @code{cons} instruction.
|
|
|
|
@end itemize
|
|
|
|
We hope to address these in the future.
|
|
|
|
The programming interface exported by @code{(ice-9 vlist)} is defined below.
|
|
Most of it is the same as SRFI-1 with an added @code{vlist-} prefix to function
|
|
names.
|
|
|
|
@deffn {Scheme Procedure} vlist? obj
|
|
Return true if @var{obj} is a VList.
|
|
@end deffn
|
|
|
|
@defvr {Scheme Variable} vlist-null
|
|
The empty VList. Note that it's possible to create an empty VList not
|
|
@code{eq?} to @code{vlist-null}; thus, callers should always use
|
|
@code{vlist-null?} when testing whether a VList is empty.
|
|
@end defvr
|
|
|
|
@deffn {Scheme Procedure} vlist-null? vlist
|
|
Return true if @var{vlist} is empty.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-cons item vlist
|
|
Return a new vlist with @var{item} as its head and @var{vlist} as its tail.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-head vlist
|
|
Return the head of @var{vlist}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-tail vlist
|
|
Return the tail of @var{vlist}.
|
|
@end deffn
|
|
|
|
@defvr {Scheme Variable} block-growth-factor
|
|
A fluid that defines the growth factor of VList blocks, 2 by default.
|
|
@end defvr
|
|
|
|
The functions below provide the usual set of higher-level list operations.
|
|
|
|
@deffn {Scheme Procedure} vlist-fold proc init vlist
|
|
@deffnx {Scheme Procedure} vlist-fold-right proc init vlist
|
|
Fold over @var{vlist}, calling @var{proc} for each element, as for SRFI-1
|
|
@code{fold} and @code{fold-right} (@pxref{SRFI-1, @code{fold}}).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-ref vlist index
|
|
Return the element at index @var{index} in @var{vlist}. This is typically a
|
|
constant-time operation.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-length vlist
|
|
Return the length of @var{vlist}. This is typically logarithmic in the number
|
|
of elements in @var{vlist}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-reverse vlist
|
|
Return a new @var{vlist} whose content are those of @var{vlist} in reverse
|
|
order.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-map proc vlist
|
|
Map @var{proc} over the elements of @var{vlist} and return a new vlist.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-for-each proc vlist
|
|
Call @var{proc} on each element of @var{vlist}. The result is unspecified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-drop vlist count
|
|
Return a new vlist that does not contain the @var{count} first elements of
|
|
@var{vlist}. This is typically a constant-time operation.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-take vlist count
|
|
Return a new vlist that contains only the @var{count} first elements of
|
|
@var{vlist}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-filter pred vlist
|
|
Return a new vlist containing all the elements from @var{vlist} that satisfy
|
|
@var{pred}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-delete x vlist [equal?]
|
|
Return a new vlist corresponding to @var{vlist} without the elements
|
|
@var{equal?} to @var{x}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-unfold p f g seed [tail-gen]
|
|
@deffnx {Scheme Procedure} vlist-unfold-right p f g seed [tail]
|
|
Return a new vlist, as for SRFI-1 @code{unfold} and @code{unfold-right}
|
|
(@pxref{SRFI-1, @code{unfold}}).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist-append vlist @dots{}
|
|
Append the given vlists and return the resulting vlist.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} list->vlist lst
|
|
Return a new vlist whose contents correspond to @var{lst}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vlist->list vlist
|
|
Return a new list whose contents match those of @var{vlist}.
|
|
@end deffn
|
|
|
|
@node Record Overview
|
|
@subsection Record Overview
|
|
|
|
@cindex record
|
|
@cindex structure
|
|
|
|
@dfn{Records}, also called @dfn{structures}, are Scheme's primary
|
|
mechanism to define new disjoint types. A @dfn{record type} defines a
|
|
list of @dfn{fields} that instances of the type consist of. This is like
|
|
C's @code{struct}.
|
|
|
|
Historically, Guile has offered several different ways to define record
|
|
types and to create records, offering different features, and making
|
|
different trade-offs. Over the years, each ``standard'' has also come
|
|
with its own new record interface, leading to a maze of record APIs.
|
|
|
|
At the highest level is SRFI-9, a high-level record interface
|
|
implemented by most Scheme implementations (@pxref{SRFI-9 Records}). It
|
|
defines a simple and efficient syntactic abstraction of record types and
|
|
their associated type predicate, fields, and field accessors. SRFI-9 is
|
|
suitable for most uses, and this is the recommended way to create record
|
|
types in Guile. Similar high-level record APIs include SRFI-35
|
|
(@pxref{SRFI-35}) and R6RS records (@pxref{rnrs records syntactic}).
|
|
|
|
Then comes Guile's historical ``records'' API (@pxref{Records}). Record
|
|
types defined this way are first-class objects. Introspection
|
|
facilities are available, allowing users to query the list of fields or
|
|
the value of a specific field at run-time, without prior knowledge of
|
|
the type.
|
|
|
|
Finally, the common denominator of these interfaces is Guile's
|
|
@dfn{structure} API (@pxref{Structures}). Guile's structures are the
|
|
low-level building block for all other record APIs. Application writers
|
|
will normally not need to use it.
|
|
|
|
Records created with these APIs may all be pattern-matched using Guile's
|
|
standard pattern matcher (@pxref{Pattern Matching}).
|
|
|
|
|
|
@node SRFI-9 Records
|
|
@subsection SRFI-9 Records
|
|
|
|
@cindex SRFI-9
|
|
@cindex record
|
|
|
|
SRFI-9 standardizes a syntax for defining new record types and creating
|
|
predicate, constructor, and field getter and setter functions. In Guile
|
|
this is the recommended option to create new record types (@pxref{Record
|
|
Overview}). It can be used with:
|
|
|
|
@example
|
|
(use-modules (srfi srfi-9))
|
|
@end example
|
|
|
|
@deffn {Scheme Syntax} define-record-type type @* (constructor fieldname @dots{}) @* predicate @* (fieldname accessor [modifier]) @dots{}
|
|
@sp 1
|
|
Create a new record type, and make various @code{define}s for using
|
|
it. This syntax can only occur at the top-level, not nested within
|
|
some other form.
|
|
|
|
@var{type} is bound to the record type, which is as per the return
|
|
from the core @code{make-record-type}. @var{type} also provides the
|
|
name for the record, as per @code{record-type-name}.
|
|
|
|
@var{constructor} is bound to a function to be called as
|
|
@code{(@var{constructor} fieldval @dots{})} to create a new record of
|
|
this type. The arguments are initial values for the fields, one
|
|
argument for each field, in the order they appear in the
|
|
@code{define-record-type} form.
|
|
|
|
The @var{fieldname}s provide the names for the record fields, as per
|
|
the core @code{record-type-fields} etc, and are referred to in the
|
|
subsequent accessor/modifier forms.
|
|
|
|
@var{predicate} is bound to a function to be called as
|
|
@code{(@var{predicate} obj)}. It returns @code{#t} or @code{#f}
|
|
according to whether @var{obj} is a record of this type.
|
|
|
|
Each @var{accessor} is bound to a function to be called
|
|
@code{(@var{accessor} record)} to retrieve the respective field from a
|
|
@var{record}. Similarly each @var{modifier} is bound to a function to
|
|
be called @code{(@var{modifier} record val)} to set the respective
|
|
field in a @var{record}.
|
|
@end deffn
|
|
|
|
@noindent
|
|
An example will illustrate typical usage,
|
|
|
|
@example
|
|
(define-record-type <employee>
|
|
(make-employee name age salary)
|
|
employee?
|
|
(name employee-name)
|
|
(age employee-age set-employee-age!)
|
|
(salary employee-salary set-employee-salary!))
|
|
@end example
|
|
|
|
This creates a new employee data type, with name, age and salary
|
|
fields. Accessor functions are created for each field, but no
|
|
modifier function for the name (the intention in this example being
|
|
that it's established only when an employee object is created). These
|
|
can all then be used as for example,
|
|
|
|
@example
|
|
<employee> @result{} #<record-type <employee>>
|
|
|
|
(define fred (make-employee "Fred" 45 20000.00))
|
|
|
|
(employee? fred) @result{} #t
|
|
(employee-age fred) @result{} 45
|
|
(set-employee-salary! fred 25000.00) ;; pay rise
|
|
@end example
|
|
|
|
The functions created by @code{define-record-type} are ordinary
|
|
top-level @code{define}s. They can be redefined or @code{set!} as
|
|
desired, exported from a module, etc.
|
|
|
|
@unnumberedsubsubsec Non-toplevel Record Definitions
|
|
|
|
The SRFI-9 specification explicitly disallows record definitions in a
|
|
non-toplevel context, such as inside @code{lambda} body or inside a
|
|
@var{let} block. However, Guile's implementation does not enforce that
|
|
restriction.
|
|
|
|
@unnumberedsubsubsec Custom Printers
|
|
|
|
You may use @code{set-record-type-printer!} to customize the default printing
|
|
behavior of records. This is a Guile extension and is not part of SRFI-9. It
|
|
is located in the @nicode{(srfi srfi-9 gnu)} module.
|
|
|
|
@deffn {Scheme Syntax} set-record-type-printer! type proc
|
|
Where @var{type} corresponds to the first argument of @code{define-record-type},
|
|
and @var{proc} is a procedure accepting two arguments, the record to print, and
|
|
an output port.
|
|
@end deffn
|
|
|
|
@noindent
|
|
This example prints the employee's name in brackets, for instance @code{[Fred]}.
|
|
|
|
@example
|
|
(set-record-type-printer! <employee>
|
|
(lambda (record port)
|
|
(write-char #\[ port)
|
|
(display (employee-name record) port)
|
|
(write-char #\] port)))
|
|
@end example
|
|
|
|
@unnumberedsubsubsec Functional ``Setters''
|
|
|
|
@cindex functional setters
|
|
|
|
When writing code in a functional style, it is desirable to never alter
|
|
the contents of records. For such code, a simple way to return new
|
|
record instances based on existing ones is highly desirable.
|
|
|
|
The @code{(srfi srfi-9 gnu)} module extends SRFI-9 with facilities to
|
|
return new record instances based on existing ones, only with one or
|
|
more field values changed---@dfn{functional setters}. First, the
|
|
@code{define-immutable-record-type} works like
|
|
@code{define-record-type}, except that fields are immutable and setters
|
|
are defined as functional setters.
|
|
|
|
@deffn {Scheme Syntax} define-immutable-record-type type @* (constructor fieldname @dots{}) @* predicate @* (fieldname accessor [modifier]) @dots{}
|
|
Define @var{type} as a new record type, like @code{define-record-type}.
|
|
However, the record type is made @emph{immutable} (records may not be
|
|
mutated, even with @code{struct-set!}), and any @var{modifier} is
|
|
defined to be a functional setter---a procedure that returns a new
|
|
record instance with the specified field changed, and leaves the
|
|
original unchanged (see example below.)
|
|
@end deffn
|
|
|
|
@noindent
|
|
In addition, the generic @code{set-field} and @code{set-fields} macros
|
|
may be applied to any SRFI-9 record.
|
|
|
|
@deffn {Scheme Syntax} set-field record (field sub-fields ...) value
|
|
Return a new record of @var{record}'s type whose fields are equal to
|
|
the corresponding fields of @var{record} except for the one specified by
|
|
@var{field}.
|
|
|
|
@var{field} must be the name of the getter corresponding to the field of
|
|
@var{record} being ``set''. Subsequent @var{sub-fields} must be record
|
|
getters designating sub-fields within that field value to be set (see
|
|
example below.)
|
|
@end deffn
|
|
|
|
@deffn {Scheme Syntax} set-fields record ((field sub-fields ...) value) ...
|
|
Like @code{set-field}, but can be used to set more than one field at a
|
|
time. This expands to code that is more efficient than a series of
|
|
single @code{set-field} calls.
|
|
@end deffn
|
|
|
|
To illustrate the use of functional setters, let's assume these two
|
|
record type definitions:
|
|
|
|
@example
|
|
(define-record-type <address>
|
|
(address street city country)
|
|
address?
|
|
(street address-street)
|
|
(city address-city)
|
|
(country address-country))
|
|
|
|
(define-immutable-record-type <person>
|
|
(person age email address)
|
|
person?
|
|
(age person-age set-person-age)
|
|
(email person-email set-person-email)
|
|
(address person-address set-person-address))
|
|
@end example
|
|
|
|
@noindent
|
|
First, note that the @code{<person>} record type definition introduces
|
|
named functional setters. These may be used like this:
|
|
|
|
@example
|
|
(define fsf-address
|
|
(address "Franklin Street" "Boston" "USA"))
|
|
|
|
(define rms
|
|
(person 30 "rms@@gnu.org" fsf-address))
|
|
|
|
(and (equal? (set-person-age rms 60)
|
|
(person 60 "rms@@gnu.org" fsf-address))
|
|
(= (person-age rms) 30))
|
|
@result{} #t
|
|
@end example
|
|
|
|
@noindent
|
|
Here, the original @code{<person>} record, to which @var{rms} is bound,
|
|
is left unchanged.
|
|
|
|
Now, suppose we want to change both the street and age of @var{rms}.
|
|
This can be achieved using @code{set-fields}:
|
|
|
|
@example
|
|
(set-fields rms
|
|
((person-age) 60)
|
|
((person-address address-street) "Temple Place"))
|
|
@result{} #<<person> age: 60 email: "rms@@gnu.org"
|
|
address: #<<address> street: "Temple Place" city: "Boston" country: "USA">>
|
|
@end example
|
|
|
|
@noindent
|
|
Notice how the above changed two fields of @var{rms}, including the
|
|
@code{street} field of its @code{address} field, in a concise way. Also
|
|
note that @code{set-fields} works equally well for types defined with
|
|
just @code{define-record-type}.
|
|
|
|
@node Records
|
|
@subsection Records
|
|
|
|
A @dfn{record type} is a first class object representing a user-defined
|
|
data type. A @dfn{record} is an instance of a record type.
|
|
|
|
Note that in many ways, this interface is too low-level for every-day
|
|
use. Most uses of records are better served by SRFI-9 records.
|
|
@xref{SRFI-9 Records}.
|
|
|
|
@deffn {Scheme Procedure} record? obj
|
|
Return @code{#t} if @var{obj} is a record of any type and @code{#f}
|
|
otherwise.
|
|
|
|
Note that @code{record?} may be true of any Scheme value; there is no
|
|
promise that records are disjoint with other Scheme types.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} make-record-type type-name field-names [print] @
|
|
[#:parent=@code{#f}] [#:uid=@code{#f}] @
|
|
[#:extensible?=@code{#f}] [#:opaque?=@code{#f}] @
|
|
[#:allow-duplicate-field-names?=@code{#t}]
|
|
Create and return a new @dfn{record-type descriptor}.
|
|
|
|
@var{type-name} is a string naming the type. Currently it's only used
|
|
in the printed representation of records, and in diagnostics.
|
|
@var{field-names} is a list of elements of the form @code{(immutable
|
|
@var{name})}, @code{(mutable @var{name})}, or @var{name}, where
|
|
@var{name} are symbols naming the fields of a record of the type.
|
|
Duplicates are not allowed among these symbols, unless
|
|
@var{allow-duplicate-field-names?} is true.
|
|
|
|
@example
|
|
(make-record-type "employee" '(name age salary))
|
|
@end example
|
|
|
|
The optional @var{print} argument is a function used by
|
|
@code{display}, @code{write}, etc, for printing a record of the new
|
|
type. It's called as @code{(@var{print} record port)} and should look
|
|
at @var{record} and write to @var{port}.
|
|
|
|
Pass the @code{#:parent} keyword to derive a record type from a
|
|
supertype. A derived record type has the fields from its parent type,
|
|
followed by fields declared in the @code{make-record-type} call. Record
|
|
predicates and field accessors for instance of a parent type will also
|
|
work on any instance of a subtype.
|
|
|
|
@cindex extensible record types
|
|
@cindex record types, extensible
|
|
Allowing record subtyping has a small amount of overhead. To avoid this
|
|
overhead, prevent extensibility by passing @code{#:extensible? #f}.
|
|
By default, record types in Guile are not extensible.
|
|
|
|
@cindex prefab record types
|
|
@cindex record types, prefab
|
|
@cindex record types, nongenerative
|
|
Generally speaking, calling @code{make-record-type} returns a fresh
|
|
record type; it @emph{generates} new record types. However sometimes
|
|
you only want to define a record type if one hasn't been defined
|
|
already. For a @emph{nongenerative} record type definition, pass a
|
|
symbol as the @code{#:uid} keyword parameter. If a record with the
|
|
given @var{uid} was already defined, it will be returned instead. The
|
|
type name, fields, parent (if any), and so on for the previously-defined
|
|
type must be compatible.
|
|
|
|
@cindex record types, opaque
|
|
R6RS defines a notion of ``opaque'' record types. Given an instance of
|
|
an opaque record type, one cannot obtain a run-time representation of
|
|
the record type. @xref{rnrs records procedural}, for full details. The
|
|
@code{#:opaque?} flag is used by Guile's R6RS layer to record this
|
|
information. The default is determined by whether the parent type, if
|
|
any, was opaque.
|
|
|
|
Fields are mutable by default, meaning that @code{record-modifier} will
|
|
return a procedure that can update a record in place. Specifying a
|
|
field using the form @code{(immutable @var{name})} instead marks a field
|
|
as immutable.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} record-constructor rtd
|
|
Return a procedure for constructing new members of the type represented
|
|
by @var{rtd}. The result will be a procedure accepting exactly as many
|
|
arguments as there are fields in the record type.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} record-predicate rtd
|
|
Return a procedure for testing membership in the type represented by
|
|
@var{rtd}. The returned procedure accepts exactly one argument and
|
|
returns a true value if the argument is a member of the indicated record
|
|
type; it returns a false value otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} record-accessor rtd field-name
|
|
Return a procedure for reading the value of a particular field of a
|
|
member of the type represented by @var{rtd}. The returned procedure
|
|
accepts exactly one argument which must be a record of the appropriate
|
|
type; it returns the current value of the field named by the symbol
|
|
@var{field-name} in that record.
|
|
|
|
If @var{field-name} is a symbol, it must be a member of the list of
|
|
field-names in the call to @code{make-record-type} that created the type
|
|
represented by @var{rtd}. If multiple fields in @var{rtd} have the same
|
|
name, @code{record-accessor} returns the first one.
|
|
|
|
If @var{field-name} is an integer, it should be an index into
|
|
@code{(record-type-fields @var{rtd})}. This allows accessing fields
|
|
with duplicate names.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} record-modifier rtd field-name
|
|
Return a procedure for writing the value of a particular field of a
|
|
member of the type represented by @var{rtd}. The returned procedure
|
|
accepts exactly two arguments: first, a record of the appropriate type,
|
|
and second, an arbitrary Scheme value; it modifies the field named by
|
|
the symbol @var{field-name} in that record to contain the given value.
|
|
The returned value of the modifier procedure is unspecified. The symbol
|
|
@var{field-name} is a field name or a field index, as in
|
|
@code{record-modifier}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} record-type-descriptor record
|
|
Return a record-type descriptor representing the type of the given
|
|
record. That is, for example, if the returned descriptor were passed to
|
|
@code{record-predicate}, the resulting predicate would return a true
|
|
value when passed the given record. Note that it is not necessarily the
|
|
case that the returned descriptor is the one that was passed to
|
|
@code{record-constructor} in the call that created the constructor
|
|
procedure that created the given record.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} record-type-name rtd
|
|
Return the type-name associated with the type represented by rtd. The
|
|
returned value is @code{eqv?} to the @var{type-name} argument given in
|
|
the call to @code{make-record-type} that created the type represented by
|
|
@var{rtd}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} record-type-fields rtd
|
|
Return a list of the symbols naming the fields in members of the type
|
|
represented by @var{rtd}. The returned value is @code{equal?} to the
|
|
field-names argument given in the call to @code{make-record-type} that
|
|
created the type represented by @var{rtd}.
|
|
@end deffn
|
|
|
|
|
|
@node Structures
|
|
@subsection Structures
|
|
@tpindex Structures
|
|
|
|
A @dfn{structure} is a first class data type which holds Scheme values
|
|
or C words in fields numbered 0 upwards. A @dfn{vtable} is a structure
|
|
that represents a structure type, giving field types and permissions,
|
|
and an optional print function for @code{write} etc.
|
|
|
|
Structures are lower level than records (@pxref{Records}). Usually,
|
|
when you need to represent structured data, you just want to use
|
|
records. But sometimes you need to implement new kinds of structured
|
|
data abstractions, and for that purpose structures are useful. Indeed,
|
|
records in Guile are implemented with structures.
|
|
|
|
@menu
|
|
* Vtables::
|
|
* Structure Basics::
|
|
* Vtable Contents::
|
|
* Meta-Vtables::
|
|
* Vtable Example::
|
|
@end menu
|
|
|
|
@node Vtables
|
|
@subsubsection Vtables
|
|
|
|
A vtable is a structure type, specifying its layout, and other
|
|
information. A vtable is actually itself a structure, but there's no
|
|
need to worry about that initially (@pxref{Vtable Contents}.)
|
|
|
|
@deffn {Scheme Procedure} make-vtable fields [print]
|
|
Create a new vtable.
|
|
|
|
@var{fields} is a string describing the fields in the structures to be
|
|
created. Each field is represented by two characters, a type letter
|
|
and a permissions letter, for example @code{"pw"}. The types are as
|
|
follows.
|
|
|
|
@itemize @bullet{}
|
|
@item
|
|
@code{p} -- a Scheme value. ``p'' stands for ``protected'' meaning
|
|
it's protected against garbage collection.
|
|
|
|
@item
|
|
@code{u} -- an arbitrary word of data (an @code{scm_t_bits}). At the
|
|
Scheme level it's read and written as an unsigned integer. ``u'' stands
|
|
for ``unboxed'', as it's stored as a raw value without additional type
|
|
annotations.
|
|
@end itemize
|
|
|
|
It used to be that the second letter for each field was a permission
|
|
code, such as @code{w} for writable or @code{r} for read-only. However
|
|
over time structs have become more of a raw low-level facility; access
|
|
control is better implemented as a layer on top. After all,
|
|
@code{struct-set!} is a cross-cutting operator that can bypass
|
|
abstractions made by higher-level record facilities; it's not generally
|
|
safe (in the sense of abstraction-preserving) to expose
|
|
@code{struct-set!} to ``untrusted'' code, even if the fields happen to
|
|
be writable. Additionally, permission checks added overhead to every
|
|
structure access in a way that couldn't be optimized out, hampering the
|
|
ability of structs to act as a low-level building block. For all of
|
|
these reasons, all fields in Guile structs are now writable; attempting
|
|
to make a read-only field will now issue a deprecation warning, and the
|
|
field will be writable regardless.
|
|
|
|
@example
|
|
(make-vtable "pw") ;; one scheme field
|
|
(make-vtable "pwuwuw") ;; one scheme and two unboxed fields
|
|
@end example
|
|
|
|
The optional @var{print} argument is a function called by
|
|
@code{display} and @code{write} (etc) to give a printed representation
|
|
of a structure created from this vtable. It's called
|
|
@code{(@var{print} struct port)} and should look at @var{struct} and
|
|
write to @var{port}. The default print merely gives a form like
|
|
@samp{#<struct ADDR:ADDR>} with a pair of machine addresses.
|
|
|
|
The following print function for example shows the two fields of its
|
|
structure.
|
|
|
|
@example
|
|
(make-vtable "pwpw"
|
|
(lambda (struct port)
|
|
(format port "#<~a and ~a>"
|
|
(struct-ref struct 0)
|
|
(struct-ref struct 1))))
|
|
@end example
|
|
@end deffn
|
|
|
|
|
|
@node Structure Basics
|
|
@subsubsection Structure Basics
|
|
|
|
This section describes the basic procedures for working with structures.
|
|
@code{make-struct/no-tail} creates a structure, and @code{struct-ref}
|
|
and @code{struct-set!} access its fields.
|
|
|
|
@deffn {Scheme Procedure} make-struct/no-tail vtable init @dots{}
|
|
Create a new structure, with layout per the given @var{vtable}
|
|
(@pxref{Vtables}).
|
|
|
|
The optional @var{init}@dots{} arguments are initial values for the
|
|
fields of the structure. This is the only way to
|
|
put values in read-only fields. If there are fewer @var{init}
|
|
arguments than fields then the defaults are @code{#f} for a Scheme
|
|
field (type @code{p}) or 0 for an unboxed field (type @code{u}).
|
|
|
|
The name is a bit strange, we admit. The reason for it is that Guile
|
|
used to have a @code{make-struct} that took an additional argument;
|
|
while we deprecate that old interface, @code{make-struct/no-tail} is the
|
|
new name for this functionality.
|
|
|
|
For example,
|
|
|
|
@example
|
|
(define v (make-vtable "pwpwpw"))
|
|
(define s (make-struct/no-tail v 123 "abc" 456))
|
|
(struct-ref s 0) @result{} 123
|
|
(struct-ref s 1) @result{} "abc"
|
|
@end example
|
|
@end deffn
|
|
|
|
@deftypefn {C Function} SCM scm_make_struct (SCM vtable, SCM tail_size, SCM init_list)
|
|
@deftypefnx {C Function} SCM scm_c_make_struct (SCM vtable, SCM tail_size, SCM init, ...)
|
|
@deftypefnx {C Function} SCM scm_c_make_structv (SCM vtable, SCM tail_size, size_t n_inits, scm_t_bits init[])
|
|
There are a few ways to make structures from C. @code{scm_make_struct}
|
|
takes a list, @code{scm_c_make_struct} takes variable arguments
|
|
terminated with SCM_UNDEFINED, and @code{scm_c_make_structv} takes a
|
|
packed array.
|
|
|
|
For all of these, @var{tail_size} should be zero (as a SCM value).
|
|
@end deftypefn
|
|
|
|
@deffn {Scheme Procedure} struct? obj
|
|
@deffnx {C Function} scm_struct_p (obj)
|
|
Return @code{#t} if @var{obj} is a structure, or @code{#f} if not.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} struct-ref struct n
|
|
@deffnx {C Function} scm_struct_ref (struct, n)
|
|
Return the contents of field number @var{n} in @var{struct}. The
|
|
first field is number 0.
|
|
|
|
An error is thrown if @var{n} is out of range.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} struct-set! struct n value
|
|
@deffnx {C Function} scm_struct_set_x (struct, n, value)
|
|
Set field number @var{n} in @var{struct} to @var{value}. The first
|
|
field is number 0.
|
|
|
|
An error is thrown if @var{n} is out of range, or if the field cannot
|
|
be written because it's @code{r} read-only.
|
|
@end deffn
|
|
|
|
Unboxed fields (those with type @code{u}) need to be accessed with
|
|
special procedures.
|
|
|
|
@deffn {Scheme Procedure} struct-ref/unboxed struct n
|
|
@deffnx {Scheme Procedure} struct-set!/unboxed struct n value
|
|
@deffnx {C Function} scm_struct_ref_unboxed (struct, n)
|
|
@deffnx {C Function} scm_struct_set_x_unboxed (struct, n, value)
|
|
Like @code{struct-ref} and @code{struct-set!}, except that these may
|
|
only be used on unboxed fields. @code{struct-ref/unboxed} will always
|
|
return a positive integer. Likewise, @code{struct-set!/unboxed} takes
|
|
an unsigned integer as the @var{value} argument, and will signal an
|
|
error otherwise.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} struct-vtable struct
|
|
@deffnx {C Function} scm_struct_vtable (struct)
|
|
Return the vtable that describes @var{struct}.
|
|
|
|
The vtable is effectively the type of the structure. See @ref{Vtable
|
|
Contents}, for more on vtables.
|
|
@end deffn
|
|
|
|
|
|
@node Vtable Contents
|
|
@subsubsection Vtable Contents
|
|
|
|
A vtable is itself a structure. It has a specific set of fields
|
|
describing various aspects of its @dfn{instances}: the structures
|
|
created from a vtable. Some of the fields are internal to Guile, some
|
|
of them are part of the public interface, and there may be additional
|
|
fields added on by the user.
|
|
|
|
Every vtable has a field for the layout of their instances, a field for
|
|
the procedure used to print its instances, and a field for the name of
|
|
the vtable itself. Access to the layout and printer is exposed directly
|
|
via field indexes. Access to the vtable name is exposed via accessor
|
|
procedures.
|
|
|
|
@defvr {Scheme Variable} vtable-index-layout
|
|
@defvrx {C Macro} scm_vtable_index_layout
|
|
The field number of the layout specification in a vtable. The layout
|
|
specification is a symbol like @code{pwpw} formed from the fields
|
|
string passed to @code{make-vtable}, or created by
|
|
@code{make-struct-layout} (@pxref{Meta-Vtables}).
|
|
|
|
@example
|
|
(define v (make-vtable "pwpw" 0))
|
|
(struct-ref v vtable-index-layout) @result{} pwpw
|
|
@end example
|
|
|
|
This field is read-only, since the layout of structures using a vtable
|
|
cannot be changed.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} vtable-index-printer
|
|
@defvrx {C Macro} scm_vtable_index_printer
|
|
The field number of the printer function. This field contains @code{#f}
|
|
if the default print function should be used.
|
|
|
|
@example
|
|
(define (my-print-func struct port)
|
|
...)
|
|
(define v (make-vtable "pwpw" my-print-func))
|
|
(struct-ref v vtable-index-printer) @result{} my-print-func
|
|
@end example
|
|
|
|
This field is writable, allowing the print function to be changed
|
|
dynamically.
|
|
@end defvr
|
|
|
|
@deffn {Scheme Procedure} struct-vtable-name vtable
|
|
@deffnx {Scheme Procedure} set-struct-vtable-name! vtable name
|
|
@deffnx {C Function} scm_struct_vtable_name (vtable)
|
|
@deffnx {C Function} scm_set_struct_vtable_name_x (vtable, name)
|
|
Get or set the name of @var{vtable}. @var{name} is a symbol and is
|
|
used in the default print function when printing structures created
|
|
from @var{vtable}.
|
|
|
|
@example
|
|
(define v (make-vtable "pw"))
|
|
(set-struct-vtable-name! v 'my-name)
|
|
|
|
(define s (make-struct v 0))
|
|
(display s) @print{} #<my-name b7ab3ae0:b7ab3730>
|
|
@end example
|
|
@end deffn
|
|
|
|
|
|
@node Meta-Vtables
|
|
@subsubsection Meta-Vtables
|
|
|
|
As a structure, a vtable also has a vtable, which is also a structure.
|
|
Structures, their vtables, the vtables of the vtables, and so on form a
|
|
tree of structures. Making a new structure adds a leaf to the tree, and
|
|
if that structure is a vtable, it may be used to create other leaves.
|
|
|
|
If you traverse up the tree of vtables, via calling
|
|
@code{struct-vtable}, eventually you reach a root which is the vtable of
|
|
itself:
|
|
|
|
@example
|
|
scheme@@(guile-user)> (current-module)
|
|
$1 = #<directory (guile-user) 221b090>
|
|
scheme@@(guile-user)> (struct-vtable $1)
|
|
$2 = #<record-type module>
|
|
scheme@@(guile-user)> (struct-vtable $2)
|
|
$3 = #<<standard-vtable> 12c30a0>
|
|
scheme@@(guile-user)> (struct-vtable $3)
|
|
$4 = #<<standard-vtable> 12c3fa0>
|
|
scheme@@(guile-user)> (struct-vtable $4)
|
|
$5 = #<<standard-vtable> 12c3fa0>
|
|
scheme@@(guile-user)> <standard-vtable>
|
|
$6 = #<<standard-vtable> 12c3fa0>
|
|
@end example
|
|
|
|
In this example, we can say that @code{$1} is an instance of @code{$2},
|
|
@code{$2} is an instance of @code{$3}, @code{$3} is an instance of
|
|
@code{$4}, and @code{$4}, strangely enough, is an instance of itself.
|
|
The value bound to @code{$4} in this console session also bound to
|
|
@code{<standard-vtable>} in the default environment.
|
|
|
|
@defvr {Scheme Variable} <standard-vtable>
|
|
A meta-vtable, useful for making new vtables.
|
|
@end defvr
|
|
|
|
All of these values are structures. All but @code{$1} are vtables. As
|
|
@code{$2} is an instance of @code{$3}, and @code{$3} is a vtable, we can
|
|
say that @code{$3} is a @dfn{meta-vtable}: a vtable that can create
|
|
vtables.
|
|
|
|
With this definition, we can specify more precisely what a vtable is: a
|
|
vtable is a structure made from a meta-vtable. Making a structure from
|
|
a meta-vtable runs some special checks to ensure that the first field of
|
|
the structure is a valid layout. Additionally, if these checks see that
|
|
the layout of the child vtable contains all the required fields of a
|
|
vtable, in the correct order, then the child vtable will also be a
|
|
meta-table, inheriting a magical bit from the parent.
|
|
|
|
@deffn {Scheme Procedure} struct-vtable? obj
|
|
@deffnx {C Function} scm_struct_vtable_p (obj)
|
|
Return @code{#t} if @var{obj} is a vtable structure: an instance of a
|
|
meta-vtable.
|
|
@end deffn
|
|
|
|
@code{<standard-vtable>} is a root of the vtable tree. (Normally there
|
|
is only one root in a given Guile process, but due to some legacy
|
|
interfaces there may be more than one.)
|
|
|
|
The set of required fields of a vtable is the set of fields in the
|
|
@code{<standard-vtable>}, and is bound to @code{standard-vtable-fields}
|
|
in the default environment. It is possible to create a meta-vtable that
|
|
with additional fields in its layout, which can be used to create
|
|
vtables with additional data:
|
|
|
|
@example
|
|
scheme@@(guile-user)> (struct-ref $3 vtable-index-layout)
|
|
$6 = pwuhuhpwphuhuhpwpwpw
|
|
scheme@@(guile-user)> (struct-ref $4 vtable-index-layout)
|
|
$7 = pwuhuhpwphuhuh
|
|
scheme@@(guile-user)> standard-vtable-fields
|
|
$8 = "pwuhuhpwphuhuh"
|
|
scheme@@(guile-user)> (struct-ref $2 vtable-offset-user)
|
|
$9 = module
|
|
@end example
|
|
|
|
In this continuation of our earlier example, @code{$2} is a vtable that
|
|
has extra fields, because its vtable, @code{$3}, was made from a
|
|
meta-vtable with an extended layout. @code{vtable-offset-user} is a
|
|
convenient definition that indicates the number of fields in
|
|
@code{standard-vtable-fields}.
|
|
|
|
@defvr {Scheme Variable} standard-vtable-fields
|
|
A string containing the ordered set of fields that a vtable must have.
|
|
@end defvr
|
|
|
|
@defvr {Scheme Variable} vtable-offset-user
|
|
The first index in a vtable that is available for a user.
|
|
@end defvr
|
|
|
|
@deffn {Scheme Procedure} make-struct-layout fields
|
|
@deffnx {C Function} scm_make_struct_layout (fields)
|
|
Return a structure layout symbol, from a @var{fields} string.
|
|
@var{fields} is as described under @code{make-vtable}
|
|
(@pxref{Vtables}). An invalid @var{fields} string is an error.
|
|
@end deffn
|
|
|
|
With these definitions, one can define @code{make-vtable} in this way:
|
|
|
|
@example
|
|
(define* (make-vtable fields #:optional printer)
|
|
(make-struct/no-tail <standard-vtable>
|
|
(make-struct-layout fields)
|
|
printer))
|
|
@end example
|
|
|
|
|
|
@node Vtable Example
|
|
@subsubsection Vtable Example
|
|
|
|
Let us bring these points together with an example. Consider a simple
|
|
object system with single inheritance. Objects will be normal
|
|
structures, and classes will be vtables with three extra class fields:
|
|
the name of the class, the parent class, and the list of fields.
|
|
|
|
So, first we need a meta-vtable that allocates instances with these
|
|
extra class fields.
|
|
|
|
@example
|
|
(define <class>
|
|
(make-vtable
|
|
(string-append standard-vtable-fields "pwpwpw")
|
|
(lambda (x port)
|
|
(format port "<<class> ~a>" (class-name x)))))
|
|
|
|
(define (class? x)
|
|
(and (struct? x)
|
|
(eq? (struct-vtable x) <class>)))
|
|
@end example
|
|
|
|
To make a structure with a specific meta-vtable, we will use
|
|
@code{make-struct/no-tail}, passing it the computed instance layout and
|
|
printer, as with @code{make-vtable}, and additionally the extra three
|
|
class fields.
|
|
|
|
@example
|
|
(define (make-class name parent fields)
|
|
(let* ((fields (compute-fields parent fields))
|
|
(layout (compute-layout fields)))
|
|
(make-struct/no-tail <class>
|
|
layout
|
|
(lambda (x port)
|
|
(print-instance x port))
|
|
name
|
|
parent
|
|
fields)))
|
|
@end example
|
|
|
|
Instances will store their associated data in slots in the structure: as
|
|
many slots as there are fields. The @code{compute-layout} procedure
|
|
below can compute a layout, and @code{field-index} returns the slot
|
|
corresponding to a field.
|
|
|
|
@example
|
|
(define-syntax-rule (define-accessor name n)
|
|
(define (name obj)
|
|
(struct-ref obj n)))
|
|
|
|
;; Accessors for classes
|
|
(define-accessor class-name (+ vtable-offset-user 0))
|
|
(define-accessor class-parent (+ vtable-offset-user 1))
|
|
(define-accessor class-fields (+ vtable-offset-user 2))
|
|
|
|
(define (compute-fields parent fields)
|
|
(if parent
|
|
(append (class-fields parent) fields)
|
|
fields))
|
|
|
|
(define (compute-layout fields)
|
|
(make-struct-layout
|
|
(string-concatenate (make-list (length fields) "pw"))))
|
|
|
|
(define (field-index class field)
|
|
(list-index (class-fields class) field))
|
|
|
|
(define (print-instance x port)
|
|
(format port "<~a" (class-name (struct-vtable x)))
|
|
(for-each (lambda (field idx)
|
|
(format port " ~a: ~a" field (struct-ref x idx)))
|
|
(class-fields (struct-vtable x))
|
|
(iota (length (class-fields (struct-vtable x)))))
|
|
(format port ">"))
|
|
@end example
|
|
|
|
So, at this point we can actually make a few classes:
|
|
|
|
@example
|
|
(define-syntax-rule (define-class name parent field ...)
|
|
(define name (make-class 'name parent '(field ...))))
|
|
|
|
(define-class <surface> #f
|
|
width height)
|
|
|
|
(define-class <window> <surface>
|
|
x y)
|
|
@end example
|
|
|
|
And finally, make an instance:
|
|
|
|
@example
|
|
(make-struct/no-tail <window> 400 300 10 20)
|
|
@result{} <<window> width: 400 height: 300 x: 10 y: 20>
|
|
@end example
|
|
|
|
And that's that. Note that there are many possible optimizations and
|
|
feature enhancements that can be made to this object system, and the
|
|
included GOOPS system does make most of them. For more simple use
|
|
cases, the records facility is usually sufficient. But sometimes you
|
|
need to make new kinds of data abstractions, and for that purpose,
|
|
structs are here.
|
|
|
|
|
|
@node Dictionary Types
|
|
@subsection Dictionary Types
|
|
|
|
A @dfn{dictionary} object is a data structure used to index
|
|
information in a user-defined way. In standard Scheme, the main
|
|
aggregate data types are lists and vectors. Lists are not really
|
|
indexed at all, and vectors are indexed only by number
|
|
(e.g.@: @code{(vector-ref foo 5)}). Often you will find it useful
|
|
to index your data on some other type; for example, in a library
|
|
catalog you might want to look up a book by the name of its
|
|
author. Dictionaries are used to help you organize information in
|
|
such a way.
|
|
|
|
An @dfn{association list} (or @dfn{alist} for short) is a list of
|
|
key-value pairs. Each pair represents a single quantity or
|
|
object; the @code{car} of the pair is a key which is used to
|
|
identify the object, and the @code{cdr} is the object's value.
|
|
|
|
A @dfn{hash table} also permits you to index objects with
|
|
arbitrary keys, but in a way that makes looking up any one object
|
|
extremely fast. A well-designed hash system makes hash table
|
|
lookups almost as fast as conventional array or vector references.
|
|
|
|
Alists are popular among Lisp programmers because they use only
|
|
the language's primitive operations (lists, @dfn{car}, @dfn{cdr}
|
|
and the equality primitives). No changes to the language core are
|
|
necessary. Therefore, with Scheme's built-in list manipulation
|
|
facilities, it is very convenient to handle data stored in an
|
|
association list. Also, alists are highly portable and can be
|
|
easily implemented on even the most minimal Lisp systems.
|
|
|
|
However, alists are inefficient, especially for storing large
|
|
quantities of data. Because we want Guile to be useful for large
|
|
software systems as well as small ones, Guile provides a rich set
|
|
of tools for using either association lists or hash tables.
|
|
|
|
@node Association Lists
|
|
@subsection Association Lists
|
|
@tpindex Association Lists
|
|
@tpindex Alist
|
|
@cindex association List
|
|
@cindex alist
|
|
@cindex database
|
|
|
|
An association list is a conventional data structure that is often used
|
|
to implement simple key-value databases. It consists of a list of
|
|
entries in which each entry is a pair. The @dfn{key} of each entry is
|
|
the @code{car} of the pair and the @dfn{value} of each entry is the
|
|
@code{cdr}.
|
|
|
|
@example
|
|
ASSOCIATION LIST ::= '( (KEY1 . VALUE1)
|
|
(KEY2 . VALUE2)
|
|
(KEY3 . VALUE3)
|
|
@dots{}
|
|
)
|
|
@end example
|
|
|
|
@noindent
|
|
Association lists are also known, for short, as @dfn{alists}.
|
|
|
|
The structure of an association list is just one example of the infinite
|
|
number of possible structures that can be built using pairs and lists.
|
|
As such, the keys and values in an association list can be manipulated
|
|
using the general list structure procedures @code{cons}, @code{car},
|
|
@code{cdr}, @code{set-car!}, @code{set-cdr!} and so on. However,
|
|
because association lists are so useful, Guile also provides specific
|
|
procedures for manipulating them.
|
|
|
|
@menu
|
|
* Alist Key Equality::
|
|
* Adding or Setting Alist Entries::
|
|
* Retrieving Alist Entries::
|
|
* Removing Alist Entries::
|
|
* Sloppy Alist Functions::
|
|
* Alist Example::
|
|
@end menu
|
|
|
|
@node Alist Key Equality
|
|
@subsubsection Alist Key Equality
|
|
|
|
All of Guile's dedicated association list procedures, apart from
|
|
@code{acons}, come in three flavours, depending on the level of equality
|
|
that is required to decide whether an existing key in the association
|
|
list is the same as the key that the procedure call uses to identify the
|
|
required entry.
|
|
|
|
@itemize @bullet
|
|
@item
|
|
Procedures with @dfn{assq} in their name use @code{eq?} to determine key
|
|
equality.
|
|
|
|
@item
|
|
Procedures with @dfn{assv} in their name use @code{eqv?} to determine
|
|
key equality.
|
|
|
|
@item
|
|
Procedures with @dfn{assoc} in their name use @code{equal?} to
|
|
determine key equality.
|
|
@end itemize
|
|
|
|
@code{acons} is an exception because it is used to build association
|
|
lists which do not require their entries' keys to be unique.
|
|
|
|
@node Adding or Setting Alist Entries
|
|
@subsubsection Adding or Setting Alist Entries
|
|
|
|
@code{acons} adds a new entry to an association list and returns the
|
|
combined association list. The combined alist is formed by consing the
|
|
new entry onto the head of the alist specified in the @code{acons}
|
|
procedure call. So the specified alist is not modified, but its
|
|
contents become shared with the tail of the combined alist that
|
|
@code{acons} returns.
|
|
|
|
In the most common usage of @code{acons}, a variable holding the
|
|
original association list is updated with the combined alist:
|
|
|
|
@example
|
|
(set! address-list (acons name address address-list))
|
|
@end example
|
|
|
|
In such cases, it doesn't matter that the old and new values of
|
|
@code{address-list} share some of their contents, since the old value is
|
|
usually no longer independently accessible.
|
|
|
|
Note that @code{acons} adds the specified new entry regardless of
|
|
whether the alist may already contain entries with keys that are, in
|
|
some sense, the same as that of the new entry. Thus @code{acons} is
|
|
ideal for building alists where there is no concept of key uniqueness.
|
|
|
|
@example
|
|
(set! task-list (acons 3 "pay gas bill" '()))
|
|
task-list
|
|
@result{}
|
|
((3 . "pay gas bill"))
|
|
|
|
(set! task-list (acons 3 "tidy bedroom" task-list))
|
|
task-list
|
|
@result{}
|
|
((3 . "tidy bedroom") (3 . "pay gas bill"))
|
|
@end example
|
|
|
|
@code{assq-set!}, @code{assv-set!} and @code{assoc-set!} are used to add
|
|
or replace an entry in an association list where there @emph{is} a
|
|
concept of key uniqueness. If the specified association list already
|
|
contains an entry whose key is the same as that specified in the
|
|
procedure call, the existing entry is replaced by the new one.
|
|
Otherwise, the new entry is consed onto the head of the old association
|
|
list to create the combined alist. In all cases, these procedures
|
|
return the combined alist.
|
|
|
|
@code{assq-set!} and friends @emph{may} destructively modify the
|
|
structure of the old association list in such a way that an existing
|
|
variable is correctly updated without having to @code{set!} it to the
|
|
value returned:
|
|
|
|
@example
|
|
address-list
|
|
@result{}
|
|
(("mary" . "34 Elm Road") ("james" . "16 Bow Street"))
|
|
|
|
(assoc-set! address-list "james" "1a London Road")
|
|
@result{}
|
|
(("mary" . "34 Elm Road") ("james" . "1a London Road"))
|
|
|
|
address-list
|
|
@result{}
|
|
(("mary" . "34 Elm Road") ("james" . "1a London Road"))
|
|
@end example
|
|
|
|
Or they may not:
|
|
|
|
@example
|
|
(assoc-set! address-list "bob" "11 Newington Avenue")
|
|
@result{}
|
|
(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
|
|
("james" . "1a London Road"))
|
|
|
|
address-list
|
|
@result{}
|
|
(("mary" . "34 Elm Road") ("james" . "1a London Road"))
|
|
@end example
|
|
|
|
The only safe way to update an association list variable when adding or
|
|
replacing an entry like this is to @code{set!} the variable to the
|
|
returned value:
|
|
|
|
@example
|
|
(set! address-list
|
|
(assoc-set! address-list "bob" "11 Newington Avenue"))
|
|
address-list
|
|
@result{}
|
|
(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
|
|
("james" . "1a London Road"))
|
|
@end example
|
|
|
|
Because of this slight inconvenience, you may find it more convenient to
|
|
use hash tables to store dictionary data. If your application will not
|
|
be modifying the contents of an alist very often, this may not make much
|
|
difference to you.
|
|
|
|
If you need to keep the old value of an association list in a form
|
|
independent from the list that results from modification by
|
|
@code{acons}, @code{assq-set!}, @code{assv-set!} or @code{assoc-set!},
|
|
use @code{list-copy} to copy the old association list before modifying
|
|
it.
|
|
|
|
@deffn {Scheme Procedure} acons key value alist
|
|
@deffnx {C Function} scm_acons (key, value, alist)
|
|
Add a new key-value pair to @var{alist}. A new pair is
|
|
created whose car is @var{key} and whose cdr is @var{value}, and the
|
|
pair is consed onto @var{alist}, and the new list is returned. This
|
|
function is @emph{not} destructive; @var{alist} is not modified.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} assq-set! alist key val
|
|
@deffnx {Scheme Procedure} assv-set! alist key value
|
|
@deffnx {Scheme Procedure} assoc-set! alist key value
|
|
@deffnx {C Function} scm_assq_set_x (alist, key, val)
|
|
@deffnx {C Function} scm_assv_set_x (alist, key, val)
|
|
@deffnx {C Function} scm_assoc_set_x (alist, key, val)
|
|
Reassociate @var{key} in @var{alist} with @var{value}: find any existing
|
|
@var{alist} entry for @var{key} and associate it with the new
|
|
@var{value}. If @var{alist} does not contain an entry for @var{key},
|
|
add a new one. Return the (possibly new) alist.
|
|
|
|
These functions do not attempt to verify the structure of @var{alist},
|
|
and so may cause unusual results if passed an object that is not an
|
|
association list.
|
|
@end deffn
|
|
|
|
@node Retrieving Alist Entries
|
|
@subsubsection Retrieving Alist Entries
|
|
@rnindex assq
|
|
@rnindex assv
|
|
@rnindex assoc
|
|
|
|
@code{assq}, @code{assv} and @code{assoc} find the entry in an alist
|
|
for a given key, and return the @code{(@var{key} . @var{value})} pair.
|
|
@code{assq-ref}, @code{assv-ref} and @code{assoc-ref} do a similar
|
|
lookup, but return just the @var{value}.
|
|
|
|
@deffn {Scheme Procedure} assq key alist
|
|
@deffnx {Scheme Procedure} assv key alist
|
|
@deffnx {Scheme Procedure} assoc key alist
|
|
@deffnx {C Function} scm_assq (key, alist)
|
|
@deffnx {C Function} scm_assv (key, alist)
|
|
@deffnx {C Function} scm_assoc (key, alist)
|
|
Return the first entry in @var{alist} with the given @var{key}. The
|
|
return is the pair @code{(KEY . VALUE)} from @var{alist}. If there's
|
|
no matching entry the return is @code{#f}.
|
|
|
|
@code{assq} compares keys with @code{eq?}, @code{assv} uses
|
|
@code{eqv?} and @code{assoc} uses @code{equal?}. See also SRFI-1
|
|
which has an extended @code{assoc} (@ref{SRFI-1 Association Lists}).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} assq-ref alist key
|
|
@deffnx {Scheme Procedure} assv-ref alist key
|
|
@deffnx {Scheme Procedure} assoc-ref alist key
|
|
@deffnx {C Function} scm_assq_ref (alist, key)
|
|
@deffnx {C Function} scm_assv_ref (alist, key)
|
|
@deffnx {C Function} scm_assoc_ref (alist, key)
|
|
Return the value from the first entry in @var{alist} with the given
|
|
@var{key}, or @code{#f} if there's no such entry.
|
|
|
|
@code{assq-ref} compares keys with @code{eq?}, @code{assv-ref} uses
|
|
@code{eqv?} and @code{assoc-ref} uses @code{equal?}.
|
|
|
|
Notice these functions have the @var{key} argument last, like other
|
|
@code{-ref} functions, but this is opposite to what @code{assq}
|
|
etc above use.
|
|
|
|
When the return is @code{#f} it can be either @var{key} not found, or
|
|
an entry which happens to have value @code{#f} in the @code{cdr}. Use
|
|
@code{assq} etc above if you need to differentiate these cases.
|
|
@end deffn
|
|
|
|
|
|
@node Removing Alist Entries
|
|
@subsubsection Removing Alist Entries
|
|
|
|
To remove the element from an association list whose key matches a
|
|
specified key, use @code{assq-remove!}, @code{assv-remove!} or
|
|
@code{assoc-remove!} (depending, as usual, on the level of equality
|
|
required between the key that you specify and the keys in the
|
|
association list).
|
|
|
|
As with @code{assq-set!} and friends, the specified alist may or may not
|
|
be modified destructively, and the only safe way to update a variable
|
|
containing the alist is to @code{set!} it to the value that
|
|
@code{assq-remove!} and friends return.
|
|
|
|
@example
|
|
address-list
|
|
@result{}
|
|
(("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
|
|
("james" . "1a London Road"))
|
|
|
|
(set! address-list (assoc-remove! address-list "mary"))
|
|
address-list
|
|
@result{}
|
|
(("bob" . "11 Newington Avenue") ("james" . "1a London Road"))
|
|
@end example
|
|
|
|
Note that, when @code{assq/v/oc-remove!} is used to modify an
|
|
association list that has been constructed only using the corresponding
|
|
@code{assq/v/oc-set!}, there can be at most one matching entry in the
|
|
alist, so the question of multiple entries being removed in one go does
|
|
not arise. If @code{assq/v/oc-remove!} is applied to an association
|
|
list that has been constructed using @code{acons}, or an
|
|
@code{assq/v/oc-set!} with a different level of equality, or any mixture
|
|
of these, it removes only the first matching entry from the alist, even
|
|
if the alist might contain further matching entries. For example:
|
|
|
|
@example
|
|
(define address-list '())
|
|
(set! address-list (assq-set! address-list "mary" "11 Elm Street"))
|
|
(set! address-list (assq-set! address-list "mary" "57 Pine Drive"))
|
|
address-list
|
|
@result{}
|
|
(("mary" . "57 Pine Drive") ("mary" . "11 Elm Street"))
|
|
|
|
(set! address-list (assoc-remove! address-list "mary"))
|
|
address-list
|
|
@result{}
|
|
(("mary" . "11 Elm Street"))
|
|
@end example
|
|
|
|
In this example, the two instances of the string "mary" are not the same
|
|
when compared using @code{eq?}, so the two @code{assq-set!} calls add
|
|
two distinct entries to @code{address-list}. When compared using
|
|
@code{equal?}, both "mary"s in @code{address-list} are the same as the
|
|
"mary" in the @code{assoc-remove!} call, but @code{assoc-remove!} stops
|
|
after removing the first matching entry that it finds, and so one of the
|
|
"mary" entries is left in place.
|
|
|
|
@deffn {Scheme Procedure} assq-remove! alist key
|
|
@deffnx {Scheme Procedure} assv-remove! alist key
|
|
@deffnx {Scheme Procedure} assoc-remove! alist key
|
|
@deffnx {C Function} scm_assq_remove_x (alist, key)
|
|
@deffnx {C Function} scm_assv_remove_x (alist, key)
|
|
@deffnx {C Function} scm_assoc_remove_x (alist, key)
|
|
Delete the first entry in @var{alist} associated with @var{key}, and return
|
|
the resulting alist.
|
|
@end deffn
|
|
|
|
@node Sloppy Alist Functions
|
|
@subsubsection Sloppy Alist Functions
|
|
|
|
@code{sloppy-assq}, @code{sloppy-assv} and @code{sloppy-assoc} behave
|
|
like the corresponding non-@code{sloppy-} procedures, except that they
|
|
return @code{#f} when the specified association list is not well-formed,
|
|
where the non-@code{sloppy-} versions would signal an error.
|
|
|
|
Specifically, there are two conditions for which the non-@code{sloppy-}
|
|
procedures signal an error, which the @code{sloppy-} procedures handle
|
|
instead by returning @code{#f}. Firstly, if the specified alist as a
|
|
whole is not a proper list:
|
|
|
|
@example
|
|
(assoc "mary" '((1 . 2) ("key" . "door") . "open sesame"))
|
|
@result{}
|
|
ERROR: In procedure assoc in expression (assoc "mary" (quote #)):
|
|
ERROR: Wrong type argument in position 2 (expecting
|
|
association list): ((1 . 2) ("key" . "door") . "open sesame")
|
|
|
|
(sloppy-assoc "mary" '((1 . 2) ("key" . "door") . "open sesame"))
|
|
@result{}
|
|
#f
|
|
@end example
|
|
|
|
@noindent
|
|
Secondly, if one of the entries in the specified alist is not a pair:
|
|
|
|
@example
|
|
(assoc 2 '((1 . 1) 2 (3 . 9)))
|
|
@result{}
|
|
ERROR: In procedure assoc in expression (assoc 2 (quote #)):
|
|
ERROR: Wrong type argument in position 2 (expecting
|
|
association list): ((1 . 1) 2 (3 . 9))
|
|
|
|
(sloppy-assoc 2 '((1 . 1) 2 (3 . 9)))
|
|
@result{}
|
|
#f
|
|
@end example
|
|
|
|
Unless you are explicitly working with badly formed association lists,
|
|
it is much safer to use the non-@code{sloppy-} procedures, because they
|
|
help to highlight coding and data errors that the @code{sloppy-}
|
|
versions would silently cover up.
|
|
|
|
@deffn {Scheme Procedure} sloppy-assq key alist
|
|
@deffnx {C Function} scm_sloppy_assq (key, alist)
|
|
Behaves like @code{assq} but does not do any error checking.
|
|
Recommended only for use in Guile internals.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} sloppy-assv key alist
|
|
@deffnx {C Function} scm_sloppy_assv (key, alist)
|
|
Behaves like @code{assv} but does not do any error checking.
|
|
Recommended only for use in Guile internals.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} sloppy-assoc key alist
|
|
@deffnx {C Function} scm_sloppy_assoc (key, alist)
|
|
Behaves like @code{assoc} but does not do any error checking.
|
|
Recommended only for use in Guile internals.
|
|
@end deffn
|
|
|
|
@node Alist Example
|
|
@subsubsection Alist Example
|
|
|
|
Here is a longer example of how alists may be used in practice.
|
|
|
|
@lisp
|
|
(define capitals '(("New York" . "Albany")
|
|
("Oregon" . "Salem")
|
|
("Florida" . "Miami")))
|
|
|
|
;; What's the capital of Oregon?
|
|
(assoc "Oregon" capitals) @result{} ("Oregon" . "Salem")
|
|
(assoc-ref capitals "Oregon") @result{} "Salem"
|
|
|
|
;; We left out South Dakota.
|
|
(set! capitals
|
|
(assoc-set! capitals "South Dakota" "Pierre"))
|
|
capitals
|
|
@result{} (("South Dakota" . "Pierre")
|
|
("New York" . "Albany")
|
|
("Oregon" . "Salem")
|
|
("Florida" . "Miami"))
|
|
|
|
;; And we got Florida wrong.
|
|
(set! capitals
|
|
(assoc-set! capitals "Florida" "Tallahassee"))
|
|
capitals
|
|
@result{} (("South Dakota" . "Pierre")
|
|
("New York" . "Albany")
|
|
("Oregon" . "Salem")
|
|
("Florida" . "Tallahassee"))
|
|
|
|
;; After Oregon secedes, we can remove it.
|
|
(set! capitals
|
|
(assoc-remove! capitals "Oregon"))
|
|
capitals
|
|
@result{} (("South Dakota" . "Pierre")
|
|
("New York" . "Albany")
|
|
("Florida" . "Tallahassee"))
|
|
@end lisp
|
|
|
|
@node VHashes
|
|
@subsection VList-Based Hash Lists or ``VHashes''
|
|
|
|
@cindex VList-based hash lists
|
|
@cindex VHash
|
|
|
|
The @code{(ice-9 vlist)} module provides an implementation of @dfn{VList-based
|
|
hash lists} (@pxref{VLists}). VList-based hash lists, or @dfn{vhashes}, are an
|
|
immutable dictionary type similar to association lists that maps @dfn{keys} to
|
|
@dfn{values}. However, unlike association lists, accessing a value given its
|
|
key is typically a constant-time operation.
|
|
|
|
The VHash programming interface of @code{(ice-9 vlist)} is mostly the same as
|
|
that of association lists found in SRFI-1, with procedure names prefixed by
|
|
@code{vhash-} instead of @code{alist-} (@pxref{SRFI-1 Association Lists}).
|
|
|
|
In addition, vhashes can be manipulated using VList operations:
|
|
|
|
@example
|
|
(vlist-head (vhash-consq 'a 1 vlist-null))
|
|
@result{} (a . 1)
|
|
|
|
(define vh1 (vhash-consq 'b 2 (vhash-consq 'a 1 vlist-null)))
|
|
(define vh2 (vhash-consq 'c 3 (vlist-tail vh1)))
|
|
|
|
(vhash-assq 'a vh2)
|
|
@result{} (a . 1)
|
|
(vhash-assq 'b vh2)
|
|
@result{} #f
|
|
(vhash-assq 'c vh2)
|
|
@result{} (c . 3)
|
|
(vlist->list vh2)
|
|
@result{} ((c . 3) (a . 1))
|
|
@end example
|
|
|
|
However, keep in mind that procedures that construct new VLists
|
|
(@code{vlist-map}, @code{vlist-filter}, etc.) return raw VLists, not vhashes:
|
|
|
|
@example
|
|
(define vh (alist->vhash '((a . 1) (b . 2) (c . 3)) hashq))
|
|
(vhash-assq 'a vh)
|
|
@result{} (a . 1)
|
|
|
|
(define vl
|
|
;; This will create a raw vlist.
|
|
(vlist-filter (lambda (key+value) (odd? (cdr key+value))) vh))
|
|
(vhash-assq 'a vl)
|
|
@result{} ERROR: Wrong type argument in position 2
|
|
|
|
(vlist->list vl)
|
|
@result{} ((a . 1) (c . 3))
|
|
@end example
|
|
|
|
@deffn {Scheme Procedure} vhash? obj
|
|
Return true if @var{obj} is a vhash.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vhash-cons key value vhash [hash-proc]
|
|
@deffnx {Scheme Procedure} vhash-consq key value vhash
|
|
@deffnx {Scheme Procedure} vhash-consv key value vhash
|
|
Return a new hash list based on @var{vhash} where @var{key} is associated with
|
|
@var{value}, using @var{hash-proc} to compute the hash of @var{key}.
|
|
@var{vhash} must be either @code{vlist-null} or a vhash returned by a previous
|
|
call to @code{vhash-cons}. @var{hash-proc} defaults to @code{hash} (@pxref{Hash
|
|
Table Reference, @code{hash} procedure}). With @code{vhash-consq}, the
|
|
@code{hashq} hash function is used; with @code{vhash-consv} the @code{hashv}
|
|
hash function is used.
|
|
|
|
All @code{vhash-cons} calls made to construct a vhash should use the same
|
|
@var{hash-proc}. Failing to do that, the result is undefined.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vhash-assoc key vhash [equal? [hash-proc]]
|
|
@deffnx {Scheme Procedure} vhash-assq key vhash
|
|
@deffnx {Scheme Procedure} vhash-assv key vhash
|
|
Return the first key/value pair from @var{vhash} whose key is equal to @var{key}
|
|
according to the @var{equal?} equality predicate (which defaults to
|
|
@code{equal?}), and using @var{hash-proc} (which defaults to @code{hash}) to
|
|
compute the hash of @var{key}. The second form uses @code{eq?} as the equality
|
|
predicate and @code{hashq} as the hash function; the last form uses @code{eqv?}
|
|
and @code{hashv}.
|
|
|
|
Note that it is important to consistently use the same hash function for
|
|
@var{hash-proc} as was passed to @code{vhash-cons}. Failing to do that, the
|
|
result is unpredictable.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vhash-delete key vhash [equal? [hash-proc]]
|
|
@deffnx {Scheme Procedure} vhash-delq key vhash
|
|
@deffnx {Scheme Procedure} vhash-delv key vhash
|
|
Remove all associations from @var{vhash} with @var{key}, comparing keys with
|
|
@var{equal?} (which defaults to @code{equal?}), and computing the hash of
|
|
@var{key} using @var{hash-proc} (which defaults to @code{hash}). The second
|
|
form uses @code{eq?} as the equality predicate and @code{hashq} as the hash
|
|
function; the last one uses @code{eqv?} and @code{hashv}.
|
|
|
|
Again the choice of @var{hash-proc} must be consistent with previous calls to
|
|
@code{vhash-cons}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vhash-fold proc init vhash
|
|
@deffnx {Scheme Procedure} vhash-fold-right proc init vhash
|
|
Fold over the key/value elements of @var{vhash} in the given direction,
|
|
with each call to @var{proc} having the form @code{(@var{proc} key value
|
|
result)}, where @var{result} is the result of the previous call to
|
|
@var{proc} and @var{init} the value of @var{result} for the first call
|
|
to @var{proc}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} vhash-fold* proc init key vhash [equal? [hash]]
|
|
@deffnx {Scheme Procedure} vhash-foldq* proc init key vhash
|
|
@deffnx {Scheme Procedure} vhash-foldv* proc init key vhash
|
|
Fold over all the values associated with @var{key} in @var{vhash}, with each
|
|
call to @var{proc} having the form @code{(proc value result)}, where
|
|
@var{result} is the result of the previous call to @var{proc} and @var{init} the
|
|
value of @var{result} for the first call to @var{proc}.
|
|
|
|
Keys in @var{vhash} are hashed using @var{hash} are compared using @var{equal?}.
|
|
The second form uses @code{eq?} as the equality predicate and @code{hashq} as
|
|
the hash function; the third one uses @code{eqv?} and @code{hashv}.
|
|
|
|
Example:
|
|
|
|
@example
|
|
(define vh
|
|
(alist->vhash '((a . 1) (a . 2) (z . 0) (a . 3))))
|
|
|
|
(vhash-fold* cons '() 'a vh)
|
|
@result{} (3 2 1)
|
|
|
|
(vhash-fold* cons '() 'z vh)
|
|
@result{} (0)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} alist->vhash alist [hash-proc]
|
|
Return the vhash corresponding to @var{alist}, an association list, using
|
|
@var{hash-proc} to compute key hashes. When omitted, @var{hash-proc} defaults
|
|
to @code{hash}.
|
|
@end deffn
|
|
|
|
|
|
@node Hash Tables
|
|
@subsection Hash Tables
|
|
@tpindex Hash Tables
|
|
|
|
Hash tables are dictionaries which offer similar functionality as
|
|
association lists: They provide a mapping from keys to values. The
|
|
difference is that association lists need time linear in the size of
|
|
elements when searching for entries, whereas hash tables can normally
|
|
search in constant time. The drawback is that hash tables require a
|
|
little bit more memory, and that you can not use the normal list
|
|
procedures (@pxref{Lists}) for working with them.
|
|
|
|
@menu
|
|
* Hash Table Examples:: Demonstration of hash table usage.
|
|
* Hash Table Reference:: Hash table procedure descriptions.
|
|
@end menu
|
|
|
|
|
|
@node Hash Table Examples
|
|
@subsubsection Hash Table Examples
|
|
|
|
For demonstration purposes, this section gives a few usage examples of
|
|
some hash table procedures, together with some explanation what they do.
|
|
|
|
First we start by creating a new hash table with 31 slots, and
|
|
populate it with two key/value pairs.
|
|
|
|
@lisp
|
|
(define h (make-hash-table 31))
|
|
|
|
;; This is an opaque object
|
|
h
|
|
@result{}
|
|
#<hash-table 0/31>
|
|
|
|
;; Inserting into a hash table can be done with hashq-set!
|
|
(hashq-set! h 'foo "bar")
|
|
@result{}
|
|
"bar"
|
|
|
|
(hashq-set! h 'braz "zonk")
|
|
@result{}
|
|
"zonk"
|
|
|
|
;; Or with hash-create-handle!
|
|
(hashq-create-handle! h 'frob #f)
|
|
@result{}
|
|
(frob . #f)
|
|
@end lisp
|
|
|
|
You can get the value for a given key with the procedure
|
|
@code{hashq-ref}, but the problem with this procedure is that you
|
|
cannot reliably determine whether a key does exists in the table. The
|
|
reason is that the procedure returns @code{#f} if the key is not in
|
|
the table, but it will return the same value if the key is in the
|
|
table and just happens to have the value @code{#f}, as you can see in
|
|
the following examples.
|
|
|
|
@lisp
|
|
(hashq-ref h 'foo)
|
|
@result{}
|
|
"bar"
|
|
|
|
(hashq-ref h 'frob)
|
|
@result{}
|
|
#f
|
|
|
|
(hashq-ref h 'not-there)
|
|
@result{}
|
|
#f
|
|
@end lisp
|
|
|
|
It is often better is to use the procedure @code{hashq-get-handle},
|
|
which makes a distinction between the two cases. Just like @code{assq},
|
|
this procedure returns a key/value-pair on success, and @code{#f} if the
|
|
key is not found.
|
|
|
|
@lisp
|
|
(hashq-get-handle h 'foo)
|
|
@result{}
|
|
(foo . "bar")
|
|
|
|
(hashq-get-handle h 'not-there)
|
|
@result{}
|
|
#f
|
|
@end lisp
|
|
|
|
Interesting results can be computed by using @code{hash-fold} to work
|
|
through each element. This example will count the total number of
|
|
elements:
|
|
|
|
@lisp
|
|
(hash-fold (lambda (key value seed) (+ 1 seed)) 0 h)
|
|
@result{}
|
|
3
|
|
@end lisp
|
|
|
|
The same thing can be done with the procedure @code{hash-count}, which
|
|
can also count the number of elements matching a particular predicate.
|
|
For example, count the number of elements with string values:
|
|
|
|
@lisp
|
|
(hash-count (lambda (key value) (string? value)) h)
|
|
@result{}
|
|
2
|
|
@end lisp
|
|
|
|
Counting all the elements is a simple task using @code{const}:
|
|
|
|
@lisp
|
|
(hash-count (const #t) h)
|
|
@result{}
|
|
3
|
|
@end lisp
|
|
|
|
@node Hash Table Reference
|
|
@subsubsection Hash Table Reference
|
|
|
|
@c FIXME: Describe in broad terms what happens for resizing, and what
|
|
@c the initial size means for this.
|
|
|
|
Like the association list functions, the hash table functions come in
|
|
several varieties, according to the equality test used for the keys.
|
|
Plain @code{hash-} functions use @code{equal?}, @code{hashq-}
|
|
functions use @code{eq?}, @code{hashv-} functions use @code{eqv?}, and
|
|
the @code{hashx-} functions use an application supplied test.
|
|
|
|
A single @code{make-hash-table} creates a hash table suitable for use
|
|
with any set of functions, but it's imperative that just one set is
|
|
then used consistently, or results will be unpredictable.
|
|
|
|
Hash tables are implemented as a vector indexed by a hash value formed
|
|
from the key, with an association list of key/value pairs for each
|
|
bucket in case distinct keys hash together. Direct access to the
|
|
pairs in those lists is provided by the @code{-handle-} functions.
|
|
|
|
When the number of entries in a hash table goes above a threshold, the
|
|
vector is made larger and the entries are rehashed, to prevent the
|
|
bucket lists from becoming too long and slowing down accesses. When the
|
|
number of entries goes below a threshold, the vector is shrunk to save
|
|
space.
|
|
|
|
For the @code{hashx-} ``extended'' routines, an application supplies a
|
|
@var{hash} function producing an integer index like @code{hashq} etc
|
|
below, and an @var{assoc} alist search function like @code{assq} etc
|
|
(@pxref{Retrieving Alist Entries}). Here's an example of such
|
|
functions implementing case-insensitive hashing of string keys,
|
|
|
|
@example
|
|
(use-modules (srfi srfi-1)
|
|
(srfi srfi-13))
|
|
|
|
(define (my-hash str size)
|
|
(remainder (string-hash-ci str) size))
|
|
(define (my-assoc str alist)
|
|
(find (lambda (pair) (string-ci=? str (car pair))) alist))
|
|
|
|
(define my-table (make-hash-table))
|
|
(hashx-set! my-hash my-assoc my-table "foo" 123)
|
|
|
|
(hashx-ref my-hash my-assoc my-table "FOO")
|
|
@result{} 123
|
|
@end example
|
|
|
|
In a @code{hashx-} @var{hash} function the aim is to spread keys
|
|
across the vector, so bucket lists don't become long. But the actual
|
|
values are arbitrary as long as they're in the range 0 to
|
|
@math{@var{size}-1}. Helpful functions for forming a hash value, in
|
|
addition to @code{hashq} etc below, include @code{symbol-hash}
|
|
(@pxref{Symbol Keys}), @code{string-hash} and @code{string-hash-ci}
|
|
(@pxref{String Comparison}), and @code{char-set-hash}
|
|
(@pxref{Character Set Predicates/Comparison}).
|
|
|
|
@sp 1
|
|
@deffn {Scheme Procedure} make-hash-table [size]
|
|
Create a new hash table object, with an optional minimum
|
|
vector @var{size}.
|
|
|
|
When @var{size} is given, the table vector will still grow and shrink
|
|
automatically, as described above, but with @var{size} as a minimum.
|
|
If an application knows roughly how many entries the table will hold
|
|
then it can use @var{size} to avoid rehashing when initial entries are
|
|
added.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} alist->hash-table alist
|
|
@deffnx {Scheme Procedure} alist->hashq-table alist
|
|
@deffnx {Scheme Procedure} alist->hashv-table alist
|
|
@deffnx {Scheme Procedure} alist->hashx-table hash assoc alist
|
|
Convert @var{alist} into a hash table. When keys are repeated in
|
|
@var{alist}, the leftmost association takes precedence.
|
|
|
|
@example
|
|
(use-modules (ice-9 hash-table))
|
|
(alist->hash-table '((foo . 1) (bar . 2)))
|
|
@end example
|
|
|
|
When converting to an extended hash table, custom @var{hash} and
|
|
@var{assoc} procedures must be provided.
|
|
|
|
@example
|
|
(alist->hashx-table hash assoc '((foo . 1) (bar . 2)))
|
|
@end example
|
|
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash-table? obj
|
|
@deffnx {C Function} scm_hash_table_p (obj)
|
|
Return @code{#t} if @var{obj} is a abstract hash table object.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash-clear! table
|
|
@deffnx {C Function} scm_hash_clear_x (table)
|
|
Remove all items from @var{table} (without triggering a resize).
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash-ref table key [dflt]
|
|
@deffnx {Scheme Procedure} hashq-ref table key [dflt]
|
|
@deffnx {Scheme Procedure} hashv-ref table key [dflt]
|
|
@deffnx {Scheme Procedure} hashx-ref hash assoc table key [dflt]
|
|
@deffnx {C Function} scm_hash_ref (table, key, dflt)
|
|
@deffnx {C Function} scm_hashq_ref (table, key, dflt)
|
|
@deffnx {C Function} scm_hashv_ref (table, key, dflt)
|
|
@deffnx {C Function} scm_hashx_ref (hash, assoc, table, key, dflt)
|
|
Lookup @var{key} in the given hash @var{table}, and return the
|
|
associated value. If @var{key} is not found, return @var{dflt}, or
|
|
@code{#f} if @var{dflt} is not given.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash-set! table key val
|
|
@deffnx {Scheme Procedure} hashq-set! table key val
|
|
@deffnx {Scheme Procedure} hashv-set! table key val
|
|
@deffnx {Scheme Procedure} hashx-set! hash assoc table key val
|
|
@deffnx {C Function} scm_hash_set_x (table, key, val)
|
|
@deffnx {C Function} scm_hashq_set_x (table, key, val)
|
|
@deffnx {C Function} scm_hashv_set_x (table, key, val)
|
|
@deffnx {C Function} scm_hashx_set_x (hash, assoc, table, key, val)
|
|
Associate @var{val} with @var{key} in the given hash @var{table}. If
|
|
@var{key} is already present then it's associated value is changed.
|
|
If it's not present then a new entry is created.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash-remove! table key
|
|
@deffnx {Scheme Procedure} hashq-remove! table key
|
|
@deffnx {Scheme Procedure} hashv-remove! table key
|
|
@deffnx {Scheme Procedure} hashx-remove! hash assoc table key
|
|
@deffnx {C Function} scm_hash_remove_x (table, key)
|
|
@deffnx {C Function} scm_hashq_remove_x (table, key)
|
|
@deffnx {C Function} scm_hashv_remove_x (table, key)
|
|
@deffnx {C Function} scm_hashx_remove_x (hash, assoc, table, key)
|
|
Remove any association for @var{key} in the given hash @var{table}.
|
|
If @var{key} is not in @var{table} then nothing is done.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash key size
|
|
@deffnx {Scheme Procedure} hashq key size
|
|
@deffnx {Scheme Procedure} hashv key size
|
|
@deffnx {C Function} scm_hash (key, size)
|
|
@deffnx {C Function} scm_hashq (key, size)
|
|
@deffnx {C Function} scm_hashv (key, size)
|
|
Return a hash value for @var{key}. This is a number in the range
|
|
@math{0} to @math{@var{size}-1}, which is suitable for use in a hash
|
|
table of the given @var{size}.
|
|
|
|
Note that @code{hashq} and @code{hashv} may use internal addresses of
|
|
objects, so if an object is garbage collected and re-created it can
|
|
have a different hash value, even when the two are notionally
|
|
@code{eq?}. For instance with symbols,
|
|
|
|
@example
|
|
(hashq 'something 123) @result{} 19
|
|
(gc)
|
|
(hashq 'something 123) @result{} 62
|
|
@end example
|
|
|
|
In normal use this is not a problem, since an object entered into a
|
|
hash table won't be garbage collected until removed. It's only if
|
|
hashing calculations are somehow separated from normal references that
|
|
its lifetime needs to be considered.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash-get-handle table key
|
|
@deffnx {Scheme Procedure} hashq-get-handle table key
|
|
@deffnx {Scheme Procedure} hashv-get-handle table key
|
|
@deffnx {Scheme Procedure} hashx-get-handle hash assoc table key
|
|
@deffnx {C Function} scm_hash_get_handle (table, key)
|
|
@deffnx {C Function} scm_hashq_get_handle (table, key)
|
|
@deffnx {C Function} scm_hashv_get_handle (table, key)
|
|
@deffnx {C Function} scm_hashx_get_handle (hash, assoc, table, key)
|
|
Return the @code{(@var{key} . @var{value})} pair for @var{key} in the
|
|
given hash @var{table}, or @code{#f} if @var{key} is not in
|
|
@var{table}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash-create-handle! table key init
|
|
@deffnx {Scheme Procedure} hashq-create-handle! table key init
|
|
@deffnx {Scheme Procedure} hashv-create-handle! table key init
|
|
@deffnx {Scheme Procedure} hashx-create-handle! hash assoc table key init
|
|
@deffnx {C Function} scm_hash_create_handle_x (table, key, init)
|
|
@deffnx {C Function} scm_hashq_create_handle_x (table, key, init)
|
|
@deffnx {C Function} scm_hashv_create_handle_x (table, key, init)
|
|
@deffnx {C Function} scm_hashx_create_handle_x (hash, assoc, table, key, init)
|
|
Return the @code{(@var{key} . @var{value})} pair for @var{key} in the
|
|
given hash @var{table}. If @var{key} is not in @var{table} then
|
|
create an entry for it with @var{init} as the value, and return that
|
|
pair.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash-map->list proc table
|
|
@deffnx {Scheme Procedure} hash-for-each proc table
|
|
@deffnx {C Function} scm_hash_map_to_list (proc, table)
|
|
@deffnx {C Function} scm_hash_for_each (proc, table)
|
|
Apply @var{proc} to the entries in the given hash @var{table}. Each
|
|
call is @code{(@var{proc} @var{key} @var{value})}. @code{hash-map->list}
|
|
returns a list of the results from these calls, @code{hash-for-each}
|
|
discards the results and returns an unspecified value.
|
|
|
|
Calls are made over the table entries in an unspecified order, and for
|
|
@code{hash-map->list} the order of the values in the returned list is
|
|
unspecified. Results will be unpredictable if @var{table} is modified
|
|
while iterating.
|
|
|
|
For example the following returns a new alist comprising all the
|
|
entries from @code{mytable}, in no particular order.
|
|
|
|
@example
|
|
(hash-map->list cons mytable)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash-for-each-handle proc table
|
|
@deffnx {C Function} scm_hash_for_each_handle (proc, table)
|
|
Apply @var{proc} to the entries in the given hash @var{table}. Each
|
|
call is @code{(@var{proc} @var{handle})}, where @var{handle} is a
|
|
@code{(@var{key} . @var{value})} pair. Return an unspecified value.
|
|
|
|
@code{hash-for-each-handle} differs from @code{hash-for-each} only in
|
|
the argument list of @var{proc}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash-fold proc init table
|
|
@deffnx {C Function} scm_hash_fold (proc, init, table)
|
|
Accumulate a result by applying @var{proc} to the elements of the
|
|
given hash @var{table}. Each call is @code{(@var{proc} @var{key}
|
|
@var{value} @var{prior-result})}, where @var{key} and @var{value} are
|
|
from the @var{table} and @var{prior-result} is the return from the
|
|
previous @var{proc} call. For the first call, @var{prior-result} is
|
|
the given @var{init} value.
|
|
|
|
Calls are made over the table entries in an unspecified order.
|
|
Results will be unpredictable if @var{table} is modified while
|
|
@code{hash-fold} is running.
|
|
|
|
For example, the following returns a count of how many keys in
|
|
@code{mytable} are strings.
|
|
|
|
@example
|
|
(hash-fold (lambda (key value prior)
|
|
(if (string? key) (1+ prior) prior))
|
|
0 mytable)
|
|
@end example
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} hash-count pred table
|
|
@deffnx {C Function} scm_hash_count (pred, table)
|
|
Return the number of elements in the given hash @var{table} that cause
|
|
@code{(@var{pred} @var{key} @var{value})} to return true. To quickly
|
|
determine the total number of elements, use @code{(const #t)} for
|
|
@var{pred}.
|
|
@end deffn
|
|
|
|
@node Other Types
|
|
@subsection Other Types
|
|
|
|
Procedures are documented in their own section. @xref{Procedures}.
|
|
|
|
Variable objects are documented as part of the description of Guile's
|
|
module system: see @ref{Variables}.
|
|
|
|
@xref{Scheduling}, for discussion of threads, mutexes, and so on.
|
|
|
|
Ports are described in the section on I/O: see @ref{Input and Output}.
|
|
|
|
Regular expressions are described in their own section: see @ref{Regular
|
|
Expressions}.
|
|
|
|
There are quite a number of additional data types documented in this
|
|
manual; if you feel a link is missing here, please file a bug.
|
|
|
|
@c Local Variables:
|
|
@c TeX-master: "guile.texi"
|
|
@c End:
|