   This reference manual documents Guile, GNU's Ubiquitous Intelligent
Language for Extensions.  This is edition 1.1 corresponding to Guile
1.8.0.

   Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005 Free
Software Foundation.

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with the
no Invariant Sections, with the Front-Cover Texts being "A GNU Manual,"
and with the Back-Cover Text "You are free to copy and modify this GNU
Manual.".  A copy of the license is included in the section entitled
"GNU Free Documentation License".

6.8 Formatted Output
====================

The `format' function is a powerful way to print numbers, strings and
other objects together with literal text under the control of a format
string.  This function is available from

     (use-modules (ice-9 format))

   A format string is generally more compact and easier than using just
the standard procedures like `display', `write' and `newline'.
Parameters in the output string allow various output styles, and
parameters can be taken from the arguments for runtime flexibility.

   `format' is similar to the Common Lisp procedure of the same name,
but it's not identical and doesn't have quite all the features found in
Common Lisp.

   C programmers will note the similarity between `format' and
`printf', though escape sequences are marked with ~ instead of %, and
are more powerful.

 -- Scheme Procedure: format dest fmt [args...]
     Write output specified by the FMT string to DEST.  DEST can be an
     output port, `#t' for `current-output-port' (see Default Ports),
     a number for `current-error-port', or `#f' to return the
     output as a string.

     FMT can contain literal text to be output, and ~ escapes.  Each
     escape has the form

          ~ [param [, param...] [:] [@] code

     code is a character determining the escape sequence.  The : and @
     characters are optional modifiers, one or both of which change the
     way various codes operate.  Optional parameters are accepted by
     some codes too.  Parameters have the following forms,

    [+/-]number
          An integer, with optional + or -.

    '  (apostrophe)
          The following character in the format string, for instance 'z
          for z.

    v
          The next function argument as the parameter.  v stands for
          "variable", a parameter can be calculated at runtime and
          included in the arguments.  Upper case V can be used too.

    #
          The number of arguments remaining.  (See ~* below for some
          usages.)

     Parameters are separated by commas (,).  A parameter can be left
     empty to keep its default value when supplying later parameters.

     The following escapes are available.  The code letters are not
     case-sensitive, upper and lower case are the same.

    ~a
    ~s
          Object output.  Parameters: MINWIDTH, PADINC, MINPAD, PADCHAR.

          ~a outputs an argument like `display', ~s outputs an argument
          like `write' (see Writing).

               (format #t "~a" "foo") -| foo
               (format #t "~s" "foo") -| "foo"

          ~:a and ~:s put objects that don't have an external
          representation in quotes like a string.

               (format #t "~:a" car) -| "#<primitive-procedure car>"

          If the output is less than MINWIDTH characters (default 0),
          it's padded on the right with PADCHAR (default space).  ~@a
          and ~@s put the padding on the left instead.

               (format #f "~5a" 'abc)       => "abc  "
               (format #f "~5,,,'-@a" 'abc) => "--abc"

          MINPAD is a minimum for the padding then plus a multiple of
          PADINC.  Ie. the padding is MINPAD + N * PADINC, where N is
          the smallest integer making the total object plus padding
          greater than or equal to MINWIDTH.  The default MINPAD is 0
          and the default PADINC is 1 (imposing no minimum or multiple).

               (format #f "~5,1,4a" 'abc) => "abc    "

    ~c
          Character.  Parameter: CHARNUM.

          Output a character.  The default is to simply output, as per
          `write-char' (see Writing).  ~@c prints in `write' style.
          ~:c prints control characters (ASCII 0 to 31) in ^X form.

               (format #t "~c" #\z)        -| z
               (format #t "~@c" #\z)       -| #\z
               (format #t "~:c" #\newline) -| ^J

          If the CHARNUM parameter is given then an argument is not
          taken but instead the character is `(integer->char CHARNUM)'
          (see Characters).  This can be used for instance to output
          characters given by their ASCII code.

               (format #t "~65c")  -| A

    ~d
    ~x
    ~o
    ~b
          Integer.  Parameters: MINWIDTH, PADCHAR, COMMACHAR,
          COMMAWIDTH.

          Output an integer argument as a decimal, hexadecimal, octal
          or binary integer (respectively).

               (format #t "~d" 123) -| 123

          ~@d etc shows a + sign is shown on positive numbers.

               (format #t "~@b" 12) -| +1100

          If the output is less than the MINWIDTH parameter (default no
          minimum), it's padded on the left with the PADCHAR parameter
          (default space).

               (format #t "~5,'*d" 12)   -| ***12
               (format #t "~5,'0d" 12)   -| 00012
               (format #t "~3d"    1234) -| 1234

          ~:d adds commas (or the COMMACHAR parameter) every three
          digits (or the COMMAWIDTH parameter many).

               (format #t "~:d" 1234567)         -| 1,234,567
               (format #t "~10,'*,'/,2:d" 12345) -| ***1/23/45

          Hexadecimal ~x output is in lower case, but the ~( and ~)
          case conversion directives described below can be used to get
          upper case.

               (format #t "~x"       65261) -| feed
               (format #t "~:@(~x~)" 65261) -| FEED

    ~r
          Integer in words, roman numerals, or a specified radix.
          Parameters: RADIX, MINWIDTH, PADCHAR, COMMACHAR, COMMAWIDTH.

          With no parameters output is in words as a cardinal like
          "ten", or ~:r prints an ordinal like "tenth".

               (format #t "~r" 9)  -| nine        ;; cardinal
               (format #t "~r" -9) -| minus nine  ;; cardinal
               (format #t "~:r" 9) -| ninth       ;; ordinal

          And also with no parameters, ~@r gives roman numerals and
          ~@:r gives old roman numerals.  In old roman numerals there's
          no "subtraction", so 9 is VIIII instead of IX.  In both cases
          only positive numbers can be output.

               (format #t "~@r" 89)  -| LXXXIX     ;; roman
               (format #t "~@:r" 89) -| LXXXVIIII  ;; old roman

          When a parameter is given it means numeric output in the
          specified RADIX.  The modifiers and parameters following the
          radix are the same as described for ~d etc above.

               (format #f "~3r" 27)   => "1000"    ;; base 3
               (format #f "~3,5r" 26) => "  222"   ;; base 3 width 5

    ~f
          Fixed-point float.  Parameters: WIDTH, DECIMALS, SCALE,
          OVERFLOWCHAR, PADCHAR.

          Output a number or number string in fixed-point format, ie.
          with a decimal point.

               (format #t "~f" 5)      -| 5.0
               (format #t "~f" "123")  -| 123.0
               (format #t "~f" "1e-1") -| 0.1

          ~@f prints a + sign on positive numbers (including zero).

               (format #t "~@f" 0) -| +0.0

          If the output is less than WIDTH characters it's padded on the
          left with PADCHAR (space by default).  If the output equals or
          exceeds WIDTH then there's no padding.  The default for WIDTH
          is no padding.

               (format #f "~6f" -1.5)      => "  -1.5"
               (format #f "~6,,,,'*f" 23)  => "**23.0"
               (format #f "~6f" 1234567.0) => "1234567.0"

          DECIMALS is how many digits to print after the decimal point,
          with the value rounded or padded with zeros as necessary.
          (The default is to output as many decimals as required.)

               (format #t "~1,2f" 3.125) -| 3.13
               (format #t "~1,2f" 1.5)   -| 1.50

          SCALE is a power of 10 applied to the value, moving the
          decimal point that many places.  A positive SCALE increases
          the value shown, a negative decreases it.

               (format #t "~,,2f" 1234)  -| 123400.0
               (format #t "~,,-2f" 1234) -| 12.34

          If OVERFLOWCHAR and WIDTH are both given and if the output
          would exceed WIDTH, then that many OVERFLOWCHARs are printed
          instead of the value.

               (format #t "~5,,,'xf" 12345) -| 12345
               (format #t "~4,,,'xf" 12345) -| xxxx

    ~e
          Exponential float.  Parameters: WIDTH, MANTDIGITS, EXPDIGITS,
          INTDIGITS, OVERFLOWCHAR, PADCHAR, EXPCHAR.

          Output a number or number string in exponential notation.

               (format #t "~e" 5000.25) -| 5.00025E+3
               (format #t "~e" "123.4") -| 1.234E+2
               (format #t "~e" "1e4")   -| 1.0E+4

          ~@e prints a + sign on positive numbers (including zero).
          (This is for the mantissa, a + or - sign is always shown on
          the exponent.)

               (format #t "~@e" 5000.0) -| +5.0E+3

          If the output is less than WIDTH characters it's padded on the
          left with PADCHAR (space by default).  The default for WIDTH
          is to output with no padding.

               (format #f "~10e" 1234.0)     => "  1.234E+3"
               (format #f "~10,,,,,'*e" 0.5) => "****5.0E-1"

          MANTDIGITS is the number of digits shown in the mantissa after
          the decimal point.  The value is rounded or trailing zeros
          are added as necessary.  The default MANTDIGITS is to show as
          much as needed by the value.

               (format #f "~,3e" 11111.0) => "1.111E+4"
               (format #f "~,8e" 123.0)   => "1.23000000E+2"

          EXPDIGITS is the minimum number of digits shown for the
          exponent, with leading zeros added if necessary.  The default
          for EXPDIGITS is to show only as many digits as required.  At
          least 1 digit is always shown.

               (format #f "~,,1e" 1.0e99) => "1.0E+99"
               (format #f "~,,6e" 1.0e99) => "1.0E+000099"

          INTDIGITS (default 1) is the number of digits to show before
          the decimal point in the mantissa.  INTDIGITS can be zero, in
          which case the integer part is a single 0, or it can be
          negative, in which case leading zeros are shown after the
          decimal point.

               (format #t "~,,,3e" 12345.0)  -| 123.45E+2
               (format #t "~,,,0e" 12345.0)  -| 0.12345E+5
               (format #t "~,,,-3e" 12345.0) -| 0.00012345E+8

          If OVERFLOWCHAR is given then WIDTH is a hard limit.  If the
          output would exceed WIDTH then instead that many
          OVERFLOWCHARs are printed.

               (format #f "~6,,,,'xe" 100.0) => "1.0E+2"
               (format #f "~3,,,,'xe" 100.0) => "xxx"

          EXPCHAR is the exponent marker character (default E).

               (format #t "~,,,,,,'ee" 100.0) -| 1.0e+2

    ~g
          General float.  Parameters: WIDTH, MANTDIGITS, EXPDIGITS,
          INTDIGITS, OVERFLOWCHAR, PADCHAR, EXPCHAR.

          Output a number or number string in either exponential format
          the same as ~e, or fixed-point format like ~f but aligned
          where the mantissa would have been and followed by padding
          where the exponent would have been.

          Fixed-point is used when the absolute value is 0.1 or more
          and it takes no more space than the mantissa in exponential
          format, ie.  basically up to MANTDIGITS digits.

               (format #f "~12,4,2g" 999.0)    => "   999.0    "
               (format #f "~12,4,2g" "100000") => "  1.0000E+05"

          The parameters are interpreted as per ~e above.  When
          fixed-point is used, the DECIMALS parameter to ~f is
          established from MANTDIGITS, so as to give a total
          MANTDIGITS+1 figures.

    ~$
          Monetary style fixed-point float.  Parameters: DECIMALS,
          INTDIGITS, WIDTH, PADCHAR.

          Output a number or number string in fixed-point format, ie.
          with a decimal point.  DECIMALS is the number of decimal
          places to show, default 2.

               (format #t "~$" 5)       -| 5.00
               (format #t "~4$" "2.25") -| 2.2500
               (format #t "~4$" "1e-2") -| 0.0100

          ~@$ prints a + sign on positive numbers (including zero).

               (format #t "~@$" 0) -| +0.00

          INTDIGITS is a minimum number of digits to show in the integer
          part of the value (default 1).

               (format #t "~,3$" 9.5)   -| 009.50
               (format #t "~,0$" 0.125) -| .13

          If the output is less than WIDTH characters (default 0), it's
          padded on the left with PADCHAR (default space).  ~:$ puts
          the padding after the sign.

               (format #f "~,,8$" -1.5)   => "   -1.50"
               (format #f "~,,8:$" -1.5)  => "-   1.50"
               (format #f "~,,8,'.@:$" 3) => "+...3.00"

          Note that floating point for dollar amounts is generally not
          a good idea, because a cent 0.01 cannot be represented
          exactly in the binary floating point Guile uses, which leads
          to slowly accumulating rounding errors.  Keeping values as
          cents (or fractions of a cent) in integers then printing with
          the scale option in ~f may be a better approach.

    ~i
          Complex fixed-point float.  Parameters: WIDTH, DECIMALS,
          SCALE, OVERFLOWCHAR, PADCHAR.

          Output the argument as a complex number, with both real and
          imaginary part shown (even if one or both are zero).

          The parameters and modifiers are the same as for fixed-point
          ~f described above.  The real and imaginary parts are both
          output with the same given parameters and modifiers, except
          that for the imaginary part the @ modifier is always enabled,
          so as to print a + sign between the real and imaginary parts.

               (format #t "~i" 1)  -| 1.0+0.0i

    ~p
          Plural.  No parameters.

          Output nothing if the argument is 1, or `s' for any other
          value.

               (format #t "enter name~p" 1) -| enter name
               (format #t "enter name~p" 2) -| enter names

          ~@p prints `y' for 1 or `ies' otherwise.

               (format #t "pupp~@p" 1) -| puppy
               (format #t "pupp~@p" 2) -| puppies

          ~:p re-uses the preceding argument instead of taking a new
          one, which can be convenient when printing some sort of count.

               (format #t "~d cat~:p" 9)   -| 9 cats
               (format #t "~d pupp~@:p" 5) -| 5 puppies

          ~p is designed for English plurals and there's no attempt to
          support other languages.  ~[ conditionals (below) may be able
          to help.  When using `gettext' to translate messages
          `ngettext' is probably best though (see
          Internationalization).

    ~y
          Pretty print.  No parameters.

          Output an argument with `pretty-print' (see Pretty Printing).

    ~?
    ~k
          Sub-format.  No parameters.

          Take a format string argument and a second argument which is
          a list of arguments for that string, and output the result.

               (format #t "~?" "~d ~d" '(1 2))    -| 1 2

          ~@? takes arguments for the sub-format directly rather than
          in a list.

               (format #t "~@? ~s" "~d ~d" 1 2 "foo") -| 1 2 "foo"

          ~? and ~k are the same, ~k is provided for T-Scheme
          compatibility.

    ~*
          Argument jumping.  Parameter: N.

          Move forward N arguments (default 1) in the argument list.
          ~:* moves backwards.  (N cannot be negative.)

               (format #f "~d ~2*~d" 1 2 3 4) => "1 4"
               (format #f "~d ~:*~d" 6)       => "6 6"

          ~@* moves to argument number N.  The first argument is number
          0 (and that's the default for N).

               (format #f "~d~d again ~@*~d~d" 1 2) => "12 again 12"
               (format #f "~d~d~d ~1@*~d~d" 1 2 3)  => "123 23"

          A # move to the end followed by a : modifier move back can be
          used for an absolute position relative to the end of the
          argument list, a reverse of what the @ modifier does.

               (format #t "~#*~2:*~a" 'a 'b 'c 'd)   -| c

          At the end of the format string the current argument postion
          doesn't matter, any further arguments are ignored.

    ~t
          Advance to a column position.  Parameters: COLNUM, COLINC,
          PADCHAR.

          Output PADCHAR (space by default) to move to the given COLNUM
          column.  The start of the line is column 0, the default for
          COLNUM is 1.

               (format #f "~tX")  => " X"
               (format #f "~3tX") => "   X"

          If the current column is already past COLNUM, then the move is
          to there plus a multiple of COLINC, ie. column COLNUM + N *
          COLINC for the smallest N which makes that value greater than
          or equal to the current column.  The default COLINC is 1
          (which means no further move).

               (format #f "abcd~2,5,'.tx") => "abcd...x"

          ~@t takes COLNUM as an offset from the current column.
          COLNUM many pad characters are output, then further padding to
          make the current column a multiple of COLINC, if it isn't
          already so.

               (format #f "a~3,5'*@tx") => "a****x"

          ~t is implemented using `port-column' (see Reading), so
          it works even there has been other output before `format'.

    ~~
          Tilde character.  Parameter: N.

          Output a tilde character ~, or N many if a parameter is
          given.  Normally ~ introduces an escape sequence, ~~ is the
          way to output a literal tilde.

    ~%
          Newline.  Parameter: N.

          Output a newline character, or N many if a parameter is given.
          A newline (or a few newlines) can of course be output just by
          including them in the format string.

    ~&
          Start a new line.  Parameter: N.

          Output a newline if not already at the start of a line.  With
          a parameter, output that many newlines, but with the first
          only if not already at the start of a line.  So for instance
          3 would be a newline if not already at the start of a line,
          and 2 further newlines.

    ~_
          Space character.  Parameter: N.

          Output a space character, or N many if a parameter is given.

          With a variable parameter this is one way to insert runtime
          calculated padding (~t or the various field widths can do
          similar things).

               (format #f "~v_foo" 4) => "    foo"

    ~/
          Tab character.  Parameter: N.

          Output a tab character, or N many if a parameter is given.

    ~|
          Formfeed character.  Parameter: N.

          Output a formfeed character, or N many if a parameter is
          given.

    ~!
          Force output.  No parameters.

          At the end of output, call `force-output' to flush any
          buffers on the destination (see Writing).  ~! can occur
          anywhere in the format string, but the force is done at the
          end of output.

          When output is to a string (destination `#f'), ~! does
          nothing.

    ~newline  (ie. newline character)
          Continuation line.  No parameters.

          Skip this newline and any following whitespace in the format
          string, ie. don't send it to the output.  This can be used to
          break up a long format string for readability, but not print
          the extra whitespace.

               (format #f "abc~
                           ~d def~
                           ~d" 1 2) => "abc1 def2"

          ~:newline skips the newline but leaves any further whitespace
          to be printed normally.

          ~@newline prints the newline then skips following whitespace.

    ~( ~)
          Case conversion.  No parameters.

          Between ~( and ~) the case of all output is changed.  The
          modifiers on ~( control the conversion.

               ~( -- lower case.

               ~@:( -- upper case.

          For example,

               (format #t "~(Hello~)")   -| hello
               (format #t "~@:(Hello~)") -| HELLO

          In the future it's intended the modifiers : and @ alone will
          capitalize the first letters of words, as per Common Lisp
          `format', but the current implementation of this is flawed and
          not recommended for use.

          Case conversions do not nest, currently.  This might change
          in the future, but if it does then it will be to Common Lisp
          style where the outermost conversion has priority, overriding
          inner ones (making those fairly pointless).

    ~{ ~}
          Iteration.  Parameter: MAXREPS (for ~{).

          The format between ~{ and ~} is iterated.  The modifiers to
          ~{ determine how arguments are taken.  The default is a list
          argument with each iteration successively consuming elements
          from it.  This is a convenient way to output a whole list.

               (format #t "~{~d~}"     '(1 2 3))       -| 123
               (format #t "~{~s=~d ~}" '("x" 1 "y" 2)) -| "x"=1 "y"=2

          ~:{ takes a single argument which is a list of lists, each of
          those contained lists gives the arguments for the iterated
          format.

               (format #t "~:{~dx~d ~}" '((1 2) (3 4) (5 6))) -| 1x2 3x4 5x6

          ~@{ takes arguments directly, with each iteration
          successively consuming arguments.

               (format #t "~@{~d~}"     1 2 3)       -| 123
               (format #t "~@{~s=~d ~}" "x" 1 "y" 2) -| "x"=1 "y"=2

          ~@:{ takes list arguments, one argument for each iteration,
          using that list for the format.

               (format #t "~@:{~dx~d ~}" '(1 2) '(3 4) '(5 6)) -| 1x2 3x4 5x6

          Iterating stops when there are no more arguments or when the
          MAXREPS parameter to ~{ is reached (default no maximum).

               (format #t "~2{~d~}" '(1 2 3 4)) -| 12

          If the format between ~{ and ~} is empty, then a format
          string argument is taken (before iteration argument(s)) and
          used instead.  This allows a sub-format (like ~? above) to be
          iterated.

               (format #t "~{~}" "~d" '(1 2 3)) -| 123

          Iterations can be nested, an inner iteration operates in the
          same way as described, but of course on the arguments the
          outer iteration provides it.  This can be used to work into
          nested list structures.  For example in the following the
          inner ~{~d~}x is applied to `(1 2)' then `(3 4 5)' etc.

               (format #t "~{~{~d~}x~}" '((1 2) (3 4 5))) -| 12x345x

          See also ~^ below for escaping from iteration.

    ~[ ~; ~]
          Conditional.  Parameter: SELECTOR.

          A conditional block is delimited by ~[ and ~], and ~;
          separates clauses within the block.  ~[ takes an integer
          argument and that number clause is used.  The first clause is
          number 0.

               (format #f "~[peach~;banana~;mango~]" 1)  => "banana"

          The SELECTOR parameter can be used for the clause number,
          instead of taking an argument.

               (format #f "~2[peach~;banana~;mango~]") => "mango"

          If the clause number is out of range then nothing is output.
          Or the last clause can be ~:; to use that for a number out of
          range.

               (format #f "~[banana~;mango~]"         99) => ""
               (format #f "~[banana~;mango~:;fruit~]" 99) => "fruit"

          ~:[ treats the argument as a flag, and expects two clauses.
          The first is used if the argument is `#f' or the second
          otherwise.

               (format #f "~:[false~;not false~]" #f)   => "false"
               (format #f "~:[false~;not false~]" 'abc) => "not false"

               (let ((n 3))
                 (format #t "~d gnu~:[s are~; is~] here" n (= 1 n)))
               -| 3 gnus are here

          ~@[ also treats the argument as a flag, and expects one
          clause.  If the argument is `#f' then no output is produced
          and the argument is consumed, otherwise the clause is used
          and the argument is not consumed, it's left for the clause.
          This can be used for instance to suppress output if `#f'
          means something not available.

               (format #f "~@[temperature=~d~]" 27) => "temperature=27"
               (format #f "~@[temperature=~d~]" #f) => ""

    ~^
          Escape.  Parameters: VAL1, VAL2, VAL3.

          Stop formatting if there are no more arguments.  This can be
          used for instance to have a format string adapt to a variable
          number of arguments.

               (format #t "~d~^ ~d" 1)   -| 1
               (format #t "~d~^ ~d" 1 2) -| 1 2

          Within a ~{ ~} iteration, ~^ stops the current iteration step
          if there are no more arguments to that step, but continuing
          with possible further steps and the rest of the format.  This
          can be used for instance to avoid a separator on the last
          iteration, or to adapt to variable length argument lists.

               (format #f "~{~d~^/~} go"    '(1 2 3))     => "1/2/3 go"
               (format #f "~:{ ~d~^~d~} go" '((1) (2 3))) => " 1 23 go"

          Within a ~? sub-format, ~^ operates just on that sub-format.
          If it terminates the sub-format then the originating format
          will still continue.

               (format #t "~? items" "~d~^ ~d" '(1))   -| 1 items
               (format #t "~? items" "~d~^ ~d" '(1 2)) -| 1 2 items

          The parameters to ~^ (which are numbers) change the condition
          used to terminate.  For a single parameter, termination is
          when that value is zero (notice this makes plain ~^
          equivalent to ~#^).  For two parameters, termination is when
          those two are equal.  For three parameters, termination is
          when VAL1 <= VAL2 and VAL2 <= VAL3.

    ~q
          Inquiry message.  Insert a copyright message into the output.

          ~:q inserts the format implementation version.

     It's an error if there are not enough arguments for the escapes in
     the format string, but any excess arguments are ignored.

     Iterations ~{ ~} and conditionals ~[ ~; ~] can be nested, but must
     be properly nested, meaning the inner form must be entirely within
     the outer form.  So it's not possible, for instance, to try to
     conditionalize the endpoint of an iteration.

          (format #t "~{ ~[ ... ~] ~}" ...)       ;; good
          (format #t "~{ ~[ ... ~} ... ~]" ...)   ;; bad

     The same applies to case conversions ~( ~), they must properly
     nest with respect to iterations and conditionals (though currently
     a case conversion cannot nest within another case conversion).

     When a sub-format (~?) is used, that sub-format string must be
     self-contained.  It cannot for instance give a ~{ to begin an
     iteration form and have the ~} up in the originating format, or
     similar.

   Guile contains a `format' procedure even when the module `(ice-9
format)' is not loaded.  The default `format' is `simple-format' (see
Writing), it doesn't support all escape sequences documented in this
section, and will signal an error if you try to use one of them.  The
reason for two versions is that the full `format' is fairly large and
requires some time to load.  `simple-format' is often adequate too.

6.9 File Tree Walk
==================

The functions in this section traverse a tree of files and directories,
in a fashion similar to the C `ftw' and `nftw' routines (see Working with Directory Trees (libc)).

     (use-modules (ice-9 ftw))

 -- Function: ftw startname proc ['hash-size n]
     Walk the filesystem tree descending from STARTNAME, calling PROC
     for each file and directory.

     Hard links and symbolic links are followed.  A file or directory is
     reported to PROC only once, and skipped if seen again in another
     place.  One consequence of this is that `ftw' is safe against
     circularly linked directory structures.

     Each PROC call is `(PROC filename statinfo flag)' and it should
     return `#t' to continue, or any other value to stop.

     FILENAME is the item visited, being STARTNAME plus a further path
     and the name of the item.  STATINFO is the return from `stat'
     (see File System) on FILENAME.  FLAG is one of the following
     symbols,

    `regular'
          FILENAME is a file, this includes special files like devices,
          named pipes, etc.

    `directory'
          FILENAME is a directory.

    `invalid-stat'
          An error occurred when calling `stat', so nothing is known.
          STATINFO is `#f' in this case.

    `directory-not-readable'
          FILENAME is a directory, but one which cannot be read and
          hence won't be recursed into.

    `symlink'
          FILENAME is a dangling symbolic link.  Symbolic links are
          normally followed and their target reported, the link itself
          is reported if the target does not exist.

     The return value from `ftw' is `#t' if it ran to completion, or
     otherwise the non-`#t' value from PROC which caused the stop.

     Optional argument symbol `hash-size' and an integer can be given
     to set the size of the hash table used to track items already
     visited.  (see Hash Table Reference)

     In the current implementation, returning non-`#t' from PROC is the
     only valid way to terminate `ftw'.  PROC must not use `throw' or
     similar to escape.

 -- Function: nftw startname proc ['chdir] ['depth] ['hash-size n]
          ['mount] ['physical]
     Walk the filesystem tree starting at STARTNAME, calling PROC for
     each file and directory.  `nftw' has extra features over the basic
     `ftw' described above.

     Hard links and symbolic links are followed, but a file or
     directory is reported to PROC only once, and skipped if seen again
     in another place.  One consequence of this is that `nftw' is safe
     against circular linked directory structures.

     Each PROC call is `(PROC filename statinfo flag basename level)'
     and it should return `#t' to continue, or any other value to stop.

     FILENAME is the item visited, being STARTNAME plus a further path
     and the name of the item.  STATINFO is the return from `stat' on
     FILENAME (see File System).  BASENAME it the item name without
     any path.  LEVEL is an integer giving the directory nesting level,
     starting from 0 for the contents of STARTNAME (or that item itself
     if it's a file).  FLAG is one of the following symbols,

    `regular'
          FILENAME is a file, this includes special files like devices,
          named pipes, etc.

    `directory'
          FILENAME is a directory.

    `directory-processed'
          FILENAME is a directory, and its contents have all been
          visited.  This flag is given instead of `directory' when the
          `depth' option below is used.

    `invalid-stat'
          An error occurred when applying `stat' to FILENAME, so
          nothing is known about it.  STATINFO is `#f' in this case.

    `directory-not-readable'
          FILENAME is a directory, but one which cannot be read and
          hence won't be recursed into.

    `symlink'
          FILENAME is a dangling symbolic link.  Symbolic links are
          normally followed and their target reported, the link itself
          is reported if the target does not exist.

          Under the `physical' option described below, `symlink' is
          instead given for symbolic links whose target does exist.

    `stale-symlink'
          Under the `physical' option described below, this indicates
          FILENAME is a dangling symbolic link, meaning its target does
          not exist.  Without the `physical' option plain `symlink'
          indicates this.

     The following optional arguments can be given to modify the way
     `nftw' works.  Each is passed as a symbol (and `hash-size' takes a
     following integer value).

    `chdir'
          Change to the directory containing the item before calling
          PROC.  When `nftw' returns the original current directory is
          restored.

          Under this option, generally the BASENAME parameter should be
          used to access the item in each PROC call.  The FILENAME
          parameter still has a path as normal and this will only be
          valid if the STARTNAME directory was absolute.

    `depth'
          Visit files "depth first", meaning PROC is called for the
          contents of each directory before it's called for the
          directory itself.  Normally a directory is reported first,
          then its contents.

          Under this option, the FLAG to PROC for a directory is
          `directory-processed' instead of `directory'.

    `hash-size N'
          Set the size of the hash table used to track items already
          visited.  (see Hash Table Reference)

    `mount'
          Don't cross a mount point, meaning only visit items on the
          same filesystem as STARTNAME.  (Ie. the same `stat:dev'.)

    `physical'
          Don't follow symbolic links, instead report them to PROC as
          `symlink', and report dangling links as `stale-symlink'.

     The return value from `nftw' is `#t' if it ran to completion, or
     otherwise the non-`#t' value from PROC which caused the stop.

     In the current implementation, returning non-`#t' from PROC is the
     only valid way to terminate `ftw'.  PROC must not use `throw' or
     similar to escape.

6.10 Queues
===========

The functions in this section are provided by

     (use-modules (ice-9 q))

   This module implements queues holding arbitrary scheme objects and
designed for efficient first-in / first-out operations.

   `make-q' creates a queue, and objects are entered and removed with
`enq!' and `deq!'.  `q-push!'  and `q-pop!' can be used too, treating
the front of the queue like a stack.

 -- Scheme Procedure: make-q
     Return a new queue.

 -- Scheme Procedure: q? obj
     Return `#t' if OBJ is a queue, or `#f' if not.

     Note that queues are not a distinct class of objects but are
     implemented with cons cells.  For that reason certain list
     structures can get `#t' from `q?'.

 -- Scheme Procedure: enq! q obj
     Add OBJ to the rear of Q, and return Q.

 -- Scheme Procedure: deq! q
 -- Scheme Procedure: q-pop! q
     Remove and return the front element from Q.  If Q is empty, a
     `q-empty' exception is thrown.

     `deq!' and `q-pop!' are the same operation, the two names just let
     an application match `enq!' with `deq!', or `q-push!' with
     `q-pop!'.

 -- Scheme Procedure: q-push! q obj
     Add OBJ to the front of Q, and return Q.

 -- Scheme Procedure: q-length q
     Return the number of elements in Q.

 -- Scheme Procedure: q-empty? q
     Return true if Q is empty.

 -- Scheme Procedure: q-empty-check q
     Throw a `q-empty' exception if Q is empty.

 -- Scheme Procedure: q-front q
     Return the first element of Q (without removing it).  If Q is
     empty, a `q-empty' exception is thrown.

 -- Scheme Procedure: q-rear q
     Return the last element of Q (without removing it).  If Q is
     empty, a `q-empty' exception is thrown.

 -- Scheme Procedure: q-remove! q obj
     Remove all occurences of OBJ from Q, and return Q.  OBJ is
     compared to queue elements using `eq?'.

   The `q-empty' exceptions described above are thrown just as `(throw
'q-empty)', there's no message etc like an error throw.

   A queue is implemented as a cons cell, the `car' containing a list
of queued elements, and the `cdr' being the last cell in that list (for
ease of enqueuing).

     (LIST . LAST-CELL)

If the queue is empty, LIST is the empty list and LAST-CELL is `#f'.

   An application can directly access the queue list if desired, for
instance to search the elements or to insert at a specific point.

 -- Scheme Procedure: sync-q! q
     Recompute the LAST-CELL field in Q.

     All the operations above maintain LAST-CELL as described, so
     normally there's no need for `sync-q!'.  But if an application
     modifies the queue LIST then it must either maintain LAST-CELL
     similarly, or call `sync-q!' to recompute it.

6.11 Streams
============

A stream represents a sequence of values, each of which is calculated
only when required.  This allows large or even infinite sequences to be
represented and manipulated with familiar operations like "car", "cdr",
"map" or "fold".  In such manipulations only as much as needed is
actually held in memory at any one time.  The functions in this section
are available from

     (use-modules (ice-9 streams))

   Streams are implemented using promises (see Delayed Evaluation),
which is how the underlying calculation of values is made only when
needed, and the values then retained so the calculation is not repeated.

Here is a simple example producing a stream of all odd numbers,

     (define odds (make-stream (lambda (state)
                                 (cons state (+ state 2)))
                               1))
     (stream-car odds)              => 1
     (stream-car (stream-cdr odds)) => 3

`stream-map' could be used to derive a stream of odd squares,

     (define (square n) (* n n))
     (define oddsquares (stream-map square odds))

   These are infinite sequences, so it's not possible to convert them to
a list, but they could be printed (infinitely) with for example

     (stream-for-each (lambda (n sq)
                        (format #t "~a squared is ~a\n" n sq))
                      odds oddsquares)
     -|
     1 squared is 1
     3 squared is 9
     5 squared is 25
     7 squared is 49
     ...

 -- Function: make-stream proc initial-state
     Return a new stream, formed by calling PROC successively.

     Each call is `(PROC STATE)', it should return a pair, the `car'
     being the value for the stream, and the `cdr' being the new STATE
     for the next call.  For the first call STATE is the given
     INITIAL-STATE.  At the end of the stream, PROC should return some
     non-pair object.

 -- Function: stream-car stream
     Return the first element from STREAM.  STREAM must not be empty.

 -- Function: stream-cdr stream
     Return a stream which is the second and subsequent elements of
     STREAM.  STREAM must not be empty.

 -- Function: stream-null? stream
     Return true if STREAM is empty.

 -- Function: list->stream list
 -- Function: vector->stream vector
     Return a stream with the contents of LIST or VECTOR.

     LIST or VECTOR should not be modified subsequently, since it's
     unspecified whether changes there will be reflected in the stream
     returned.

 -- Function: port->stream port readproc
     Return a stream which is the values obtained by reading from PORT
     using READPROC.  Each read call is `(READPROC PORT)', and it
     should return an EOF object (see Reading) at the end of input.

     For example a stream of characters from a file,

          (port->stream (open-input-file "/foo/bar.txt") read-char)

 -- Function: stream->list stream
     Return a list which is the entire contents of STREAM.

 -- Function: stream->reversed-list stream
     Return a list which is the entire contents of STREAM, but in
     reverse order.

 -- Function: stream->list&length stream
     Return two values (see Multiple Values), being firstly a list
     which is the entire contents of STREAM, and secondly the number of
     elements in that list.

 -- Function: stream->reversed-list&length stream
     Return two values (see Multiple Values) being firstly a list
     which is the entire contents of STREAM, but in reverse order, and
     secondly the number of elements in that list.

 -- Function: stream->vector stream
     Return a vector which is the entire contents of STREAM.

 -- Function: stream-fold proc init stream0 ... streamN
     Apply PROC successively over the elements of the given streams,
     from first to last until the end of the shortest stream is reached.
     Return the result from the last PROC call.

     Each call is `(PROC elem0 ... elemN prev)', where each ELEM is
     from the corresponding STREAM.  PREV is the return from the
     previous PROC call, or the given INIT for the first call.

 -- Function: stream-for-each proc stream0 ... streamN
     Call PROC on the elements from the given STREAMs.  The return
     value is unspecified.

     Each call is `(PROC elem0 ... elemN)', where each ELEM is from the
     corresponding STREAM.  `stream-for-each' stops when it reaches the
     end of the shortest STREAM.

 -- Function: stream-map proc stream0 ... streamN
     Return a new stream which is the results of applying PROC to the
     elements of the given STREAMs.

     Each call is `(PROC elem0 ... elemN)', where each ELEM is from the
     corresponding STREAM.  The new stream ends when the end of the
     shortest given STREAM is reached.

6.12 Expect
===========

The macros in this section are made available with:

     (use-modules (ice-9 expect))

   `expect' is a macro for selecting actions based on the output from a
port.  The name comes from a tool of similar functionality by Don Libes.
Actions can be taken when a particular string is matched, when a timeout
occurs, or when end-of-file is seen on the port.  The `expect' macro is
described below; `expect-strings' is a front-end to `expect' based on
regexec (see the regular expression documentation).

 -- Macro: expect-strings clause ...
     By default, `expect-strings' will read from the current input port.
     The first term in each clause consists of an expression evaluating
     to a string pattern (regular expression).  As characters are read
     one-by-one from the port, they are accumulated in a buffer string
     which is matched against each of the patterns.  When a pattern
     matches, the remaining expression(s) in the clause are evaluated
     and the value of the last is returned.  For example:

          (with-input-from-file "/etc/passwd"
            (lambda ()
              (expect-strings
                ("^nobody" (display "Got a nobody user.\n")
                           (display "That's no problem.\n"))
                ("^daemon" (display "Got a daemon user.\n")))))

     The regular expression is compiled with the `REG_NEWLINE' flag, so
     that the ^ and $ anchors will match at any newline, not just at
     the start and end of the string.

     There are two other ways to write a clause:

     The expression(s) to evaluate can be omitted, in which case the
     result of the regular expression match (converted to strings, as
     obtained from regexec with match-pick set to "") will be returned
     if the pattern matches.

     The symbol `=>' can be used to indicate that the expression is a
     procedure which will accept the result of a successful regular
     expression match.  E.g.,

          ("^daemon" => write)
          ("^d(aemon)" => (lambda args (for-each write args)))
          ("^da(em)on" => (lambda (all sub)
                            (write all) (newline)
                            (write sub) (newline)))

     The order of the substrings corresponds to the order in which the
     opening brackets occur.

     A number of variables can be used to control the behaviour of
     `expect' (and `expect-strings').  Most have default top-level
     bindings to the value `#f', which produces the default behaviour.
     They can be redefined at the top level or locally bound in a form
     enclosing the expect expression.

    `expect-port'
          A port to read characters from, instead of the current input
          port.

    `expect-timeout'
          `expect' will terminate after this number of seconds,
          returning `#f' or the value returned by expect-timeout-proc.

    `expect-timeout-proc'
          A procedure called if timeout occurs.  The procedure takes a
          single argument: the accumulated string.

    `expect-eof-proc'
          A procedure called if end-of-file is detected on the input
          port.  The procedure takes a single argument: the accumulated
          string.

    `expect-char-proc'
          A procedure to be called every time a character is read from
          the port.  The procedure takes a single argument: the
          character which was read.

    `expect-strings-compile-flags'
          Flags to be used when compiling a regular expression, which
          are passed to `make-regexp' Regexp Functions.  The
          default value is `regexp/newline'.

    `expect-strings-exec-flags'
          Flags to be used when executing a regular expression, which
          are passed to regexp-exec Regexp Functions.  The
          default value is `regexp/noteol', which prevents `$' from
          matching the end of the string while it is still accumulating,
          but still allows it to match after a line break or at the end
          of file.

     Here's an example using all of the variables:

          (let ((expect-port (open-input-file "/etc/passwd"))
                (expect-timeout 1)
                (expect-timeout-proc
                  (lambda (s) (display "Times up!\n")))
                (expect-eof-proc
                  (lambda (s) (display "Reached the end of the file!\n")))
                (expect-char-proc display)
                (expect-strings-compile-flags (logior regexp/newline regexp/icase))
                (expect-strings-exec-flags 0))
             (expect-strings
               ("^nobody"  (display "Got a nobody user\n"))))

 -- Macro: expect clause ...
     `expect' is used in the same way as `expect-strings', but tests
     are specified not as patterns, but as procedures.  The procedures
     are called in turn after each character is read from the port,
     with two arguments: the value of the accumulated string and a flag
     to indicate whether end-of-file has been reached.  The flag will
     usually be `#f', but if end-of-file is reached, the procedures are
     called an additional time with the final accumulated string and
     `#t'.

     The test is successful if the procedure returns a non-false value.

     If the `=>' syntax is used, then if the test succeeds it must
     return a list containing the arguments to be provided to the
     corresponding expression.

     In the following example, a string will only be matched at the
     beginning of the file:

          (let ((expect-port (open-input-file "/etc/passwd")))
            (expect
               ((lambda (s eof?) (string=? s "fnord!"))
                  (display "Got a nobody user!\n"))))

     The control variables described for `expect-strings' also
     influence the behaviour of `expect', with the exception of
     variables whose names begin with `expect-strings-'.

6.13 The Scheme shell (scsh)
============================

An incomplete port of the Scheme shell (scsh) is available for Guile as
a separate package.  The current status of guile-scsh can be found at
`http://arglist.com/guile/'.

   For information about scsh see `http://www.scsh.net/'.

   The closest emulation of scsh can be obtained by running:

     (load-from-path "scsh/init")

   See the USAGE file supplied with guile-scsh for more details.

Appendix A Data Representation in Guile
***************************************

*by Jim Blandy*

   [Due to the rather non-orthogonal and performance-oriented nature of
the SCM interface, you need to understand SCM internals *before* you
can use the SCM API.  That's why this chapter comes first.]

   [NOTE: this is Jim Blandy's essay almost entirely unmodified.  It
has to be adapted to fit this manual smoothly.]

   In order to make sense of Guile's SCM_ functions, or read libguile's
source code, it's essential to have a good grasp of how Guile actually
represents Scheme values.  Otherwise, a lot of the code, and the
conventions it follows, won't make very much sense.  This essay is meant
to provide the background necessary to read and write C code that
manipulates Scheme values in a way that is compatible with libguile.

   We assume you know both C and Scheme, but we do not assume you are
familiar with Guile's implementation.

A.1 Data Representation in Scheme
=================================

Scheme is a latently-typed language; this means that the system cannot,
in general, determine the type of a given expression at compile time.
Types only become apparent at run time.  Variables do not have fixed
types; a variable may hold a pair at one point, an integer at the next,
and a thousand-element vector later.  Instead, values, not variables,
have fixed types.

   In order to implement standard Scheme functions like `pair?' and
`string?' and provide garbage collection, the representation of every
value must contain enough information to accurately determine its type
at run time.  Often, Scheme systems also use this information to
determine whether a program has attempted to apply an operation to an
inappropriately typed value (such as taking the `car' of a string).

   Because variables, pairs, and vectors may hold values of any type,
Scheme implementations use a uniform representation for values -- a
single type large enough to hold either a complete value or a pointer
to a complete value, along with the necessary typing information.

   The following sections will present a simple typing system, and then
make some refinements to correct its major weaknesses.  However, this is
not a description of the system Guile actually uses.  It is only an
illustration of the issues Guile's system must address.  We provide all
the information one needs to work with Guile's data in How Guile does it.

A.1.1 A Simple Representation
-----------------------------

The simplest way to meet the above requirements in C would be to
represent each value as a pointer to a structure containing a type
indicator, followed by a union carrying the real value.  Assuming that
`SCM' is the name of our universal type, we can write:

     enum type { integer, pair, string, vector, ... };

     typedef struct value *SCM;

     struct value {
       enum type type;
       union {
         int integer;
         struct { SCM car, cdr; } pair;
         struct { int length; char *elts; } string;
         struct { int length; SCM  *elts; } vector;
         ...
       } value;
     };
   with the ellipses replaced with code for the remaining Scheme types.

   This representation is sufficient to implement all of Scheme's
semantics.  If X is an `SCM' value:
   *   To test if X is an integer, we can write `X->type == integer'.

   *   To find its value, we can write `X->value.integer'.

   *   To test if X is a vector, we can write `X->type == vector'.

   *   If we know X is a vector, we can write
     `X->value.vector.elts[0]' to refer to its first element.

   *   If we know X is a pair, we can write   `X->value.pair.car' to
     extract its car.

A.1.2 Faster Integers
---------------------

Unfortunately, the above representation has a serious disadvantage.  In
order to return an integer, an expression must allocate a `struct
value', initialize it to represent that integer, and return a pointer to
it.  Furthermore, fetching an integer's value requires a memory
reference, which is much slower than a register reference on most
processors.  Since integers are extremely common, this representation is
too costly, in both time and space.  Integers should be very cheap to
create and manipulate.

   One possible solution comes from the observation that, on many
architectures, structures must be aligned on a four-byte boundary.
(Whether or not the machine actually requires it, we can write our own
allocator for `struct value' objects that assures this is true.)  In
this case, the lower two bits of the structure's address are known to
be zero.

   This gives us the room we need to provide an improved representation
for integers.  We make the following rules:
   * If the lower two bits of an `SCM' value are zero, then the SCM
     value is a pointer to a `struct value', and everything proceeds as
     before.

   * Otherwise, the `SCM' value represents an integer, whose value
     appears in its upper bits.

   Here is C code implementing this convention:
     enum type { pair, string, vector, ... };

     typedef struct value *SCM;

     struct value {
       enum type type;
       union {
         struct { SCM car, cdr; } pair;
         struct { int length; char *elts; } string;
         struct { int length; SCM  *elts; } vector;
         ...
       } value;
     };

     #define POINTER_P(x) (((int) (x) & 3) == 0)
     #define INTEGER_P(x) (! POINTER_P (x))

     #define GET_INTEGER(x)  ((int) (x) >> 2)
     #define MAKE_INTEGER(x) ((SCM) (((x) << 2) | 1))

   Notice that `integer' no longer appears as an element of `enum
type', and the union has lost its `integer' member.  Instead, we use
the `POINTER_P' and `INTEGER_P' macros to make a coarse classification
of values into integers and non-integers, and do further type testing
as before.

   Here's how we would answer the questions posed above (again, assume
X is an `SCM' value):
   *   To test if X is an integer, we can write `INTEGER_P (X)'.

   *   To find its value, we can write `GET_INTEGER (X)'.

   *   To test if X is a vector, we can write:
            `POINTER_P (X) && X->type == vector'
       Given the new representation, we must make sure X is truly a
     pointer before we dereference it to determine its complete type.

   *   If we know X is a vector, we can write
     `X->value.vector.elts[0]' to refer to its first element, as
     before.

   *   If we know X is a pair, we can write   `X->value.pair.car' to
     extract its car, just as before.

   This representation allows us to operate more efficiently on integers
than the first.  For example, if X and Y are known to be integers, we
can compute their sum as follows:
     MAKE_INTEGER (GET_INTEGER (X) + GET_INTEGER (Y))
   Now, integer math requires no allocation or memory references.  Most
real Scheme systems actually use an even more efficient representation,
but this essay isn't about bit-twiddling.  (Hint: what if pointers had
`01' in their least significant bits, and integers had `00'?)

A.1.3 Cheaper Pairs
-------------------

However, there is yet another issue to confront.  Most Scheme heaps
contain more pairs than any other type of object; Jonathan Rees says
that pairs occupy 45% of the heap in his Scheme implementation, Scheme
48.  However, our representation above spends three `SCM'-sized words
per pair -- one for the type, and two for the CAR and CDR.  Is there
any way to represent pairs using only two words?

   Let us refine the convention we established earlier.  Let us assert
that:
   *   If the bottom two bits of an `SCM' value are `#b00', then   it
     is a pointer, as before.

   *   If the bottom two bits are `#b01', then the upper bits are an
     integer.  This is a bit more restrictive than before.

   *   If the bottom two bits are `#b10', then the value, with the
     bottom   two bits masked out, is the address of a pair.

   Here is the new C code:
     enum type { string, vector, ... };

     typedef struct value *SCM;

     struct value {
       enum type type;
       union {
         struct { int length; char *elts; } string;
         struct { int length; SCM  *elts; } vector;
         ...
       } value;
     };

     struct pair {
       SCM car, cdr;
     };

     #define POINTER_P(x) (((int) (x) & 3) == 0)

     #define INTEGER_P(x)  (((int) (x) & 3) == 1)
     #define GET_INTEGER(x)  ((int) (x) >> 2)
     #define MAKE_INTEGER(x) ((SCM) (((x) << 2) | 1))

     #define PAIR_P(x) (((int) (x) & 3) == 2)
     #define GET_PAIR(x) ((struct pair *) ((int) (x) & ~3))

   Notice that `enum type' and `struct value' now only contain
provisions for vectors and strings; both integers and pairs have become
special cases.  The code above also assumes that an `int' is large
enough to hold a pointer, which isn't generally true.

   Our list of examples is now as follows:
   *   To test if X is an integer, we can write `INTEGER_P   (X)'; this
     is as before.

   *   To find its value, we can write `GET_INTEGER (X)', as   before.

   *   To test if X is a vector, we can write:
            `POINTER_P (X) && X->type == vector'
       We must still make sure that X is a pointer to a `struct
     value' before dereferencing it to find its type.

   *   If we know X is a vector, we can write
     `X->value.vector.elts[0]' to refer to its first element, as
     before.

   *   We can write `PAIR_P (X)' to determine if X is a   pair, and
     then write `GET_PAIR (X)->car' to refer to its   car.

   This change in representation reduces our heap size by 15%.  It also
makes it cheaper to decide if a value is a pair, because no memory
references are necessary; it suffices to check the bottom two bits of
the `SCM' value.  This may be significant when traversing lists, a
common activity in a Scheme system.

   Again, most real Scheme systems use a slightly different
implementation; for example, if GET_PAIR subtracts off the low bits of
`x', instead of masking them off, the optimizer will often be able to
combine that subtraction with the addition of the offset of the
structure member we are referencing, making a modified pointer as fast
to use as an unmodified pointer.

A.1.4 Guile Is Hairier
----------------------

We originally started with a very simple typing system -- each object
has a field that indicates its type.  Then, for the sake of efficiency
in both time and space, we moved some of the typing information directly
into the `SCM' value, and left the rest in the `struct value'.  Guile
itself employs a more complex hierarchy, storing finer and finer
gradations of type information in different places, depending on the
object's coarser type.

   In the author's opinion, Guile could be simplified greatly without
significant loss of efficiency, but the simplified system would still be
more complex than what we've presented above.

A.2 How Guile does it
=====================

Here we present the specifics of how Guile represents its data.  We
don't go into complete detail; an exhaustive description of Guile's
system would be boring, and we do not wish to encourage people to write
code which depends on its details anyway.  We do, however, present
everything one need know to use Guile's data.

   This section is in limbo.  It used to document the 'low-level' C API
of Guile that was used both by clients of libguile and by libguile
itself.

   In the future, clients should only need to look into the sections
Programming in C and API Reference.  This section will
in the end only contain stuff about the internals of Guile.

A.2.1 General Rules
-------------------

Any code which operates on Guile datatypes must `#include' the header
file `<libguile.h>'.  This file contains a definition for the `SCM'
typedef (Guile's universal type, as in the examples above), and
definitions and declarations for a host of macros and functions that
operate on `SCM' values.

   All identifiers declared by `<libguile.h>' begin with `scm_' or
`SCM_'.

   The functions described here generally check the types of their
`SCM' arguments, and signal an error if their arguments are of an
inappropriate type.  Macros generally do not, unless that is their
specified purpose.  You must verify their argument types beforehand, as
necessary.

   Macros and functions that return a boolean value have names ending in
`P' or `_p' (for "predicate").  Those that return a negated boolean
value have names starting with `SCM_N'.  For example, `SCM_IMP (X)' is
a predicate which returns non-zero iff X is an immediate value (an
`IM').  `SCM_NCONSP (X)' is a predicate which returns non-zero iff X is
_not_ a pair object (a `CONS').

A.2.2 Conservative Garbage Collection
-------------------------------------

Aside from the latent typing, the major source of constraints on a
Scheme implementation's data representation is the garbage collector.
The collector must be able to traverse every live object in the heap, to
determine which objects are not live.

   There are many ways to implement this, but Guile uses an algorithm
called "mark and sweep".  The collector scans the system's global
variables and the local variables on the stack to determine which
objects are immediately accessible by the C code.  It then scans those
objects to find the objects they point to, et cetera.  The collector
sets a "mark bit" on each object it finds, so each object is traversed
only once.  This process is called "tracing".

   When the collector can find no unmarked objects pointed to by marked
objects, it assumes that any objects that are still unmarked will never
be used by the program (since there is no path of dereferences from any
global or local variable that reaches them) and deallocates them.

   In the above paragraphs, we did not specify how the garbage collector
finds the global and local variables; as usual, there are many different
approaches.  Frequently, the programmer must maintain a list of pointers
to all global variables that refer to the heap, and another list
(adjusted upon entry to and exit from each function) of local variables,
for the collector's benefit.

   The list of global variables is usually not too difficult to
maintain, since global variables are relatively rare.  However, an
explicitly maintained list of local variables (in the author's personal
experience) is a nightmare to maintain.  Thus, Guile uses a technique
called "conservative garbage collection", to make the local variable
list unnecessary.

   The trick to conservative collection is to treat the stack as an
ordinary range of memory, and assume that _every_ word on the stack is
a pointer into the heap.  Thus, the collector marks all objects whose
addresses appear anywhere in the stack, without knowing for sure how
that word is meant to be interpreted.

   Obviously, such a system will occasionally retain objects that are
actually garbage, and should be freed.  In practice, this is not a
problem.  The alternative, an explicitly maintained list of local
variable addresses, is effectively much less reliable, due to programmer
error.

   To accommodate this technique, data must be represented so that the
collector can accurately determine whether a given stack word is a
pointer or not.  Guile does this as follows:

   * Every heap object has a two-word header, called a "cell".  Some
     objects, like pairs, fit entirely in a cell's two words; others may
     store pointers to additional memory in either of the words.  For
     example, strings and vectors store their length in the first word,
     and a pointer to their elements in the second.

   * Guile allocates whole arrays of cells at a time, called "heap
     segments".  These segments are always allocated so that the cells
     they contain fall on eight-byte boundaries, or whatever is
     appropriate for the machine's word size.  Guile keeps all cells in
     a heap segment initialized, whether or not they are currently in
     use.

   * Guile maintains a sorted table of heap segments.

   Thus, given any random word W fetched from the stack, Guile's
garbage collector can consult the table to see if W falls within a
known heap segment, and check W's alignment.  If both tests pass, the
collector knows that W is a valid pointer to a cell, intentional or
not, and proceeds to trace the cell.

   Note that heap segments do not contain all the data Guile uses; cells
for objects like vectors and strings contain pointers to other memory
areas.  However, since those pointers are internal, and not shared among
many pieces of code, it is enough for the collector to find the cell,
and then use the cell's type to find more pointers to trace.

A.2.3 Immediates vs Non-immediates
----------------------------------

Guile classifies Scheme objects into two kinds: those that fit entirely
within an `SCM', and those that require heap storage.

   The former class are called "immediates".  The class of immediates
includes small integers, characters, boolean values, the empty list, the
mysterious end-of-file object, and some others.

   The remaining types are called, not surprisingly, "non-immediates".
They include pairs, procedures, strings, vectors, and all other data
types in Guile.

 -- Macro: int SCM_IMP (SCM X)
     Return non-zero iff X is an immediate object.

 -- Macro: int SCM_NIMP (SCM X)
     Return non-zero iff X is a non-immediate object.  This is the
     exact complement of `SCM_IMP', above.

   Note that for versions of Guile prior to 1.4 it was necessary to use
the `SCM_NIMP' macro before calling a finer-grained predicate to
determine X's type, such as `SCM_CONSP' or `SCM_VECTORP'.  This is no
longer required: the definitions of all Guile type predicates now
include a call to `SCM_NIMP' where necessary.

A.2.4 Immediate Datatypes
-------------------------

The following datatypes are immediate values; that is, they fit entirely
within an `SCM' value.  The `SCM_IMP' and `SCM_NIMP' macros will
distinguish these from non-immediates; see Immediates vs Non-immediates
for an explanation of the distinction.

   Note that the type predicates for immediate values work correctly on
any `SCM' value; you do not need to call `SCM_IMP' first, to establish
that a value is immediate.

A.2.4.1 Integers
................

Here are functions for operating on small integers, that fit within an
`SCM'.  Such integers are called "immediate numbers", or "INUMs".  In
general, INUMs occupy all but two bits of an `SCM'.

   Bignums and floating-point numbers are non-immediate objects, and
have their own, separate accessors.  The functions here will not work on
them.  This is not as much of a problem as you might think, however,
because the system never constructs bignums that could fit in an INUM,
and never uses floating point values for exact integers.

 -- Macro: int SCM_INUMP (SCM X)
     Return non-zero iff X is a small integer value.

 -- Macro: int SCM_NINUMP (SCM X)
     The complement of SCM_INUMP.

 -- Macro: int SCM_INUM (SCM X)
     Return the value of X as an ordinary, C integer.  If X is not an
     INUM, the result is undefined.

 -- Macro: SCM SCM_MAKINUM (int I)
     Given a C integer I, return its representation as an `SCM'.  This
     function does not check for overflow.

A.2.4.2 Characters
..................

Here are functions for operating on characters.

 -- Macro: int SCM_CHARP (SCM X)
     Return non-zero iff X is a character value.

 -- Macro: unsigned int SCM_CHAR (SCM X)
     Return the value of `x' as a C character.  If X is not a Scheme
     character, the result is undefined.

 -- Macro: SCM SCM_MAKE_CHAR (int C)
     Given a C character C, return its representation as a Scheme
     character value.

A.2.4.3 Booleans
................

Booleans are represented as two specific immediate SCM values,
`SCM_BOOL_T' and `SCM_BOOL_F'.  See Booleans, for more information.

A.2.4.4 Unique Values
.....................

The immediate values that are neither small integers, characters, nor
booleans are all unique values -- that is, datatypes with only one
instance.

 -- Macro: SCM SCM_EOL
     The Scheme empty list object, or "End Of List" object, usually
     written in Scheme as `'()'.

 -- Macro: SCM SCM_EOF_VAL
     The Scheme end-of-file value.  It has no standard written
     representation, for obvious reasons.

 -- Macro: SCM SCM_UNSPECIFIED
     The value returned by expressions which the Scheme standard says
     return an "unspecified" value.

     This is sort of a weirdly literal way to take things, but the
     standard read-eval-print loop prints nothing when the expression
     returns this value, so it's not a bad idea to return this when you
     can't think of anything else helpful.

 -- Macro: SCM SCM_UNDEFINED
     The "undefined" value.  Its most important property is that is not
     equal to any valid Scheme value.  This is put to various internal
     uses by C code interacting with Guile.

     For example, when you write a C function that is callable from
     Scheme and which takes optional arguments, the interpreter passes
     `SCM_UNDEFINED' for any arguments you did not receive.

     We also use this to mark unbound variables.

 -- Macro: int SCM_UNBNDP (SCM X)
     Return true if X is `SCM_UNDEFINED'.  Apply this to a symbol's
     value to see if it has a binding as a global variable.

A.2.5 Non-immediate Datatypes
-----------------------------

A non-immediate datatype is one which lives in the heap, either because
it cannot fit entirely within a `SCM' word, or because it denotes a
specific storage location (in the nomenclature of the Revised^5 Report
on Scheme).

   The `SCM_IMP' and `SCM_NIMP' macros will distinguish these from
immediates; see Immediates vs Non-immediates.

   Given a cell, Guile distinguishes between pairs and other
non-immediate types by storing special "tag" values in a non-pair
cell's car, that cannot appear in normal pairs.  A cell with a non-tag
value in its car is an ordinary pair.  The type of a cell with a tag in
its car depends on the tag; the non-immediate type predicates test this
value.  If a tag value appears elsewhere (in a vector, for example),
the heap may become corrupted.

   Note how the type information for a non-immediate object is split
between the `SCM' word and the cell that the `SCM' word points to.  The
`SCM' word itself only indicates that the object is non-immediate -- in
other words stored in a heap cell.  The tag stored in the first word of
the heap cell indicates more precisely the type of that object.

   The type predicates for non-immediate values work correctly on any
`SCM' value; you do not need to call `SCM_NIMP' first, to establish
that a value is non-immediate.

A.2.5.1 Pairs
.............

Pairs are the essential building block of list structure in Scheme.  A
pair object has two fields, called the "car" and the "cdr".

   It is conventional for a pair's CAR to contain an element of a list,
and the CDR to point to the next pair in the list, or to contain
`SCM_EOL', indicating the end of the list.  Thus, a set of pairs
chained through their CDRs constitutes a singly-linked list.  Scheme
and libguile define many functions which operate on lists constructed
in this fashion, so although lists chained through the CARs of pairs
will work fine too, they may be less convenient to manipulate, and
receive less support from the community.

   Guile implements pairs by mapping the CAR and CDR of a pair directly
into the two words of the cell.

 -- Macro: int SCM_CONSP (SCM X)
     Return non-zero iff X is a Scheme pair object.

 -- Macro: int SCM_NCONSP (SCM X)
     The complement of SCM_CONSP.

 -- Function: SCM scm_cons (SCM CAR, SCM CDR)
     Allocate ("CONStruct") a new pair, with CAR and CDR as its
     contents.

   The macros below perform no type checking.  The results are
undefined if CELL is an immediate.  However, since all non-immediate
Guile objects are constructed from cells, and these macros simply
return the first element of a cell, they actually can be useful on
datatypes other than pairs.  (Of course, it is not very modular to use
them outside of the code which implements that datatype.)

 -- Macro: SCM SCM_CAR (SCM CELL)
     Return the CAR, or first field, of CELL.

 -- Macro: SCM SCM_CDR (SCM CELL)
     Return the CDR, or second field, of CELL.

 -- Macro: void SCM_SETCAR (SCM CELL, SCM X)
     Set the CAR of CELL to X.

 -- Macro: void SCM_SETCDR (SCM CELL, SCM X)
     Set the CDR of CELL to X.

 -- Macro: SCM SCM_CAAR (SCM CELL)
 -- Macro: SCM SCM_CADR (SCM CELL)
 -- Macro: SCM SCM_CDAR (SCM CELL) ...
 -- Macro: SCM SCM_CDDDDR (SCM CELL)
     Return the CAR of the CAR of CELL, the CAR of the CDR of CELL, et
     cetera.

A.2.5.2 Vectors, Strings, and Symbols
.....................................

Vectors, strings, and symbols have some properties in common.  They all
have a length, and they all have an array of elements.  In the case of a
vector, the elements are `SCM' values; in the case of a string or
symbol, the elements are characters.

   All these types store their length (along with some tagging bits) in
the CAR of their header cell, and store a pointer to the elements in
their CDR.  Thus, the `SCM_CAR' and `SCM_CDR' macros are (somewhat)
meaningful when applied to these datatypes.

 -- Macro: int SCM_VECTORP (SCM X)
     Return non-zero iff X is a vector.

 -- Macro: int SCM_STRINGP (SCM X)
     Return non-zero iff X is a string.

 -- Macro: int SCM_SYMBOLP (SCM X)
     Return non-zero iff X is a symbol.

 -- Macro: int SCM_VECTOR_LENGTH (SCM X)
 -- Macro: int SCM_STRING_LENGTH (SCM X)
 -- Macro: int SCM_SYMBOL_LENGTH (SCM X)
     Return the length of the object X.  The result is undefined if X
     is not a vector, string, or symbol, respectively.

 -- Macro: SCM * SCM_VECTOR_BASE (SCM X)
     Return a pointer to the array of elements of the vector X.  The
     result is undefined if X is not a vector.

 -- Macro: char * SCM_STRING_CHARS (SCM X)
 -- Macro: char * SCM_SYMBOL_CHARS (SCM X)
     Return a pointer to the characters of X.  The result is undefined
     if X is not a symbol or string, respectively.

   There are also a few magic values stuffed into memory before a
symbol's characters, but you don't want to know about those.  What
cruft!

   Note that `SCM_VECTOR_BASE', `SCM_STRING_CHARS' and
`SCM_SYMBOL_CHARS' return pointers to data within the respective
object.  Care must be taken that the object is not garbage collected
while that data is still being accessed.  This is the same as for a
smob, see Remembering During Operations.

A.2.5.3 Procedures
..................

Guile provides two kinds of procedures: "closures", which are the
result of evaluating a `lambda' expression, and "subrs", which are C
functions packaged up as Scheme objects, to make them available to
Scheme programmers.

   (There are actually other sorts of procedures: compiled closures, and
continuations; see the source code for details about them.)

 -- Function: SCM scm_procedure_p (SCM X)
     Return `SCM_BOOL_T' iff X is a Scheme procedure object, of any
     sort.  Otherwise, return `SCM_BOOL_F'.

A.2.5.4 Closures
................

[FIXME: this needs to be further subbed, but texinfo has no subsubsub]

   A closure is a procedure object, generated as the value of a
`lambda' expression in Scheme.  The representation of a closure is
straightforward -- it contains a pointer to the code of the lambda
expression from which it was created, and a pointer to the environment
it closes over.

   In Guile, each closure also has a property list, allowing the system
to store information about the closure.  I'm not sure what this is used
for at the moment -- the debugger, maybe?

 -- Macro: int SCM_CLOSUREP (SCM X)
     Return non-zero iff X is a closure.

 -- Macro: SCM SCM_PROCPROPS (SCM X)
     Return the property list of the closure X.  The results are
     undefined if X is not a closure.

 -- Macro: void SCM_SETPROCPROPS (SCM X, SCM P)
     Set the property list of the closure X to P.  The results are
     undefined if X is not a closure.

 -- Macro: SCM SCM_CODE (SCM X)
     Return the code of the closure X.  The result is undefined if X is
     not a closure.

     This function should probably only be used internally by the
     interpreter, since the representation of the code is intimately
     connected with the interpreter's implementation.

 -- Macro: SCM SCM_ENV (SCM X)
     Return the environment enclosed by X.  The result is undefined if
     X is not a closure.

     This function should probably only be used internally by the
     interpreter, since the representation of the environment is
     intimately connected with the interpreter's implementation.

A.2.5.5 Subrs
.............

[FIXME: this needs to be further subbed, but texinfo has no subsubsub]

   A subr is a pointer to a C function, packaged up as a Scheme object
to make it callable by Scheme code.  In addition to the function
pointer, the subr also contains a pointer to the name of the function,
and information about the number of arguments accepted by the C
function, for the sake of error checking.

   There is no single type predicate macro that recognizes subrs, as
distinct from other kinds of procedures.  The closest thing is
`scm_procedure_p'; see Procedures.

 -- Macro: char * SCM_SNAME (X)
     Return the name of the subr X.  The result is undefined if X is
     not a subr.

 -- Function: SCM scm_c_define_gsubr (char *NAME, int REQ, int OPT, int
          REST, SCM (*FUNCTION)())
     Create a new subr object named NAME, based on the C function
     FUNCTION, make it visible to Scheme the value of as a global
     variable named NAME, and return the subr object.

     The subr object accepts REQ required arguments, OPT optional
     arguments, and a REST argument iff REST is non-zero.  The C
     function FUNCTION should accept `REQ + OPT' arguments, or `REQ +
     OPT + 1' arguments if `rest' is non-zero.

     When a subr object is applied, it must be applied to at least REQ
     arguments, or else Guile signals an error.  FUNCTION receives the
     subr's first REQ arguments as its first REQ arguments.  If there
     are fewer than OPT arguments remaining, then FUNCTION receives the
     value `SCM_UNDEFINED' for any missing optional arguments.

     If RST is non-zero, then any arguments after the first `REQ + OPT'
     are packaged up as a list and passed as FUNCTION's last argument.
     FUNCTION must not modify that list.  (Because when subr is called
     through `apply' the list is directly from the `apply' argument,
     which the caller will expect to be unchanged.)

     Note that subrs can actually only accept a predefined set of
     combinations of required, optional, and rest arguments.  For
     example, a subr can take one required argument, or one required
     and one optional argument, but a subr can't take one required and
     two optional arguments.  It's bizarre, but that's the way the
     interpreter was written.  If the arguments to `scm_c_define_gsubr'
     do not fit one of the predefined patterns, then
     `scm_c_define_gsubr' will return a compiled closure object instead
     of a subr object.

A.2.5.6 Ports
.............

Haven't written this yet, 'cos I don't understand ports yet.

A.2.6 Signalling Type Errors
----------------------------

Every function visible at the Scheme level should aggressively check the
types of its arguments, to avoid misinterpreting a value, and perhaps
causing a segmentation fault.  Guile provides some macros to make this
easier.

 -- Macro: void SCM_ASSERT (int TEST, SCM OBJ, unsigned int POSITION,
          const char *SUBR)
     If TEST is zero, signal a "wrong type argument" error, attributed
     to the subroutine named SUBR, operating on the value OBJ, which is
     the POSITION'th argument of SUBR.

 -- Macro: int SCM_ARG1
 -- Macro: int SCM_ARG2
 -- Macro: int SCM_ARG3
 -- Macro: int SCM_ARG4
 -- Macro: int SCM_ARG5
 -- Macro: int SCM_ARG6
 -- Macro: int SCM_ARG7
     One of the above values can be used for POSITION to indicate the
     number of the argument of SUBR which is being checked.
     Alternatively, a positive integer number can be used, which allows
     to check arguments after the seventh.  However, for parameter
     numbers up to seven it is preferable to use `SCM_ARGN' instead of
     the corresponding raw number, since it will make the code easier to
     understand.

 -- Macro: int SCM_ARGn
     Passing a value of zero or `SCM_ARGn' for POSITION allows to leave
     it unspecified which argument's type is incorrect.  Again,
     `SCM_ARGn' should be preferred over a raw zero constant.

A.2.7 Unpacking the SCM Type
----------------------------

The previous sections have explained how `SCM' values can refer to
immediate and non-immediate Scheme objects.  For immediate objects, the
complete object value is stored in the `SCM' word itself, while for
non-immediates, the `SCM' word contains a pointer to a heap cell, and
further information about the object in question is stored in that
cell.  This section describes how the `SCM' type is actually
represented and used at the C level.

   In fact, there are two basic C data types to represent objects in
Guile: `SCM' and `scm_t_bits'.

A.2.7.1 Relationship between `SCM' and `scm_t_bits'
...................................................

A variable of type `SCM' is guaranteed to hold a valid Scheme object.
A variable of type `scm_t_bits', on the other hand, may hold a
representation of a `SCM' value as a C integral type, but may also hold
any C value, even if it does not correspond to a valid Scheme object.

   For a variable X of type `SCM', the Scheme object's type information
is stored in a form that is not directly usable.  To be able to work on
the type encoding of the scheme value, the `SCM' variable has to be
transformed into the corresponding representation as a `scm_t_bits'
variable Y by using the `SCM_UNPACK' macro.  Once this has been done,
the type of the scheme object X can be derived from the content of the
bits of the `scm_t_bits' value Y, in the way illustrated by the example
earlier in this chapter (see Cheaper Pairs).  Conversely, a valid
bit encoding of a Scheme value as a `scm_t_bits' variable can be
transformed into the corresponding `SCM' value using the `SCM_PACK'
macro.

A.2.7.2 Immediate objects
.........................

A Scheme object may either be an immediate, i.e. carrying all necessary
information by itself, or it may contain a reference to a "cell" with
additional information on the heap.  Although in general it should be
irrelevant for user code whether an object is an immediate or not,
within Guile's own code the distinction is sometimes of importance.
Thus, the following low level macro is provided:

 -- Macro: int SCM_IMP (SCM X)
     A Scheme object is an immediate if it fulfills the `SCM_IMP'
     predicate, otherwise it holds an encoded reference to a heap cell.
     The result of the predicate is delivered as a C style boolean
     value.  User code and code that extends Guile should normally not
     be required to use this macro.

Summary:
   * Given a Scheme object X of unknown type, check first with `SCM_IMP
     (X)' if it is an immediate object.

   * If so, all of the type and value information can be determined
     from the `scm_t_bits' value that is delivered by `SCM_UNPACK (X)'.

A.2.7.3 Non-immediate objects
.............................

A Scheme object of type `SCM' that does not fulfill the `SCM_IMP'
predicate holds an encoded reference to a heap cell.  This reference
can be decoded to a C pointer to a heap cell using the `SCM2PTR' macro.
The encoding of a pointer to a heap cell into a `SCM' value is done
using the `PTR2SCM' macro.

 -- Macro: ( scm_t_cell *) SCM2PTR (SCM X)
     Extract and return the heap cell pointer from a non-immediate `SCM'
     object X.

 -- Macro: SCM PTR2SCM (scm_t_cell * X)
     Return a `SCM' value that encodes a reference to the heap cell
     pointer X.

   Note that it is also possible to transform a non-immediate `SCM'
value by using `SCM_UNPACK' into a `scm_t_bits' variable.  However, the
result of `SCM_UNPACK' may not be used as a pointer to a `scm_t_cell':
only `SCM2PTR' is guaranteed to transform a `SCM' object into a valid
pointer to a heap cell.  Also, it is not allowed to apply `PTR2SCM' to
anything that is not a valid pointer to a heap cell.

Summary:
   * Only use `SCM2PTR' on `SCM' values for which `SCM_IMP' is false!

   * Don't use `(scm_t_cell *) SCM_UNPACK (X)'!  Use `SCM2PTR (X)'
     instead!

   * Don't use `PTR2SCM' for anything but a cell pointer!

A.2.7.4 Allocating Cells
........................

Guile provides both ordinary cells with two slots, and double cells
with four slots.  The following two function are the most primitive way
to allocate such cells.

   If the caller intends to use it as a header for some other type, she
must pass an appropriate magic value in WORD_0, to mark it as a member
of that type, and pass whatever value as WORD_1, etc that the type
expects.  You should generally not need these functions, unless you are
implementing a new datatype, and thoroughly understand the code in
`<libguile/tags.h>'.

   If you just want to allocate pairs, use `scm_cons'.

 -- Function: SCM scm_cell (scm_t_bits word_0, scm_t_bits word_1)
     Allocate a new cell, initialize the two slots with WORD_0 and
     WORD_1, and return it.

     Note that WORD_0 and WORD_1 are of type `scm_t_bits'.  If you want
     to pass a `SCM' object, you need to use `SCM_UNPACK'.

 -- Function: SCM scm_double_cell (scm_t_bits word_0, scm_t_bits
          word_1, scm_t_bits word_2, scm_t_bits word_3)
     Like `scm_cell', but allocates a double cell with four slots.

A.2.7.5 Heap Cell Type Information
..................................

Heap cells contain a number of entries, each of which is either a scheme
object of type `SCM' or a raw C value of type `scm_t_bits'.  Which of
the cell entries contain Scheme objects and which contain raw C values
is determined by the first entry of the cell, which holds the cell type
information.

 -- Macro: scm_t_bits SCM_CELL_TYPE (SCM X)
     For a non-immediate Scheme object X, deliver the content of the
     first entry of the heap cell referenced by X.  This value holds
     the information about the cell type.

 -- Macro: void SCM_SET_CELL_TYPE (SCM X, scm_t_bits T)
     For a non-immediate Scheme object X, write the value T into the
     first entry of the heap cell referenced by X.  The value T must
     hold a valid cell type.

A.2.7.6 Accessing Cell Entries
..............................

For a non-immediate Scheme object X, the object type can be determined
by reading the cell type entry using the `SCM_CELL_TYPE' macro.  For
each different type of cell it is known which cell entries hold Scheme
objects and which cell entries hold raw C data.  To access the
different cell entries appropriately, the following macros are provided.

 -- Macro: scm_t_bits SCM_CELL_WORD (SCM X, unsigned int N)
     Deliver the cell entry N of the heap cell referenced by the
     non-immediate Scheme object X as raw data.  It is illegal, to
     access cell entries that hold Scheme objects by using these
     macros.  For convenience, the following macros are also provided.
        * SCM_CELL_WORD_0 (X) => SCM_CELL_WORD (X, 0)

        * SCM_CELL_WORD_1 (X) => SCM_CELL_WORD (X, 1)

        * ...

        * SCM_CELL_WORD_N (X) => SCM_CELL_WORD (X, N)

 -- Macro: SCM SCM_CELL_OBJECT (SCM X, unsigned int N)
     Deliver the cell entry N of the heap cell referenced by the
     non-immediate Scheme object X as a Scheme object.  It is illegal,
     to access cell entries that do not hold Scheme objects by using
     these macros.  For convenience, the following macros are also
     provided.
        * SCM_CELL_OBJECT_0 (X) => SCM_CELL_OBJECT (X, 0)

        * SCM_CELL_OBJECT_1 (X) => SCM_CELL_OBJECT (X, 1)

        * ...

        * SCM_CELL_OBJECT_N (X) => SCM_CELL_OBJECT (X, N)

 -- Macro: void SCM_SET_CELL_WORD (SCM X, unsigned int N, scm_t_bits W)
     Write the raw C value W into entry number N of the heap cell
     referenced by the non-immediate Scheme value X.  Values that are
     written into cells this way may only be read from the cells using
     the `SCM_CELL_WORD' macros or, in case cell entry 0 is written,
     using the `SCM_CELL_TYPE' macro.  For the special case of cell
     entry 0 it has to be made sure that W contains a cell type
     information which does not describe a Scheme object.  For
     convenience, the following macros are also provided.
        * SCM_SET_CELL_WORD_0 (X, W) => SCM_SET_CELL_WORD (X, 0, W)

        * SCM_SET_CELL_WORD_1 (X, W) => SCM_SET_CELL_WORD (X, 1, W)

        * ...

        * SCM_SET_CELL_WORD_N (X, W) => SCM_SET_CELL_WORD (X, N, W)

 -- Macro: void SCM_SET_CELL_OBJECT (SCM X, unsigned int N, SCM O)
     Write the Scheme object O into entry number N of the heap cell
     referenced by the non-immediate Scheme value X.  Values that are
     written into cells this way may only be read from the cells using
     the `SCM_CELL_OBJECT' macros or, in case cell entry 0 is written,
     using the `SCM_CELL_TYPE' macro.  For the special case of cell
     entry 0 the writing of a Scheme object into this cell is only
     allowed if the cell forms a Scheme pair.  For convenience, the
     following macros are also provided.
        * SCM_SET_CELL_OBJECT_0 (X, O) => SCM_SET_CELL_OBJECT (X, 0, O)

        * SCM_SET_CELL_OBJECT_1 (X, O) => SCM_SET_CELL_OBJECT (X, 1, O)

        * ...

        * SCM_SET_CELL_OBJECT_N (X, O) => SCM_SET_CELL_OBJECT (X, N, O)

Summary:
   * For a non-immediate Scheme object X of unknown type, get the type
     information by using `SCM_CELL_TYPE (X)'.

   * As soon as the cell type information is available, only use the
     appropriate access methods to read and write data to the different
     cell entries.

A.2.7.7 Basic Rules for Accessing Cell Entries
..............................................

For each cell type it is generally up to the implementation of that type
which of the corresponding cell entries hold Scheme objects and which
hold raw C values.  However, there is one basic rule that has to be
followed: Scheme pairs consist of exactly two cell entries, which both
contain Scheme objects.  Further, a cell which contains a Scheme object
in it first entry has to be a Scheme pair.  In other words, it is not
allowed to store a Scheme object in the first cell entry and a non
Scheme object in the second cell entry.

 -- Macro: int SCM_CONSP (SCM X)
     Determine, whether the Scheme object X is a Scheme pair, i.e.
     whether X references a heap cell consisting of exactly two
     entries, where both entries contain a Scheme object.  In this
     case, both entries will have to be accessed using the
     `SCM_CELL_OBJECT' macros.  On the contrary, if the `SCM_CONSP'
     predicate is not fulfilled, the first entry of the Scheme cell is
     guaranteed not to be a Scheme value and thus the first cell entry
     must be accessed using the `SCM_CELL_WORD_0' macro.

Appendix B GNU Free Documentation License
*****************************************

                      Version 1.2, November 2002

     Copyright (C) 2000,2001,2002, 2006 Free Software Foundation, Inc.
     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

     Everyone is permitted to copy and distribute verbatim copies
     of this license document, but changing it is not allowed.

  0. PREAMBLE

     The purpose of this License is to make a manual, textbook, or other
     functional and useful document "free" in the sense of freedom: to
     assure everyone the effective freedom to copy and redistribute it,
     with or without modifying it, either commercially or
     noncommercially.  Secondarily, this License preserves for the
     author and publisher a way to get credit for their work, while not
     being considered responsible for modifications made by others.

     This License is a kind of "copyleft", which means that derivative
     works of the document must themselves be free in the same sense.
     It complements the GNU General Public License, which is a copyleft
     license designed for free software.

     We have designed this License in order to use it for manuals for
     free software, because free software needs free documentation: a
     free program should come with manuals providing the same freedoms
     that the software does.  But this License is not limited to
     software manuals; it can be used for any textual work, regardless
     of subject matter or whether it is published as a printed book.
     We recommend this License principally for works whose purpose is
     instruction or reference.

  1. APPLICABILITY AND DEFINITIONS

     This License applies to any manual or other work, in any medium,
     that contains a notice placed by the copyright holder saying it
     can be distributed under the terms of this License.  Such a notice
     grants a world-wide, royalty-free license, unlimited in duration,
     to use that work under the conditions stated herein.  The
     "Document", below, refers to any such manual or work.  Any member
     of the public is a licensee, and is addressed as "you".  You
     accept the license if you copy, modify or distribute the work in a
     way requiring permission under copyright law.

     A "Modified Version" of the Document means any work containing the
     Document or a portion of it, either copied verbatim, or with
     modifications and/or translated into another language.

     A "Secondary Section" is a named appendix or a front-matter section
     of the Document that deals exclusively with the relationship of the
     publishers or authors of the Document to the Document's overall
     subject (or to related matters) and contains nothing that could
     fall directly within that overall subject.  (Thus, if the Document
     is in part a textbook of mathematics, a Secondary Section may not
     explain any mathematics.)  The relationship could be a matter of
     historical connection with the subject or with related matters, or
     of legal, commercial, philosophical, ethical or political position
     regarding them.

     The "Invariant Sections" are certain Secondary Sections whose
     titles are designated, as being those of Invariant Sections, in
     the notice that says that the Document is released under this
     License.  If a section does not fit the above definition of
     Secondary then it is not allowed to be designated as Invariant.
     The Document may contain zero Invariant Sections.  If the Document
     does not identify any Invariant Sections then there are none.

     The "Cover Texts" are certain short passages of text that are
     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
     that says that the Document is released under this License.  A
     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
     be at most 25 words.

     A "Transparent" copy of the Document means a machine-readable copy,
     represented in a format whose specification is available to the
     general public, that is suitable for revising the document
     straightforwardly with generic text editors or (for images
     composed of pixels) generic paint programs or (for drawings) some
     widely available drawing editor, and that is suitable for input to
     text formatters or for automatic translation to a variety of
     formats suitable for input to text formatters.  A copy made in an
     otherwise Transparent file format whose markup, or absence of
     markup, has been arranged to thwart or discourage subsequent
     modification by readers is not Transparent.  An image format is
     not Transparent if used for any substantial amount of text.  A
     copy that is not "Transparent" is called "Opaque".

     Examples of suitable formats for Transparent copies include plain
     ASCII without markup, Texinfo input format, LaTeX input format,
     SGML or XML using a publicly available DTD, and
     standard-conforming simple HTML, PostScript or PDF designed for
     human modification.  Examples of transparent image formats include
     PNG, XCF and JPG.  Opaque formats include proprietary formats that
     can be read and edited only by proprietary word processors, SGML or
     XML for which the DTD and/or processing tools are not generally
     available, and the machine-generated HTML, PostScript or PDF
     produced by some word processors for output purposes only.

     The "Title Page" means, for a printed book, the title page itself,
     plus such following pages as are needed to hold, legibly, the
     material this License requires to appear in the title page.  For
     works in formats which do not have any title page as such, "Title
     Page" means the text near the most prominent appearance of the
     work's title, preceding the beginning of the body of the text.

     A section "Entitled XYZ" means a named subunit of the Document
     whose title either is precisely XYZ or contains XYZ in parentheses
     following text that translates XYZ in another language.  (Here XYZ
     stands for a specific section name mentioned below, such as
     "Acknowledgements", "Dedications", "Endorsements", or "History".)
     To "Preserve the Title" of such a section when you modify the
     Document means that it remains a section "Entitled XYZ" according
     to this definition.

     The Document may include Warranty Disclaimers next to the notice
     which states that this License applies to the Document.  These
     Warranty Disclaimers are considered to be included by reference in
     this License, but only as regards disclaiming warranties: any other
     implication that these Warranty Disclaimers may have is void and
     has no effect on the meaning of this License.

  2. VERBATIM COPYING

     You may copy and distribute the Document in any medium, either
     commercially or noncommercially, provided that this License, the
     copyright notices, and the license notice saying this License
     applies to the Document are reproduced in all copies, and that you
     add no other conditions whatsoever to those of this License.  You
     may not use technical measures to obstruct or control the reading
     or further copying of the copies you make or distribute.  However,
     you may accept compensation in exchange for copies.  If you
     distribute a large enough number of copies you must also follow
     the conditions in section 3.

     You may also lend copies, under the same conditions stated above,
     and you may publicly display copies.

  3. COPYING IN QUANTITY

     If you publish printed copies (or copies in media that commonly
     have printed covers) of the Document, numbering more than 100, and
     the Document's license notice requires Cover Texts, you must
     enclose the copies in covers that carry, clearly and legibly, all
     these Cover Texts: Front-Cover Texts on the front cover, and
     Back-Cover Texts on the back cover.  Both covers must also clearly
     and legibly identify you as the publisher of these copies.  The
     front cover must present the full title with all words of the
     title equally prominent and visible.  You may add other material
     on the covers in addition.  Copying with changes limited to the
     covers, as long as they preserve the title of the Document and
     satisfy these conditions, can be treated as verbatim copying in
     other respects.

     If the required texts for either cover are too voluminous to fit
     legibly, you should put the first ones listed (as many as fit
     reasonably) on the actual cover, and continue the rest onto
     adjacent pages.

     If you publish or distribute Opaque copies of the Document
     numbering more than 100, you must either include a
     machine-readable Transparent copy along with each Opaque copy, or
     state in or with each Opaque copy a computer-network location from
     which the general network-using public has access to download
     using public-standard network protocols a complete Transparent
     copy of the Document, free of added material.  If you use the
     latter option, you must take reasonably prudent steps, when you
     begin distribution of Opaque copies in quantity, to ensure that
     this Transparent copy will remain thus accessible at the stated
     location until at least one year after the last time you
     distribute an Opaque copy (directly or through your agents or
     retailers) of that edition to the public.

     It is requested, but not required, that you contact the authors of
     the Document well before redistributing any large number of
     copies, to give them a chance to provide you with an updated
     version of the Document.

  4. MODIFICATIONS

     You may copy and distribute a Modified Version of the Document
     under the conditions of sections 2 and 3 above, provided that you
     release the Modified Version under precisely this License, with
     the Modified Version filling the role of the Document, thus
     licensing distribution and modification of the Modified Version to
     whoever possesses a copy of it.  In addition, you must do these
     things in the Modified Version:

       A. Use in the Title Page (and on the covers, if any) a title
          distinct from that of the Document, and from those of
          previous versions (which should, if there were any, be listed
          in the History section of the Document).  You may use the
          same title as a previous version if the original publisher of
          that version gives permission.

       B. List on the Title Page, as authors, one or more persons or
          entities responsible for authorship of the modifications in
          the Modified Version, together with at least five of the
          principal authors of the Document (all of its principal
          authors, if it has fewer than five), unless they release you
          from this requirement.

       C. State on the Title page the name of the publisher of the
          Modified Version, as the publisher.

       D. Preserve all the copyright notices of the Document.

       E. Add an appropriate copyright notice for your modifications
          adjacent to the other copyright notices.

       F. Include, immediately after the copyright notices, a license
          notice giving the public permission to use the Modified
          Version under the terms of this License, in the form shown in
          the Addendum below.

       G. Preserve in that license notice the full lists of Invariant
          Sections and required Cover Texts given in the Document's
          license notice.

       H. Include an unaltered copy of this License.

       I. Preserve the section Entitled "History", Preserve its Title,
          and add to it an item stating at least the title, year, new
          authors, and publisher of the Modified Version as given on
          the Title Page.  If there is no section Entitled "History" in
          the Document, create one stating the title, year, authors,
          and publisher of the Document as given on its Title Page,
          then add an item describing the Modified Version as stated in
          the previous sentence.

       J. Preserve the network location, if any, given in the Document
          for public access to a Transparent copy of the Document, and
          likewise the network locations given in the Document for
          previous versions it was based on.  These may be placed in
          the "History" section.  You may omit a network location for a
          work that was published at least four years before the
          Document itself, or if the original publisher of the version
          it refers to gives permission.

       K. For any section Entitled "Acknowledgements" or "Dedications",
          Preserve the Title of the section, and preserve in the
          section all the substance and tone of each of the contributor
          acknowledgements and/or dedications given therein.

       L. Preserve all the Invariant Sections of the Document,
          unaltered in their text and in their titles.  Section numbers
          or the equivalent are not considered part of the section
          titles.

       M. Delete any section Entitled "Endorsements".  Such a section
          may not be included in the Modified Version.

       N. Do not retitle any existing section to be Entitled
          "Endorsements" or to conflict in title with any Invariant
          Section.

       O. Preserve any Warranty Disclaimers.

     If the Modified Version includes new front-matter sections or
     appendices that qualify as Secondary Sections and contain no
     material copied from the Document, you may at your option
     designate some or all of these sections as invariant.  To do this,
     add their titles to the list of Invariant Sections in the Modified
     Version's license notice.  These titles must be distinct from any
     other section titles.

     You may add a section Entitled "Endorsements", provided it contains
     nothing but endorsements of your Modified Version by various
     parties--for example, statements of peer review or that the text
     has been approved by an organization as the authoritative
     definition of a standard.

     You may add a passage of up to five words as a Front-Cover Text,
     and a passage of up to 25 words as a Back-Cover Text, to the end
     of the list of Cover Texts in the Modified Version.  Only one
     passage of Front-Cover Text and one of Back-Cover Text may be
     added by (or through arrangements made by) any one entity.  If the
     Document already includes a cover text for the same cover,
     previously added by you or by arrangement made by the same entity
     you are acting on behalf of, you may not add another; but you may
     replace the old one, on explicit permission from the previous
     publisher that added the old one.

     The author(s) and publisher(s) of the Document do not by this
     License give permission to use their names for publicity for or to
     assert or imply endorsement of any Modified Version.

  5. COMBINING DOCUMENTS

     You may combine the Document with other documents released under
     this License, under the terms defined in section 4 above for
     modified versions, provided that you include in the combination
     all of the Invariant Sections of all of the original documents,
     unmodified, and list them all as Invariant Sections of your
     combined work in its license notice, and that you preserve all
     their Warranty Disclaimers.

     The combined work need only contain one copy of this License, and
     multiple identical Invariant Sections may be replaced with a single
     copy.  If there are multiple Invariant Sections with the same name
     but different contents, make the title of each such section unique
     by adding at the end of it, in parentheses, the name of the
     original author or publisher of that section if known, or else a
     unique number.  Make the same adjustment to the section titles in
     the list of Invariant Sections in the license notice of the
     combined work.

     In the combination, you must combine any sections Entitled
     "History" in the various original documents, forming one section
     Entitled "History"; likewise combine any sections Entitled
     "Acknowledgements", and any sections Entitled "Dedications".  You
     must delete all sections Entitled "Endorsements."

  6. COLLECTIONS OF DOCUMENTS

     You may make a collection consisting of the Document and other
     documents released under this License, and replace the individual
     copies of this License in the various documents with a single copy
     that is included in the collection, provided that you follow the
     rules of this License for verbatim copying of each of the
     documents in all other respects.

     You may extract a single document from such a collection, and
     distribute it individually under this License, provided you insert
     a copy of this License into the extracted document, and follow
     this License in all other respects regarding verbatim copying of
     that document.

  7. AGGREGATION WITH INDEPENDENT WORKS

     A compilation of the Document or its derivatives with other
     separate and independent documents or works, in or on a volume of
     a storage or distribution medium, is called an "aggregate" if the
     copyright resulting from the compilation is not used to limit the
     legal rights of the compilation's users beyond what the individual
     works permit.  When the Document is included in an aggregate, this
     License does not apply to the other works in the aggregate which
     are not themselves derivative works of the Document.

     If the Cover Text requirement of section 3 is applicable to these
     copies of the Document, then if the Document is less than one half
     of the entire aggregate, the Document's Cover Texts may be placed
     on covers that bracket the Document within the aggregate, or the
     electronic equivalent of covers if the Document is in electronic
     form.  Otherwise they must appear on printed covers that bracket
     the whole aggregate.

  8. TRANSLATION

     Translation is considered a kind of modification, so you may
     distribute translations of the Document under the terms of section
     4.  Replacing Invariant Sections with translations requires special
     permission from their copyright holders, but you may include
     translations of some or all Invariant Sections in addition to the
     original versions of these Invariant Sections.  You may include a
     translation of this License, and all the license notices in the
     Document, and any Warranty Disclaimers, provided that you also
     include the original English version of this License and the
     original versions of those notices and disclaimers.  In case of a
     disagreement between the translation and the original version of
     this License or a notice or disclaimer, the original version will
     prevail.

     If a section in the Document is Entitled "Acknowledgements",
     "Dedications", or "History", the requirement (section 4) to
     Preserve its Title (section 1) will typically require changing the
     actual title.

  9. TERMINATION

     You may not copy, modify, sublicense, or distribute the Document
     except as expressly provided for under this License.  Any other
     attempt to copy, modify, sublicense or distribute the Document is
     void, and will automatically terminate your rights under this
     License.  However, parties who have received copies, or rights,
     from you under this License will not have their licenses
     terminated so long as such parties remain in full compliance.

 10. FUTURE REVISIONS OF THIS LICENSE

     The Free Software Foundation may publish new, revised versions of
     the GNU Free Documentation License from time to time.  Such new
     versions will be similar in spirit to the present version, but may
     differ in detail to address new problems or concerns.  See
     `http://www.gnu.org/copyleft/'.

     Each version of the License is given a distinguishing version
     number.  If the Document specifies that a particular numbered
     version of this License "or any later version" applies to it, you
     have the option of following the terms and conditions either of
     that specified version or of any later version that has been
     published (not as a draft) by the Free Software Foundation.  If
     the Document does not specify a version number of this License,
     you may choose any version ever published (not as a draft) by the
     Free Software Foundation.

B.0.1 ADDENDUM: How to use this License for your documents
----------------------------------------------------------

To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and license
notices just after the title page:

       Copyright (C)  YEAR  YOUR NAME.
       Permission is granted to copy, distribute and/or modify this document
       under the terms of the GNU Free Documentation License, Version 1.2
       or any later version published by the Free Software Foundation;
       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
       Texts.  A copy of the license is included in the section entitled ``GNU
       Free Documentation License''.

   If you have Invariant Sections, Front-Cover Texts and Back-Cover
Texts, replace the "with...Texts." line with this:

         with the Invariant Sections being LIST THEIR TITLES, with
         the Front-Cover Texts being LIST, and with the Back-Cover Texts
         being LIST.

   If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.

   If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of
free software license, such as the GNU General Public License, to
permit their use in free software.

Concept Index
*************

This index contains concepts, keywords and non-Schemey names for several
features, to make it easier to locate the desired sections.