diff --git a/doc/scheme-data.texi b/doc/scheme-data.texi index e69de29bb..07022b2ad 100755 --- a/doc/scheme-data.texi +++ b/doc/scheme-data.texi @@ -0,0 +1,5230 @@ +@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} otherwise. +@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} otherwise. + +@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} otherwise. +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} +otherwise. Note that the set of integer values forms a subset of +the set of rational numbers, i. e. the predicate will also be +fulfilled if @var{x} is an integer number. 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} +otherwise. Note that the sets of real, rational and integer +values form subsets of the set of complex numbers, i. e. the +predicate will also be fulfilled if @var{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} +otherwise. +@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 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 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 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? +@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} +# +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 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 "#" + (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{} # +@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{} + # + +(enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) @result{} + # +@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{} # +@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 [n_args] +Create a hook for storing procedure of arity @var{n_args}. +@var{n_args} defaults to zero. The returned value is a hook +object to be used with the other hook procedures. +@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. The return value of this +procedure is not specified. +@end deffn + +@deffn primitive remove-hook! hook proc +Remove the procedure @var{proc} from the hook @var{hook}. The +return value of this procedure is not specified. +@end deffn + +@deffn primitive reset-hook! hook +Remove all procedures from the hook @var{hook}. The return +value of this procedure is not specified. +@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. The return value of this procedure is not specified. +@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: