diff options
author | Martin Grabmüller <mgrabmue@cs.tu-berlin.de> | 2001-07-04 06:11:19 +0000 |
---|---|---|
committer | Martin Grabmüller <mgrabmue@cs.tu-berlin.de> | 2001-07-04 06:11:19 +0000 |
commit | 04e3da4f2242f6733cecff384af39d0f5f26bc7e (patch) | |
tree | 9bd562cf94438e55b2ddd78dae4bd0d82663ae04 | |
parent | 6d52dbf2efa11332118d201323df2b92261a3444 (diff) | |
download | guile-04e3da4f2242f6733cecff384af39d0f5f26bc7e.tar.gz |
* scheme-data.texi (Hook Reference): Removed documentation for
`make-hook-with-name', which does note exist. Added note about
unspecified return values to all procedure documentation
-rw-r--r-- | doc/ChangeLog | 6 | ||||
-rwxr-xr-x | doc/scheme-data.texi | 5232 |
2 files changed, 6 insertions, 5232 deletions
diff --git a/doc/ChangeLog b/doc/ChangeLog index bafa78884..ef0012f8d 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,9 @@ +2001-07-04 Martin Grabmueller <mgrabmue@cs.tu-berlin.de> + + * scheme-data.texi (Hook Reference): Removed documentation for + `make-hook-with-name', which does note exist. Added note about + unspecified return values to all procedure documentation + 2001-07-02 Martin Grabmueller <mgrabmue@cs.tu-berlin.de> * srfi-modules.texi (SRFI-1 Fold and Map): Documented extended diff --git a/doc/scheme-data.texi b/doc/scheme-data.texi index 120a2b638..e69de29bb 100755 --- a/doc/scheme-data.texi +++ b/doc/scheme-data.texi @@ -1,5232 +0,0 @@ -@page -@node Data Types -@chapter Data Types for Generic Use - -This chapter describes all the data types that Guile provides for -``generic use''. - -One of the great strengths of Scheme is that there is no straightforward -distinction between ``data'' and ``functionality''. For example, -Guile's support for dynamic linking could be described - -@itemize @bullet -@item -either in a ``data-centric'' way, as the behaviour and properties of the -``dynamically linked object'' data type, and the operations that may be -applied to instances of this type - -@item -or in a ``functionality-centric'' way, as the set of procedures that -constitute Guile's support for dynamic linking, in the context of the -module system. -@end itemize - -The contents of this chapter are, therefore, a matter of judgement. By -``generic use'', we mean to select those data types whose typical use as -@emph{data} in a wide variety of programming contexts is more important -than their use in the implementation of a particular piece of -@emph{functionality}. - -@ifinfo -The following menu -@end ifinfo -@iftex -The table of contents for this chapter -@end iftex -@ifhtml -The following table of contents -@end ifhtml -shows the data types that are documented in this chapter. The final -section of this chapter lists all the core Guile data types that are not -documented here, and provides links to the ``functionality-centric'' -sections of this manual that cover them. - -@menu -* Booleans:: True/false values. -* Numbers:: Numerical data types. -* Characters:: New character names. -* Strings:: Special things about strings. -* Regular Expressions:: Pattern matching and substitution. -* Symbols and Variables:: Manipulating the Scheme symbol table. -* 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. -* Records:: -* Structures:: -* Arrays:: Arrays of values. -* Association Lists and Hash Tables:: Dictionary data types. -* Hooks:: User-customizable event lists. -* Other Data Types:: Data types that are documented elsewhere. -@end menu - - -@node Booleans -@section Booleans -@tpindex Booleans - -The two boolean values are @code{#t} for true and @code{#f} for false. - -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{if -cond case}), 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). - -The @code{not} procedure returns the boolean inverse of its argument: - -@rnindex not -@deffn primitive not x -Return @code{#t} iff @var{x} is @code{#f}, else return @code{#f}. -@end deffn - -The @code{boolean?} procedure is a predicate that returns @code{#t} if -its argument is one of the boolean values, otherwise @code{#f}. - -@rnindex boolean? -@deffn primitive boolean? obj -Return @code{#t} iff @var{obj} is either @code{#t} or @code{#f}. -@end deffn - - -@node Numbers -@section 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 -@xref{Numbers,,,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. -* Primitive Numerics:: Primitive numeric functions. -* Bitwise Operations:: Logical AND, OR, NOT, and so on. -* Random:: Random number generation. -@end menu - - -@node Numerical Tower -@subsection Scheme's Numerical ``Tower'' -@rnindex number? - -Scheme's numerical ``tower'' consists of the following categories of -numbers: - -@itemize @bullet -@item -integers (whole numbers) - -@item -rationals (the set of numbers that can be expressed as P/Q where P and Q -are integers) - -@item -real numbers (the set of numbers that describes all possible positions -along a one dimensional line) - -@item -complex numbers (the set of numbers that describes all possible -positions in a two dimensional space) -@end itemize - -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). - -Of these, Guile implements integers, reals and complex numbers as -distinct types. Rationals are implemented as regards the read syntax -for rational numbers that is specified by R5RS, but are immediately -converted by Guile to the corresponding real number. - -The @code{number?} predicate may be applied to any Scheme value to -discover whether the value is any of the supported numerical types. - -@deffn primitive number? obj -Return @code{#t} if @var{obj} is any kind of number, @code{#f} else. -@end deffn - -For example: - -@lisp -(number? 3) -@result{} -#t - -(number? "hello there!") -@result{} -#f - -(define pi 3.141592654) -(number? pi) -@result{} -#t -@end lisp - -The next few subsections document each of Guile's numerical data types -in detail. - -@node Integers -@subsection Integers - -@tpindex Integer numbers - -@rnindex integer? - -Integers are whole numbers, that is numbers with no fractional part, -such as 2, 83 and -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 REFFIXME Maybe point here to discussion of handling immediates/bignums -@c on the C level, where the conversion is not so automatic - NJ - -@deffn primitive integer? x -Return @code{#t} if @var{x} is an integer number, @code{#f} else. - -@lisp -(integer? 487) -@result{} -#t - -(integer? -3.4) -@result{} -#f -@end lisp -@end deffn - - -@node Reals and Rationals -@subsection 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 P/Q, where P and Q are integers. All rational numbers are -also real, but there are real numbers that are not rational, for example -the square root of 2, and pi. - -Guile represents both real and rational numbers approximately using a -floating point encoding with limited precision. Even though the actual -encoding 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 ``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, -@code{-0.00000142857931198} is the same as @code{142857931198} divided by -@code{100000000000000000}. In Guile's current incarnation, therefore, -the @code{rational?} and @code{real?} predicates are equivalent. - -Another aspect of this equivalence is that Guile currently does not -preserve the exactness that is possible with rational arithmetic. -If such exactness is needed, it is of course possible to implement -exact rational arithmetic at the Scheme level using Guile's arbitrary -size integers. - -A planned future revision of Guile's numerical tower will make it -possible to implement exact representations and arithmetic for both -rational numbers and real irrational numbers such as square roots, -and in such a way that the new kinds of number integrate seamlessly -with those that are already implemented. - -@deffn primitive real? obj -Return @code{#t} if @var{obj} is a real number, @code{#f} else. -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 primitive rational? x -Return @code{#t} if @var{x} is a rational number, @code{#f} -else. 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. Real numbers -will also satisfy this predicate, because of their limited -precision. -@end deffn - - -@node Complex Numbers -@subsection 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 - -Guile represents a complex number as a pair of numbers both of which are -real, so the real and imaginary parts of a complex number have the same -properties of inexactness and limited precision as single real numbers. - -@deffn primitive complex? x -Return @code{#t} if @var{x} is a complex number, @code{#f} -else. 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{x} is a real, -rational or integer number. -@end deffn - - -@node Exactness -@subsection Exact and Inexact Numbers -@tpindex Exact numbers -@tpindex Inexact numbers - -@rnindex exact? -@rnindex inexact? -@rnindex exact->inexact -@rnindex inexact->exact - -R5RS requires that a calculation involving inexact numbers always -produces an inexact result. To meet this requirement, Guile -distinguishes between an exact integer value such as @code{5} and the -corresponding inexact real value which, to the limited precision -available, has no fractional part, and is printed as @code{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. - -@deffn primitive exact? x -Return @code{#t} if @var{x} is an exact number, @code{#f} -otherwise. -@end deffn - -@deffn primitive inexact? x -Return @code{#t} if @var{x} is an inexact number, @code{#f} -else. -@end deffn - -@deffn primitive inexact->exact z -Return an exact number that is numerically closest to @var{z}. -@end deffn - -@c begin (texi-doc-string "guile" "exact->inexact") -@deffn primitive exact->inexact z -Convert the number @var{z} to its inexact representation. -@end deffn - - -@node Number Syntax -@subsection 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: - -@itemize @bullet -@item -@code{#b}, @code{#B} --- the integer is written in binary (base 2) - -@item -@code{#o}, @code{#O} --- the integer is written in octal (base 8) - -@item -@code{#d}, @code{#D} --- the integer is written in decimal (base 10) - -@item -@code{#x}, @code{#X} --- the integer is written in hexadecimal (base 16). -@end itemize - -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: - -@itemize @bullet -@item -@code{#e}, @code{#E} --- the number is exact - -@item -@code{#i}, @code{#I} --- the number is inexact. -@end itemize - -If the exactness indicator is omitted, the integer is assumed to be exact, -since Guile's internal representation for integers is always exact. -Real numbers have limited precision similar to the precision of the -@code{double} type in C. A consequence of the limited precision is that -all real numbers in Guile are also rational, since any number R with a -limited number of decimal places, say N, can be made into an integer by -multiplying by 10^N. - - -@node Integer Operations -@subsection Operations on Integer Values -@rnindex odd? -@rnindex even? -@rnindex quotient -@rnindex remainder -@rnindex modulo -@rnindex gcd -@rnindex lcm - -@deffn primitive odd? n -Return @code{#t} if @var{n} is an odd number, @code{#f} -otherwise. -@end deffn - -@deffn primitive even? n -Return @code{#t} if @var{n} is an even number, @code{#f} -otherwise. -@end deffn - -@c begin (texi-doc-string "guile" "quotient") -@deffn primitive quotient -Return the quotient of the numbers @var{x} and @var{y}. -@end deffn - -@c begin (texi-doc-string "guile" "remainder") -@deffn primitive remainder -Return the remainder of the numbers @var{x} and @var{y}. -@lisp -(remainder 13 4) @result{} 1 -(remainder -13 4) @result{} -1 -@end lisp -@end deffn - -@c begin (texi-doc-string "guile" "modulo") -@deffn primitive modulo -Return the modulo of the numbers @var{x} and @var{y}. -@lisp -(modulo 13 4) @result{} 1 -(modulo -13 4) @result{} 3 -@end lisp -@end deffn - -@c begin (texi-doc-string "guile" "gcd") -@deffn primitive gcd -Return the greatest common divisor of all arguments. -If called without arguments, 0 is returned. -@end deffn - -@c begin (texi-doc-string "guile" "lcm") -@deffn primitive lcm -Return the least common multiple of the arguments. -If called without arguments, 1 is returned. -@end deffn - - -@node Comparison -@subsection Comparison Predicates -@rnindex zero? -@rnindex positive? -@rnindex negative? - -@c begin (texi-doc-string "guile" "=") -@deffn primitive = -Return @code{#t} if all parameters are numerically equal. -@end deffn - -@c begin (texi-doc-string "guile" "<") -@deffn primitive < -Return @code{#t} if the list of parameters is monotonically -increasing. -@end deffn - -@c begin (texi-doc-string "guile" ">") -@deffn primitive > -Return @code{#t} if the list of parameters is monotonically -decreasing. -@end deffn - -@c begin (texi-doc-string "guile" "<=") -@deffn primitive <= -Return @code{#t} if the list of parameters is monotonically -non-decreasing. -@end deffn - -@c begin (texi-doc-string "guile" ">=") -@deffn primitive >= -Return @code{#t} if the list of parameters is monotonically -non-increasing. -@end deffn - -@c begin (texi-doc-string "guile" "zero?") -@deffn primitive zero? -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 primitive positive? -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 primitive negative? -Return @code{#t} if @var{x} is an exact or inexact number less than -zero. -@end deffn - - -@node Conversion -@subsection Converting Numbers To and From Strings -@rnindex number->string -@rnindex string->number - -@deffn primitive number->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 primitive string->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 - - -@node Complex -@subsection Complex Number Operations -@rnindex make-rectangular -@rnindex make-polar -@rnindex real-part -@rnindex imag-part -@rnindex magnitude -@rnindex angle - -@deffn primitive make-rectangular real imaginary -Return a complex number constructed of the given @var{real} and -@var{imaginary} parts. -@end deffn - -@deffn primitive make-polar x y -Return the complex number @var{x} * e^(i * @var{y}). -@end deffn - -@c begin (texi-doc-string "guile" "real-part") -@deffn primitive real-part -Return the real part of the number @var{z}. -@end deffn - -@c begin (texi-doc-string "guile" "imag-part") -@deffn primitive imag-part -Return the imaginary part of the number @var{z}. -@end deffn - -@c begin (texi-doc-string "guile" "magnitude") -@deffn primitive magnitude -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 primitive angle -Return the angle of the complex number @var{z}. -@end deffn - - -@node Arithmetic -@subsection Arithmetic Functions -@rnindex max -@rnindex min -@rnindex + -@rnindex * -@rnindex - -@rnindex / -@rnindex abs -@rnindex floor -@rnindex ceiling -@rnindex truncate -@rnindex round - -@c begin (texi-doc-string "guile" "+") -@deffn primitive + z1 @dots{} -Return the sum of all parameter values. Return 0 if called without any -parameters. -@end deffn - -@c begin (texi-doc-string "guile" "-") -@deffn primitive - z1 z2 @dots{} -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 primitive * z1 @dots{} -Return the product of all arguments. If called without arguments, 1 is -returned. -@end deffn - -@c begin (texi-doc-string "guile" "/") -@deffn primitive / z1 z2 @dots{} -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 - -@c begin (texi-doc-string "guile" "abs") -@deffn primitive abs x -Return the absolute value of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "max") -@deffn primitive max x1 x2 @dots{} -Return the maximum of all parameter values. -@end deffn - -@c begin (texi-doc-string "guile" "min") -@deffn primitive min x1 x2 @dots{} -Return the minium of all parameter values. -@end deffn - -@c begin (texi-doc-string "guile" "truncate") -@deffn primitive truncate -Round the inexact number @var{x} towards zero. -@end deffn - -@c begin (texi-doc-string "guile" "round") -@deffn primitive round x -Round the inexact number @var{x} towards zero. -@end deffn - -@c begin (texi-doc-string "guile" "floor") -@deffn primitive floor x -Round the number @var{x} towards minus infinity. -@end deffn - -@c begin (texi-doc-string "guile" "ceiling") -@deffn primitive ceiling x -Round the number @var{x} towards infinity. -@end deffn - - -@node Scientific -@subsection 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 procedure sqrt z -Return the square root of @var{z}. -@end deffn - -@rnindex expt -@c begin (texi-doc-string "guile" "expt") -@deffn 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 procedure sin z -Return the sine of @var{z}. -@end deffn - -@rnindex cos -@c begin (texi-doc-string "guile" "cos") -@deffn procedure cos z -Return the cosine of @var{z}. -@end deffn - -@rnindex tan -@c begin (texi-doc-string "guile" "tan") -@deffn procedure tan z -Return the tangent of @var{z}. -@end deffn - -@rnindex asin -@c begin (texi-doc-string "guile" "asin") -@deffn procedure asin z -Return the arcsine of @var{z}. -@end deffn - -@rnindex acos -@c begin (texi-doc-string "guile" "acos") -@deffn procedure acos z -Return the arccosine of @var{z}. -@end deffn - -@rnindex atan -@c begin (texi-doc-string "guile" "atan") -@deffn procedure atan z -Return the arctangent of @var{z}. -@end deffn - -@rnindex exp -@c begin (texi-doc-string "guile" "exp") -@deffn 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 procedure log z -Return the natural logarithm of @var{z}. -@end deffn - -@c begin (texi-doc-string "guile" "log10") -@deffn procedure log10 z -Return the base 10 logarithm of @var{z}. -@end deffn - -@c begin (texi-doc-string "guile" "sinh") -@deffn procedure sinh z -Return the hyperbolic sine of @var{z}. -@end deffn - -@c begin (texi-doc-string "guile" "cosh") -@deffn procedure cosh z -Return the hyperbolic cosine of @var{z}. -@end deffn - -@c begin (texi-doc-string "guile" "tanh") -@deffn procedure tanh z -Return the hyperbolic tangent of @var{z}. -@end deffn - -@c begin (texi-doc-string "guile" "asinh") -@deffn procedure asinh z -Return the hyperbolic arcsine of @var{z}. -@end deffn - -@c begin (texi-doc-string "guile" "acosh") -@deffn procedure acosh z -Return the hyperbolic arccosine of @var{z}. -@end deffn - -@c begin (texi-doc-string "guile" "atanh") -@deffn procedure atanh z -Return the hyperbolic arctangent of @var{z}. -@end deffn - - -@node Primitive Numerics -@subsection Primitive Numeric Functions - -Many of Guile's numeric procedures which accept any kind of numbers as -arguments, including complex numbers, are implemented as Scheme -procedures that use the following real number-based primitives. These -primitives signal an error if they are called with complex arguments. - -@c begin (texi-doc-string "guile" "$abs") -@deffn primitive $abs x -Return the absolute value of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$sqrt") -@deffn primitive $sqrt x -Return the square root of @var{x}. -@end deffn - -@deffn primitive $expt x y -Return @var{x} raised to the power of @var{y}. This -procedure does not accept complex arguments. -@end deffn - -@c begin (texi-doc-string "guile" "$sin") -@deffn primitive $sin x -Return the sine of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$cos") -@deffn primitive $cos x -Return the cosine of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$tan") -@deffn primitive $tan x -Return the tangent of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$asin") -@deffn primitive $asin x -Return the arcsine of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$acos") -@deffn primitive $acos x -Return the arccosine of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$atan") -@deffn primitive $atan x -Return the arctangent of @var{x} in the range -PI/2 to PI/2. -@end deffn - -@deffn primitive $atan2 x y -Return the arc tangent of the two arguments @var{x} and -@var{y}. This is similar to calculating the arc tangent of -@var{x} / @var{y}, except that the signs of both arguments -are used to determine the quadrant of the result. This -procedure does not accept complex arguments. -@end deffn - -@c begin (texi-doc-string "guile" "$exp") -@deffn primitive $exp x -Return e to the power of @var{x}, where e is the base of natural -logarithms (2.71828@dots{}). -@end deffn - -@c begin (texi-doc-string "guile" "$log") -@deffn primitive $log x -Return the natural logarithm of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$sinh") -@deffn primitive $sinh x -Return the hyperbolic sine of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$cosh") -@deffn primitive $cosh x -Return the hyperbolic cosine of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$tanh") -@deffn primitive $tanh x -Return the hyperbolic tangent of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$asinh") -@deffn primitive $asinh x -Return the hyperbolic arcsine of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$acosh") -@deffn primitive $acosh x -Return the hyperbolic arccosine of @var{x}. -@end deffn - -@c begin (texi-doc-string "guile" "$atanh") -@deffn primitive $atanh x -Return the hyperbolic arctangent of @var{x}. -@end deffn - - -@node Bitwise Operations -@subsection Bitwise Operations - -@deffn primitive logand n1 n2 -Return the integer which is the bit-wise AND of the two integer -arguments. - -@lisp -(number->string (logand #b1100 #b1010) 2) - @result{} "1000" -@end lisp -@end deffn - -@deffn primitive logior n1 n2 -Return the integer which is the bit-wise OR of the two integer -arguments. - -@lisp -(number->string (logior #b1100 #b1010) 2) - @result{} "1110" -@end lisp -@end deffn - -@deffn primitive logxor n1 n2 -Return the integer which is the bit-wise XOR of the two integer -arguments. - -@lisp -(number->string (logxor #b1100 #b1010) 2) - @result{} "110" -@end lisp -@end deffn - -@deffn primitive lognot n -Return the integer which is the 2s-complement of the integer -argument. - -@lisp -(number->string (lognot #b10000000) 2) - @result{} "-10000001" -(number->string (lognot #b0) 2) - @result{} "-1" -@end lisp -@end deffn - -@deffn primitive logtest j k -@lisp -(logtest j k) @equiv{} (not (zero? (logand j k))) - -(logtest #b0100 #b1011) @result{} #f -(logtest #b0100 #b0111) @result{} #t -@end lisp -@end deffn - -@deffn primitive logbit? index j -@lisp -(logbit? index j) @equiv{} (logtest (integer-expt 2 index) j) - -(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 primitive ash n cnt -The function ash performs an arithmetic shift left by @var{cnt} -bits (or shift right, if @var{cnt} is negative). 'Arithmetic' -means, that the function does not guarantee to keep the bit -structure of @var{n}, but rather guarantees that the result -will always be rounded towards minus infinity. Therefore, the -results of ash and a corresponding bitwise shift will differ if -@var{n} is negative. - -Formally, the function returns an integer equivalent to -@code{(inexact->exact (floor (* @var{n} (expt 2 @var{cnt}))))}. - -@lisp -(number->string (ash #b1 3) 2) @result{} "1000" -(number->string (ash #b1010 -1) 2) @result{} "101" -@end lisp -@end deffn - -@deffn primitive logcount n -Return the number of bits in integer @var{n}. If integer 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 0, 0 is returned. - -@lisp -(logcount #b10101010) - @result{} 4 -(logcount 0) - @result{} 0 -(logcount -2) - @result{} 1 -@end lisp -@end deffn - -@deffn primitive integer-length n -Return the number of bits neccessary to represent @var{n}. - -@lisp -(integer-length #b10101010) - @result{} 8 -(integer-length 0) - @result{} 0 -(integer-length #b1111) - @result{} 4 -@end lisp -@end deffn - -@deffn primitive integer-expt n k -Return @var{n} raised to the non-negative integer exponent -@var{k}. - -@lisp -(integer-expt 2 5) - @result{} 32 -(integer-expt -3 3) - @result{} -27 -@end lisp -@end deffn - -@deffn primitive 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 -@subsection Random Number Generation - -@deffn primitive copy-random-state [state] -Return a copy of the random state @var{state}. -@end deffn - -@deffn primitive random n [state] -Return a number in [0,N). - -Accepts a positive integer or real n and returns a -number of the same type between zero (inclusive) and -N (exclusive). The values returned have a uniform -distribution. - -The optional argument @var{state} must be of the type produced -by @code{seed->random-state}. It defaults to the value of the -variable @var{*random-state*}. This object is used to maintain -the state of the pseudo-random-number generator and is altered -as a side effect of the random operation. -@end deffn - -@deffn primitive random:exp [state] -Return an inexact real in an exponential distribution with mean -1. For an exponential distribution with mean u use (* u -(random:exp)). -@end deffn - -@deffn primitive random:hollow-sphere! v [state] -Fills vect with inexact real random numbers -the sum of whose squares is equal to 1.0. -Thinking of vect as coordinates in space of -dimension n = (vector-length vect), the coordinates -are uniformly distributed over the surface of the -unit n-shere. -@end deffn - -@deffn primitive 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 m and standard deviation d use -@code{(+ m (* d (random:normal)))}. -@end deffn - -@deffn primitive random:normal-vector! v [state] -Fills vect with inexact real random numbers that are -independent and standard normally distributed -(i.e., with mean 0 and variance 1). -@end deffn - -@deffn primitive random:solid-sphere! v [state] -Fills vect with inexact real random numbers -the sum of whose squares is less than 1.0. -Thinking of vect as coordinates in space of -dimension n = (vector-length vect), the coordinates -are uniformly distributed within the unit n-shere. -The sum of the squares of the numbers is returned. -@end deffn - -@deffn primitive random:uniform [state] -Return a uniformly distributed inexact real random number in -[0,1). -@end deffn - -@deffn primitive seed->random-state seed -Return a new random state using @var{seed}. -@end deffn - - -@node Characters -@section Characters -@tpindex Characters - -Most of the characters in the ASCII character set may be referred to by -name: for example, @code{#\tab}, @code{#\esc}, @code{#\stx}, and so on. -The following table describes the ASCII names 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{#\nl} - @tab 11 = @code{#\vt} -@item 12 = @code{#\np} - @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 @code{delete} character (octal 177) may be referred to with the name -@code{#\del}. - -Several characters have more than one name: - -@itemize @bullet -@item -@code{#\space}, @code{#\sp} -@item -@code{#\newline}, @code{#\nl} -@item -@code{#\tab}, @code{#\ht} -@item -@code{#\backspace}, @code{#\bs} -@item -@code{#\return}, @code{#\cr} -@item -@code{#\page}, @code{#\np} -@item -@code{#\null}, @code{#\nul} -@end itemize - -@rnindex char? -@deffn primitive char? x -Return @code{#t} iff @var{x} is a character, else @code{#f}. -@end deffn - -@rnindex char=? -@deffn primitive char=? x y -Return @code{#t} iff @var{x} is the same character as @var{y}, else @code{#f}. -@end deffn - -@rnindex char<? -@deffn primitive char<? x y -Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence, -else @code{#f}. -@end deffn - -@rnindex char<=? -@deffn primitive char<=? x y -Return @code{#t} iff @var{x} is less than or equal to @var{y} in the -ASCII sequence, else @code{#f}. -@end deffn - -@rnindex char>? -@deffn primitive char>? x y -Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII -sequence, else @code{#f}. -@end deffn - -@rnindex char>=? -@deffn primitive char>=? x y -Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the -ASCII sequence, else @code{#f}. -@end deffn - -@rnindex char-ci=? -@deffn primitive char-ci=? x y -Return @code{#t} iff @var{x} is the same character as @var{y} ignoring -case, else @code{#f}. -@end deffn - -@rnindex char-ci<? -@deffn primitive char-ci<? x y -Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence -ignoring case, else @code{#f}. -@end deffn - -@rnindex char-ci<=? -@deffn primitive char-ci<=? x y -Return @code{#t} iff @var{x} is less than or equal to @var{y} in the -ASCII sequence ignoring case, else @code{#f}. -@end deffn - -@rnindex char-ci>? -@deffn primitive char-ci>? x y -Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII -sequence ignoring case, else @code{#f}. -@end deffn - -@rnindex char-ci>=? -@deffn primitive char-ci>=? x y -Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the -ASCII sequence ignoring case, else @code{#f}. -@end deffn - -@rnindex char-alphabetic? -@deffn primitive char-alphabetic? chr -Return @code{#t} iff @var{chr} is alphabetic, else @code{#f}. -Alphabetic means the same thing as the isalpha C library function. -@end deffn - -@rnindex char-numeric? -@deffn primitive char-numeric? chr -Return @code{#t} iff @var{chr} is numeric, else @code{#f}. -Numeric means the same thing as the isdigit C library function. -@end deffn - -@rnindex char-whitespace? -@deffn primitive char-whitespace? chr -Return @code{#t} iff @var{chr} is whitespace, else @code{#f}. -Whitespace means the same thing as the isspace C library function. -@end deffn - -@rnindex char-upper-case? -@deffn primitive char-upper-case? chr -Return @code{#t} iff @var{chr} is uppercase, else @code{#f}. -Uppercase means the same thing as the isupper C library function. -@end deffn - -@rnindex char-lower-case? -@deffn primitive char-lower-case? chr -Return @code{#t} iff @var{chr} is lowercase, else @code{#f}. -Lowercase means the same thing as the islower C library function. -@end deffn - -@deffn primitive char-is-both? chr -Return @code{#t} iff @var{chr} is either uppercase or lowercase, else @code{#f}. -Uppercase and lowercase are as defined by the isupper and islower -C library functions. -@end deffn - -@rnindex char->integer -@deffn primitive char->integer chr -Return the number corresponding to ordinal position of @var{chr} in the -ASCII sequence. -@end deffn - -@rnindex integer->char -@deffn primitive integer->char n -Return the character at position @var{n} in the ASCII sequence. -@end deffn - -@rnindex char-upcase -@deffn primitive char-upcase chr -Return the uppercase character version of @var{chr}. -@end deffn - -@rnindex char-downcase -@deffn primitive char-downcase chr -Return the lowercase character version of @var{chr}. -@end deffn - - -@node Strings -@section 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 REPL or in Scheme source files. - -Guile provides a rich set of string processing procedures, because text -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 NUL character @code{'\0'}. But note: Since most operating -system calls dealing with strings (such as for file operations) expect -strings to be zero-terminated, they might do unexpected things when -called with string containing unusal characters. - -@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. -* Appending Strings:: Appending strings to form a new string. -* String Miscellanea:: Miscellaneous string procedures. -@end menu - -@node String Syntax -@subsection String Read Syntax - -The read syntax for strings is an arbitrarily long sequence of -characters enclosed in double quotes (@code{"}). @footnote{Actually, the -current implementation restricts strings to a length of 2^24 -characters.} If you want to insert a double quote character into a -string literal, it must be prefixed with a backslash @code{\} character -(called an @emph{escape character}). - -The following are examples of string literals: - -@lisp -"foo" -"bar plonk" -"Hello World" -"\"Hi\", he said." -@end lisp - -@c FIXME::martin: What about escape sequences like \r, \n etc.? - -@node String Predicates -@subsection String Predicates - -The following procedures can be used to check whether a given string -fulfills some specified property. - -@rnindex string? -@deffn primitive string? obj -Return @code{#t} iff @var{obj} is a string, else returns -@code{#f}. -@end deffn - -@deffn primitive string-null? str -Return @code{#t} if @var{str}'s length is nonzero, and -@code{#f} otherwise. -@lisp -(string-null? "") @result{} #t -y @result{} "foo" -(string-null? y) @result{} #f -@end lisp -@end deffn - -@node String Constructors -@subsection String Constructors - -The string constructor procedures create new string objects, possibly -initializing them with some specified character data. - -@c FIXME::martin: list->string belongs into `List/String Conversion' - -@rnindex string -@rnindex list->string -@deffn primitive string . chrs -@deffnx primitive list->string chrs -Return a newly allocated string composed of the arguments, -@var{chrs}. -@end deffn - -@rnindex make-string -@deffn primitive 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 @var{string} are unspecified. -@end deffn - -@node List/String Conversion -@subsection 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 primitive string->list str -Return a newly allocated list of the characters that make up -the given string @var{str}. @code{string->list} and -@code{list->string} are inverses as far as @samp{equal?} is -concerned. -@end deffn - -@deffn primitive string-split str chr -Split the string @var{str} into the a list of the substrings delimited -by appearances of the character @var{chr}. 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 -@subsection 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 primitive string-length string -Return the number of characters in @var{string}. -@end deffn - -@rnindex string-ref -@deffn primitive 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 - -@rnindex string-copy -@deffn primitive string-copy str -Return a newly allocated copy of the given @var{string}. -@end deffn - -@rnindex substring -@deffn primitive substring str start [end] -Return a newly allocated 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} <= (string-length @var{str}). -@end deffn - -@node String Modification -@subsection String Modification - -These procedures are for modifying strings in-place. That means, that -not a new string is the result of a string operation, but that the -actual memory representation of a string is modified. - -@rnindex string-set! -@deffn primitive string-set! 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 - -@rnindex string-fill! -@deffn primitive string-fill! str chr -Store @var{char} in every element of the given @var{string} and -return an unspecified value. -@end deffn - -@deffn primitive substring-fill! str start end fill -Change every character in @var{str} between @var{start} and -@var{end} to @var{fill}. - -@lisp -(define y "abcdefg") -(substring-fill! y 1 3 #\r) -y -@result{} "arrdefg" -@end lisp -@end deffn - -@deffn primitive substring-move! str1 start1 end1 str2 start2 -@deffnx primitive substring-move-left! str1 start1 end1 str2 start2 -@deffnx primitive substring-move-right! 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{end2}. -@code{substring-move-right!} begins copying from the rightmost character -and moves left, and @code{substring-move-left!} copies from the leftmost -character moving right. - -It is useful to have two functions that copy in different directions so -that substrings can be copied back and forth within a single string. If -you wish to copy text from the left-hand side of a string to the -right-hand side of the same string, and the source and destination -overlap, you must be careful to copy the rightmost characters of the -text first, to avoid clobbering your data. Hence, when @var{str1} and -@var{str2} are the same string, you should use -@code{substring-move-right!} when moving text from left to right, and -@code{substring-move-left!} otherwise. If @code{str1} and @samp{str2} -are different strings, it does not matter which function you use. - -@example -(define x (make-string 10 #\a)) -(define y "bcd") -(substring-move-left! x 2 5 y 0) -y -@result{} "aaa" - -x -@result{} "aaaaaaaaaa" - -(define y "bcdefg") -(substring-move-left! x 2 5 y 0) -y -@result{} "aaaefg" - -(define y "abcdefg") -(substring-move-left! y 2 5 y 3) -y -@result{} "abccccg" - -(define y "abcdefg") -(substring-move-right! y 2 5 y 0) -y -@result{} "ededefg" - -(define y "abcdefg") -(substring-move-right! y 2 5 y 3) -y -@result{} "abccdeg" -@end example -@end deffn - - -@node String Comparison -@subsection String Comparison - -The procedures in this section are similar to the character ordering -predicates (@pxref{Characters}), but are defined on character sequences. -They all return @code{#t} on success and @code{#f} on failure. The -predicates ending in @code{-ci} ignore the character case when comparing -strings. - - -@rnindex string=? -@deffn primitive string=? s1 s2 -Lexicographic equality predicate; return @code{#t} if the two -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 primitive string<? s1 s2 -Lexicographic ordering predicate; return @code{#t} if @var{s1} -is lexicographically less than @var{s2}. -@end deffn - -@rnindex string<=? -@deffn primitive string<=? s1 s2 -Lexicographic ordering predicate; return @code{#t} if @var{s1} -is lexicographically less than or equal to @var{s2}. -@end deffn - -@rnindex string>? -@deffn primitive string>? s1 s2 -Lexicographic ordering predicate; return @code{#t} if @var{s1} -is lexicographically greater than @var{s2}. -@end deffn - -@rnindex string>=? -@deffn primitive string>=? s1 s2 -Lexicographic ordering predicate; return @code{#t} if @var{s1} -is lexicographically greater than or equal to @var{s2}. -@end deffn - -@rnindex string-ci=? -@deffn primitive string-ci=? s1 s2 -Case-insensitive string equality predicate; return @code{#t} if -the two 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 primitive string-ci<? s1 s2 -Case insensitive lexicographic ordering predicate; return -@code{#t} if @var{s1} is lexicographically less than @var{s2} -regardless of case. -@end deffn - -@rnindex string<=? -@deffn primitive string-ci<=? s1 s2 -Case insensitive lexicographic ordering predicate; return -@code{#t} if @var{s1} is lexicographically less than or equal -to @var{s2} regardless of case. -@end deffn - -@rnindex string-ci>? -@deffn primitive string-ci>? s1 s2 -Case insensitive lexicographic ordering predicate; return -@code{#t} if @var{s1} is lexicographically greater than -@var{s2} regardless of case. -@end deffn - -@rnindex string-ci>=? -@deffn primitive string-ci>=? s1 s2 -Case insensitive lexicographic ordering predicate; return -@code{#t} if @var{s1} is lexicographically greater than or -equal to @var{s2} regardless of case. -@end deffn - - -@node String Searching -@subsection String Searching - -When searching the index of a character in a string, these procedures -can be used. - -@deffn primitive string-index str chr [frm [to]] -Return the index of the first occurrence of @var{chr} in -@var{str}. The optional integer arguments @var{frm} and -@var{to} limit the search to a portion of the string. This -procedure essentially implements the @code{index} or -@code{strchr} functions from the C library. - -@lisp -(string-index "weiner" #\e) -@result{} 1 - -(string-index "weiner" #\e 2) -@result{} 4 - -(string-index "weiner" #\e 2 4) -@result{} #f -@end lisp -@end deffn - -@deffn primitive string-rindex str chr [frm [to]] -Like @code{string-index}, but search from the right of the -string rather than from the left. This procedure essentially -implements the @code{rindex} or @code{strrchr} functions from -the C library. - -@lisp -(string-rindex "weiner" #\e) -@result{} 4 - -(string-rindex "weiner" #\e 2 4) -@result{} #f - -(string-rindex "weiner" #\e 2 5) -@result{} 4 -@end lisp -@end deffn - -@node Alphabetic Case Mapping -@subsection Alphabetic Case Mapping - -These are procedures for mapping strings to their upper- or lower-case -equivalents, respectively, or for capitalizing strings. - -@deffn primitive string-upcase str -Return a freshly allocated string containing the characters of -@var{str} in upper case. -@end deffn - -@deffn primitive string-upcase! str -Destructively upcase every character in @var{str} and return -@var{str}. -@lisp -y @result{} "arrdefg" -(string-upcase! y) @result{} "ARRDEFG" -y @result{} "ARRDEFG" -@end lisp -@end deffn - -@deffn primitive string-downcase str -Return a freshly allocation string containing the characters in -@var{str} in lower case. -@end deffn - -@deffn primitive string-downcase! str -Destructively downcase every character in @var{str} and return -@var{str}. -@lisp -y @result{} "ARRDEFG" -(string-downcase! y) @result{} "arrdefg" -y @result{} "arrdefg" -@end lisp -@end deffn - -@deffn primitive 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 primitive string-capitalize! 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 - - -@node Appending Strings -@subsection Appending Strings - -The procedure @code{string-append} appends several strings together to -form a longer result string. - -@rnindex string-append -@deffn primitive string-append string1 @dots{} -Return a newly allocated string whose characters form the -concatenation of the given strings. -@end deffn - - -@node String Miscellanea -@subsection String Miscellanea - -This section contains all remaining string procedures. - -@deffn primitive string-ci->symbol str -Return the symbol whose name is @var{str}. @var{str} is -converted to lowercase before the conversion is done, if Guile -is currently reading symbols case-insensitively. -@end deffn - - -@node Regular Expressions -@section Regular Expressions -@tpindex Regular expressions - -@cindex regular expressions -@cindex regex -@cindex emacs regexp - -A @dfn{regular expression} (or @dfn{regexp}) is a pattern that -describes a whole class of strings. A full description of regular -expressions and their syntax is beyond the scope of this manual; -an introduction can be found in the Emacs manual (@pxref{Regexps, -, Syntax of Regular Expressions, emacs, The GNU Emacs Manual}, or -in many general Unix reference books. - -If your system does not include a POSIX regular expression library, and -you have not linked Guile with a third-party regexp library such as Rx, -these functions will not be available. You can tell whether your Guile -installation includes regular expression support by checking whether the -@code{*features*} list includes the @code{regex} symbol. - -@menu -* Regexp Functions:: Functions that create and match regexps. -* Match Structures:: Finding what was matched by a regexp. -* Backslash Escapes:: Removing the special meaning of regexp metacharacters. -* Rx Interface:: Tom Lord's Rx library does things differently. -@end menu - -[FIXME: it may be useful to include an Examples section. Parts of this -interface are bewildering on first glance.] - -@node Regexp Functions -@subsection Regexp Functions - -By default, Guile supports POSIX extended regular expressions. -That means that the characters @samp{(}, @samp{)}, @samp{+} and -@samp{?} are special, and must be escaped if you wish to match the -literal characters. - -This regular expression interface was modeled after that -implemented by SCSH, the Scheme Shell. It is intended to be -upwardly compatible with SCSH regular expressions. - -@c begin (scm-doc-string "regex.scm" "string-match") -@deffn procedure string-match pattern str [start] -Compile the string @var{pattern} into a regular expression and compare -it with @var{str}. The optional numeric argument @var{start} specifies -the position of @var{str} at which to begin matching. - -@code{string-match} returns a @dfn{match structure} which -describes what, if anything, was matched by the regular -expression. @xref{Match Structures}. If @var{str} does not match -@var{pattern} at all, @code{string-match} returns @code{#f}. -@end deffn - -Each time @code{string-match} is called, it must compile its -@var{pattern} argument into a regular expression structure. This -operation is expensive, which makes @code{string-match} inefficient if -the same regular expression is used several times (for example, in a -loop). For better performance, you can compile a regular expression in -advance and then match strings against the compiled regexp. - -@deffn primitive make-regexp pat . flags -Compile the regular expression described by @var{pat}, and -return the compiled regexp structure. If @var{pat} does not -describe a legal regular expression, @code{make-regexp} throws -a @code{regular-expression-syntax} error. - -The @var{flags} arguments change the behavior of the compiled -regular expression. The following flags may be supplied: - -@table @code -@item regexp/icase -Consider uppercase and lowercase letters to be the same when -matching. -@item regexp/newline -If a newline appears in the target string, then permit the -@samp{^} and @samp{$} operators to match immediately after or -immediately before the newline, respectively. Also, the -@samp{.} and @samp{[^...]} operators will never match a newline -character. The intent of this flag is to treat the target -string as a buffer containing many lines of text, and the -regular expression as a pattern that may match a single one of -those lines. -@item regexp/basic -Compile a basic (``obsolete'') regexp instead of the extended -(``modern'') regexps that are the default. Basic regexps do -not consider @samp{|}, @samp{+} or @samp{?} to be special -characters, and require the @samp{@{...@}} and @samp{(...)} -metacharacters to be backslash-escaped (@pxref{Backslash -Escapes}). There are several other differences between basic -and extended regular expressions, but these are the most -significant. -@item regexp/extended -Compile an extended regular expression rather than a basic -regexp. This is the default behavior; this flag will not -usually be needed. If a call to @code{make-regexp} includes -both @code{regexp/basic} and @code{regexp/extended} flags, the -one which comes last will override the earlier one. -@end table -@end deffn - -@deffn primitive regexp-exec rx str [start [flags]] -Match the compiled regular expression @var{rx} against -@code{str}. If the optional integer @var{start} argument is -provided, begin matching from that position in the string. -Return a match structure describing the results of the match, -or @code{#f} if no match could be found. -@end deffn - -@deffn primitive regexp? obj -Return @code{#t} if @var{obj} is a compiled regular expression, -or @code{#f} otherwise. -@end deffn - -Regular expressions are commonly used to find patterns in one string and -replace them with the contents of another string. - -@c begin (scm-doc-string "regex.scm" "regexp-substitute") -@deffn procedure regexp-substitute port match [item@dots{}] -Write to the output port @var{port} selected contents of the match -structure @var{match}. Each @var{item} specifies what should be -written, and may be one of the following arguments: - -@itemize @bullet -@item -A string. String arguments are written out verbatim. - -@item -An integer. The submatch with that number is written. - -@item -The symbol @samp{pre}. The portion of the matched string preceding -the regexp match is written. - -@item -The symbol @samp{post}. The portion of the matched string following -the regexp match is written. -@end itemize - -@var{port} may be @code{#f}, in which case nothing is written; instead, -@code{regexp-substitute} constructs a string from the specified -@var{item}s and returns that. -@end deffn - -@c begin (scm-doc-string "regex.scm" "regexp-substitute") -@deffn procedure regexp-substitute/global port regexp target [item@dots{}] -Similar to @code{regexp-substitute}, but can be used to perform global -substitutions on @var{str}. Instead of taking a match structure as an -argument, @code{regexp-substitute/global} takes two string arguments: a -@var{regexp} string describing a regular expression, and a @var{target} -string which should be matched against this regular expression. - -Each @var{item} behaves as in @var{regexp-substitute}, with the -following exceptions: - -@itemize @bullet -@item -A function may be supplied. When this function is called, it will be -passed one argument: a match structure for a given regular expression -match. It should return a string to be written out to @var{port}. - -@item -The @samp{post} symbol causes @code{regexp-substitute/global} to recurse -on the unmatched portion of @var{str}. This @emph{must} be supplied in -order to perform global search-and-replace on @var{str}; if it is not -present among the @var{item}s, then @code{regexp-substitute/global} will -return after processing a single match. -@end itemize -@end deffn - -@node Match Structures -@subsection Match Structures - -@cindex match structures - -A @dfn{match structure} is the object returned by @code{string-match} and -@code{regexp-exec}. It describes which portion of a string, if any, -matched the given regular expression. Match structures include: a -reference to the string that was checked for matches; the starting and -ending positions of the regexp match; and, if the regexp included any -parenthesized subexpressions, the starting and ending positions of each -submatch. - -In each of the regexp match functions described below, the @code{match} -argument must be a match structure returned by a previous call to -@code{string-match} or @code{regexp-exec}. Most of these functions -return some information about the original target string that was -matched against a regular expression; we will call that string -@var{target} for easy reference. - -@c begin (scm-doc-string "regex.scm" "regexp-match?") -@deffn procedure regexp-match? obj -Return @code{#t} if @var{obj} is a match structure returned by a -previous call to @code{regexp-exec}, or @code{#f} otherwise. -@end deffn - -@c begin (scm-doc-string "regex.scm" "match:substring") -@deffn procedure match:substring match [n] -Return the portion of @var{target} matched by subexpression number -@var{n}. Submatch 0 (the default) represents the entire regexp match. -If the regular expression as a whole matched, but the subexpression -number @var{n} did not match, return @code{#f}. -@end deffn - -@c begin (scm-doc-string "regex.scm" "match:start") -@deffn procedure match:start match [n] -Return the starting position of submatch number @var{n}. -@end deffn - -@c begin (scm-doc-string "regex.scm" "match:end") -@deffn procedure match:end match [n] -Return the ending position of submatch number @var{n}. -@end deffn - -@c begin (scm-doc-string "regex.scm" "match:prefix") -@deffn procedure match:prefix match -Return the unmatched portion of @var{target} preceding the regexp match. -@end deffn - -@c begin (scm-doc-string "regex.scm" "match:suffix") -@deffn procedure match:suffix match -Return the unmatched portion of @var{target} following the regexp match. -@end deffn - -@c begin (scm-doc-string "regex.scm" "match:count") -@deffn procedure match:count match -Return the number of parenthesized subexpressions from @var{match}. -Note that the entire regular expression match itself counts as a -subexpression, and failed submatches are included in the count. -@end deffn - -@c begin (scm-doc-string "regex.scm" "match:string") -@deffn procedure match:string match -Return the original @var{target} string. -@end deffn - -@node Backslash Escapes -@subsection Backslash Escapes - -Sometimes you will want a regexp to match characters like @samp{*} or -@samp{$} exactly. For example, to check whether a particular string -represents a menu entry from an Info node, it would be useful to match -it against a regexp like @samp{^* [^:]*::}. However, this won't work; -because the asterisk is a metacharacter, it won't match the @samp{*} at -the beginning of the string. In this case, we want to make the first -asterisk un-magic. - -You can do this by preceding the metacharacter with a backslash -character @samp{\}. (This is also called @dfn{quoting} the -metacharacter, and is known as a @dfn{backslash escape}.) When Guile -sees a backslash in a regular expression, it considers the following -glyph to be an ordinary character, no matter what special meaning it -would ordinarily have. Therefore, we can make the above example work by -changing the regexp to @samp{^\* [^:]*::}. The @samp{\*} sequence tells -the regular expression engine to match only a single asterisk in the -target string. - -Since the backslash is itself a metacharacter, you may force a regexp to -match a backslash in the target string by preceding the backslash with -itself. For example, to find variable references in a @TeX{} program, -you might want to find occurrences of the string @samp{\let\} followed -by any number of alphabetic characters. The regular expression -@samp{\\let\\[A-Za-z]*} would do this: the double backslashes in the -regexp each match a single backslash in the target string. - -@c begin (scm-doc-string "regex.scm" "regexp-quote") -@deffn procedure regexp-quote str -Quote each special character found in @var{str} with a backslash, and -return the resulting string. -@end deffn - -@strong{Very important:} Using backslash escapes in Guile source code -(as in Emacs Lisp or C) can be tricky, because the backslash character -has special meaning for the Guile reader. For example, if Guile -encounters the character sequence @samp{\n} in the middle of a string -while processing Scheme code, it replaces those characters with a -newline character. Similarly, the character sequence @samp{\t} is -replaced by a horizontal tab. Several of these @dfn{escape sequences} -are processed by the Guile reader before your code is executed. -Unrecognized escape sequences are ignored: if the characters @samp{\*} -appear in a string, they will be translated to the single character -@samp{*}. - -This translation is obviously undesirable for regular expressions, since -we want to be able to include backslashes in a string in order to -escape regexp metacharacters. Therefore, to make sure that a backslash -is preserved in a string in your Guile program, you must use @emph{two} -consecutive backslashes: - -@lisp -(define Info-menu-entry-pattern (make-regexp "^\\* [^:]*")) -@end lisp - -The string in this example is preprocessed by the Guile reader before -any code is executed. The resulting argument to @code{make-regexp} is -the string @samp{^\* [^:]*}, which is what we really want. - -This also means that in order to write a regular expression that matches -a single backslash character, the regular expression string in the -source code must include @emph{four} backslashes. Each consecutive pair -of backslashes gets translated by the Guile reader to a single -backslash, and the resulting double-backslash is interpreted by the -regexp engine as matching a single backslash character. Hence: - -@lisp -(define tex-variable-pattern (make-regexp "\\\\let\\\\=[A-Za-z]*")) -@end lisp - -The reason for the unwieldiness of this syntax is historical. Both -regular expression pattern matchers and Unix string processing systems -have traditionally used backslashes with the special meanings -described above. The POSIX regular expression specification and ANSI C -standard both require these semantics. Attempting to abandon either -convention would cause other kinds of compatibility problems, possibly -more severe ones. Therefore, without extending the Scheme reader to -support strings with different quoting conventions (an ungainly and -confusing extension when implemented in other languages), we must adhere -to this cumbersome escape syntax. - -@node Rx Interface -@subsection Rx Interface - -@c FIXME::martin: Shouldn't this be removed or moved to the -@c ``Guile Modules'' chapter? The functions are not available in -@c plain Guile... - -[FIXME: this is taken from Gary and Mark's quick summaries and should be -reviewed and expanded. Rx is pretty stable, so could already be done!] - -@cindex rx -@cindex finite automaton - -Guile includes an interface to Tom Lord's Rx library (currently only to -POSIX regular expressions). Use of the library requires a two step -process: compile a regular expression into an efficient structure, then -use the structure in any number of string comparisons. - -For example, given the -regular expression @samp{abc.} (which matches any string containing -@samp{abc} followed by any single character): - -@smalllisp -guile> @kbd{(define r (regcomp "abc."))} -guile> @kbd{r} -#<rgx abc.> -guile> @kbd{(regexec r "abc")} -#f -guile> @kbd{(regexec r "abcd")} -#((0 . 4)) -guile> -@end smalllisp - -The definitions of @code{regcomp} and @code{regexec} are as follows: - -@c NJFIXME not in libguile! -@deffn primitive regcomp pattern [flags] -Compile the regular expression pattern using POSIX rules. Flags is -optional and should be specified using symbolic names: -@defvar REG_EXTENDED -use extended POSIX syntax -@end defvar -@defvar REG_ICASE -use case-insensitive matching -@end defvar -@defvar REG_NEWLINE -allow anchors to match after newline characters in the -string and prevents @code{.} or @code{[^...]} from matching newlines. -@end defvar - -The @code{logior} procedure can be used to combine multiple flags. -The default is to use -POSIX basic syntax, which makes @code{+} and @code{?} literals and @code{\+} -and @code{\?} -operators. Backslashes in @var{pattern} must be escaped if specified in a -literal string e.g., @code{"\\(a\\)\\?"}. -@end deffn - -@c NJFIXME not in libguile! -@deffn primitive regexec regex string [match-pick] [flags] - -Match @var{string} against the compiled POSIX regular expression -@var{regex}. -@var{match-pick} and @var{flags} are optional. Possible flags (which can be -combined using the logior procedure) are: - -@defvar REG_NOTBOL -The beginning of line operator won't match the beginning of -@var{string} (presumably because it's not the beginning of a line) -@end defvar - -@defvar REG_NOTEOL -Similar to REG_NOTBOL, but prevents the end of line operator -from matching the end of @var{string}. -@end defvar - -If no match is possible, regexec returns #f. Otherwise @var{match-pick} -determines the return value: - -@code{#t} or unspecified: a newly-allocated vector is returned, -containing pairs with the indices of the matched part of @var{string} and any -substrings. - -@code{""}: a list is returned: the first element contains a nested list -with the matched part of @var{string} surrounded by the the unmatched parts. -Remaining elements are matched substrings (if any). All returned -substrings share memory with @var{string}. - -@code{#f}: regexec returns #t if a match is made, otherwise #f. - -vector: the supplied vector is returned, with the first element replaced -by a pair containing the indices of the matched portion of @var{string} and -further elements replaced by pairs containing the indices of matched -substrings (if any). - -list: a list will be returned, with each member of the list -specified by a code in the corresponding position of the supplied list: - -a number: the numbered matching substring (0 for the entire match). - -@code{#\<}: the beginning of @var{string} to the beginning of the part matched -by regex. - -@code{#\>}: the end of the matched part of @var{string} to the end of -@var{string}. - -@code{#\c}: the "final tag", which seems to be associated with the "cut -operator", which doesn't seem to be available through the posix -interface. - -e.g., @code{(list #\< 0 1 #\>)}. The returned substrings share memory with -@var{string}. -@end deffn - -Here are some other procedures that might be used when using regular -expressions: - -@c NJFIXME not in libguile! -@deffn primitive compiled-regexp? obj -Test whether obj is a compiled regular expression. -@end deffn - -@c NJFIXME not in libguile! -@deffn primitive regexp->dfa regex [flags] -@end deffn - -@c NJFIXME not in libguile! -@deffn primitive dfa-fork dfa -@end deffn - -@c NJFIXME not in libguile! -@deffn primitive reset-dfa! dfa -@end deffn - -@c NJFIXME not in libguile! -@deffn primitive dfa-final-tag dfa -@end deffn - -@c NJFIXME not in libguile! -@deffn primitive dfa-continuable? dfa -@end deffn - -@c NJFIXME not in libguile! -@deffn primitive advance-dfa! dfa string -@end deffn - - -@node Symbols and Variables -@section Symbols and Variables - -@c FIXME::martin: Review me! - -Symbols are a data type with a special property. On the one hand, -symbols are used for denoting variables in a Scheme program, on the -other they can be used as literal data as well. - -The association between symbols and values is maintained in special data -structures, the symbol tables. - -In addition, Guile offers variables as first-class objects. They can -be used for interacting with the module system. - -@menu -* Symbols:: All about symbols as a data type. -* Symbol Tables:: Tables for mapping symbols to values. -* Variables:: First-class variables. -@end menu - -@node Symbols -@subsection Symbols -@tpindex Symbols - -@c FIXME::martin: Review me! - -Symbols are especially useful because two symbols which are spelled the -same way are equivalent in the sense of @code{eq?}. That means that -they are actually the same Scheme object. The advantage is that symbols -can be compared extremely efficiently, although they carry more -information for the human reader than, say, numbers. - -It is very common in Scheme programs to use symbols as keys in -association lists (@pxref{Association Lists}) or hash tables -(@pxref{Hash Tables}), because this usage improves the readability a -lot, and does not cause any performance loss. - -The read syntax for symbols is a sequence of letters, digits, and -@emph{extended alphabetic characters} that begins with a character that -cannot begin a number is an identifier. In addition, @code{+}, -@code{-}, and @code{...} are identifiers. - -Extended alphabetic characters may be used within identifiers as if -they were letters. The following are extended alphabetic characters: - -@example -! $ % & * + - . / : < = > ? @@ ^ _ ~ -@end example - -In addition to the read syntax defined above (which is taken from R5RS -(@pxref{Formal syntax,,,r5rs,The Revised^5 Report on Scheme})), Guile -provides a method for writing symbols with unusual characters, such as -space characters. If you (for whatever reason) need to write a symbol -containing characters not mentioned above, you write symbols as follows: - -@itemize @bullet -@item -Begin the symbol with the two character @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 -containing a space character, the second containing a line break and the -last one looks like a number. - -@lisp -#@{foo bar@}# -#@{what -ever@}# -#@{4242@}# -@end lisp - -Usage of this form of read syntax is discouraged, because it is not -portable at all, and is not very readable. - -@rnindex symbol? -@deffn primitive symbol? obj -Return @code{#t} if @var{obj} is a symbol, otherwise return -@code{#f}. -@end deffn - -@rnindex string->symbol -@deffn primitive string->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. See -@code{symbol->string}. - -The following examples assume that the implementation's -standard case is lower case: - -@lisp -(eq? 'mISSISSIppi 'mississippi) @result{} #t -(string->symbol "mISSISSIppi") @result{} @r{the symbol with name "mISSISSIppi"} -(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #f -(eq? 'JollyWog - (string->symbol (symbol->string 'JollyWog))) @result{} #t -(string=? "K. Harper, M.D." - (symbol->string - (string->symbol "K. Harper, M.D."))) @result{}#t -@end lisp -@end deffn - -@rnindex symbol->string -@deffn primitive symbol->string s -Return the name of @var{symbol} as a string. If the symbol was -part of an object returned as the value of a literal expression -(section @pxref{Literal expressions,,,r5rs, The Revised^5 -Report on Scheme}) or by a call to the @code{read} procedure, -and its name contains alphabetic characters, then the string -returned will contain characters in the implementation's -preferred standard case--some implementations will prefer -upper case, others lower case. If the symbol was returned by -@code{string->symbol}, the case of characters in the string -returned will be the same as the case in the string that was -passed to @code{string->symbol}. It is an error to apply -mutation procedures like @code{string-set!} to strings returned -by this procedure. - -The following examples assume that the implementation's -standard case is lower case: - -@lisp -(symbol->string 'flying-fish) @result{} "flying-fish" -(symbol->string 'Martin) @result{} "martin" -(symbol->string - (string->symbol "Malvina")) @result{} "Malvina" -@end lisp -@end deffn - -@node Symbol Tables -@subsection Symbol Tables - -@c FIXME::martin: Review me! - -@c FIXME::martin: Are all these procedures still relevant? - -Guile symbol tables are hash tables. Each hash table, also called an -@dfn{obarray} (for `object array'), is a vector of association lists. -Each entry in the alists is a pair (@var{SYMBOL} . @var{VALUE}). To -@dfn{intern} a symbol in a symbol table means to return its -(@var{SYMBOL} . @var{VALUE}) pair, adding a new entry to the symbol -table (with an undefined value) if none is yet present. - -@c FIXME::martin: According to NEWS, removed. Remove here too, or -@c leave for compatibility? -@c @c docstring begin (texi-doc-string "guile" "builtin-bindings") -@c @deffn primitive builtin-bindings -@c Create and return a copy of the global symbol table, removing all -@c unbound symbols. -@c @end deffn - -@deffn primitive 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 @code{g}. The counter -is increased by 1 at each call. There is no provision for -resetting the counter. -@end deffn - -@deffn primitive gentemp [prefix [obarray]] -Create a new symbol with a name unique in an obarray. -The name is constructed from an optional string @var{prefix} -and a counter value. The default prefix is @code{t}. The -@var{obarray} is specified as a second optional argument. -Default is the system obarray where all normal symbols are -interned. The counter is increased by 1 at each -call. There is no provision for resetting the counter. -@end deffn - -@deffn primitive intern-symbol obarray string -Add a new symbol to @var{obarray} with name @var{string}, bound to an -unspecified initial value. The symbol table is not modified if a symbol -with this name is already present. -@end deffn - -@deffn primitive string->obarray-symbol obarray string [soft?] -Intern a new symbol in @var{obarray}, a symbol table, with name -@var{string}. -@end deffn - -@deffn primitive symbol-binding obarray string -Look up in @var{obarray} the symbol whose name is @var{string}, and -return the value to which it is bound. If @var{obarray} is @code{#f}, -use the global symbol table. If @var{string} is not interned in -@var{obarray}, an error is signalled. -@end deffn - -@deffn primitive symbol-bound? obarray string -Return @code{#t} if @var{obarray} contains a symbol with name -@var{string} bound to a defined value. This differs from -@var{symbol-interned?} in that the mere mention of a symbol -usually causes it to be interned; @code{symbol-bound?} -determines whether a symbol has been given any meaningful -value. -@end deffn - -@deffn primitive symbol-fref symbol -Return the contents of @var{symbol}'s @dfn{function slot}. -@end deffn - -@deffn primitive symbol-fset! symbol value -Change the binding of @var{symbol}'s function slot. -@end deffn - -@deffn primitive symbol-hash symbol -Return a hash value for @var{symbol}. -@end deffn - -@deffn primitive symbol-interned? obarray string -Return @code{#t} if @var{obarray} contains a symbol with name -@var{string}, and @code{#f} otherwise. -@end deffn - -@deffn primitive symbol-pref symbol -Return the @dfn{property list} currently associated with @var{symbol}. -@end deffn - -@deffn primitive symbol-pset! symbol value -Change the binding of @var{symbol}'s property slot. -@end deffn - -@deffn primitive symbol-set! obarray string value -Find the symbol in @var{obarray} whose name is @var{string}, and rebind -it to @var{value}. An error is signalled if @var{string} is not present -in @var{obarray}. -@end deffn - -@deffn primitive unintern-symbol obarray string -Remove the symbol with name @var{string} from @var{obarray}. This -function returns @code{#t} if the symbol was present and @code{#f} -otherwise. -@end deffn - -@node Variables -@subsection Variables -@tpindex Variables - -@c FIXME::martin: Review me! - -Variables are objects with two fields. They contain a value and they -can contain a symbol, which is the name of the variable. A variable is -said to be bound if it does not contain the object denoting unbound -variables in the value slot. - -Variables do not have a read syntax, they have to be created by calling -one of the constructor procedures @code{make-variable} or -@code{make-undefined-variable} or retrieved by @code{builtin-variable}. - -First-class variables are especially useful for interacting with the -current module system (@pxref{The Guile module system}). - -@deffn primitive builtin-variable name -Return the built-in variable with the name @var{name}. -@var{name} must be a symbol (not a string). -Then use @code{variable-ref} to access its value. -@end deffn - -@deffn primitive make-undefined-variable [name-hint] -Return a variable object initialized to an undefined value. -If given, uses @var{name-hint} as its internal (debugging) -name, otherwise just treat it as an anonymous variable. -Remember, of course, that multiple bindings to the same -variable may exist, so @var{name-hint} is just that---a hint. -@end deffn - -@deffn primitive make-variable init [name-hint] -Return a variable object initialized to value @var{init}. -If given, uses @var{name-hint} as its internal (debugging) -name, otherwise just treat it as an anonymous variable. -Remember, of course, that multiple bindings to the same -variable may exist, so @var{name-hint} is just that---a hint. -@end deffn - -@deffn primitive variable-bound? var -Return @code{#t} iff @var{var} is bound to a value. -Throws an error if @var{var} is not a variable object. -@end deffn - -@deffn primitive variable-ref var -Dereference @var{var} and return its value. -@var{var} must be a variable object; see @code{make-variable} -and @code{make-undefined-variable}. -@end deffn - -@deffn primitive variable-set! var val -Set the value of the variable @var{var} to @var{val}. -@var{var} must be a variable object, @var{val} can be any -value. Return an unspecified value. -@end deffn - -@deffn primitive variable? obj -Return @code{#t} iff @var{obj} is a variable object, else -return @code{#f} -@end deffn - - -@node Keywords -@section 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{#:}. - -@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. -* Keyword Primitives:: The underlying primitive procedures. -@end menu - -@node Why Use Keywords? -@subsection 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 -colour depth -- Default: the colour depth for the screen - -@item -background colour -- 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 ;; Colour depth - 'default ;; Background colour - 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 -@subsection 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, @ref{Optional -Arguments}. - - -@node Keyword Read Syntax -@subsection Keyword Read Syntax - -Guile, by default, only recognizes the keyword syntax specified by R5RS. -A token of the form @code{#:NAME}, where @code{NAME} has the same syntax -as a Scheme symbol, 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{keyword} 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. - -To enable and disable the alternative non-R5RS keyword syntax, you use -the @code{read-options} procedure documented in @ref{General option -interface} and @ref{Reader options}. - -@smalllisp -(read-set! keywords 'prefix) - -#:type -@result{} -#:type - -:type -@result{} -#:type - -(read-set! keywords #f) - -#:type -@result{} -#:type - -:type -@result{} -ERROR: In expression :type: -ERROR: Unbound variable: :type -ABORT: (unbound-variable) -@end smalllisp - -@node Keyword Procedures -@subsection Keyword Procedures - -@c FIXME::martin: Review me! - -The following procedures can be used for converting symbols to keywords -and back. - -@deffn procedure symbol->keyword sym -Return a keyword with the same characters as in @var{sym}. -@end deffn - -@deffn procedure keyword->symbol kw -Return a symbol with the same characters as in @var{kw}. -@end deffn - - -@node Keyword Primitives -@subsection Keyword Primitives - -Internally, a keyword is implemented as something like a tagged symbol, -where the tag identifies the keyword as being self-evaluating, and the -symbol, known as the keyword's @dfn{dash symbol} has the same name as -the keyword name but prefixed by a single dash. For example, the -keyword @code{#:name} has the corresponding dash symbol @code{-name}. - -Most keyword objects are constructed automatically by the reader when it -reads a token beginning with @code{#:}. However, if you need to -construct a keyword object programmatically, you can do so by calling -@code{make-keyword-from-dash-symbol} with the corresponding dash symbol -(as the reader does). The dash symbol for a keyword object can be -retrieved using the @code{keyword-dash-symbol} procedure. - -@deffn primitive make-keyword-from-dash-symbol symbol -Make a keyword object from a @var{symbol} that starts with a dash. -@end deffn - -@deffn primitive keyword? obj -Return @code{#t} if the argument @var{obj} is a keyword, else -@code{#f}. -@end deffn - -@deffn primitive keyword-dash-symbol keyword -Return the dash symbol for @var{keyword}. -This is the inverse of @code{make-keyword-from-dash-symbol}. -@end deffn - -@node Pairs -@section Pairs -@tpindex Pairs - -@c FIXME::martin: Review me! - -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 @emph{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 whould 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 (REFFIXME). 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 -@emph{construct}. Use the procedure @code{pair?} to test whether a -given Scheme object is a pair or not. - -@rnindex cons -@deffn primitive 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 primitive pair? x -Return @code{#t} if @var{x} is a pair; otherwise return -@code{#f}. -@end deffn - -The two parts of a pair are traditionally called @emph{car} and -@emph{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 pair, or the car of the cdr of -a pair, etc., the procedures called @code{caar}, @code{cadr} and so on -are also predefined. - -@rnindex car -@rnindex cdr -@deffn primitive car pair -@deffnx primitive cdr pair -Return the car or the cdr of @var{pair}, respectively. -@end deffn - -@deffn primitive caar pair -@deffnx primitive cadr pair @dots{} -@deffnx primitive cdddar pair -@deffnx primitive cddddr 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 -@end deffn - -@rnindex set-car! -@deffn primitive set-car! 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 primitive set-cdr! 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 -@section Lists -@tpindex Lists - -@c FIXME::martin: Review me! - -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 @emph{list}. Lists are made up of -chained @emph{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 Modifification:: Modifying list structure. -* List Searching:: Searching for list elements -* List Mapping:: Applying procedures to lists. -@end menu - -@node List Syntax -@subsection List Read Syntax - -@c FIXME::martin: Review me! - -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 (REFFIXME) when -written, because they would otherwise be mistakingly taken as procedure -applications (@pxref{Simple Invocation}). - - -@node List Predicates -@subsection List Predicates - -@c FIXME::martin: Review me! - -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 primitive list? x -Return @code{#t} iff @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, teh algorithm terminates. - -@rnindex null? -@deffn primitive null? x -Return @code{#t} iff @var{x} is the empty list, else @code{#f}. -@end deffn - -@node List Constructors -@subsection 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. - -@rnindex list -@deffn primitive list arg1 @dots{} -Return a list containing @var{objs}, the arguments to -@code{list}. -@end deffn - -@deffn primitive 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 primitive list-copy lst -Return a (newly-created) copy of @var{lst}. -@end deffn - -@deffn 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 modyfies 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} (@pxref{Copying}). - -@node List Selection -@subsection List Selection - -@c FIXME::martin: Review me! - -These procedures are used to get some information about a list, or to -retrieve one or more elements of a list. - -@rnindex length -@deffn primitive length lst -Return the number of elements in list @var{lst}. -@end deffn - -@deffn primitive last-pair lst -Return a pointer to the last pair in @var{lst}, signalling an error if -@var{lst} is circular. -@end deffn - -@rnindex list-ref -@deffn primitive list-ref list k -Return the @var{k}th element from @var{list}. -@end deffn - -@rnindex list-tail -@deffn primitive list-tail lst k -@deffnx primitive list-cdr-ref 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 primitive 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 -@subsection Append and Reverse - -@c FIXME::martin: Review me! - -@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 primitive append . args -Return a list consisting of the elements the lists passed as -arguments. -@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 resulting list is always newly allocated, except that it -shares structure with the last list argument. The last -argument 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 -@end deffn - -@deffn primitive append! . lists -A destructive version of @code{append} (@pxref{Pairs and -lists,,,r5rs, The Revised^5 Report on Scheme}). The cdr field -of each list's final pair is changed to point to the head of -the next list, so no consing is performed. Return a pointer to -the mutated list. -@end deffn - -@rnindex reverse -@deffn primitive reverse lst -Return a new list that contains the elements of @var{lst} but -in reverse order. -@end deffn - -@c NJFIXME explain new_tail -@deffn primitive reverse! lst [new_tail] -A destructive version of @code{reverse} (@pxref{Pairs and lists,,,r5rs, -The Revised^5 Report on Scheme}). The cdr of each cell in @var{lst} is -modified to point to the previous list element. Return a pointer to the -head of the reversed list. - -Caveat: because the list is modified in place, the tail of the original -list now becomes its head, and the head of the original list now becomes -the tail. Therefore, the @var{lst} symbol to which the head of the -original list was bound now points to the tail. To ensure that the head -of the modified list is not lost, it is wise to save the return value of -@code{reverse!} -@end deffn - -@node List Modifification -@subsection List Modification - -@c FIXME::martin: Review me! - -The following procedures modify existing list. @code{list-set!} and -@code{list-cdr-set!} change which elements a list contains, the various -deletion procedures @code{delq}, @code{delv} etc. - -@deffn primitive list-set! list k val -Set the @var{k}th element of @var{list} to @var{val}. -@end deffn - -@deffn primitive list-cdr-set! list k val -Set the @var{k}th cdr of @var{list} to @var{val}. -@end deffn - -@deffn primitive 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 primitive 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 primitive 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?}. -@end deffn - -@deffn primitive delq! item lst -@deffnx primitive delv! item lst -@deffnx primitive delete! 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 primitive delq1! 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 primitive delv1! 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 primitive delete1! 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 - -@node List Searching -@subsection List Searching - -@c FIXME::martin: Review me! - -The following procedures search lists for particular elements. They use -different comparison predicates for comparing list elements with the -object to be seached. 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 primitive 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 primitive 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 primitive 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. -@end deffn - -[FIXME: is there any reason to have the `sloppy' functions available at -high level at all? Maybe these docs should be relegated to a "Guile -Internals" node or something. -twp] - -@deffn primitive sloppy-memq x lst -This procedure behaves like @code{memq}, but does no type or error checking. -Its use is recommended only in writing Guile internals, -not for high-level Scheme programs. -@end deffn - -@deffn primitive sloppy-memv x lst -This procedure behaves like @code{memv}, but does no type or error checking. -Its use is recommended only in writing Guile internals, -not for high-level Scheme programs. -@end deffn - -@deffn primitive sloppy-member x lst -This procedure behaves like @code{member}, but does no type or error checking. -Its use is recommended only in writing Guile internals, -not for high-level Scheme programs. -@end deffn - -@node List Mapping -@subsection List Mapping - -@c FIXME::martin: Review me! - -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 what -the result of the invocation is. - -@rnindex map -@c begin (texi-doc-string "guile" "map") -@deffn primitive map proc arg1 arg2 @dots{} -@deffnx primitive map-in-order proc arg1 arg2 @dots{} -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 primitive 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 - - -@node Vectors -@section Vectors -@tpindex Vectors - -@c FIXME::martin: Review me! - -@c FIXME::martin: Should the subsections of this section be nodes -@c of their own, or are the resulting nodes too short, then? - -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 is constant, whereas lists have an access time linear to the -index of the accessed element in the list. - -Note that the vectors documented in this section can contain any kind of -Scheme object, it is even possible to have different types of objects in -the same vector. - -@subsection Vector Read Syntax - -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. 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 hexidecimal notation. - -@lisp -#(1 2 3) -#("Hello" foo #xdeadbeef) -@end lisp - -@subsection Vector Predicates - -@rnindex vector? -@deffn primitive vector? obj -Return @code{#t} if @var{obj} is a vector, otherwise return -@code{#f}. -@end deffn - -@subsection Vector Constructors - -@rnindex make-vector -@deffn primitive make-vector k [fill] -Return a newly allocated vector of @var{k} elements. If a -second argument is given, then each element is initialized to -@var{fill}. Otherwise the initial contents of each element is -unspecified. -@end deffn - -@rnindex vector -@rnindex list->vector -@deffn primitive vector . l -@deffnx primitive list->vector l -Return a newly allocated vector whose elements contain the -given arguments. Analogous to @code{list}. - -@lisp -(vector 'a 'b 'c) @result{} #(a b c) -@end lisp -@end deffn - -@rnindex vector->list -@deffn primitive vector->list v -Return a newly allocated list of the objects contained in the -elements of @var{vector}. - -@lisp -(vector->list '#(dah dah didah)) @result{} (dah dah didah) -(list->vector '(dididit dah)) @result{} #(dididit dah) -@end lisp -@end deffn - -@subsection Vector Modification - -A vector created by any of the vector constructor procedures -(@pxref{Vectors}) documented above can be modified using the -following procedures. - -According to R5RS, using any of these procedures on literally entered -vectors is an error, because these vectors are considered to be -constant, although Guile currently does not detect this error. - -@rnindex vector-set! -@deffn primitive vector-set! vector k obj -@var{k} must be a valid index of @var{vector}. -@code{Vector-set!} stores @var{obj} in element @var{k} of @var{vector}. -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") -(vector-set! '#(0 1 2) 1 "doe") @result{} @emph{error} ; constant vector -@end lisp -@end deffn - -@rnindex vector-fill! -@deffn primitive vector-fill! v fill -Store @var{fill} in every element of @var{vector}. The value -returned by @code{vector-fill!} is unspecified. -@end deffn - -@deffn primitive vector-move-left! vec1 start1 end1 vec2 start2 -Vector version of @code{substring-move-left!}. -@end deffn - -@deffn primitive vector-move-right! vec1 start1 end1 vec2 start2 -Vector version of @code{substring-move-right!}. -@end deffn - -@subsection Vector Selection - -These procedures return information about a given vector, such as the -size or what elements are contained in the vector. - -@rnindex vector-length -@deffn primitive vector-length vector -Returns the number of elements in @var{vector} as an exact integer. -@end deffn - -@rnindex vector-ref -@deffn primitive vector-ref vector k -@var{k} must be a valid index of @var{vector}. -@samp{Vector-ref} returns the contents of element @var{k} of -@var{vector}. -@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 - - -@node Records -@section Records - -[FIXME: this is pasted in from Tom Lord's original guile.texi and should -be reviewed] - -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. - -@deffn procedure record? obj -Returns @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 procedure make-record-type type-name field-names -Returns a @dfn{record-type descriptor}, a value representing a new data -type disjoint from all others. The @var{type-name} argument must be a -string, but is only used for debugging purposes (such as the printed -representation of a record of the new type). The @var{field-names} -argument is a list of symbols naming the @dfn{fields} of a record of the -new type. It is an error if the list contains any duplicates. It is -unspecified how record-type descriptors are represented.@refill -@end deffn - -@deffn procedure record-constructor rtd [field-names] -Returns a procedure for constructing new members of the type represented -by @var{rtd}. The returned procedure accepts exactly as many arguments -as there are symbols in the given list, @var{field-names}; these are -used, in order, as the initial values of those fields in a new record, -which is returned by the constructor procedure. The values of any -fields not named in that list are unspecified. The @var{field-names} -argument defaults to the list of field names in the call to -@code{make-record-type} that created the type represented by @var{rtd}; -if the @var{field-names} argument is provided, it is an error if it -contains any duplicates or any symbols not in the default list.@refill -@end deffn - -@deffn procedure record-predicate rtd -Returns 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.@refill -@end deffn - -@deffn procedure record-accessor rtd field-name -Returns 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. The symbol @var{field-name} 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}.@refill -@end deffn - -@deffn procedure record-modifier rtd field-name -Returns 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} 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}.@refill -@end deffn - -@deffn procedure record-type-descriptor record -Returns 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.@refill -@end deffn - -@deffn procedure record-type-name rtd -Returns 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}.@refill -@end deffn - -@deffn procedure record-type-fields rtd -Returns 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}.@refill -@end deffn - - -@node Structures -@section Structures -@tpindex Structures - -[FIXME: this is pasted in from Tom Lord's original guile.texi and should -be reviewed] - -A @dfn{structure type} is a first class user-defined data type. A -@dfn{structure} is an instance of a structure type. A structure type is -itself a structure. - -Structures are less abstract and more general than traditional records. -In fact, in Guile Scheme, records are implemented using structures. - -@menu -* Structure Concepts:: The structure of Structures -* Structure Layout:: Defining the layout of structure types -* Structure Basics:: make-, -ref and -set! procedures for structs -* Vtables:: Accessing type-specific data -@end menu - -@node Structure Concepts -@subsection Structure Concepts - -A structure object consists of a handle, structure data, and a vtable. -The handle is a Scheme value which points to both the vtable and the -structure's data. Structure data is a dynamically allocated region of -memory, private to the structure, divided up into typed fields. A -vtable is another structure used to hold type-specific data. Multiple -structures can share a common vtable. - -Three concepts are key to understanding structures. - -@itemize @bullet{} -@item @dfn{layout specifications} - -Layout specifications determine how memory allocated to structures is -divided up into fields. Programmers must write a layout specification -whenever a new type of structure is defined. - -@item @dfn{structural accessors} - -Structure access is by field number. There is only one set of -accessors common to all structure objects. - -@item @dfn{vtables} - -Vtables, themselves structures, are first class representations of -disjoint sub-types of structures in general. In most cases, when a -new structure is created, programmers must specifiy a vtable for the -new structure. Each vtable has a field describing the layout of its -instances. Vtables can have additional, user-defined fields as well. -@end itemize - - - -@node Structure Layout -@subsection Structure Layout - -When a structure is created, a region of memory is allocated to hold its -state. The @dfn{layout} of the structure's type determines how that -memory is divided into fields. - -Each field has a specified type. There are only three types allowed, each -corresponding to a one letter code. The allowed types are: - -@itemize @bullet{} -@item 'u' -- unprotected - -The field holds binary data that is not GC protected. - -@item 'p' -- protected - -The field holds a Scheme value and is GC protected. - -@item 's' -- self - -The field holds a Scheme value and is GC protected. When a structure is -created with this type of field, the field is initialized to refer to -the structure's own handle. This kind of field is mainly useful when -mixing Scheme and C code in which the C code may need to compute a -structure's handle given only the address of its malloced data. -@end itemize - - -Each field also has an associated access protection. There are only -three kinds of protection, each corresponding to a one letter code. -The allowed protections are: - -@itemize @bullet{} -@item 'w' -- writable - -The field can be read and written. - -@item 'r' -- readable - -The field can be read, but not written. - -@item 'o' -- opaque - -The field can be neither read nor written. This kind -of protection is for fields useful only to built-in routines. -@end itemize - -A layout specification is described by stringing together pairs -of letters: one to specify a field type and one to specify a field -protection. For example, a traditional cons pair type object could -be described as: - -@example -; cons pairs have two writable fields of Scheme data -"pwpw" -@end example - -A pair object in which the first field is held constant could be: - -@example -"prpw" -@end example - -Binary fields, (fields of type "u"), hold one @emph{word} each. The -size of a word is a machine dependent value defined to be equal to the -value of the C expression: @code{sizeof (long)}. - -The last field of a structure layout may specify a tail array. -A tail array is indicated by capitalizing the field's protection -code ('W', 'R' or 'O'). A tail-array field is replaced by -a read-only binary data field containing an array size. The array -size is determined at the time the structure is created. It is followed -by a corresponding number of fields of the type specified for the -tail array. For example, a conventional Scheme vector can be -described as: - -@example -; A vector is an arbitrary number of writable fields holding Scheme -; values: -"pW" -@end example - -In the above example, field 0 contains the size of the vector and -fields beginning at 1 contain the vector elements. - -A kind of tagged vector (a constant tag followed by conventioal -vector elements) might be: - -@example -"prpW" -@end example - - -Structure layouts are represented by specially interned symbols whose -name is a string of type and protection codes. To create a new -structure layout, use this procedure: - -@deffn primitive make-struct-layout fields -Return a new structure layout object. - -@var{fields} must be a string made up of pairs of characters -strung together. The first character of each pair describes a field -type, the second a field protection. Allowed types are 'p' for -GC-protected Scheme data, 'u' for unprotected binary data, and 's' for -a field that points to the structure itself. Allowed protections -are 'w' for mutable fields, 'r' for read-only fields, and 'o' for opaque -fields. The last field protection specification may be capitalized to -indicate that the field is a tail-array. -@end deffn - - - -@node Structure Basics -@subsection Structure Basics - -This section describes the basic procedures for creating and accessing -structures. - -@deffn primitive make-struct vtable tail_array_size . init -Create a new structure. - -@var{type} must be a vtable structure (@pxref{Vtables}). - -@var{tail-elts} must be a non-negative integer. If the layout -specification indicated by @var{type} includes a tail-array, -this is the number of elements allocated to that array. - -The @var{init1}, @dots{} are optional arguments describing how -successive fields of the structure should be initialized. Only fields -with protection 'r' or 'w' can be initialized, except for fields of -type 's', which are automatically initialized to point to the new -structure itself; fields with protection 'o' can not be initialized by -Scheme programs. - -If fewer optional arguments than initializable fields are supplied, -fields of type 'p' get default value #f while fields of type 'u' are -initialized to 0. - -Structs are currently the basic representation for record-like data -structures in Guile. The plan is to eventually replace them with a -new representation which will at the same time be easier to use and -more powerful. - -For more information, see the documentation for @code{make-vtable-vtable}. -@end deffn - -@deffn primitive struct? x -Return @code{#t} iff @var{obj} is a structure object, else -@code{#f}. -@end deffn - - -@deffn primitive struct-ref handle pos -@deffnx primitive struct-set! struct n value -Access (or modify) the @var{n}th field of @var{struct}. - -If the field is of type 'p', then it can be set to an arbitrary value. - -If the field is of type 'u', then it can only be set to a non-negative -integer value small enough to fit in one machine word. -@end deffn - - - -@node Vtables -@subsection Vtables - -Vtables are structures that are used to represent structure types. Each -vtable contains a layout specification in field -@code{vtable-index-layout} -- instances of the type are laid out -according to that specification. Vtables contain additional fields -which are used only internally to libguile. The variable -@code{vtable-offset-user} is bound to a field number. Vtable fields -at that position or greater are user definable. - -@deffn primitive struct-vtable handle -Return the vtable structure that describes the type of @var{struct}. -@end deffn - -@deffn primitive struct-vtable? x -Return @code{#t} iff obj is a vtable structure. -@end deffn - -If you have a vtable structure, @code{V}, you can create an instance of -the type it describes by using @code{(make-struct V ...)}. But where -does @code{V} itself come from? One possibility is that @code{V} is an -instance of a user-defined vtable type, @code{V'}, so that @code{V} is -created by using @code{(make-struct V' ...)}. Another possibility is -that @code{V} is an instance of the type it itself describes. Vtable -structures of the second sort are created by this procedure: - -@deffn primitive make-vtable-vtable user_fields tail_array_size . init -Return a new, self-describing vtable structure. - -@var{user-fields} is a string describing user defined fields of the -vtable beginning at index @code{vtable-offset-user} -(see @code{make-struct-layout}). - -@var{tail-size} specifies the size of the tail-array (if any) of -this vtable. - -@var{init1}, @dots{} are the optional initializers for the fields of -the vtable. - -Vtables have one initializable system field---the struct printer. -This field comes before the user fields in the initializers passed -to @code{make-vtable-vtable} and @code{make-struct}, and thus works as -a third optional argument to @code{make-vtable-vtable} and a fourth to -@code{make-struct} when creating vtables: - -If the value is a procedure, it will be called instead of the standard -printer whenever a struct described by this vtable is printed. -The procedure will be called with arguments STRUCT and PORT. - -The structure of a struct is described by a vtable, so the vtable is -in essence the type of the struct. The vtable is itself a struct with -a vtable. This could go on forever if it weren't for the -vtable-vtables which are self-describing vtables, and thus terminate -the chain. - -There are several potential ways of using structs, but the standard -one is to use three kinds of structs, together building up a type -sub-system: one vtable-vtable working as the root and one or several -"types", each with a set of "instances". (The vtable-vtable should be -compared to the class <class> which is the class of itself.) - -@lisp -(define ball-root (make-vtable-vtable "pr" 0)) - -(define (make-ball-type ball-color) - (make-struct ball-root 0 - (make-struct-layout "pw") - (lambda (ball port) - (format port "#<a ~A ball owned by ~A>" - (color ball) - (owner ball))) - ball-color)) -(define (color ball) (struct-ref (struct-vtable ball) vtable-offset-user)) -(define (owner ball) (struct-ref ball 0)) - -(define red (make-ball-type 'red)) -(define green (make-ball-type 'green)) - -(define (make-ball type owner) (make-struct type 0 owner)) - -(define ball (make-ball green 'Nisse)) -ball @result{} #<a green ball owned by Nisse> -@end lisp -@end deffn - -@deffn primitive struct-vtable-name vtable -Return the name of the vtable @var{vtable}. -@end deffn - -@deffn primitive set-struct-vtable-name! vtable name -Set the name of the vtable @var{vtable} to @var{name}. -@end deffn - -@deffn primitive struct-vtable-tag handle -Return the vtable tag of the structure @var{handle}. -@end deffn - - -@node Arrays -@section Arrays -@tpindex Arrays - -@menu -* Conventional Arrays:: Arrays with arbitrary data. -* Array Mapping:: Applying a procedure to the contents of an array. -* Uniform Arrays:: Arrays with data of a single type. -* Bit Vectors:: Vectors of bits. -@end menu - -@node Conventional Arrays -@subsection Conventional Arrays - -@dfn{Conventional arrays} are a collection of cells organised into an -arbitrary number of dimensions. Each cell can hold any kind of Scheme -value and can be accessed in constant time by supplying an index for -each dimension. This contrasts with uniform arrays, which use memory -more efficiently but can hold data of only a single type, and lists -where inserting and deleting cells is more efficient, but more time -is usually required to access a particular cell. - -A conventional array is displayed as @code{#} followed by the @dfn{rank} -(number of dimensions) followed by the cells, organised into dimensions -using parentheses. The nesting depth of the parentheses is equal to -the rank. - -When an array is created, the number of dimensions and range of each -dimension must be specified, e.g., to create a 2x3 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 - -A conventional array with one dimension based at zero is identical to -a vector: - -@example -(make-array 'ho 3) @result{} -#(ho ho ho) -@end example - -The following procedures can be used with conventional arrays (or vectors). - -@deffn primitive array? v [prot] -Return @code{#t} if the @var{obj} is an array, and @code{#f} if -not. The @var{prototype} argument is used with uniform arrays -and is described elsewhere. -@end deffn - -@deffn procedure make-array initial-value bound1 bound2 @dots{} -Creates and returns an array that has as many dimensions as there are -@var{bound}s and fills it with @var{initial-value}. -@end deffn - -@c array-ref's type is `compiled-closure'. There's some weird stuff -@c going on in array.c, too. Let's call it a primitive. -twp - -@deffn primitive uniform-vector-ref v args -@deffnx primitive array-ref v . args -Return the element at the @code{(index1, index2)} element in -@var{array}. -@end deffn - -@deffn primitive array-in-bounds? v . args -Return @code{#t} if its arguments would be acceptable to -@code{array-ref}. -@end deffn - -@deffn primitive array-set! v obj . args -@deffnx primitive uniform-array-set1! v obj args -Sets the element at the @code{(index1, index2)} element in @var{array} to -@var{new-value}. The value returned by array-set! is unspecified. -@end deffn - -@deffn primitive make-shared-array oldra mapfunc . dims -@code{make-shared-array} can be used to create shared subarrays of other -arrays. The @var{mapper} is a function that translates coordinates in -the new array into coordinates in the old array. A @var{mapper} must be -linear, and its range must stay within the bounds of the old array, but -it can be otherwise arbitrary. A simple example: -@lisp -(define fred (make-array #f 8 8)) -(define freds-diagonal - (make-shared-array fred (lambda (i) (list i i)) 8)) -(array-set! freds-diagonal 'foo 3) -(array-ref fred 3 3) @result{} foo -(define freds-center - (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2)) -(array-ref freds-center 0 0) @result{} foo -@end lisp -@end deffn - -@deffn primitive shared-array-increments ra -For each dimension, return the distance between elements in the root vector. -@end deffn - -@deffn primitive shared-array-offset ra -Return the root vector index of the first element in the array. -@end deffn - -@deffn primitive shared-array-root ra -Return the root vector of a shared array. -@end deffn - -@deffn primitive transpose-array ra . args -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{dim0}, @var{dim1}, @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{dim0}, @var{dim1}, @dots{} correspond to -dimensions in the array to be returned, 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 - -@deffn primitive enclose-array ra . axes -@var{dim0}, @var{dim1} @dots{} should be nonnegative integers less than -the rank of @var{array}. @var{enclose-array} returns an array -resembling an array of shared arrays. The dimensions of each shared -array are the same as the @var{dim}th dimensions of the original array, -the dimensions of the outer array are the same as those of the original -array that did not match a @var{dim}. - -An enclosed array is not a general Scheme array. Its elements may not -be set using @code{array-set!}. Two references to the same element of -an enclosed array will be @code{equal?} but will not in general be -@code{eq?}. The value returned by @var{array-prototype} when given an -enclosed array is unspecified. - -examples: -@lisp -(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) @result{} - #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))> - -(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) @result{} - #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))> -@end lisp -@end deffn - -@deffn procedure array-shape array -Returns a list of inclusive bounds of integers. -@example -(array-shape (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) (0 4)) -@end example -@end deffn - -@deffn primitive array-dimensions ra -@code{Array-dimensions} is similar to @code{array-shape} but replaces -elements with a @code{0} minimum with one greater than the maximum. So: -@lisp -(array-dimensions (make-array 'foo '(-1 3) 5)) @result{} ((-1 3) 5) -@end lisp -@end deffn - -@deffn primitive array-rank ra -Return the number of dimensions of @var{obj}. If @var{obj} is -not an array, @code{0} is returned. -@end deffn - -@deffn primitive array->list v -Return a list consisting of all the elements, in order, of -@var{array}. -@end deffn - -@deffn primitive array-copy! src dst -@deffnx primitive array-copy-in-order! src dst -Copies every element from vector or array @var{source} to the -corresponding element of @var{destination}. @var{destination} must have -the same rank as @var{source}, and be at least as large in each -dimension. The order is unspecified. -@end deffn - -@deffn primitive array-fill! ra fill -Stores @var{fill} in every element of @var{array}. The value returned -is unspecified. -@end deffn - -@c begin (texi-doc-string "guile" "array-equal?") -@deffn primitive array-equal? ra0 ra1 -Returns @code{#t} iff 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?} in that a one dimensional shared array may be -@var{array-equal?} but not @var{equal?} to a vector or uniform vector. -@end deffn - -@deffn primitive array-contents ra [strict] -@deffnx primitive 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 @var{make-array} and -@var{make-uniform-array} may be unrolled, some arrays made by -@var{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 - -@node Array Mapping -@subsection Array Mapping - -@deffn primitive array-map! ra0 proc . lra -@deffnx primitive array-map-in-order! ra0 proc . lra -@var{array1}, @dots{} must have the same number of dimensions as -@var{array0} and have a range for each index which includes the range -for the corresponding index in @var{array0}. @var{proc} is applied to -each tuple of elements of @var{array1} @dots{} and the result is stored -as the corresponding element in @var{array0}. The value returned is -unspecified. The order of application is unspecified. -@end deffn - -@deffn primitive array-for-each proc ra0 . lra -@var{proc} is applied to each tuple of elements of @var{array0} @dots{} -in row-major order. The value returned is unspecified. -@end deffn - -@deffn primitive array-index-map! ra proc -applies @var{proc} to the indices of each element of @var{array} in -turn, storing the result in the corresponding element. The value -returned and the order of application are unspecified. - -One can implement @var{array-indexes} as -@lisp -(define (array-indexes array) - (let ((ra (apply make-array #f (array-shape array)))) - (array-index-map! ra (lambda x x)) - ra)) -@end lisp -Another example: -@lisp -(define (apl:index-generator n) - (let ((v (make-uniform-vector n 1))) - (array-index-map! v (lambda (i) i)) - v)) -@end lisp -@end deffn - -@node Uniform Arrays -@subsection Uniform Arrays -@tpindex Uniform Arrays - -@noindent -@dfn{Uniform arrays} have elements all of the -same type and occupy less storage than conventional -arrays. Uniform arrays with a single zero-based dimension -are also known as @dfn{uniform vectors}. The procedures in -this section can also be used on conventional arrays, vectors, -bit-vectors and strings. - -@noindent -When creating a uniform array, the type of data to be stored -is indicated with a @var{prototype} argument. The following table -lists the types available and example prototypes: - -@example -prototype type printing character - -#t boolean (bit-vector) b -#\a char (string) a -#\nul byte (integer) y -'s short (integer) h -1 unsigned long (integer) u --1 signed long (integer) e -'l signed long long (integer) l -1.0 float (single precision) s -1/3 double (double precision float) i -0+i complex (double precision) c -() conventional vector -@end example - -@noindent -Unshared uniform arrays of characters with a single zero-based dimension -are identical to strings: - -@example -(make-uniform-array #\a 3) @result{} -"aaa" -@end example - -@noindent -Unshared uniform arrays of booleans with a single zero-based dimension -are identical to @ref{Bit Vectors, bit-vectors}. - -@example -(make-uniform-array #t 3) @result{} -#*111 -@end example - -@noindent -Other uniform vectors are written in a form similar to that of vectors, -except that a single character from the above table is put between -@code{#} and @code{(}. For example, a uniform vector of signed -long integers is displayed in the form @code{'#e(3 5 9)}. - -@deffn primitive array? v [prot] -Returns @code{#t} if the @var{obj} is an array, and @code{#f} if not. - -The @var{prototype} argument is used with uniform arrays and is described -elsewhere. -@end deffn - -@deffn procedure make-uniform-array prototype bound1 bound2 @dots{} -Creates and returns a uniform array of type corresponding to -@var{prototype} that has as many dimensions as there are @var{bound}s -and fills it with @var{prototype}. -@end deffn - -@deffn primitive array-prototype ra -Return an object that would produce an array of the same type -as @var{array}, if used as the @var{prototype} for -@code{make-uniform-array}. -@end deffn - -@deffn primitive list->uniform-array ndim prot lst -@deffnx procedure list->uniform-vector prot lst -Return a uniform array of the type indicated by prototype -@var{prot} with elements the same as those of @var{lst}. -Elements must be of the appropriate type, no coercions are -done. -@end deffn - -@deffn primitive uniform-vector-fill! uve fill -Stores @var{fill} in every element of @var{uve}. The value returned is -unspecified. -@end deffn - -@deffn primitive uniform-vector-length v -Return the number of elements in @var{uve}. -@end deffn - -@deffn primitive dimensions->uniform-array dims prot [fill] -@deffnx primitive make-uniform-vector length prototype [fill] -Create and return a uniform array or vector of type -corresponding to @var{prototype} with dimensions @var{dims} or -length @var{length}. If @var{fill} is supplied, it's used to -fill the array, otherwise @var{prototype} is used. -@end deffn - -@c Another compiled-closure. -twp - -@deffn primitive uniform-array-read! ra [port_or_fd [start [end]]] -@deffnx primitive uniform-vector-read! uve [port-or-fdes] [start] [end] -Attempts to read all elements of @var{ura}, in lexicographic order, as -binary objects from @var{port-or-fdes}. -If an end of file is encountered during -uniform-array-read! the objects up to that point only are put into @var{ura} -(starting at the beginning) and the remainder of the array is -unchanged. - -The optional arguments @var{start} and @var{end} allow -a specified region of a vector (or linearized array) to be read, -leaving the remainder of the vector unchanged. - -@code{uniform-array-read!} returns the number of objects read. -@var{port-or-fdes} may be omitted, in which case it defaults to the value -returned by @code{(current-input-port)}. -@end deffn - -@deffn primitive uniform-array-write v [port_or_fd [start [end]]] -@deffnx primitive uniform-vector-write uve [port-or-fdes] [start] [end] -Writes all elements of @var{ura} as binary objects to -@var{port-or-fdes}. - -The optional arguments @var{start} -and @var{end} allow -a specified region of a vector (or linearized array) to be written. - -The number of objects actually written is returned. -@var{port-or-fdes} may be -omitted, in which case it defaults to the value returned by -@code{(current-output-port)}. -@end deffn - -@node Bit Vectors -@subsection Bit Vectors - -@noindent -Bit vectors are a specific type of uniform array: an array of booleans -with a single zero-based index. - -@noindent -They are displayed as a sequence of @code{0}s and -@code{1}s prefixed by @code{#*}, e.g., - -@example -(make-uniform-vector 8 #t #f) @result{} -#*00000000 - -#b(#t #f #t) @result{} -#*101 -@end example - -@deffn primitive bit-count b bitvector -Return the number of occurrences of the boolean @var{b} in -@var{bitvector}. -@end deffn - -@deffn primitive bit-position item v k -Return the minimum index of an occurrence of @var{bool} in -@var{bv} which is at least @var{k}. If no @var{bool} occurs -within the specified range @code{#f} is returned. -@end deffn - -@deffn primitive bit-invert! v -Modifies @var{bv} by replacing each element with its negation. -@end deffn - -@deffn primitive bit-set*! v kv obj -If uve is a bit-vector @var{bv} and uve must be of the same -length. If @var{bool} is @code{#t}, uve is OR'ed into -@var{bv}; If @var{bool} is @code{#f}, the inversion of uve is -AND'ed into @var{bv}. - -If uve is a unsigned long integer vector all the elements of uve -must be between 0 and the @code{length} of @var{bv}. The bits -of @var{bv} corresponding to the indexes in uve are set to -@var{bool}. The return value is unspecified. -@end deffn - -@deffn primitive bit-count* v kv obj -Return -@lisp -(bit-count (bit-set*! (if bool bv (bit-invert! bv)) uve #t) #t). -@end lisp -@var{bv} is not modified. -@end deffn - - -@node Association Lists and Hash Tables -@section Association Lists and Hash Tables - -This chapter discusses dictionary objects: data structures that are -useful for organizing and indexing large bodies of information. - -@menu -* Dictionary Types:: About dictionary types; what they're good for. -* Association Lists:: List-based dictionaries. -* Hash Tables:: Table-based dictionaries. -@end menu - -@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 primitive acons key value alist -Adds 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 primitive assq-set! alist key val -@deffnx primitive assv-set! alist key value -@deffnx primitive assoc-set! alist key value -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} take an alist and a key as -arguments and return the entry for that key if an entry exists, or -@code{#f} if there is no entry for that key. Note that, in the cases -where an entry exists, these procedures return the complete entry, that -is @code{(KEY . VALUE)}, not just the value. - -@deffn primitive assq key alist -@deffnx primitive assv key alist -@deffnx primitive assoc key alist -Fetches the entry in @var{alist} that is associated with @var{key}. To -decide whether the argument @var{key} matches a particular entry in -@var{alist}, @code{assq} compares keys with @code{eq?}, @code{assv} -uses @code{eqv?} and @code{assoc} uses @code{equal?}. If @var{key} -cannot be found in @var{alist} (according to whichever equality -predicate is in use), then @code{#f} is returned. These functions -return the entire alist entry found (i.e. both the key and the value). -@end deffn - -@code{assq-ref}, @code{assv-ref} and @code{assoc-ref}, on the other -hand, take an alist and a key and return @emph{just the value} for that -key, if an entry exists. If there is no entry for the specified key, -these procedures return @code{#f}. - -This creates an ambiguity: if the return value is @code{#f}, it means -either that there is no entry with the specified key, or that there -@emph{is} an entry for the specified key, with value @code{#f}. -Consequently, @code{assq-ref} and friends should only be used where it -is known that an entry exists, or where the ambiguity doesn't matter -for some other reason. - -@deffn primitive assq-ref alist key -@deffnx primitive assv-ref alist key -@deffnx primitive assoc-ref alist key -Like @code{assq}, @code{assv} and @code{assoc}, except that only the -value associated with @var{key} in @var{alist} is returned. These -functions are equivalent to - -@lisp -(let ((ent (@var{associator} @var{key} @var{alist}))) - (and ent (cdr ent))) -@end lisp - -where @var{associator} is one of @code{assq}, @code{assv} or @code{assoc}. -@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 primitive assq-remove! alist key -@deffnx primitive assv-remove! alist key -@deffnx primitive assoc-remove! 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 NULLP): "open sesame" -ABORT: (wrong-type-arg) - -(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 CONSP): 2 -ABORT: (wrong-type-arg) - -(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 primitive 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 primitive 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 primitive 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" "Bismarck")) -capitals -@result{} (("South Dakota" . "Bismarck") - ("New York" . "Albany") - ("Oregon" . "Salem") - ("Florida" . "Miami")) - -;; And we got Florida wrong. -(set! capitals - (assoc-set! capitals "Florida" "Tallahassee")) -capitals -@result{} (("South Dakota" . "Bismarck") - ("New York" . "Albany") - ("Oregon" . "Salem") - ("Florida" . "Tallahassee")) - -;; After Oregon secedes, we can remove it. -(set! capitals - (assoc-remove! capitals "Oregon")) -capitals -@result{} (("South Dakota" . "Bismarck") - ("New York" . "Albany") - ("Florida" . "Tallahassee")) -@end lisp - -@node Hash Tables -@subsection Hash Tables -@tpindex Hash Tables - -@c FIXME::martin: Review me! - -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 - -@c FIXME::martin: Review me! - -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)) - -(hashq-create-handle! h 'foo "bar") -@result{} -(foo . "bar") - -(hashq-create-handle! h 'braz "zonk") -@result{} -(braz . "zonk") - -(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 - -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 - -There is no procedure for calculating the number of key/value-pairs in -a hash table, but @code{hash-fold} can be used for doing exactly that. - -@lisp -(hash-fold (lambda (key value seed) (+ 1 seed)) 0 h) -@result{} -3 -@end lisp - -@node Hash Table Reference -@subsubsection Hash Table Reference - -Like the association list functions, the hash table functions come -in several varieties: @code{hashq}, @code{hashv}, and @code{hash}. -The @code{hashq} functions use @code{eq?} to determine whether two -keys match. The @code{hashv} functions use @code{eqv?}, and the -@code{hash} functions use @code{equal?}. - -In each of the functions that follow, the @var{table} argument -must be a vector. The @var{key} and @var{value} arguments may be -any Scheme object. - -@deffn procedure make-hash-table size -Create a new hash table of @var{size} slots. Note that the number of -slots does not limit the size of the table, it just tells how large -the underlying vector will be. The @var{size} should be similar to -the expected number of elements which will be added to the table, but -they need not match. For good performance, it might be a good idea to -use a prime number as the @var{size}. -@end deffn - -@deffn primitive hashq-ref table key [dflt] -Look up @var{key} in the hash table @var{table}, and return the -value (if any) associated with it. If @var{key} is not found, -return @var{default} (or @code{#f} if no @var{default} argument -is supplied). Uses @code{eq?} for equality testing. -@end deffn - -@deffn primitive hashv-ref table key [dflt] -Look up @var{key} in the hash table @var{table}, and return the -value (if any) associated with it. If @var{key} is not found, -return @var{default} (or @code{#f} if no @var{default} argument -is supplied). Uses @code{eqv?} for equality testing. -@end deffn - -@deffn primitive hash-ref table key [dflt] -Look up @var{key} in the hash table @var{table}, and return the -value (if any) associated with it. If @var{key} is not found, -return @var{default} (or @code{#f} if no @var{default} argument -is supplied). Uses @code{equal?} for equality testing. -@end deffn - -@deffn primitive hashq-set! table key val -Find the entry in @var{table} associated with @var{key}, and -store @var{value} there. Uses @code{eq?} for equality testing. -@end deffn - -@deffn primitive hashv-set! table key val -Find the entry in @var{table} associated with @var{key}, and -store @var{value} there. Uses @code{eqv?} for equality testing. -@end deffn - -@deffn primitive hash-set! table key val -Find the entry in @var{table} associated with @var{key}, and -store @var{value} there. Uses @code{equal?} for equality -testing. -@end deffn - -@deffn primitive hashq-remove! table key -Remove @var{key} (and any value associated with it) from -@var{table}. Uses @code{eq?} for equality tests. -@end deffn - -@deffn primitive hashv-remove! table key -Remove @var{key} (and any value associated with it) from -@var{table}. Uses @code{eqv?} for equality tests. -@end deffn - -@deffn primitive hash-remove! table key -Remove @var{key} (and any value associated with it) from -@var{table}. Uses @code{equal?} for equality tests. -@end deffn - -The standard hash table functions may be too limited for some -applications. For example, you may want a hash table to store -strings in a case-insensitive manner, so that references to keys -named ``foobar'', ``FOOBAR'' and ``FooBaR'' will all yield the -same item. Guile provides you with @dfn{extended} hash tables -that permit you to specify a hash function and associator function -of your choosing. The functions described in the rest of this section -can be used to implement such custom hash table structures. - -If you are unfamiliar with the inner workings of hash tables, then -this facility will probably be a little too abstract for you to -use comfortably. If you are interested in learning more, see an -introductory textbook on data structures or algorithms for an -explanation of how hash tables are implemented. - -@deffn primitive hashq key size -Determine a hash value for @var{key} that is suitable for -lookups in a hashtable of size @var{size}, where @code{eq?} is -used as the equality predicate. The function returns an -integer in the range 0 to @var{size} - 1. Note that -@code{hashq} may use internal addresses. Thus two calls to -hashq where the keys are @code{eq?} are not guaranteed to -deliver the same value if the key object gets garbage collected -in between. This can happen, for example with symbols: -@code{(hashq 'foo n) (gc) (hashq 'foo n)} may produce two -different values, since @code{foo} will be garbage collected. -@end deffn - -@deffn primitive hashv key size -Determine a hash value for @var{key} that is suitable for -lookups in a hashtable of size @var{size}, where @code{eqv?} is -used as the equality predicate. The function returns an -integer in the range 0 to @var{size} - 1. Note that -@code{(hashv key)} may use internal addresses. Thus two calls -to hashv where the keys are @code{eqv?} are not guaranteed to -deliver the same value if the key object gets garbage collected -in between. This can happen, for example with symbols: -@code{(hashv 'foo n) (gc) (hashv 'foo n)} may produce two -different values, since @code{foo} will be garbage collected. -@end deffn - -@deffn primitive hash key size -Determine a hash value for @var{key} that is suitable for -lookups in a hashtable of size @var{size}, where @code{equal?} -is used as the equality predicate. The function returns an -integer in the range 0 to @var{size} - 1. -@end deffn - -@deffn primitive hashx-ref hash assoc table key [dflt] -This behaves the same way as the corresponding @code{ref} -function, but uses @var{hash} as a hash function and -@var{assoc} to compare keys. @code{hash} must be a function -that takes two arguments, a key to be hashed and a table size. -@code{assoc} must be an associator function, like @code{assoc}, -@code{assq} or @code{assv}. - -By way of illustration, @code{hashq-ref table key} is -equivalent to @code{hashx-ref hashq assq table key}. -@end deffn - -@deffn primitive hashx-set! hash assoc table key val -This behaves the same way as the corresponding @code{set!} -function, but uses @var{hash} as a hash function and -@var{assoc} to compare keys. @code{hash} must be a function -that takes two arguments, a key to be hashed and a table size. -@code{assoc} must be an associator function, like @code{assoc}, -@code{assq} or @code{assv}. - - By way of illustration, @code{hashq-set! table key} is -equivalent to @code{hashx-set! hashq assq table key}. -@end deffn - -@deffn primitive hashq-get-handle table key -This procedure returns the @code{(key . value)} pair from the -hash table @var{table}. If @var{table} does not hold an -associated value for @var{key}, @code{#f} is returned. -Uses @code{eq?} for equality testing. -@end deffn - -@deffn primitive hashv-get-handle table key -This procedure returns the @code{(key . value)} pair from the -hash table @var{table}. If @var{table} does not hold an -associated value for @var{key}, @code{#f} is returned. -Uses @code{eqv?} for equality testing. -@end deffn - -@deffn primitive hash-get-handle table key -This procedure returns the @code{(key . value)} pair from the -hash table @var{table}. If @var{table} does not hold an -associated value for @var{key}, @code{#f} is returned. -Uses @code{equal?} for equality testing. -@end deffn - -@deffn primitive hashx-get-handle hash assoc table key -This behaves the same way as the corresponding -@code{-get-handle} function, but uses @var{hash} as a hash -function and @var{assoc} to compare keys. @code{hash} must be -a function that takes two arguments, a key to be hashed and a -table size. @code{assoc} must be an associator function, like -@code{assoc}, @code{assq} or @code{assv}. -@end deffn - -@deffn primitive hashq-create-handle! table key init -This function looks up @var{key} in @var{table} and returns its handle. -If @var{key} is not already present, a new handle is created which -associates @var{key} with @var{init}. -@end deffn - -@deffn primitive hashv-create-handle! table key init -This function looks up @var{key} in @var{table} and returns its handle. -If @var{key} is not already present, a new handle is created which -associates @var{key} with @var{init}. -@end deffn - -@deffn primitive hash-create-handle! table key init -This function looks up @var{key} in @var{table} and returns its handle. -If @var{key} is not already present, a new handle is created which -associates @var{key} with @var{init}. -@end deffn - -@deffn primitive hashx-create-handle! hash assoc table key init -This behaves the same way as the corresponding -@code{-create-handle} function, but uses @var{hash} as a hash -function and @var{assoc} to compare keys. @code{hash} must be -a function that takes two arguments, a key to be hashed and a -table size. @code{assoc} must be an associator function, like -@code{assoc}, @code{assq} or @code{assv}. -@end deffn - -@deffn primitive hash-fold proc init table -An iterator over hash-table elements. -Accumulates and returns a result by applying PROC successively. -The arguments to PROC are "(key value prior-result)" where key -and value are successive pairs from the hash table TABLE, and -prior-result is either INIT (for the first application of PROC) -or the return value of the previous application of PROC. -For example, @code{(hash-fold acons '() tab)} will convert a hash -table into an a-list of key-value pairs. -@end deffn - - -@node Hooks -@section Hooks -@tpindex Hooks - -@c FIXME::martin: Review me! - -A hook is basically a list of procedures to be called at well defined -points in time. Hooks are used internally for several debugging -facilities, but they can be used in user code, too. - -Hooks are created with @code{make-hook}, then procedures can be added to -a hook with @code{add-hook!} or removed with @code{remove-hook!} or -@code{reset-hook!}. The procedures stored in a hook can be invoked with -@code{run-hook}. - -@menu -* Hook Examples:: Hook usage by example. -* Hook Reference:: Reference of all hook procedures. -@end menu - -@node Hook Examples -@subsection Hook Examples - -Hook usage is shown by some examples in this section. First, we will -define a hook of arity 2 --- that is, the procedures stored in the hook -will have to accept two arguments. - -@lisp -(define hook (make-hook 2)) -hook -@result{} #<hook 2 40286c90> -@end lisp - -Now we are ready to add some procedures to the newly created hook with -@code{add-hook!}. In the following example, two procedures are added, -which print different messages and do different things with their -arguments. When the procedures have been added, we can invoke them -using @code{run-hook}. - -@lisp -(add-hook! hook (lambda (x y) - (display "Foo: ") - (display (+ x y)) - (newline))) -(add-hook! hook (lambda (x y) - (display "Bar: ") - (display (* x y)) - (newline))) -(run-hook hook 3 4) -@print{} Bar: 12 -@print{} Foo: 7 -@end lisp - -Note that the procedures are called in reverse order than they were -added. This can be changed by providing the optional third argument -on the second call to @code{add-hook!}. - -@lisp -(add-hook! hook (lambda (x y) - (display "Foo: ") - (display (+ x y)) - (newline))) -(add-hook! hook (lambda (x y) - (display "Bar: ") - (display (* x y)) - (newline)) - #t) ; @r{<- Change here!} -(run-hook hook 3 4) -@print{} Foo: 7 -@print{} Bar: 12 -@end lisp - -@node Hook Reference -@subsection Hook Reference - -When a hook is created with @code{make-hook}, you can supply the arity -of the procedures which can be added to the hook. The arity defaults to -zero. All procedures of a hook must have the same arity, and when the -procedures are invoked using @code{run-hook}, the number of arguments -must match the arity of the procedures. - -The order in which procedures are added to a hook matters. If the third -parameter to @var{add-hook!} is omitted or is equal to @code{#f}, the -procedure is added in front of the procedures which might already be on -that hook, otherwise the procedure is added at the end. The procedures -are always called from first to last when they are invoked via -@code{run-hook}. - -When calling @code{hook->list}, the procedures in the resulting list are -in the same order as they would have been called by @code{run-hook}. - -@deffn primitive make-hook-with-name name [n_args] -Create a named hook with the name @var{name} for storing -procedures of arity @var{n_args}. @var{n_args} defaults to -zero. -@end deffn - -@deffn primitive make-hook [n_args] -Create a hook for storing procedure of arity -@var{n_args}. @var{n_args} defaults to zero. -@end deffn - -@deffn primitive hook? x -Return @code{#t} if @var{x} is a hook, @code{#f} otherwise. -@end deffn - -@deffn primitive hook-empty? hook -Return @code{#t} if @var{hook} is an empty hook, @code{#f} -otherwise. -@end deffn - -@deffn primitive add-hook! hook proc [append_p] -Add the procedure @var{proc} to the hook @var{hook}. The -procedure is added to the end if @var{append_p} is true, -otherwise it is added to the front. -@end deffn - -@deffn primitive remove-hook! hook proc -Remove the procedure @var{proc} from the hook @var{hook}. -@end deffn - -@deffn primitive reset-hook! hook -Remove all procedures from the hook @var{hook}. -@end deffn - -@deffn primitive run-hook hook . args -Apply all procedures from the hook @var{hook} to the arguments -@var{args}. The order of the procedure application is first to -last. -@end deffn - -@deffn primitive hook->list hook -Convert the procedure list of @var{hook} to a list. -@end deffn - - -@node Other Data Types -@section Other Core Guile Data Types - -@c Local Variables: -@c TeX-master: "guile.texi" -@c End: |