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

  * 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

  * 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.

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 data in a wide variety of programming contexts is more important than their use in the implementation of a particular piece of functionality.

The following menu 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.

Booleans
========

The two boolean values are #t for true and #f for false.

Boolean values are returned by predicate procedures, such as the general equality predicates eq?, eqv? and equal? (see Equality) and numerical and string comparison operators like string=? (REFFIXME) and <= (REFFIXME).

     (<= 3 8)
     =>
     #t

     (<= 3 -3)
     =>
     #f

     (equal? "house" "houses")
     =>
     #f

     (eq? #f #f)
     =>
     #t

In test condition contexts like if (REFFIXME) and cond (REFFIXME), where a group of subexpressions will be evaluated only if a CONDITION expression evaluates to ``true'', ``true'' means any value at all except #f.

     (if #t "yes" "no")
     =>
     "yes"

     (if 0 "yes" "no")
     =>
     "yes"

     (if #f "yes" "no")
     =>
     "no"

A result of this asymmetry is that typical Scheme source code more often uses #f explicitly than #t: #f is necessary to represent an if or cond false value, whereas #t is not necessary to represent an if or cond true value.

It is important to note that #f is not equivalent to any other Scheme value.  In particular, #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 not procedure returns the boolean inverse of its argument:

 -- primitive: not x
     Return #t iff X is #f, else return #f.

The boolean? procedure is a predicate that returns #t if its argument is one of the boolean values, otherwise #f.

 -- primitive: boolean? obj
     Return #t iff OBJ is either #t or #f.

Numerical data types
====================

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 Numbers (r5rs).

Scheme's Numerical ``Tower''
----------------------------

Scheme's numerical ``tower'' consists of the following categories of numbers:

  * integers (whole numbers)

  * rationals (the set of numbers that can be expressed as P/Q where P and Q are integers)

  * real numbers (the set of numbers that describes all possible positions along a one dimensional line)

  * complex numbers (the set of numbers that describes all possible positions in a two dimensional space)

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 number? predicate may be applied to any Scheme value to discover whether the value is any of the supported numerical types.

 -- primitive: number? obj
     Return #t if OBJ is any kind of number, #f else.

For example:

     (number? 3)
     =>
     #t

     (number? "hello there!")
     =>
     #f

     (define pi 3.141592654)
     (number? pi)
     =>
     #t

The next few subsections document each of Guile's numerical data types in detail.

Integers
--------

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.

     (define (factorial n)
       (let loop ((n n) (product 1))
         (if (= n 0)
             product
             (loop (- n 1) (* product n)))))

     (factorial 3)
     =>
     6

     (factorial 20)
     =>
     2432902008176640000

     (- (factorial 45))
     =>
     -119622220865480194561963161495657715064383733760000000000

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.

 -- primitive: integer? x
     Return #t if X is an integer number, #f else.

          (integer? 487)
          =>
          #t

          (integer? -3.4)
          =>
          #f

Real and Rational Numbers
-------------------------

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:

     0.34
     -0.00000142857931198
     -5648394822220000000000.0
     4.0

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, -0.00000142857931198 is the same as 142857931198 divided by 100000000000000000.  In Guile's current incarnation, therefore, the rational? and 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.

 -- primitive: real? obj
     Return #t if OBJ is a real number, #f else. Note that the sets of integer and rational values form subsets of the set of real numbers, so the predicate will also be fulfilled if OBJ is an integer number or a rational number.

 -- primitive: rational? x
     Return #t if X is a rational number, #f else.  Note that the set of integer values forms a subset of the set of rational numbers, i. e. the predicate will also be fulfilled if X is an integer number.  Real numbers will also satisfy this predicate, because of their limited precision.

Complex Numbers
---------------

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 real and 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 i to indicate the imaginary part.

     3+4i
     =>
     3.0+4.0i

     (* 3-8i 2.3+0.3i)
     =>
     9.3-17.5i

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.

 -- primitive: complex? x
     Return #t if X is a complex number, #f else.  Note that the sets of real, rational and integer values form subsets of the set of complex numbers, i. e. the predicate will also be fulfilled if X is a real, rational or integer number.

Exact and Inexact Numbers
-------------------------

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 5 and the corresponding inexact real value which, to the limited precision available, has no fractional part, and is printed as 5.0.  Guile will only convert the latter value to the former when forced to do so by an invocation of the inexact->exact procedure.

 -- primitive: exact? x
     Return #t if X is an exact number, #f otherwise.

 -- primitive: inexact? x
     Return #t if X is an inexact number, #f else.

 -- primitive: inexact->exact z
     Return an exact number that is numerically closest to Z.

 -- primitive: exact->inexact z
     Convert the number Z to its inexact representation.

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:

  * #b, #B --- the integer is written in binary (base 2)

  * #o, #O --- the integer is written in octal (base 8)

  * #d, #D --- the integer is written in decimal (base 10)

  * #x, #X --- the integer is written in hexadecimal (base 16).

If the base code is omitted, the integer is assumed to be decimal.  The following examples show how these base codes are used.

     -13
     =>
     -13

     #d-13
     =>
     -13

     #x-13
     =>
     -19

     #b+1101
     =>
     13

     #o377
     =>
     255

The codes for indicating exactness (which can, incidentally, be applied to all numerical values) are:

  * #e, #E --- the number is exact

  * #i, #I --- the number is inexact.

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 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.

Operations on Integer Values
----------------------------

 -- primitive: odd? n
     Return #t if N is an odd number, #f otherwise.

 -- primitive: even? n
     Return #t if N is an even number, #f otherwise.

 -- primitive: quotient
     Return the quotient of the numbers X and Y.

 -- primitive: remainder
     Return the remainder of the numbers X and Y.

          (remainder 13 4) => 1
          (remainder -13 4) => -1

 -- primitive: modulo
     Return the modulo of the numbers X and Y.

          (modulo 13 4) => 1
          (modulo -13 4) => 3

 -- primitive: gcd
     Return the greatest common divisor of all arguments. If called without arguments, 0 is returned.

 -- primitive: lcm
     Return the least common multiple of the arguments. If called without arguments, 1 is returned.

Comparison Predicates
---------------------

 -- primitive: =
     Return #t if all parameters are numerically equal.

 -- primitive: <
     Return #t if the list of parameters is monotonically increasing.

 -- primitive: >
     Return #t if the list of parameters is monotonically decreasing.

 -- primitive: <=
     Return #t if the list of parameters is monotonically non-decreasing.

 -- primitive: >=
     Return #t if the list of parameters is monotonically non-increasing.

 -- primitive: zero?
     Return #t if Z is an exact or inexact number equal to zero.

 -- primitive: positive?
     Return #t if X is an exact or inexact number greater than zero.

 -- primitive: negative?
     Return #t if X is an exact or inexact number less than zero.

Converting Numbers To and From Strings
--------------------------------------

 -- primitive: number->string n [radix]
     Return a string holding the external representation of the number N in the given RADIX.  If N is inexact, a radix of 10 will be used.

 -- primitive: string->number string [radix]
     Return a number of the maximally precise representation expressed by the given STRING. RADIX must be an exact integer, either 2, 8, 10, or 16. If supplied, RADIX is a default radix that may be overridden by an explicit radix prefix in STRING (e.g. "#o177"). If RADIX is not supplied, then the default radix is 10. If string is not a syntactically valid notation for a number, then string->number returns #f.

Complex Number Operations
-------------------------

 -- primitive: make-rectangular real imaginary
     Return a complex number constructed of the given REAL and IMAGINARY parts.

 -- primitive: make-polar x y
     Return the complex number X * e^(i * Y).

 -- primitive: real-part
     Return the real part of the number Z.

 -- primitive: imag-part
     Return the imaginary part of the number Z.

 -- primitive: magnitude
     Return the magnitude of the number Z. This is the same as abs for real arguments, but also allows complex numbers.

 -- primitive: angle
     Return the angle of the complex number Z.

Arithmetic Functions
--------------------

 -- primitive: + z1 ...
     Return the sum of all parameter values.  Return 0 if called without any parameters.

 -- primitive: - z1 z2 ...
     If called without arguments, 0 is returned. Otherwise the sum of all but the first argument are subtracted from the first argument.

 -- primitive: * z1 ...
     Return the product of all arguments.  If called without arguments, 1 is returned.

 -- primitive: / z1 z2 ...
     Divide the first argument by the product of the remaining arguments.

 -- primitive: abs x
     Return the absolute value of X.

 -- primitive: max x1 x2 ...
     Return the maximum of all parameter values.

 -- primitive: min x1 x2 ...
     Return the minium of all parameter values.

 -- primitive: truncate
     Round the inexact number X towards zero.

 -- primitive: round x
     Round the inexact number X towards zero.

 -- primitive: floor x
     Round the number X towards minus infinity.

 -- primitive: ceiling x
     Round the number X towards infinity.

Scientific Functions
--------------------

The following procedures accept any kind of number as arguments, including complex numbers.

 -- procedure: sqrt z
     Return the square root of Z.

 -- procedure: expt z1 z2
     Return Z1 raised to the power of Z2.

 -- procedure: sin z
     Return the sine of Z.

 -- procedure: cos z
     Return the cosine of Z.

 -- procedure: tan z
     Return the tangent of Z.

 -- procedure: asin z
     Return the arcsine of Z.

 -- procedure: acos z
     Return the arccosine of Z.

 -- procedure: atan z
     Return the arctangent of Z.

 -- procedure: exp z
     Return e to the power of Z, where e is the base of natural logarithms (2.71828...).

 -- procedure: log z
     Return the natural logarithm of Z.

 -- procedure: log10 z
     Return the base 10 logarithm of Z.

 -- procedure: sinh z
     Return the hyperbolic sine of Z.

 -- procedure: cosh z
     Return the hyperbolic cosine of Z.

 -- procedure: tanh z
     Return the hyperbolic tangent of Z.

 -- procedure: asinh z
     Return the hyperbolic arcsine of Z.

 -- procedure: acosh z
     Return the hyperbolic arccosine of Z.

 -- procedure: atanh z
     Return the hyperbolic arctangent of Z.

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.

 -- primitive: $abs x
     Return the absolute value of X.

 -- primitive: $sqrt x
     Return the square root of X.

 -- primitive: $expt x y
     Return X raised to the power of Y. This procedure does not accept complex arguments.

 -- primitive: $sin x
     Return the sine of X.

 -- primitive: $cos x
     Return the cosine of X.

 -- primitive: $tan x
     Return the tangent of X.

 -- primitive: $asin x
     Return the arcsine of X.

 -- primitive: $acos x
     Return the arccosine of X.

 -- primitive: $atan x
     Return the arctangent of X in the range -PI/2 to PI/2.

 -- primitive: $atan2 x y
     Return the arc tangent of the two arguments X and Y. This is similar to calculating the arc tangent of X / Y, except that the signs of both arguments are used to determine the quadrant of the result. This procedure does not accept complex arguments.

 -- primitive: $exp x
     Return e to the power of X, where e is the base of natural logarithms (2.71828...).

 -- primitive: $log x
     Return the natural logarithm of X.

 -- primitive: $sinh x
     Return the hyperbolic sine of X.

 -- primitive: $cosh x
     Return the hyperbolic cosine of X.

 -- primitive: $tanh x
     Return the hyperbolic tangent of X.

 -- primitive: $asinh x
     Return the hyperbolic arcsine of X.

 -- primitive: $acosh x
     Return the hyperbolic arccosine of X.

 -- primitive: $atanh x
     Return the hyperbolic arctangent of X.

Bitwise Operations
------------------

 -- primitive: logand n1 n2
     Return the integer which is the bit-wise AND of the two integer arguments.

          (number->string (logand #b1100 #b1010) 2)
             => "1000"

 -- primitive: logior n1 n2
     Return the integer which is the bit-wise OR of the two integer arguments.

          (number->string (logior #b1100 #b1010) 2)
             => "1110"

 -- primitive: logxor n1 n2
     Return the integer which is the bit-wise XOR of the two integer arguments.

          (number->string (logxor #b1100 #b1010) 2)
             => "110"

 -- primitive: lognot n
     Return the integer which is the 2s-complement of the integer argument.

          (number->string (lognot #b10000000) 2)
             => "-10000001"
          (number->string (lognot #b0) 2)
             => "-1"

 -- primitive: logtest j k

          (logtest j k) == (not (zero? (logand j k)))

          (logtest #b0100 #b1011) => #f
          (logtest #b0100 #b0111) => #t

 -- primitive: logbit? index j

          (logbit? index j) == (logtest (integer-expt 2 index) j)

          (logbit? 0 #b1101) => #t
          (logbit? 1 #b1101) => #f
          (logbit? 2 #b1101) => #t
          (logbit? 3 #b1101) => #t
          (logbit? 4 #b1101) => #f

 -- primitive: ash n cnt
     The function ash performs an arithmetic shift left by CNT bits (or shift right, if CNT is negative).  'Arithmetic' means, that the function does not guarantee to keep the bit structure of 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 N is negative. Formally, the function returns an integer equivalent to (inexact->exact (floor (* N (expt 2 CNT)))).

          (number->string (ash #b1 3) 2)     => "1000"
          (number->string (ash #b1010 -1) 2) => "101"

 -- primitive: logcount n
     Return the number of bits in integer 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.

          (logcount #b10101010)
             => 4
          (logcount 0)
             => 0
          (logcount -2)
             => 1

 -- primitive: integer-length n
     Return the number of bits neccessary to represent N.

          (integer-length #b10101010)
             => 8
          (integer-length 0)
             => 0
          (integer-length #b1111)
             => 4

 -- primitive: integer-expt n k
     Return N raised to the non-negative integer exponent K.

          (integer-expt 2 5)
             => 32
          (integer-expt -3 3)
             => -27

 -- primitive: bit-extract n start end
     Return the integer composed of the START (inclusive) through END (exclusive) bits of N.  The STARTth bit becomes the 0-th bit in the result.

          (number->string (bit-extract #b1101101010 0 4) 2)
             => "1010"
          (number->string (bit-extract #b1101101010 4 9) 2)
             => "10110"

Random Number Generation
------------------------

 -- primitive: copy-random-state [state]
     Return a copy of the random state STATE.

 -- 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 STATE must be of the type produced by seed->random-state. It defaults to the value of the variable *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.

 -- 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)).

 -- 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.

 -- 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 (+ m (* d (random:normal))).

 -- 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).

 -- 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.

 -- primitive: random:uniform [state]
     Return a uniformly distributed inexact real random number in [0,1).

 -- primitive: seed->random-state seed
     Return a new random state using SEED.

Characters
==========

Most of the characters in the ASCII character set may be referred to by name: for example, #\tab, #\esc, #\stx, and so on. The following table describes the ASCII names for each character.

0 = #\nul
1 = #\soh
2 = #\stx
3 = #\etx
4 = #\eot
5 = #\enq
6 = #\ack
7 = #\bel
8 = #\bs
9 = #\ht
10 = #\nl
11 = #\vt
12 = #\np
13 = #\cr
14 = #\so
15 = #\si
16 = #\dle
17 = #\dc1
18 = #\dc2
19 = #\dc3
20 = #\dc4
21 = #\nak
22 = #\syn
23 = #\etb
24 = #\can
25 = #\em
26 = #\sub
27 = #\esc
28 = #\fs
29 = #\gs
30 = #\rs
31 = #\us
32 = #\sp

The delete character (octal 177) may be referred to with the name #\del.

Several characters have more than one name:

  * #\space, #\sp

  * #\newline, #\nl

  * #\tab, #\ht

  * #\backspace, #\bs

  * #\return, #\cr

  * #\page, #\np

  * #\null, #\nul

 -- primitive: char? x
     Return #t iff X is a character, else #f.

 -- primitive: char=? x y
     Return #t iff X is the same character as Y, else #f.

 -- primitive: char<? x y
     Return #t iff X is less than Y in the ASCII sequence, else #f.

 -- primitive: char<=? x y
     Return #t iff X is less than or equal to Y in the ASCII sequence, else #f.

 -- primitive: char>? x y
     Return #t iff X is greater than Y in the ASCII sequence, else #f.

 -- primitive: char>=? x y
     Return #t iff X is greater than or equal to Y in the ASCII sequence, else #f.

 -- primitive: char-ci=? x y
     Return #t iff X is the same character as Y ignoring case, else #f.

 -- primitive: char-ci<? x y
     Return #t iff X is less than Y in the ASCII sequence ignoring case, else #f.

 -- primitive: char-ci<=? x y
     Return #t iff X is less than or equal to Y in the ASCII sequence ignoring case, else #f.

 -- primitive: char-ci>? x y
     Return #t iff X is greater than Y in the ASCII sequence ignoring case, else #f.

 -- primitive: char-ci>=? x y
     Return #t iff X is greater than or equal to Y in the ASCII sequence ignoring case, else #f.

 -- primitive: char-alphabetic? chr
     Return #t iff CHR is alphabetic, else #f. Alphabetic means the same thing as the isalpha C library function.

 -- primitive: char-numeric? chr
     Return #t iff CHR is numeric, else #f. Numeric means the same thing as the isdigit C library function.

 -- primitive: char-whitespace? chr
     Return #t iff CHR is whitespace, else #f. Whitespace means the same thing as the isspace C library function.

 -- primitive: char-upper-case? chr
     Return #t iff CHR is uppercase, else #f. Uppercase means the same thing as the isupper C library function.

 -- primitive: char-lower-case? chr
     Return #t iff CHR is lowercase, else #f. Lowercase means the same thing as the islower C library function.

 -- primitive: char-is-both? chr
     Return #t iff CHR is either uppercase or lowercase, else #f. Uppercase and lowercase are as defined by the isupper and islower C library functions.

 -- primitive: char->integer chr
     Return the number corresponding to ordinal position of CHR in the ASCII sequence.

 -- primitive: integer->char n
     Return the character at position N in the ASCII sequence.

 -- primitive: char-upcase chr
     Return the uppercase character version of CHR.

 -- primitive: char-downcase chr
     Return the lowercase character version of CHR.

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 '\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.

String Read Syntax
------------------

The read syntax for strings is an arbitrarily long sequence of characters enclosed in double quotes (").  (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 \ character (called an escape character).

The following are examples of string literals:

     "foo"
     "bar plonk"
     "Hello World"
     "\"Hi\", he said."

String Predicates
-----------------

The following procedures can be used to check whether a given string fulfills some specified property.

 -- primitive: string? obj
     Return #t iff OBJ is a string, else returns #f.

 -- primitive: string-null? str
     Return #t if STR's length is nonzero, and #f otherwise.

          (string-null? "")  => #t
          y                    => "foo"
          (string-null? y)     => #f

String Constructors
-------------------

The string constructor procedures create new string objects, possibly initializing them with some specified character data.

 -- primitive: string . chrs
 -- primitive: list->string chrs
     Return a newly allocated string composed of the arguments, CHRS.

 -- primitive: make-string k [chr]
     Return a newly allocated string of length K.  If CHR is given, then all elements of the string are initialized to CHR, otherwise the contents of the STRING are unspecified.

List/String conversion
----------------------

When processing strings, it is often convenient to first convert them into a list representation by using the procedure string->list, work with the resulting list, and then convert it back into a string. These procedures are useful for similar tasks.

 -- primitive: string->list str
     Return a newly allocated list of the characters that make up the given string STR. string->list and list->string are inverses as far as equal? is concerned.

String Selection
----------------

Portions of strings can be extracted by these procedures. string-ref delivers individual characters whereas substring can be used to extract substrings from longer strings.

 -- primitive: string-length string
     Return the number of characters in STRING.

 -- primitive: string-ref str k
     Return character K of STR using zero-origin indexing. K must be a valid index of STR.

 -- primitive: string-copy str
     Return a newly allocated copy of the given STRING.

 -- primitive: substring str start [end]
     Return a newly allocated string formed from the characters of STR beginning with index START (inclusive) and ending with index END (exclusive). STR must be a string, START and END must be exact integers satisfying:

     0 <= START <= END <= (string-length STR).

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.

 -- primitive: string-set! str k chr
     Store CHR in element K of STR and return an unspecified value. K must be a valid index of STR.

 -- primitive: string-fill! str chr
     Store CHAR in every element of the given STRING and return an unspecified value.

 -- primitive: substring-fill! str start end fill
     Change every character in STR between START and END to FILL.

          (define y "abcdefg")
          (substring-fill! y 1 3 #\r)
          y
          => "arrdefg"

 -- primitive: substring-move! str1 start1 end1 str2 start2
 -- primitive: substring-move-left! str1 start1 end1 str2 start2
 -- primitive: substring-move-right! str1 start1 end1 str2 start2
     Copy the substring of STR1 bounded by START1 and END1 into STR2 beginning at position END2. substring-move-right! begins copying from the rightmost character and moves left, and 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 STR1 and STR2 are the same string, you should use substring-move-right! when moving text from left to right, and substring-move-left!  otherwise.  If str1 and str2 are different strings, it does not matter which function you use.

 -- primitive: substring-move-left! str1 start1 end1 str2 start2

 -- C Function: SCM scm_substring_move_left_x (SCM STR1, SCM START1, SCM END1, SCM STR2, SCM START2)
     [Note: this is only valid if you've applied the strop patch].

     Moves a substring of STR1, from START1 to END1 (END1 is exclusive), into STR2, starting at START2. Allows overlapping strings.

          (define x (make-string 10 #\a))
          (define y "bcd")
          (substring-move-left! x 2 5 y 0)
          y
          => "aaa"

          x
          => "aaaaaaaaaa"

          (define y "bcdefg")
          (substring-move-left! x 2 5 y 0)
          y
          => "aaaefg"

          (define y "abcdefg")
          (substring-move-left! y 2 5 y 3)
          y
          => "abccccg"

 -- substring-move-right!: str1 start1 end1 str2 start2

 -- C Function: SCM scm_substring_move_right_x (SCM STR1, SCM START1, SCM END1, SCM STR2, SCM START2)
     [Note: this is only valid if you've applied the strop patch, if it hasn't made it into the guile tree].

     Does much the same thing as substring-move-left!, except it starts moving at the end of the sequence, rather than the beginning.

          (define y "abcdefg")
          (substring-move-right! y 2 5 y 0)
          y
          => "ededefg"

          (define y "abcdefg")
          (substring-move-right! y 2 5 y 3)
          y
          => "abccdeg"

String Comparison
-----------------

The procedures in this section are similar to the character ordering predicates (REFFIXME), but are defined on character sequences.  They all return #t on success and #f on failure.  The predicates ending in -ci ignore the character case when comparing strings.

 -- primitive: string=? s1 s2
     Lexicographic equality predicate; return #t if the two strings are the same length and contain the same characters in the same positions, otherwise return #f. The procedure string-ci=? treats upper and lower case letters as though they were the same character, but string=? treats upper and lower case as distinct characters.

 -- primitive: string<? s1 s2
     Lexicographic ordering predicate; return #t if S1 is lexicographically less than S2.

 -- primitive: string<=? s1 s2
     Lexicographic ordering predicate; return #t if S1 is lexicographically less than or equal to S2.

 -- primitive: string>? s1 s2
     Lexicographic ordering predicate; return #t if S1 is lexicographically greater than S2.

 -- primitive: string>=? s1 s2
     Lexicographic ordering predicate; return #t if S1 is lexicographically greater than or equal to S2.

 -- primitive: string-ci=? s1 s2
     Case-insensitive string equality predicate; return #t if the two strings are the same length and their component characters match (ignoring case) at each position; otherwise return #f.

 -- primitive: string-ci<? s1 s2
     Case insensitive lexicographic ordering predicate; return #t if S1 is lexicographically less than S2 regardless of case.

 -- primitive: string-ci<=? s1 s2
     Case insensitive lexicographic ordering predicate; return #t if S1 is lexicographically less than or equal to S2 regardless of case.

 -- primitive: string-ci>? s1 s2
     Case insensitive lexicographic ordering predicate; return #t if S1 is lexicographically greater than S2 regardless of case.

 -- primitive: string-ci>=? s1 s2
     Case insensitive lexicographic ordering predicate; return #t if S1 is lexicographically greater than or equal to S2 regardless of case.

String Searching
----------------

When searching the index of a character in a string, these procedures can be used.

 -- primitive: string-index str chr [frm [to]]
     Return the index of the first occurrence of CHR in STR.  The optional integer arguments FRM and TO limit the search to a portion of the string.  This procedure essentially implements the index or strchr functions from the C library.

          (string-index "weiner" #\e)
          => 1

          (string-index "weiner" #\e 2)
          => 4

          (string-index "weiner" #\e 2 4)
          => #f

 -- primitive: string-rindex str chr [frm [to]]
     Like string-index, but search from the right of the string rather than from the left.  This procedure essentially implements the rindex or strrchr functions from the C library.

          (string-rindex "weiner" #\e)
          => 4

          (string-rindex "weiner" #\e 2 4)
          => #f

          (string-rindex "weiner" #\e 2 5)
          => 4

Alphabetic Case Mapping
-----------------------

These are procedures for mapping strings to their upper-- or lower--case equivalents, respectively, or for capitalizing strings.

 -- primitive: string-upcase str
     Return a freshly allocated string containing the characters of STR in upper case.

 -- primitive: string-upcase! str
     Destructively upcase every character in STR and return STR.

          y                  => "arrdefg"
          (string-upcase! y) => "ARRDEFG"
          y                  => "ARRDEFG"

 -- primitive: string-downcase str
     Return a freshly allocation string containing the characters in STR in lower case.

 -- primitive: string-downcase! str
     Destructively downcase every character in STR and return STR.

          y                     => "ARRDEFG"
          (string-downcase! y)  => "arrdefg"
          y                     => "arrdefg"

 -- primitive: string-capitalize str
     Return a freshly allocated string with the characters in STR, where the first character of every word is capitalized.

 -- primitive: string-capitalize! str
     Upcase the first character of every word in STR destructively and return STR.

          y                      => "hello world"
          (string-capitalize! y) => "Hello World"
          y                      => "Hello World"

Appending Strings
-----------------

The procedure string-append appends several strings together to form a longer result string.

 -- primitive: string-append . args
     Return a newly allocated string whose characters form the concatenation of the given strings, ARGS.

String Miscellanea
------------------

This section contains several remaining string procedures.

 -- primitive: string-ci->symbol str
     Return the symbol whose name is STR.  STR is converted to lowercase before the conversion is done, if Guile is currently reading symbols case--insensitively.

Shared Substrings
-----------------

[FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed]

Whenever you extract a substring using substring, the Scheme interpreter allocates a new string and copies data from the old string. This is expensive, but substring is so convenient for manipulating text that programmers use it often.

Guile Scheme provides the concept of the shared substring to improve performance of many substring-related operations.  A shared substring is an object that mostly behaves just like an ordinary substring, except that it actually shares storage space with its parent string.

 -- primitive: make-shared-substring str [start [end]]
     Return a shared substring of STR.  The semantics are the same as for the substring function: the shared substring returned includes all of the text from STR between indexes START (inclusive) and END (exclusive).  If END is omitted, it defaults to the end of STR.  The shared substring returned by make-shared-substring occupies the same storage space as STR.

Example:

     (define foo "the quick brown fox")
     (define bar (make-shared-substring some-string 4 9))

     foo => "t h e   q u i c k   b r o w n   f o x"
     bar =========> |---------|

The shared substring BAR is not given its own storage space. Instead, the Guile interpreter notes internally that BAR points to a portion of the memory allocated to FOO.  However, BAR behaves like an ordinary string in most respects: it may be used with string primitives like string-length, string-ref, string=?.  Guile makes the necessary translation between indices of BAR and indices of FOO automatically.

     (string-length? bar) => 5	; bar only extends from indices 4 to 9
     (string-ref bar 3)  => #\c	; same as (string-ref foo 7)
     (make-shared-substring bar 2)
       => "ick"			; can even make a shared substring!

Because creating a shared substring does not require allocating new storage from the heap, it is a very fast operation.  However, because it shares memory with its parent string, a change to the contents of the parent string will implicitly change the contents of its shared substrings.

     (string-set! foo 7 #\r)
     bar => "quirk"

Guile considers shared substrings to be immutable.  This is because programmers might not always be aware that a given string is really a shared substring, and might innocently try to mutate it without realizing that the change would affect its parent string.  (We are currently considering a "copy-on-write" strategy that would permit modifying shared substrings without affecting the parent string.)

In general, shared substrings are useful in circumstances where it is important to divide a string into smaller portions, but you do not expect to change the contents of any of the strings involved.

Read Only Strings
-----------------

Type-checking in Guile primitives distinguishes between mutable strings and read only strings.  Mutable strings answer #t to string?  while read only strings may or may not.   All kinds of strings, whether or not they are mutable return #t to this:

 -- primitive: read-only-string? obj
     Return true if OBJ can be read as a string,

     This illustrates the difference between string? and read-only-string?:

          (string? "a string") => #t
          (string? 'a-symbol) => #f

          (read-only-string? "a string") => #t
          (read-only-string? 'a-symbol) => #t

"Read-only" refers to how the string will be used, not how the string is permitted to be used.  In particular, all strings are "read-only strings" even if they are mutable, because a function that only reads from a string can certainly operate on even a mutable string.

Symbols are an example of read-only strings.  Many string functions, such as string-append are happy to operate on symbols.  Many functions that expect a string argument, such as open-file, will accept a symbol as well.

Shared substrings, discussed in the previous chapter, also happen to be read-only strings.

Regular Expressions
===================

A regular expression (or 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 (see Syntax of Regular Expressions (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 *features* list includes the regex symbol.

[FIXME: it may be useful to include an Examples section.  Parts of this interface are bewildering on first glance.]

Regexp Functions
----------------

By default, Guile supports POSIX extended regular expressions. That means that the characters (, ), + and ? 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.

 -- procedure: string-match pattern str [start]
     Compile the string PATTERN into a regular expression and compare it with STR.  The optional numeric argument START specifies the position of STR at which to begin matching.

     string-match returns a match structure which describes what, if anything, was matched by the regular expression.  See Match Structures.  If STR does not match PATTERN at all, string-match returns #f.

Each time string-match is called, it must compile its PATTERN argument into a regular expression structure.  This operation is expensive, which makes 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.

 -- primitive: make-regexp pat . flags
     Compile the regular expression described by PAT, and return the compiled regexp structure.  If PAT does not describe a legal regular expression, make-regexp throws a regular-expression-syntax error. The FLAGS arguments change the behavior of the compiled regular expression.  The following flags may be supplied:

     regexp/icase
          Consider uppercase and lowercase letters to be the same when matching.

     regexp/newline
          If a newline appears in the target string, then permit the ^ and $ operators to match immediately after or immediately before the newline, respectively.  Also, the . and [^...] 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.

     regexp/basic
          Compile a basic (``obsolete'') regexp instead of the extended (``modern'') regexps that are the default.  Basic regexps do not consider |, + or ? to be special characters, and require the {...} and (...) metacharacters to be backslash-escaped (see Backslash Escapes).  There are several other differences between basic and extended regular expressions, but these are the most significant.

     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 make-regexp includes both regexp/basic and regexp/extended flags, the one which comes last will override the earlier one.

 -- primitive: regexp-exec rx str [start [flags]]
     Match the compiled regular expression RX against str.  If the optional integer START argument is provided, begin matching from that position in the string. Return a match structure describing the results of the match, or #f if no match could be found.

 -- primitive: regexp? obj
     Return #t if OBJ is a compiled regular expression, or #f otherwise.

Regular expressions are commonly used to find patterns in one string and replace them with the contents of another string.

 -- procedure: regexp-substitute port match [item...]
     Write to the output port PORT selected contents of the match structure MATCH.  Each ITEM specifies what should be written, and may be one of the following arguments:

       * A string.  String arguments are written out verbatim.

       * An integer.  The submatch with that number is written.

       * The symbol pre.  The portion of the matched string preceding the regexp match is written.

       * The symbol post.  The portion of the matched string following the regexp match is written.

     PORT may be #f, in which case nothing is written; instead, regexp-substitute constructs a string from the specified ITEMs and returns that.

 -- procedure: regexp-substitute/global port regexp target [item...]
     Similar to regexp-substitute, but can be used to perform global substitutions on STR.  Instead of taking a match structure as an argument, regexp-substitute/global takes two string arguments: a REGEXP string describing a regular expression, and a TARGET string which should be matched against this regular expression.

     Each ITEM behaves as in REGEXP-SUBSTITUTE, with the following exceptions:

       * 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 PORT.

       * The post symbol causes regexp-substitute/global to recurse on the unmatched portion of STR.  This must be supplied in order to perform global search-and-replace on STR; if it is not present among the ITEMs, then regexp-substitute/global will return after processing a single match.

Match Structures
----------------

A match structure is the object returned by string-match and 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 match argument must be a match structure returned by a previous call to string-match or 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 TARGET for easy reference.

 -- procedure: regexp-match? obj
     Return #t if OBJ is a match structure returned by a previous call to regexp-exec, or #f otherwise.

 -- procedure: match:substring match [n]
     Return the portion of TARGET matched by subexpression number N.  Submatch 0 (the default) represents the entire regexp match. If the regular expression as a whole matched, but the subexpression number N did not match, return #f.

 -- procedure: match:start match [n]
     Return the starting position of submatch number N.

 -- procedure: match:end match [n]
     Return the ending position of submatch number N.

 -- procedure: match:prefix match
     Return the unmatched portion of TARGET preceding the regexp match.

 -- procedure: match:suffix match
     Return the unmatched portion of TARGET following the regexp match.

 -- procedure: match:count match
     Return the number of parenthesized subexpressions from MATCH. Note that the entire regular expression match itself counts as a subexpression, and failed submatches are included in the count.

 -- procedure: match:string match
     Return the original TARGET string.

Backslash Escapes
-----------------

Sometimes you will want a regexp to match characters like * or $ 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 ^* [^:]*::.  However, this won't work; because the asterisk is a metacharacter, it won't match the * 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 \.  (This is also called quoting the metacharacter, and is known as a 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 ^\* [^:]*::.  The \* 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 \let\ followed by any number of alphabetic characters.  The regular expression \\let\\[A-Za-z]* would do this: the double backslashes in the regexp each match a single backslash in the target string.

 -- procedure: regexp-quote str
     Quote each special character found in STR with a backslash, and return the resulting string.

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 \n in the middle of a string while processing Scheme code, it replaces those characters with a newline character.  Similarly, the character sequence \t is replaced by a horizontal tab.  Several of these escape sequences are processed by the Guile reader before your code is executed. Unrecognized escape sequences are ignored: if the characters \* appear in a string, they will be translated to the single character *.

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 two consecutive backslashes:

     (define Info-menu-entry-pattern (make-regexp "^\\* [^:]*"))

The string in this example is preprocessed by the Guile reader before any code is executed.  The resulting argument to make-regexp is the string ^\* [^:]*, 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 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:

     (define tex-variable-pattern (make-regexp "\\\\let\\\\=[A-Za-z]*"))

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.

Rx Interface
------------

[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!]

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 abc. (which matches any string containing abc followed by any single character):

     guile> (define r (regcomp "abc."))
     guile> r
     #<rgx abc.>
     guile> (regexec r "abc")
     #f
     guile> (regexec r "abcd")
     #((0 . 4))
     guile>

The definitions of regcomp and regexec are as follows:

 -- primitive: regcomp pattern [flags]
     Compile the regular expression pattern using POSIX rules.  Flags is optional and should be specified using symbolic names:
      -- Variable: REG_EXTENDED
          use extended POSIX syntax

      -- Variable: REG_ICASE
          use case-insensitive matching

      -- Variable: REG_NEWLINE
          allow anchors to match after newline characters in the string and prevents . or [^...] from matching newlines.

     The logior procedure can be used to combine multiple flags. The default is to use POSIX basic syntax, which makes + and ?  literals and \+ and \? operators.  Backslashes in PATTERN must be escaped if specified in a literal string e.g., "\\(a\\)\\?".

 -- primitive: regexec regex string [match-pick] [flags]

     Match STRING against the compiled POSIX regular expression REGEX. MATCH-PICK and FLAGS are optional.  Possible flags (which can be combined using the logior procedure) are:

      -- Variable: REG_NOTBOL
          The beginning of line operator won't match the beginning of STRING (presumably because it's not the beginning of a line)

      -- Variable: REG_NOTEOL
          Similar to REG_NOTBOL, but prevents the end of line operator from matching the end of STRING.

     If no match is possible, regexec returns #f.  Otherwise MATCH-PICK determines the return value:

     #t or unspecified: a newly-allocated vector is returned, containing pairs with the indices of the matched part of STRING and any substrings.

     "": a list is returned: the first element contains a nested list with the matched part of STRING surrounded by the the unmatched parts. Remaining elements are matched substrings (if any).  All returned substrings share memory with STRING.

     #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 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).

     #\<: the beginning of STRING to the beginning of the part matched by regex.

     #\>: the end of the matched part of STRING to the end of STRING.

     #\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., (list #\< 0 1 #\>).  The returned substrings share memory with STRING.

Here are some other procedures that might be used when using regular expressions:

 -- primitive: compiled-regexp? obj
     Test whether obj is a compiled regular expression.

 -- primitive: regexp->dfa regex [flags]

 -- primitive: dfa-fork dfa

 -- primitive: reset-dfa! dfa

 -- primitive: dfa-final-tag dfa

 -- primitive: dfa-continuable? dfa

 -- primitive: advance-dfa! dfa string

Symbols and Variables
=====================

Guile symbol tables are hash tables.  Each hash table, also called an obarray (for `object array'), is a vector of association lists. Each entry in the alists is a pair (SYMBOL . VALUE).  To intern a symbol in a symbol table means to return its (SYMBOL . VALUE) pair, adding a new entry to the symbol table (with an undefined value) if none is yet present.

 -- primitive: gensym [prefix]
     Create a new symbol with a name constructed from a prefix and a counter value. The string PREFIX can be specified as an optional argument. Default prefix is g.  The counter is increased by 1 at each call. There is no provision for resetting the counter.

 -- primitive: gentemp [prefix [obarray]]
     Create a new symbol with a name unique in an obarray. The name is constructed from an optional string PREFIX and a counter value.  The default prefix is t.  The 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.

 -- primitive: intern-symbol obarray string
     Add a new symbol to OBARRAY with name STRING, bound to an unspecified initial value.  The symbol table is not modified if a symbol with this name is already present.

 -- primitive: string->obarray-symbol obarray string [soft?]
     Intern a new symbol in OBARRAY, a symbol table, with name STRING.

     If OBARRAY is #f, use the default system symbol table.  If OBARRAY is #t, the symbol should not be interned in any symbol table; merely return the pair (SYMBOL . #<UNDEFINED>).

     The SOFT? argument determines whether new symbol table entries should be created when the specified symbol is not already present in OBARRAY.  If SOFT? is specified and is a true value, then new entries should not be added for symbols not already present in the table; instead, simply return #f.

 -- primitive: string->symbol string
     Return the symbol whose name is 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 symbol->string. The following examples assume that the implementation's standard case is lower case:

          (eq? 'mISSISSIppi 'mississippi) => #t
          (string->symbol "mISSISSIppi") => the symbol with name "mISSISSIppi"
          (eq? 'bitBlt (string->symbol "bitBlt")) => #f
          (eq? 'JollyWog
            (string->symbol (symbol->string 'JollyWog))) => #t
          (string=? "K. Harper, M.D."
            (symbol->string
              (string->symbol "K. Harper, M.D."))) =>#t

 -- primitive: symbol->string s
     Return the name of SYMBOL as a string.  If the symbol was part of an object returned as the value of a literal expression (section see Literal expressions (The Revised^4 Report on Scheme)) or by a call to the 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 string->symbol, the case of characters in the string returned will be the same as the case in the string that was passed to string->symbol.  It is an error to apply mutation procedures like string-set! to strings returned by this procedure. The following examples assume that the implementation's standard case is lower case:

          (symbol->string 'flying-fish)    => "flying-fish"
          (symbol->string 'Martin)         =>  "martin"
          (symbol->string
             (string->symbol "Malvina")) => "Malvina"

 -- primitive: symbol-binding obarray string
     Look up in OBARRAY the symbol whose name is STRING, and return the value to which it is bound.  If OBARRAY is #f, use the global symbol table.  If STRING is not interned in OBARRAY, an error is signalled.

 -- primitive: symbol-bound? obarray string
     Return #t if OBARRAY contains a symbol with name STRING bound to a defined value.  This differs from SYMBOL-INTERNED? in that the mere mention of a symbol usually causes it to be interned; symbol-bound? determines whether a symbol has been given any meaningful value.

 -- primitive: symbol-fref symbol
     Return the contents of SYMBOL's function slot.

 -- primitive: symbol-fset! symbol value
     Change the binding of SYMBOL's function slot.

 -- primitive: symbol-hash symbol
     Return a hash value for SYMBOL.

 -- primitive: symbol-interned? obarray string
     Return #t if OBARRAY contains a symbol with name STRING, and #f otherwise.

 -- primitive: symbol-pref symbol
     Return the property list currently associated with SYMBOL.

 -- primitive: symbol-pset! symbol value
     Change the binding of SYMBOL's property slot.

 -- primitive: symbol-set! obarray string value
     Find the symbol in OBARRAY whose name is STRING, and rebind it to VALUE.  An error is signalled if STRING is not present in OBARRAY.

 -- primitive: symbol? obj
     Return #t if OBJ is a symbol, otherwise return #f.

 -- primitive: unintern-symbol obarray string
     Remove the symbol with name STRING from OBARRAY.  This function returns #t if the symbol was present and #f otherwise.

 -- primitive: builtin-variable name
     Return the built-in variable with the name NAME. NAME must be a symbol (not a string). Then use variable-ref to access its value.

 -- primitive: make-undefined-variable [name-hint]
     Return a variable object initialized to an undefined value. If given, uses 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 NAME-HINT is just that---a hint.

 -- primitive: make-variable init [name-hint]
     Return a variable object initialized to value INIT. If given, uses 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 NAME-HINT is just that---a hint.

 -- primitive: variable-bound? var
     Return #t iff VAR is bound to a value. Throws an error if VAR is not a variable object.

 -- primitive: variable-ref var
     Dereference VAR and return its value. VAR must be a variable object; see make-variable and make-undefined-variable.

 -- primitive: variable-set! var val
     Set the value of the variable VAR to VAL. VAR must be a variable object, VAL can be any value. Return an unspecified value.

 -- primitive: variable? obj
     Return #t iff OBJ is a variable object, else return #f

Keywords
========

Keywords are self-evaluating objects with a convenient read syntax that makes them easy to type.

Guile's keyword support conforms to R4RS, and adds a (switchable) read syntax extension to permit keywords to begin with : as well as #:.

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 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:

  * colour depth -- Default: the colour depth for the screen

  * background colour -- Default: white

  * width -- Default: 600

  * height -- Default: 400

If 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:

     (make-window 'default              ;; Colour depth
                  'default              ;; Background colour
                  800                   ;; Width
                  100                   ;; Height
                  ...)                  ;; More make-window arguments

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:

     (make-window #:width 800 #:height 100)

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 cons, for example, would not be improved if it had to be invoked as

     (cons #:car x #:cdr y)

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.

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 make-window uses a helper procedure called get-keyword-value to extract individual keyword arguments from the rest argument.

     (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))
             ...)
         ...))

But you don't need to write get-keyword-value.  The (ice-9 optargs) module provides a set of powerful macros that you can use to implement keyword-supporting procedures like this:

     (use-modules (ice-9 optargs))

     (define (make-window . args)
       (let-keywords args #f ((depth  screen-depth)
                              (bg     "white")
                              (width  800)
                              (height 100))
         ...))

Or, even more economically, like this:

     (use-modules (ice-9 optargs))

     (define* (make-window #:key (depth  screen-depth)
                                 (bg     "white")
                                 (width  800)
                                 (height 100))
       ...)

For further details on let-keywords, define* and other facilities provided by the (ice-9 optargs) module, Optional Arguments.

Keyword Read Syntax
-------------------

Guile, by default, only recognizes the keyword syntax specified by R5RS. A token of the form #:NAME, where NAME has the same syntax as a Scheme symbol, is the external representation of the keyword named 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 keyword read option is set to 'prefix, Guile also recognizes the alternative read syntax :NAME.  Otherwise, tokens of the form :NAME are read as symbols, as required by R4RS.

To enable and disable the alternative non-R4RS keyword syntax, you use the read-options procedure documented in General option interface and Reader options.

     (read-set! keywords 'prefix)

     #:type
     =>
     #:type

     :type
     =>
     #:type

     (read-set! keywords #f)

     #:type
     =>
     #:type

     :type
     =>
     ERROR: In expression :type:
     ERROR: Unbound variable: :type
     ABORT: (unbound-variable)

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 dash symbol has the same name as the keyword name but prefixed by a single dash.  For example, the keyword #:name has the corresponding dash symbol -name.

Most keyword objects are constructed automatically by the reader when it reads a token beginning with #:.  However, if you need to construct a keyword object programmatically, you can do so by calling 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 keyword-dash-symbol procedure.

 -- primitive: make-keyword-from-dash-symbol symbol
     Make a keyword object from a SYMBOL that starts with a dash.

 -- primitive: keyword? obj
     Return #t if the argument OBJ is a keyword, else #f.

 -- primitive: keyword-dash-symbol keyword
     Return the dash symbol for KEYWORD. This is the inverse of make-keyword-from-dash-symbol.

Pairs
=====

Pairs are used to combine two Scheme objects into one compound object. Hence the name: A pair stores a pair of objects.

The data type 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 (see Lists).

Pairs can literally get entered in source code or at the REPL, in the so-called 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 foo and 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.

     (1 . 2)
     (foo . bar)

But beware, if you want to try out these examples, you have to quote the expressions.  More information about quotation is available in the section (REFFIXME).  The correct way to try these examples is as follows.

     '(1 . 2)
     =>
     (1 . 2)
     '(foo . bar)
     =>
     (foo . bar)

A new pair is made by calling the procedure cons with two arguments.  Then the argument values are stored into a newly allocated pair, and the pair is returned.  The name cons stands for construct.  Use the procedure pair? to test whether a given Scheme object is a pair or not.

 -- primitive: cons x y
     Return a newly allocated pair whose car is X and whose cdr is Y.  The pair is guaranteed to be different (in the sense of eq?) from every previously existing object.

 -- primitive: pair? x
     Return #t if X is a pair; otherwise return #f.

The two parts of a pair are traditionally called car and cdr.  They can be retrieved with procedures of the same name (car and cdr), and can be modified with the procedures set-car! and 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 caar, cadr and so on are also predefined.

 -- primitive: car pair
 -- primitive: cdr pair
     Return the car or the cdr of PAIR, respectively.

 -- primitive: caar pair
 -- primitive: cadr pair ...
 -- primitive: cdddar pair
 -- primitive: cddddr pair
     These procedures are compositions of car and cdr, where for example caddr could be defined by

          (define caddr (lambda (x) (car (cdr (cdr x)))))

 -- primitive: set-car! pair value
     Stores VALUE in the car field of PAIR.  The value returned by set-car! is unspecified.

 -- primitive: set-cdr! pair value
     Stores VALUE in the cdr field of PAIR.  The value returned by set-cdr! is unspecified.

Lists
=====

A very important datatype in Scheme---as well as in all other Lisp dialects---is the data type list. (Strictly speaking, Scheme does not have a real datatype list.  Lists are made up of chained pairs, and only exist by definition --- A list is a chain of pairs which looks like a list.)

This is the short definition of what a list is:

  * Either the empty list (),

  * or a pair which has a list in its cdr.

List Read Syntax
----------------

The syntax for lists is an opening parentheses, then all the elements of the list (separated by whitespace) and finally a closing parentheses. (Note that there is no separation character between the list elements, like a comma or a semicolon.).

     (1 2 3)            ; a list of the numbers 1, 2 and 3
     ("foo" bar 3.1415) ; a string, a symbol and a real number
     ()                 ; the empty list

The last example needs a bit more explanation.  A list with no elements, called the 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:

     (car '(1))
     =>
     1
     (cdr '(1))
     =>
     ()

This example also shows that lists have to be quoted (REFFIXME) when written, because they would otherwise be mistakingly taken as procedure applications (REFFIXME).

List Predicates
---------------

Often it is useful to test whether a given Scheme object is a list or not.  List--processing procedures could use this information to test whether their input is valid, or they could do different things depending on the datatype of their arguments.

 -- primitive: list? x
     Return #t iff X is a proper list, else #f.

The predicate 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 null?.  Then, teh algorithm terminates.

 -- primitive: null? x
     Return #t iff X is the empty list, else #f.

List Constructors
-----------------

This section describes the procedures for constructing new lists. list simply returns a list where the elements are the arguments, cons* is similar, but the last argument is stored in the cdr of the last pair of the list.

 -- primitive: list arg1 ...
     Return a list containing OBJS, the arguments to list.

 -- primitive: cons* arg1 arg2 ...
     Like list, but the last arg provides the tail of the constructed list, returning (cons ARG1 (cons ARG2 (cons ... ARGN))).  Requires at least one argument.  If given one argument, that argument is returned as result.  This function is called list* in some other Schemes and in Common LISP.

 -- primitive: list-copy lst
     Return a (newly-created) copy of LST.

Note that 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 set-cdr! or 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 copy-tree (REFFIXME).

List Selection
--------------

These procedures are used to get some information about a list, or to retrieve one or more elements of a list.

 -- primitive: length lst
     Return the number of elements in list LST.

 -- primitive: last-pair lst
     Return a pointer to the last pair in LST, signalling an error if LST is circular.

 -- primitive: list-ref list k
     Return the Kth element from LIST.

 -- primitive: list-tail lst k
 -- primitive: list-cdr-ref lst k
     Return the "tail" of LST beginning with its Kth element. The first element of the list is considered to be element 0.

     list-tail and list-cdr-ref are identical.  It may help to think of list-cdr-ref as accessing the Kth cdr of the list, or returning the results of cdring K times down LST.

 -- primitive: list-head lst k
     Copy the first K elements from LST into a new list, and return it.

Append and Reverse
------------------

append and append! are used to concatenate two or more lists in order to form a new list.  reverse and reverse! return lists with the same elements as their arguments, but in reverse order.  The procedure variants with an ! 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.

 -- primitive: append . args
     Return a list consisting of the elements the lists passed as arguments.

          (append '(x) '(y))          =>  (x y)
          (append '(a) '(b c d))      =>  (a b c d)
          (append '(a (b)) '((c)))    =>  (a (b) (c))

     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.

          (append '(a b) '(c . d))    =>  (a b c . d)
          (append '() 'a)             =>  a

 -- primitive: append! . lists
     A destructive version of append (see Pairs and Lists (The Revised^4 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.

 -- primitive: reverse lst
     Return a new list that contains the elements of LST but in reverse order.

 -- primitive: reverse! lst [new_tail]
     A destructive version of reverse (see Pairs and Lists (The Revised^4 Report on Scheme)).  The cdr of each cell in 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 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 reverse!

List Modification
-----------------

The following procedures modify existing list.  list-set!  and list-cdr-set! change which elements a list contains, the various deletion procedures delq, delv etc.

 -- primitive: list-set! list k val
     Set the Kth element of LIST to VAL.

 -- primitive: list-cdr-set! list k val
     Set the Kth cdr of LIST to VAL.

 -- primitive: delq item lst
     Return a newly-created copy of LST with elements eq? to ITEM removed.  This procedure mirrors memq: delq compares elements of LST against ITEM with eq?.

 -- primitive: delv item lst
     Return a newly-created copy of LST with elements eqv?  to ITEM removed.  This procedure mirrors memv: delv compares elements of LST against ITEM with eqv?.

 -- primitive: delete item lst
     Return a newly-created copy of LST with elements equal?  to ITEM removed.  This procedure mirrors member: delete compares elements of LST against ITEM with equal?.

 -- primitive: delq! item lst
 -- primitive: delv! item lst
 -- primitive: delete! item lst
     These procedures are destructive versions of delq, delv and delete: they modify the pointers in the existing LST rather than creating a new list.  Caveat evaluator: Like other destructive list functions, these functions cannot modify the binding of LST, and so cannot be used to delete the first element of LST destructively.

 -- primitive: delq1! item lst
     Like delq!, but only deletes the first occurrence of ITEM from LST.  Tests for equality using eq?.  See also delv1! and delete1!.

 -- primitive: delv1! item lst
     Like delv!, but only deletes the first occurrence of ITEM from LST.  Tests for equality using eqv?.  See also delq1! and delete1!.

 -- primitive: delete1! item lst
     Like delete!, but only deletes the first occurrence of ITEM from LST.  Tests for equality using equal?.  See also delq1! and delv1!.

List Searching
--------------

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 #f, otherwise they return the sublist whose car is equal to the search object, where equality depends on the equality predicate used.

 -- primitive: memq x lst
     Return the first sublist of LST whose car is eq? to X where the sublists of LST are the non-empty lists returned by (list-tail LST K) for K less than the length of LST.  If X does not occur in LST, then #f (not the empty list) is returned.

 -- primitive: memv x lst
     Return the first sublist of LST whose car is eqv? to X where the sublists of LST are the non-empty lists returned by (list-tail LST K) for K less than the length of LST.  If X does not occur in LST, then #f (not the empty list) is returned.

 -- primitive: member x lst
     Return the first sublist of LST whose car is equal? to X where the sublists of LST are the non-empty lists returned by (list-tail LST K) for K less than the length of LST.  If X does not occur in LST, then #f (not the empty list) is returned.

[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]

 -- primitive: sloppy-memq x lst
     This procedure behaves like memq, but does no type or error checking. Its use is recommended only in writing Guile internals, not for high-level Scheme programs.

 -- primitive: sloppy-memv x lst
     This procedure behaves like memv, but does no type or error checking. Its use is recommended only in writing Guile internals, not for high-level Scheme programs.

 -- primitive: sloppy-member x lst
     This procedure behaves like member, but does no type or error checking. Its use is recommended only in writing Guile internals, not for high-level Scheme programs.

List Mapping
------------

List processing is very convenient in Scheme because the process of iterating over the elements of a list can be highly abstracted.  The procedures in this section are the most basic iterating procedures for lists.  They take a procedure and one or more lists as arguments, and apply the procedure to each element of the list.  They differ in what the result of the invocation is.

 -- primitive: map proc arg1 arg2 ...
 -- primitive: map-in-order proc arg1 arg2 ...
     Apply PROC to each element of the list 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 map, the order of procedure applications is not specified, map-in-order applies the procedure from left to right to the list elements.

 -- primitive: for-each proc arg1 arg2 ...
     Like 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.

Records
=======

[FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed]

A record type is a first class object representing a user-defined data type.  A record is an instance of a record type.

 -- procedure: record? obj
     Returns #t if OBJ is a record of any type and #f otherwise.

     Note that record? may be true of any Scheme value; there is no promise that records are disjoint with other Scheme types.

 -- procedure: make-record-type type-name field-names
     Returns a record-type descriptor, a value representing a new data type disjoint from all others.  The 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 FIELD-NAMES argument is a list of symbols naming the 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.

 -- procedure: record-constructor rtd [field-names]
     Returns a procedure for constructing new members of the type represented by RTD.  The returned procedure accepts exactly as many arguments as there are symbols in the given list, 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 FIELD-NAMES argument defaults to the list of field names in the call to make-record-type that created the type represented by RTD; if the FIELD-NAMES argument is provided, it is an error if it contains any duplicates or any symbols not in the default list.

 -- procedure: record-predicate rtd
     Returns a procedure for testing membership in the type represented by 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.

 -- 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 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 FIELD-NAME in that record.  The symbol FIELD-NAME must be a member of the list of field-names in the call to make-record-type that created the type represented by RTD.

 -- 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 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 FIELD-NAME in that record to contain the given value. The returned value of the modifier procedure is unspecified.  The symbol FIELD-NAME must be a member of the list of field-names in the call to make-record-type that created the type represented by RTD.

 -- 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 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 record-constructor in the call that created the constructor procedure that created the given record.

 -- procedure: record-type-name rtd
     Returns the type-name associated with the type represented by rtd.  The returned value is eqv? to the TYPE-NAME argument given in the call to make-record-type that created the type represented by RTD.

 -- procedure: record-type-fields rtd
     Returns a list of the symbols naming the fields in members of the type represented by RTD.  The returned value is equal? to the field-names argument given in the call to make-record-type that created the type represented by RTD.

Structures
==========

[FIXME: this is pasted in from Tom Lord's original guile.texi and should be reviewed]

A structure type is a first class user-defined data type.  A 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.

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.

  * 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.

  * structural accessors

     Structure access is by field number.   There is only one set of accessors common to all structure objects.

  * 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.

Structure Layout
----------------

When a structure is created, a region of memory is allocated to hold its state.  The 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:

  * 'u' -- unprotected

     The field holds binary data that is not GC protected.

  * 'p' -- protected

     The field holds a Scheme value and is GC protected.

  * '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.

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:

  * 'w' -- writable

     The field can be read and written.

  * 'r' -- readable

     The field can be read, but not written.

  * 'o' -- opaque

     The field can be neither read nor written.   This kind of protection is for fields useful only to built-in routines.

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:

     ; cons pairs have two writable fields of Scheme data
     "pwpw"

A pair object in which the first field is held constant could be:

     "prpw"

Binary fields, (fields of type "u"), hold one word each.  The size of a word is a machine dependent value defined to be equal to the value of the C expression: 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:

     ; A vector is an arbitrary number of writable fields holding Scheme
     ; values:
     "pW"

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:

     "prpW"

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:

 -- primitive: make-struct-layout fields
     Return a new structure layout object.

     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.

Structure Basics
----------------

This section describes the basic procedures for creating and accessing structures.

 -- primitive: make-struct vtable tail_array_size . init
     Create a new structure.

     TYPE must be a vtable structure (see Vtables).

     TAIL-ELTS must be a non-negative integer.  If the layout specification indicated by TYPE includes a tail-array, this is the number of elements allocated to that array.

     The INIT1, ... 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 make-vtable-vtable.

 -- primitive: struct? x
     Return #t iff OBJ is a structure object, else #f.

 -- primitive: struct-ref handle pos
 -- primitive: struct-set! struct n value
     Access (or modify) the Nth field of 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.

Vtables
-------

Vtables are structures that are used to represent structure types.  Each vtable contains a layout specification in field 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 vtable-offset-user is bound to a field number.  Vtable fields at that position or greater are user definable.

 -- primitive: struct-vtable handle
     Return the vtable structure that describes the type of STRUCT.

 -- primitive: struct-vtable? x
     Return #t iff obj is a vtable structure.

If you have a vtable structure, V, you can create an instance of the type it describes by using (make-struct V ...).  But where does V itself come from?  One possibility is that V is an instance of a user-defined vtable type, V', so that V is created by using (make-struct V' ...).  Another possibility is that V is an instance of the type it itself describes.  Vtable structures of the second sort are created by this procedure:

 -- primitive: make-vtable-vtable user_fields tail_array_size . init
     Return a new, self-describing vtable structure.

     USER-FIELDS is a string describing user defined fields of the vtable beginning at index vtable-offset-user (see make-struct-layout).

     TAIL-SIZE specifies the size of the tail-array (if any) of this vtable.

     INIT1, ... 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 make-vtable-vtable and make-struct, and thus works as a third optional argument to make-vtable-vtable and a fourth to make-struct when creating vtables:

     If the value is a procedure, it will be called instead of the standard printer whenever a struct described by this vtable is printed. The procedure will be called with arguments STRUCT and PORT.

     The structure of a struct is described by a vtable, so the vtable is in essence the type of the struct.  The vtable is itself a struct with a vtable.  This could go on forever if it weren't for the vtable-vtables which are self-describing vtables, and thus terminate the chain.

     There are several potential ways of using structs, but the standard one is to use three kinds of structs, together building up a type sub-system: one vtable-vtable working as the root and one or several "types", each with a set of "instances".  (The vtable-vtable should be compared to the class <class> which is the class of itself.)

          (define ball-root (make-vtable-vtable "pr" 0))

          (define (make-ball-type ball-color)
            (make-struct ball-root 0
          	       (make-struct-layout "pw")
                         (lambda (ball port)
                           (format port "#<a ~A ball owned by ~A>"
                                   (color ball)
                                   (owner ball)))
                         ball-color))
          (define (color ball) (struct-ref (struct-vtable ball) vtable-offset-user))
          (define (owner ball) (struct-ref ball 0))

          (define red (make-ball-type 'red))
          (define green (make-ball-type 'green))

          (define (make-ball type owner) (make-struct type 0 owner))

          (define ball (make-ball green 'Nisse))
          ball => #<a green ball owned by Nisse>

 -- primitive: struct-vtable-name vtable
     Return the name of the vtable VTABLE.

 -- primitive: set-struct-vtable-name! vtable name
     Set the name of the vtable VTABLE to NAME.

 -- primitive: struct-vtable-tag handle
     Return the vtable tag of the structure HANDLE.

Arrays
======

Conventional Arrays
-------------------

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 # followed by the 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:

     (make-array 'ho 2 3) =>
     #2((ho ho ho) (ho ho ho))

The range of each dimension can also be given explicitly, e.g., another way to create the same array:

     (make-array 'ho '(0 1) '(0 2)) =>
     #2((ho ho ho) (ho ho ho))

A conventional array with one dimension based at zero is identical to a vector:

     (make-array 'ho 3) =>
     #(ho ho ho)

The following procedures can be used with conventional arrays (or vectors).

 -- primitive: array? v [prot]
     Return #t if the OBJ is an array, and #f if not.  The PROTOTYPE argument is used with uniform arrays and is described elsewhere.

 -- procedure: make-array initial-value bound1 bound2 ...
     Creates and returns an array that has as many dimensions as there are BOUNDs and fills it with INITIAL-VALUE.

 -- primitive: uniform-vector-ref v args
 -- primitive: array-ref v . args
     Return the element at the (index1, index2) element in ARRAY.

 -- primitive: array-in-bounds? v . args
     Return #t if its arguments would be acceptable to array-ref.

 -- primitive: array-set! v obj . args
 -- primitive: uniform-array-set1! v obj args
     Sets the element at the (index1, index2) element in ARRAY to NEW-VALUE.  The value returned by array-set! is unspecified.

 -- primitive: make-shared-array oldra mapfunc . dims
     make-shared-array can be used to create shared subarrays of other arrays.  The MAPPER is a function that translates coordinates in the new array into coordinates in the old array.  A 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:

          (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) => foo
          (define freds-center
            (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) 2 2))
          (array-ref freds-center 0 0) => foo

 -- primitive: shared-array-increments ra
     For each dimension, return the distance between elements in the root vector.

 -- primitive: shared-array-offset ra
     Return the root vector index of the first element in the array.

 -- primitive: shared-array-root ra
     Return the root vector of a shared array.

 -- primitive: transpose-array ra . args
     Return an array sharing contents with ARRAY, but with dimensions arranged in a different order.  There must be one DIM argument for each dimension of ARRAY. DIM0, DIM1, ... 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 DIM0, DIM1, ... correspond to dimensions in the array to be returned, their positions in the argument list to dimensions of ARRAY.  Several DIMs may have the same value, in which case the returned array will have smaller rank than ARRAY.

          (transpose-array '#2((a b) (c d)) 1 0) => #2((a c) (b d))
          (transpose-array '#2((a b) (c d)) 0 0) => #1(a d)
          (transpose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 1 0) =>
                          #2((a 4) (b 5) (c 6))

 -- primitive: enclose-array ra . axes
     DIM0, DIM1 ... should be nonnegative integers less than the rank of ARRAY.  ENCLOSE-ARRAY returns an array resembling an array of shared arrays.  The dimensions of each shared array are the same as the DIMth 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 DIM.

     An enclosed array is not a general Scheme array.  Its elements may not be set using array-set!.  Two references to the same element of an enclosed array will be equal? but will not in general be eq?.  The value returned by ARRAY-PROTOTYPE when given an enclosed array is unspecified.

     examples:

          (enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1) =>
             #<enclosed-array (#1(a d) #1(b e) #1(c f)) (#1(1 4) #1(2 5) #1(3 6))>

          (enclose-array '#3(((a b c) (d e f)) ((1 2 3) (4 5 6))) 1 0) =>
             #<enclosed-array #2((a 1) (d 4)) #2((b 2) (e 5)) #2((c 3) (f 6))>

 -- procedure: array-shape array
     Returns a list of inclusive bounds of integers.

          (array-shape (make-array 'foo '(-1 3) 5)) => ((-1 3) (0 4))

 -- primitive: array-dimensions ra
     Array-dimensions is similar to array-shape but replaces elements with a 0 minimum with one greater than the maximum. So:

          (array-dimensions (make-array 'foo '(-1 3) 5)) => ((-1 3) 5)

 -- primitive: array-rank ra
     Return the number of dimensions of OBJ.  If OBJ is not an array, 0 is returned.

 -- primitive: array->list v
     Return a list consisting of all the elements, in order, of ARRAY.

 -- primitive: array-copy! src dst
 -- primitive: array-copy-in-order! src dst
     Copies every element from vector or array SOURCE to the corresponding element of DESTINATION.  DESTINATION must have the same rank as SOURCE, and be at least as large in each dimension.  The order is unspecified.

 -- primitive: array-fill! ra fill
     Stores FILL in every element of ARRAY.  The value returned is unspecified.

 -- primitive: array-equal? ra0 ra1
     Returns #t iff all arguments are arrays with the same shape, the same type, and have corresponding elements which are either equal?  or array-equal?.  This function differs from equal? in that a one dimensional shared array may be ARRAY-EQUAL? but not EQUAL? to a vector or uniform vector.

 -- primitive: array-contents ra [strict]
 -- primitive: array-contents array strict
     If ARRAY may be unrolled into a one dimensional shared array without changing their order (last subscript changing fastest), then array-contents returns that shared array, otherwise it returns #f.  All arrays made by MAKE-ARRAY and MAKE-UNIFORM-ARRAY may be unrolled, some arrays made by MAKE-SHARED-ARRAY may not be.

     If the optional argument STRICT is provided, a shared array will be returned only if its elements are stored internally contiguous in memory.

Array Mapping
-------------

 -- primitive: array-map! ra0 proc . lra
 -- primitive: array-map-in-order! ra0 proc . lra
     ARRAY1, ... must have the same number of dimensions as ARRAY0 and have a range for each index which includes the range for the corresponding index in ARRAY0.  PROC is applied to each tuple of elements of ARRAY1 ... and the result is stored as the corresponding element in ARRAY0.  The value returned is unspecified.  The order of application is unspecified.

 -- primitive: array-for-each proc ra0 . lra
     PROC is applied to each tuple of elements of ARRAY0 ... in row-major order.  The value returned is unspecified.

 -- primitive: array-index-map! ra proc
     applies PROC to the indices of each element of ARRAY in turn, storing the result in the corresponding element.  The value returned and the order of application are unspecified.

     One can implement ARRAY-INDEXES as

          (define (array-indexes array)
              (let ((ra (apply make-array #f (array-shape array))))
                (array-index-map! ra (lambda x x))
                ra))

     Another example:

          (define (apl:index-generator n)
              (let ((v (make-uniform-vector n 1)))
                (array-index-map! v (lambda (i) i))
                v))

Uniform Arrays
--------------

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 uniform vectors.  The procedures in this section can also be used on conventional arrays, vectors, bit-vectors and strings.

When creating a uniform array, the type of data to be stored is indicated with a PROTOTYPE argument.  The following table lists the types available and example prototypes:

     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

Unshared uniform arrays of characters with a single zero-based dimension are identical to strings:

     (make-uniform-array #\a 3) =>
     "aaa"

Unshared uniform arrays of booleans with a single zero-based dimension are identical to bit-vectors.

     (make-uniform-array #t 3) =>
     #*111

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 # and (.  For example, a uniform vector of signed long integers is displayed in the form '#e(3 5 9).

 -- primitive: array? v [prot]
     Returns #t if the OBJ is an array, and #f if not.

     The PROTOTYPE argument is used with uniform arrays and is described elsewhere.

 -- procedure: make-uniform-array prototype bound1 bound2 ...
     Creates and returns a uniform array of type corresponding to PROTOTYPE that has as many dimensions as there are BOUNDs and fills it with PROTOTYPE.

 -- primitive: array-prototype ra
     Return an object that would produce an array of the same type as ARRAY, if used as the PROTOTYPE for make-uniform-array.

 -- primitive: list->uniform-array ndim prot lst
 -- procedure: list->uniform-vector prot lst
     Return a uniform array of the type indicated by prototype PROT with elements the same as those of LST. Elements must be of the appropriate type, no coercions are done.

 -- primitive: uniform-vector-fill! uve fill
     Stores FILL in every element of UVE.  The value returned is unspecified.

 -- primitive: uniform-vector-length v
     Return the number of elements in UVE.

 -- primitive: dimensions->uniform-array dims prot [fill]
 -- primitive: make-uniform-vector length prototype [fill]
     Create and return a uniform array or vector of type corresponding to PROTOTYPE with dimensions DIMS or length LENGTH.  If FILL is supplied, it's used to fill the array, otherwise PROTOTYPE is used.

 -- primitive: uniform-array-read! ra [port_or_fd [start [end]]]
 -- primitive: uniform-vector-read! uve [port-or-fdes] [start] [end]
     Attempts to read all elements of URA, in lexicographic order, as binary objects from PORT-OR-FDES. If an end of file is encountered during uniform-array-read! the objects up to that point only are put into URA (starting at the beginning) and the remainder of the array is unchanged.

     The optional arguments START and END allow a specified region of a vector (or linearized array) to be read, leaving the remainder of the vector unchanged.

     uniform-array-read! returns the number of objects read. PORT-OR-FDES may be omitted, in which case it defaults to the value returned by (current-input-port).

 -- primitive: uniform-array-write v [port_or_fd [start [end]]]
 -- primitive: uniform-vector-write uve [port-or-fdes] [start] [end]
     Writes all elements of URA as binary objects to PORT-OR-FDES.

     The optional arguments START and END allow a specified region of a vector (or linearized array) to be written.

     The number of objects actually written is returned. PORT-OR-FDES may be omitted, in which case it defaults to the value returned by (current-output-port).

Bit Vectors
-----------

Bit vectors are a specific type of uniform array: an array of booleans with a single zero-based index.

They are displayed as a sequence of 0s and 1s prefixed by #*, e.g.,

     (make-uniform-vector 8 #t #f) =>
     #*00000000

     #b(#t #f #t) =>
     #*101

 -- primitive: bit-count b bitvector
     Return the number of occurrences of the boolean B in BITVECTOR.

 -- primitive: bit-position item v k
     Return the minimum index of an occurrence of BOOL in BV which is at least K.  If no BOOL occurs within the specified range #f is returned.

 -- primitive: bit-invert! v
     Modifies BV by replacing each element with its negation.

 -- primitive: bit-set*! v kv obj
     If uve is a bit-vector BV and uve must be of the same length.  If BOOL is #t, uve is OR'ed into BV; If BOOL is #f, the inversion of uve is AND'ed into BV.

     If uve is a unsigned integer vector all the elements of uve must be between 0 and the length of BV.  The bits of BV corresponding to the indexes in uve are set to BOOL.  The return value is unspecified.

 -- primitive: bit-count* v kv obj
     Return

          (bit-count (bit-set*! (if bool bv (bit-invert! bv)) uve #t) #t).

     BV is not modified.

Association Lists and Hash Tables
=================================

This chapter discusses dictionary objects: data structures that are useful for organizing and indexing large bodies of information.

Dictionary Types
----------------

A 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. (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 association list (or alist for short) is a list of key-value pairs.  Each pair represents a single quantity or object; the car of the pair is a key which is used to identify the object, and the cdr is the object's value.

A 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, car, 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.

Association Lists
-----------------

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 key of each entry is the car of the pair and the value of each entry is the cdr.

     ASSOCIATION LIST ::=  '( (KEY1 . VALUE1)
                              (KEY2 . VALUE2)
                              (KEY3 . VALUE3)
                              ...
                            )

Association lists are also known, for short, as 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 cons, car, cdr, set-car!, set-cdr! and so on.  However, because association lists are so useful, Guile also provides specific procedures for manipulating them.

Alist Key Equality
..................

All of Guile's dedicated association list procedures, apart from 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.

  * Procedures with assq in their name use eq? to determine key equality.

  * Procedures with assv in their name use eqv? to determine key equality.

  * Procedures with assoc in their name use equal? to determine key equality.

acons is an exception because it is used to build association lists which do not require their entries' keys to be unique.

Adding or Setting Alist Entries
...............................

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 acons procedure call.  So the specified alist is not modified, but its contents become shared with the tail of the combined alist that acons returns.

In the most common usage of acons, a variable holding the original association list is updated with the combined alist:

     (set! address-list (acons name address address-list))

In such cases, it doesn't matter that the old and new values of address-list share some of their contents, since the old value is usually no longer independently accessible.

Note that 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 acons is ideal for building alists where there is no concept of key uniqueness.

     (set! task-list (acons 3 "pay gas bill" '()))
     task-list
     =>
     ((3 . "pay gas bill"))

     (set! task-list (acons 3 "tidy bedroom" task-list))
     task-list
     =>
     ((3 . "tidy bedroom") (3 . "pay gas bill"))

assq-set!, assv-set! and assoc-set! are used to add or replace an entry in an association list where there 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.

assq-set! and friends may destructively modify the structure of the old association list in such a way that an existing variable is correctly updated without having to set! it to the value returned:

     address-list
     =>
     (("mary" . "34 Elm Road") ("james" . "16 Bow Street"))

     (assoc-set! address-list "james" "1a London Road")
     =>
     (("mary" . "34 Elm Road") ("james" . "1a London Road"))

     address-list
     =>
     (("mary" . "34 Elm Road") ("james" . "1a London Road"))

Or they may not:

     (assoc-set! address-list "bob" "11 Newington Avenue")
     =>
     (("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
      ("james" . "1a London Road"))

     address-list
     =>
     (("mary" . "34 Elm Road") ("james" . "1a London Road"))

The only safe way to update an association list variable when adding or replacing an entry like this is to set! the variable to the returned value:

     (set! address-list
           (assoc-set! address-list "bob" "11 Newington Avenue"))
     address-list
     =>
     (("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
      ("james" . "1a London Road"))

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 acons, assq-set!, assv-set! or assoc-set!, use list-copy to copy the old association list before modifying it.

 -- primitive: acons key value alist
     Adds a new key-value pair to ALIST.  A new pair is created whose car is KEY and whose cdr is VALUE, and the pair is consed onto ALIST, and the new list is returned.  This function is not destructive; ALIST is not modified.

 -- primitive: assq-set! alist key val
 -- primitive: assv-set! alist key value
 -- primitive: assoc-set! alist key value
     Reassociate KEY in ALIST with VALUE: find any existing ALIST entry for KEY and associate it with the new VALUE.  If ALIST does not contain an entry for KEY, add a new one.  Return the (possibly new) alist.

     These functions do not attempt to verify the structure of ALIST, and so may cause unusual results if passed an object that is not an association list.

Retrieving Alist Entries
........................

assq, assv and assoc take an alist and a key as arguments and return the entry for that key if an entry exists, or #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 (KEY . VALUE), not just the value.

 -- primitive: assq key alist
 -- primitive: assv key alist
 -- primitive: assoc key alist
     Fetches the entry in ALIST that is associated with KEY.  To decide whether the argument KEY matches a particular entry in ALIST, assq compares keys with eq?, assv uses eqv? and assoc uses equal?.  If KEY cannot be found in ALIST (according to whichever equality predicate is in use), then #f is returned.  These functions return the entire alist entry found (i.e. both the key and the value).

assq-ref, assv-ref and assoc-ref, on the other hand, take an alist and a key and return just the value for that key, if an entry exists.  If there is no entry for the specified key, these procedures return #f.

This creates an ambiguity: if the return value is #f, it means either that there is no entry with the specified key, or that there is an entry for the specified key, with value #f. Consequently, 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.

 -- primitive: assq-ref alist key
 -- primitive: assv-ref alist key
 -- primitive: assoc-ref alist key
     Like assq, assv and assoc, except that only the value associated with KEY in ALIST is returned.  These functions are equivalent to

          (let ((ent (ASSOCIATOR KEY ALIST)))
            (and ent (cdr ent)))

     where ASSOCIATOR is one of assq, assv or assoc.

Removing Alist Entries
......................

To remove the element from an association list whose key matches a specified key, use assq-remove!, assv-remove! or 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 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 set! it to the value that assq-remove! and friends return.

     address-list
     =>
     (("bob" . "11 Newington Avenue") ("mary" . "34 Elm Road")
      ("james" . "1a London Road"))

     (set! address-list (assoc-remove! address-list "mary"))
     address-list
     =>
     (("bob" . "11 Newington Avenue") ("james" . "1a London Road"))

Note that, when assq/v/oc-remove! is used to modify an association list that has been constructed only using the corresponding 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 assq/v/oc-remove! is applied to an association list that has been constructed using acons, or an 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:

     (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
     =>
     (("mary" . "57 Pine Drive") ("mary" . "11 Elm Street"))

     (set! address-list (assoc-remove! address-list "mary"))
     address-list
     =>
     (("mary" . "11 Elm Street"))

In this example, the two instances of the string "mary" are not the same when compared using eq?, so the two assq-set! calls add two distinct entries to address-list.  When compared using equal?, both "mary"s in address-list are the same as the "mary" in the assoc-remove! call, but assoc-remove! stops after removing the first matching entry that it finds, and so one of the "mary" entries is left in place.

 -- primitive: assq-remove! alist key
 -- primitive: assv-remove! alist key
 -- primitive: assoc-remove! alist key
     Delete the first entry in ALIST associated with KEY, and return the resulting alist.

Sloppy Alist Functions
......................

sloppy-assq, sloppy-assv and sloppy-assoc behave like the corresponding non-sloppy- procedures, except that they return #f when the specified association list is not well-formed, where the non-sloppy- versions would signal an error.

Specifically, there are two conditions for which the non-sloppy- procedures signal an error, which the sloppy- procedures handle instead by returning #f.  Firstly, if the specified alist as a whole is not a proper list:

     (assoc "mary" '((1 . 2) ("key" . "door") . "open sesame"))
     =>
     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"))
     =>
     #f

Secondly, if one of the entries in the specified alist is not a pair:

     (assoc 2 '((1 . 1) 2 (3 . 9)))
     =>
     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)))
     =>
     #f

Unless you are explicitly working with badly formed association lists, it is much safer to use the non-sloppy- procedures, because they help to highlight coding and data errors that the sloppy- versions would silently cover up.

 -- primitive: sloppy-assq key alist
     Behaves like assq but does not do any error checking. Recommended only for use in Guile internals.

 -- primitive: sloppy-assv key alist
     Behaves like assv but does not do any error checking. Recommended only for use in Guile internals.

 -- primitive: sloppy-assoc key alist
     Behaves like assoc but does not do any error checking. Recommended only for use in Guile internals.

Alist Example
.............

Here is a longer example of how alists may be used in practice.

     (define capitals '(("New York" . "Albany")
                        ("Oregon"   . "Salem")
                        ("Florida"  . "Miami")))

     ;; What's the capital of Oregon?
     (assoc "Oregon" capitals)       => ("Oregon" . "Salem")
     (assoc-ref capitals "Oregon")   => "Salem"

     ;; We left out South Dakota.
     (set! capitals
           (assoc-set! capitals "South Dakota" "Bismarck"))
     capitals
     => (("South Dakota" . "Bismarck")
         ("New York" . "Albany")
         ("Oregon" . "Salem")
         ("Florida" . "Miami"))

     ;; And we got Florida wrong.
     (set! capitals
           (assoc-set! capitals "Florida" "Tallahassee"))
     capitals
     => (("South Dakota" . "Bismarck")
         ("New York" . "Albany")
         ("Oregon" . "Salem")
         ("Florida" . "Tallahassee"))

     ;; After Oregon secedes, we can remove it.
     (set! capitals
           (assoc-remove! capitals "Oregon"))
     capitals
     => (("South Dakota" . "Bismarck")
         ("New York" . "Albany")
         ("Florida" . "Tallahassee"))

Hash Tables
-----------

Like the association list functions, the hash table functions come in several varieties: hashq, hashv, and hash. The hashq functions use eq? to determine whether two keys match.  The hashv functions use eqv?, and the hash functions use equal?.

In each of the functions that follow, the TABLE argument must be a vector.  The KEY and VALUE arguments may be any Scheme object.

 -- primitive: hashq-ref table key [dflt]
     Look up KEY in the hash table TABLE, and return the value (if any) associated with it.  If KEY is not found, return DEFAULT (or #f if no DEFAULT argument is supplied).  Uses eq? for equality testing.

 -- primitive: hashv-ref table key [dflt]
     Look up KEY in the hash table TABLE, and return the value (if any) associated with it.  If KEY is not found, return DEFAULT (or #f if no DEFAULT argument is supplied).  Uses eqv? for equality testing.

 -- primitive: hash-ref table key [dflt]
     Look up KEY in the hash table TABLE, and return the value (if any) associated with it.  If KEY is not found, return DEFAULT (or #f if no DEFAULT argument is supplied).  Uses equal? for equality testing.

 -- primitive: hashq-set! table key val
     Find the entry in TABLE associated with KEY, and store VALUE there. Uses eq? for equality testing.

 -- primitive: hashv-set! table key val
     Find the entry in TABLE associated with KEY, and store VALUE there. Uses eqv? for equality testing.

 -- primitive: hash-set! table key val
     Find the entry in TABLE associated with KEY, and store VALUE there. Uses equal? for equality testing.

 -- primitive: hashq-remove! table key
     Remove KEY (and any value associated with it) from TABLE.  Uses eq? for equality tests.

 -- primitive: hashv-remove! table key
     Remove KEY (and any value associated with it) from TABLE.  Uses eqv? for equality tests.

 -- primitive: hash-remove! table key
     Remove KEY (and any value associated with it) from TABLE.  Uses equal? for equality tests.

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 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.

 -- primitive: hashq key size
     Determine a hash value for KEY that is suitable for lookups in a hashtable of size SIZE, where eq? is used as the equality predicate.  The function returns an integer in the range 0 to SIZE - 1.  Note that hashq may use internal addresses.  Thus two calls to hashq where the keys are 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: (hashq 'foo n) (gc) (hashq 'foo n) may produce two different values, since foo will be garbage collected.

 -- primitive: hashv key size
     Determine a hash value for KEY that is suitable for lookups in a hashtable of size SIZE, where eqv? is used as the equality predicate.  The function returns an integer in the range 0 to SIZE - 1.  Note that (hashv key) may use internal addresses.  Thus two calls to hashv where the keys are 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: (hashv 'foo n) (gc) (hashv 'foo n) may produce two different values, since foo will be garbage collected.

 -- primitive: hash key size
     Determine a hash value for KEY that is suitable for lookups in a hashtable of size SIZE, where equal? is used as the equality predicate.  The function returns an integer in the range 0 to SIZE - 1.

 -- primitive: hashx-ref hash assoc table key [dflt]
     This behaves the same way as the corresponding ref function, but uses HASH as a hash function and ASSOC to compare keys.  hash must be a function that takes two arguments, a key to be hashed and a table size. assoc must be an associator function, like assoc, assq or assv. By way of illustration, hashq-ref table key is equivalent to hashx-ref hashq assq table key.

 -- primitive: hashx-set! hash assoc table key val
     This behaves the same way as the corresponding set! function, but uses HASH as a hash function and ASSOC to compare keys.  hash must be a function that takes two arguments, a key to be hashed and a table size. assoc must be an associator function, like assoc, assq or assv. By way of illustration, hashq-set! table key is equivalent to hashx-set!  hashq assq table key.

 -- primitive: hashq-get-handle table key
     This procedure returns the (key . value) pair from the hash table TABLE.  If TABLE does not hold an associated value for KEY, #f is returned. Uses eq? for equality testing.

 -- primitive: hashv-get-handle table key
     This procedure returns the (key . value) pair from the hash table TABLE.  If TABLE does not hold an associated value for KEY, #f is returned. Uses eqv? for equality testing.

 -- primitive: hash-get-handle table key
     This procedure returns the (key . value) pair from the hash table TABLE.  If TABLE does not hold an associated value for KEY, #f is returned. Uses equal? for equality testing.

 -- primitive: hashx-get-handle hash assoc table key
     This behaves the same way as the corresponding -get-handle function, but uses HASH as a hash function and ASSOC to compare keys.  hash must be a function that takes two arguments, a key to be hashed and a table size.  assoc must be an associator function, like assoc, assq or assv.

 -- primitive: hashq-create-handle! table key init
     This function looks up KEY in TABLE and returns its handle. If KEY is not already present, a new handle is created which associates KEY with INIT.

 -- primitive: hashv-create-handle! table key init
     This function looks up KEY in TABLE and returns its handle. If KEY is not already present, a new handle is created which associates KEY with INIT.

 -- primitive: hash-create-handle! table key init
     This function looks up KEY in TABLE and returns its handle. If KEY is not already present, a new handle is created which associates KEY with INIT.

 -- primitive: hashx-create-handle! hash assoc table key init
     This behaves the same way as the corresponding -create-handle function, but uses HASH as a hash function and ASSOC to compare keys.  hash must be a function that takes two arguments, a key to be hashed and a table size.  assoc must be an associator function, like assoc, assq or assv.

 -- 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, (hash-fold acons () tab) will convert a hash table into an a-list of key-value pairs.

Vectors
=======

Vectors are sequences of Scheme objects.  Unlike lists, the length of a vector, once the vector is created, cannot be changed.  The advantage of vectors over lists is that the time required to access one element of a vector 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.

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 (#), 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.

     #(1 2 3)
     #("Hello" foo #xdeadbeef)

Vector Predicates
-----------------

 -- primitive: vector? obj
     Return #t if OBJ is a vector, otherwise return #f.

Vector Constructors
-------------------

 -- primitive: make-vector k [fill]
     Return a newly allocated vector of K elements.  If a second argument is given, then each element is initialized to FILL.  Otherwise the initial contents of each element is unspecified.

 -- primitive: vector . l
 -- primitive: list->vector l
     Return a newly allocated vector whose elements contain the given arguments.  Analogous to list.

          (vector 'a 'b 'c) => #(a b c)

 -- primitive: vector->list v
     Return a newly allocated list of the objects contained in the elements of VECTOR.

          (vector->list '#(dah dah didah)) =>  (dah dah didah)
          (list->vector '(dididit dah)) =>  #(dididit dah)

Vector Modification
-------------------

A vector created by any of the vector constructor procedures (REFFIXME) 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.

 -- primitive: vector-set! vector k obj
     K must be a valid index of VECTOR. Vector-set! stores OBJ in element K of VECTOR. The value returned by vector-set! is unspecified.

          (let ((vec (vector 0 '(2 2 2 2) "Anna")))
            (vector-set! vec 1 '("Sue" "Sue"))
            vec) =>  #(0 ("Sue" "Sue") "Anna")
          (vector-set! '#(0 1 2) 1 "doe") => error ; constant vector

 -- primitive: vector-fill! v fill
     Store FILL in every element of VECTOR.  The value returned by vector-fill! is unspecified.

 -- primitive: vector-move-left! vec1 start1 end1 vec2 start2
     Vector version of substring-move-left!.

 -- primitive: vector-move-right! vec1 start1 end1 vec2 start2
     Vector version of substring-move-right!.

Vector Selection
----------------

These procedures return information about a given vector, such as the size or what elements are contained in the vector.

 -- primitive: vector-length vector
     Returns the number of elements in VECTOR as an exact integer.

 -- primitive: vector-ref vector k
     K must be a valid index of VECTOR. Vector-ref returns the contents of element K of VECTOR.

          (vector-ref '#(1 1 2 3 5 8 13 21) 5) => 8
          (vector-ref '#(1 1 2 3 5 8 13 21)
              (let ((i (round (* 2 (acos -1)))))
                (if (inexact? i)
                  (inexact->exact i)
                     i))) => 13

Hooks
=====

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 make-hook, then procedures can be added to a hook with add-hook! or removed with remove-hook! or reset-hook!.  The procedures stored in a hook can be invoked with run-hook.

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.

     (define hook (make-hook 2))
     hook
     => #<hook 2 40286c90>

Now we are ready to add some procedures to the newly created hook with 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 run-hook.

     (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)
     Bar: 12
     Foo: 7

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 add-hook!.

     (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)   ; <- Change here!
     (run-hook hook 3 4)
     Foo: 7
     Bar: 12

Hook Reference
--------------

When a hook is created with 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 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 ADD-HOOK! is omitted or is equal to #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 run-hook.

When calling hook->list, the procedures in the resulting list are in the same order as they would have been called by run-hook.

 -- primitive: make-hook-with-name name [n_args]
     Create a named hook with the name NAME for storing procedures of arity N_ARGS.  N_ARGS defaults to zero.

 -- primitive: make-hook [n_args]
     Create a hook for storing procedure of arity N_ARGS.  N_ARGS defaults to zero.

 -- primitive: hook? x
     Return #t if X is a hook, #f otherwise.

 -- primitive: hook-empty? hook
     Return #t if HOOK is an empty hook, #f otherwise.

 -- primitive: add-hook! hook proc [append_p]
     Add the procedure PROC to the hook HOOK. The procedure is added to the end if APPEND_P is true, otherwise it is added to the front.

 -- primitive: remove-hook! hook proc
     Remove the procedure PROC from the hook HOOK.

 -- primitive: reset-hook! hook
     Remove all procedures from the hook HOOK.

 -- primitive: run-hook hook . args
     Apply all procedures from the hook HOOK to the arguments ARGS.  The order of the procedure application is first to last.

 -- primitive: hook->list hook
     Convert the procedure list of HOOK to a list.

Other Core Guile Data Types
===========================