   This is Edition 1.2, last updated 8 September 2000, of `The librep
Manual', for librep, Version 0.13.

   Copyright 1999-2000 John Harper.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Compilation Tips
----------------

   Here are some tips for making compiled code run fast(er):

   * Instead of using `while' loops to traverse lists, use `mapc' or
     tail recursion.

     For example you might code a function to scan a list using
     iteration through a `while' loop:

          (defun scan-list (lst elt)
            "Search the LST for an element similar to ELT.
          Return it if one is found."
            (catch 'return
              (while (consp lst)
                (when (equal (car lst) elt)
                  (throw 'return elt))
                (setq lst (cdr lst)))))

     As well as obscuring what is actually happening, this will
     probably be fairly slow to execute. A more elegant solution is to
     use tail-recursion:

          (defun scan-list (lst elt)
            (if (equal (car lst) elt)
                elt
              (scan-list (cdr lst) elt)))

     An alternative idiom is to map an anonymous function over the list
     using the `mapc' function:

          (defun scan-list (lst elt)
            (catch 'return
              (mapc (lambda (x)
                      (when (equal x elt)
                        (throw 'return elt)))
                    lst)
              nil))

     In fact, the compiler knows that calls to `mapc' with a constant
     lambda expression can be open-coded, so it will code the list
     traversal directly using the virtual machine stack.

     However, in most cases the execution time differences are likely to
     negligible.

   * In some cases the functions `member', `memq', `assoc', etc... can
     be used to search lists. Since these are primitives written in C
     they will probably execute several times faster than an equivalent
     Lisp function.

     So the above `scan-list' example can again be rewritten, this time
     as:

          (defun scan-list (lst elt)
            (car (member elt lst)))

   * All conditional structures are equivalent when compiled (they are
     all translated to `cond' statements), so use whichever is the
     easiest to understand.

   * A certain amount of constant folding is performed. If a function is
     known to be free of side effects, and all its arguments are
     constants, then it is evaluated at compile-time, and the result
     folded into the program in its place. For example

          (logor (lsh 1 6) x)
              ==> (logor 32 x)

   * Careful use of named constants (see Defining Variables) can
     increase the speed of some programs. For example, in the Lisp
     compiler itself all the opcode values (small integers) are defined
     as constants.

     It must be stressed that in some cases constants may _not_ be
     suitable; they may drastically increase the size of the compiled
     program (when the constants are `big' objects, i.e. long lists) or
     even introduce subtle bugs (since two references to the same
     constant may not be `eq' whereas two references to the same
     variable are always `eq').

   * Many primitives have corresponding byte-code instructions; these
     primitives will be quicker to call than those that don't (and
     incur a normal function call). Currently, the functions which have
     byte-code instructions (apart from all the special forms) are:

     `cons', `car', `cdr', `rplaca', `rplacd', `nth', `nthcdr', `aset',
     `aref', `length', `eval', `+', `*', `/', `%', `mod', `lognot',
     `not', `logior', `logand', `logxor', `equal', `eq', `=', `/=',
     `>', `<', `>=', `<=', `1+', `1-', `-', `set', `lsh', `zerop',
     `null', `atom', `consp', `listp', `numberp', `stringp', `vectorp',
     `throw', `boundp', `symbolp', `get', `put', `signal', `return',
     `reverse', `nreverse', `assoc', `assq', `rassoc', `rassq', `last',
     `mapcar', `mapc', `member', `memq', `delete', `delq', `delete-if',
     `delete-if-not', `copy-sequence', `sequencep', `functionp',
     `special-form-p', `subrp', `eql', `max', `min', `filter',
     `macrop', `bytecodep', `bind-object'.

   * When a file is being compiled each top-level form it contains is
     inspected to see if it should be compiled into a byte-code form.
     Different types of form are processed in different ways:

        * Function and macro definitions have their body forms compiled
          into a single byte-code form. The doc-string and interactive
          declaration are not compiled.

        * If the form is a list form (see List Forms) and the
          symbol which is the car of the list is one of:

          `if', `cond', `when', `unless', `let', `let*', `catch',
          `unwind-protect', `error-protect', `with-buffer',
          `with-window', `progn', `prog1', `prog2', `while', `and',
          `or', `case'.

          then the form is compiled. Otherwise it is just written to
          the output file in its uncompiled state.

     If your program contains a lot of top-level forms which you know
     will not be compiled automatically, consider putting them in a
     `progn' block to make the compiler coalesce them into one
     byte-code form.

Disassembly
-----------

   It is possible to disassemble byte-code forms; originally this was
so I could figure out why the compiler wasn't working but if you're
curious about how the compiler compiles a form it may be of use to you.

   Naturally, the output of the disassembler is a listing in the
assembly language of the `librep' virtual machine--it won't take a
byte-code form and produce the equivalent Lisp code!

 - Command: disassemble-fun function #!optional stream
     This function disassembles the compile Lisp function FUNCTION. It
     writes a listing to the output stream STREAM (normally the value
     of the `standard-output' variable).

     When called interactively it will prompt for a function to
     disassemble.

   When reading the output of the disassembler bear in mind that
`librep' simulates a stack machine for the code to run on. All
calculations are performed on the stack, the value left on the stack
when the piece of code ends is the value of the byte-code form.

   Here is a small example. Consider the `fib' function given at the
start of this section:

     (define (fib n)
       (if (<= n 2)
           1
         (+ (fib (- n 1))
            (fib (- n 2)))))

After compilation and disassembly, the following is produced (but
without the annotations):

     Disassembly of #<closure fib>:

     21 bytes, 1 constants, and (5,0,1) stack slots

     0    required-arg       ;requires a single parameter
     1    dup
     2    slot-set #0        ;store it in register 0 (r0)
     3    pushi 2
     4    le
     5    jn 10              ;unless r0 <= 2, goto 10
     8    pushi 1
     9    return             ;else, return 1
     10   refg [0] fib
     11   slot-ref #0
     12   dec
     13   call #1            ;push result of (fib (1- n))
     14   refg [0] fib
     15   slot-ref #0
     16   pushi 2
     17   sub
     18   call #1            ;push (fib (- n 2))
     19   add
     20   return             ;return the sum of the two calls

Datums
======

   "Datums" are the mechanism by which `librep' allows Lisp programs to
define new data types, such that these types are completely distinct
from the built-in data types (i.e. they match none of the standard type
predicates).

   They also provide encapsulation, in that the data objects they
provide are completely opaque, unless a pre-defined value is known
(which was specified when the object was created, and is typically
known only by the object's creator).

 - Function: make-datum value key
     Create and return a new datum object. It has the value VALUE
     associated with it, and has type KEY.

 - Function: datum-ref arg key
     If ARG has type KEY, then return the value associated with it.
     Otherwise, an error is signalled.

 - Function: datum-set arg key value
     If ARG has type KEY, then set the value associated with it to be
     VALUE. Otherwise, an error is signalled.

 - Function: has-type-p arg key
     Return true if ARG has type KEY.

 - Function: define-datum-printer key printer
     Associate the function PRINTER with all datum objects of type KEY.
     When any such object is printed, PRINTER is applied to two
     arguments, the datum and the stream to which it should be printed
     (see Output Streams).

Queues
======

   A "queue" is an ordered set of objects, such that objects enter at
one end of the queue (the "tail"), and leave from the other end of the
queue (the "head"). The acts of entering and leaving a queue are often
called "enqueing" and "dequeueing".

   `librep' provides a straightforward queue implementation,
implemented by the `rep.data.queues' module (see Modules).

 - Function: make-queue
     Create and return a new queue object. The queue will initially be
     empty.

 - Function: enqueue q arg
     Add the object ARG to the tail of the queue Q.

 - Function: dequeue q
     Remove the object at the head of the queue Q, and return it. If Q
     is empty, an error is signalled.

 - Function: queue-empty-p q
     Return true if the queue Q is not empty.

 - Function: queuep arg
     Return true if the object ARG is a queue.

 - Function: queue->list q
     Return a list of objects representing the contents of the queue Q,
     with objects ordered from head to tail. Modifying the list
     structure causes undefined effects to the queue itself.

 - Function: queue-length q
     Return the number of objects stored in the queue Q.

 - Function: delete-from-queue q arg
     Removes any occurrences of the object ARG from the queue Q.

Records
=======

   `librep' provides a convenient means of defining structured data
types, these types are known as "records". Each record is a distinct
data type, meaning that there will only be a single type-predicate
matching objects of any individual record type.

   All definitions documented in this section are provided by the
`rep.data.records' module (see Modules).

   Record types are defined using the `define-record-type' macro, this
in turn defines a number of functions implementing the type. These
functions include a constructor, a type predicate, and a user-defined
set of field-accessor and -modifier functions.

 - Macro: define-record-type type (constructor fields...) [predicate]
          (field accessor [modifier])...
     This macro creates a new record type storing an opaque object
     identifying the type in the variable named TYPE.

     It then defines a function CONSTRUCTOR with parameter list as
     specified by the FIELDS..., and a predicate function called
     PREDICATE if PREDICATE is given.

     The fields of the record are defined by the sequence of `(FIELD
     ACCESSOR [MODIFIER])' forms, each form describes a single field
     (named FIELD, which may match one of the constructor arguments).

     For each field a function ACCESSOR will be defined that when
     applied to an argument of the record type, returns the value
     stored in the associated FIELD. If the MODIFIER name is defined a
     function will be defined of that name, that when applied to a
     record and an object, stores the object into the associated field
     of the record.

     Note that the FIELDS... may include all the standard lambda-list
     features (see Lambda Expressions), including keyword
     parameters and default values.

   Here is an example record definition:

     (define-record-type :pare
       (kons x y)                         ; constructor
       pare?                              ; predicate
       (x kar set-kar!)                   ; fields w/ optional accessors
       (y kdr))                           ;and modifiers

the variable `:pare' is bound to the record type. Following this
definition, the record type could be used as follows:

     (define x (kons 1 2))

     (pare? x)
         => t

     (kar x)
         => 1

     (set-kar! x 42)

     (kar x)
         => 42

   By default record objects print as the name of their type in angle
brackets, e.g. for the above `pare' type, each object would print as
the string `#<:pare>'. This may be redefined using the
`define-record-discloser' function.

 - Function: define-record-discloser type discloser
     Associate the function DISCLOSER with the record type TYPE.  When
     any record of this type is printed, DISCLOSER is applied to the
     object, it should return the value that will actually be printed.

   For the above example, the following could be used:

     (define-record-discloser :pare (lambda (x) `(pare ,(kar x) ,(kdr x))))

     (kons 'a 'b)
         => (pare a b)

   Constructors for records with large numbers of fields often benefit
from using keyword parameters. For example the `kons' record above
could be defined as follows (though this would make more sense if it
had more than two fields):

     (define-record-type :pare
       (kons #!key (kar 1) (kdr 2))
       pare?
       (kar kar set-kar!)
       (kdr kdr set-kdr!))

     (kons #:kar 42) => (pare 42 2)
     (kons #:kdr 42) => (pare 1 42)

Hash Tables
===========

   The `rep.data.tables' module provides a flexible hash table
implementation (see Modules). Each hash table is represented by a
lisp object satisfying the `tablep' predicate:

 - Function: tablep arg
     Return true if ARG is a hash table.

   Hash tables may be created by using the `make-table' and
`make-weak-table' functions:

 - Function: make-table hash-fun compare-fun
     Create and return a new hash table. When storing and referencing
     keys it will use the function HASH-FUN to map keys to hash codes
     (positive fixnums), and the predicate function COMPARE-FUN to
     compare two keys (should return true if the keys are considered
     equal).

 - Function: make-weak-table hash-fun compare-fun
     Similar to `make-table', except that key-value pairs stored in the
     table are said to be "weakly keyed". That is, they are only
     retained in the table as long the key has not been garbage
     collected.

     Unlike with tables created by the `make-table' function, the fact
     that the key is stored in the table is not considered good enough
     to prevent it being garbage collected.

 - Function: table-ref table key
     Return the value stored in hash table TABLE indexed by object KEY.
     Returns false if no such value exists.

 - Function: table-bound-p table key
     Returns true if the hash table TABLE contains a value associated
     with KEY.

 - Function: table-set table key value
     Associate the value VALUE with KEY in hash table TABLE. Returns
     `value'.

 - Function: table-unset table key
     Remove any value stored in TABLE associated with KEY.

 - Function: table-walk function table
     Call function FUNCTION for every key-value pair stored in hash
     table TABLE. For each pair, the function is called with arguments
     `(KEY VALUE)'.

   Several hash functions are also provided:

 - Function: string-hash string
     Return an integer representing the string STRING.

 - Function: symbol-hash symbol
     Call `(string-hash (symbol-name SYMBOL))'.

 - Function: eq-hash arg
     Return a hash value representing object ARG. The hash is generated
     from the _address_ of the object.

 - Function: equal-hash arg
     Return a hash value representing object ARG. The hash is generated
     from the _contents_ of the object.

Guardians
=========

   A "guardian" is a lisp object used to control when other data
objects are recycled by the garbage collector (see Garbage Collection).
(1) The usual behaviour of the collector is to recycle
objects as soon as they have no remaining references.

   Guardians allow the programmer to detect when a specified object
would be freed by the garbage collector, and to implement their own
allocation policy. This can be useful, for example, with objects that
have a high creation-overhead, and thus need to be cached for
performance reasons.

 - Function: make-guardian
     This function allocates and returns a new guardian. Each guardian
     has a list of data objects associated with it; some of which may
     have been proved to have no remaining references to them (except
     from the guardian system).

     Calling the guardian object with a single argument, adds that
     value to the list of objects associated with that guardian.
     Calling the guardian with no arguments has one of two effects:

        * If objects are associated with the guardian that have been
          proved to be inaccessible, then return one of those objects,
          and remove it from the list of objects associated with the
          guardian.

        * If none of the associated objects have been proved to be
          inaccessible, then return the value false.

   Note the use of the word "prove" in the above description, objects
are only moved into a guardian's inaccessible set by the garbage
collector.

   Here is an example use of the guardian system:

     ;; create a new guardian object
     (setq G (make-guardian))

     ;; create a lisp object
     (setq x (cons 'a 'b))
        => (a . b)

     ;; protect the object using the guardian
     (G x)

     ;; remove the sole reference to the object
     (setq x nil)
        => ()

     ;; invoke the garbage collector, this will
     ;; prove that the value added to the
     ;; guardian is no longer accessible
     (garbage-collect)

     ;; call the guardian to retrieve the
     ;; inaccessible value
     (G)
        => (a . b)

     ;; no more inaccessible values available
     (G)
        => ()

   ---------- Footnotes ----------

   (1) Guardians were first described in a paper by R.  Kent Dybvig,
Carl Bruggeman, and David Eby: `"Guardians in a Generation-Based
Garbage Collector", ACM SIGPLAN Conference on Programming Language
Design and Implementation, June 1993.'

Streams
=======

   A "stream" is a Lisp object which is either a data sink (an "output
stream") or a data source (an "input stream"). All streams produce or
consume sequences of 8-bit characters.

   Streams are very flexible, functions using streams for their input
and output do not need to know the type of stream being accessed. For
example the Lisp reader (the `read' function) takes an input stream as
its sole argument, it then reads characters from this stream until it
has parsed a whole object. This stream could be a file, a function, or
even a string; the `read' function does not need to differentiate.

 - Function: streamp arg
     Return true if ARG is a stream.

 - Function: input-stream-p arg
     Return true if ARG is an input stream.

 - Function: output-stream-p arg
     Return true if ARG is an output stream.

Input Streams
-------------

   These are the possible types of input stream, for the functions which
use them see Input Functions.

`FILE'
     Characters are read from the file object FILE, for the functions
     which manipulate file objects see Files.

`FUNCTION'
     Each time an input character is required the FUNCTION is called
     with no arguments. It should return the character read (an
     integer) or false if for some reason no character is available.

     FUNCTION should also be able to `unread' one character. When this
     happens the function will be called with one argument--the value of
     the last character read. The function should arrange it so that the
     next time it is called it returns this character. A possible
     implementation could be,

          (defvar ms-unread-char nil
            "If true the character which was pushed back.")

          (defun my-stream (#!optional unread-char)
            (if unread-char
                (setq ms-unread-char unread-char)
              (if ms-unread-char
                  (prog1
                    ms-unread-char
                    (setq ms-unread-char nil))
                ;; Normal case -- read and return a character from somewhere
                ...

`nil'
     Read from the stream stored in the variable `standard-input'.

   It is also possible to use a string as an input stream. The string to
be read from must be applied to the `make-string-input-stream' function
and the result from this function used as the input stream.

 - Function: make-string-input-stream string #!optional start
     Returns an input stream which will supply the characters of the
     string STRING in order starting with the character at position
     START (or from position zero if this argument is undefined).

          (read (make-string-input-stream "(1 . 2)"))
              => (1 . 2)

 - Variable: standard-input
     The input stream which is used when no other is specified or is
     false.

   Applications that embed `librep', or dynamically loaded extensions,
may provide further input stream types.

Output Streams
--------------

   These are the different types of output stream, for the functions
which use them see Output Functions.

`FILE'
     Writes to the file object FILE. See Files.

`FUNCTION'
     The function FUNCTION is called with one argument, either a string
     or a character. This should be used as the circumstances dictate.
     If the function returns a number it is the number of characters
     actually used, otherwise it is assumed that all the characters
     were successful.

`PROCESS'
     Writes to the standard input of the process object PROCESS. If
     PROCESS isn't running an error is signalled. See Processes.

`t'
     Appends the character(s) to the end of the status line message.

`()'
     Write to the stream stored in the variable `standard-output'.

   It is also possible to store the characters sent to an output stream
in a string.

 - Function: make-string-output-stream
     Returns an output stream. It accumulates the text sent to it for
     the benefit of the `get-output-stream-string' function.

 - Function: get-output-stream-string string-output-stream
     Returns a string consisting of the text sent to the
     STRING-OUTPUT-STREAM since the last call to
     GET-OUTPUT-STREAM-STRING (or since this stream was created by
     `make-string-output-stream').

          (setq stream (make-string-output-stream))
              => ("" . 0)
          (prin1 keymap-path stream)
              => ("(lisp-mode-keymap global-keymap)" . 64)
          (get-output-stream-string stream)
              => "(lisp-mode-keymap global-keymap)"

 - Variable: standard-output
     This variable contains the output stream which is used when no
     other is specified (or when the given output stream is false).

 - Variable: standard-error
     This variable contains the output stream which is used when an
     error message is being reported.

   Applications that embed `librep', or dynamically loaded extensions,
may provide further output stream types.

Input Functions
---------------

 - Function: read-char stream
     Read and return the next character from the input stream STREAM. If
     the end of the stream is reached false is returned.

 - Function: read-line stream
     This function reads one line of text from the input stream STREAM,
     a string containing the line (including the newline character
     which terminates the line).

     If the end of stream is reached before any characters can be read
     false is returned, if the end of stream is reached but some
     characters have been read (but not the newline) these characters
     are made into a string and returned.

     Note that unlike the Common Lisp function of the same name, the
     newline character is not removed from the returned string.

 - Function: read stream
     This function is the function which encapsulates the Lisp reader
     (see The Lisp Reader). It reads as many characters from the
     input stream STREAM as required to form the read syntax of a single
     Lisp object (see Read Syntax), this object is then returned.

 - Function: read-from-string string #!optional start
     Reads one Lisp object from the string STRING, the first character
     is read from position START (or position zero).

          (read-from-string STRING START)
          ==
          (read (make-string-input-stream STRING START))

Output Functions
----------------

 - Function: write stream data #!optional length
     Writes the specified character(s) to the output stream STREAM.
     DATA is either the character or the string to be written. If DATA
     is a string the optional argument LENGTH may specify how many
     characters are to be written. The value returned is the number of
     characters successfully written.

          (write standard-output "Testing 1.. 2.. 3..")
              -| Testing 1.. 2.. 3..
              => 19

 - Function: copy-stream input-stream output-stream
     This function copies all characters which may be read from
     INPUT-STREAM to OUTPUT-STREAM. The copying process is not stopped
     until the end of the input stream is read. Returns the number of
     characters copied.

     Be warned, if you don't choose the streams carefully you may get a
     deadlock which only an interrupt signal can break!

 - Function: print object #!optional stream
     Outputs a newline character to the output stream STREAM, then
     writes a textual representation of OBJECT to the stream.

     If possible, this representation will be the read syntax of OBJECT.

     OBJECT is returned.

          (print '(1 2 3))
              -|
              -| (1 2 3)
              => (1 2 3)

 - Function: prin1 object #!optional stream
     Similar to `print' but no initial newline is output.

          (prin1 '(1 2 3))
              -| (1 2 3)
              => (1 2 3)

          (prin1 '|(xy((z]|)              ;A strange symbol
              -| \(xy\(\(z\]
              => \(xy\(\(z\]

 - Function: prin1-to-string object
     Returns a string containing the characters that `prin1' would
     output when it prints OBJECT.

          (prin1-to-string '(1 2 3))
              => "(1 2 3)"

 - Function: princ object #!optional stream
     Prints a textual representation of OBJECT to the output stream
     STREAM. No steps are taken to create output that `read' can parse;
     in particular, no double-quote characters surround strings.

          (princ "foo")
              -| foo
              => "foo"

          (princ '|(xy((z]|)
              -| (xy((z]
              => \(xy\(\(z\]

   Several variables may be used to control how objects are printed.

 - Variable: print-escape
     This defines which control characters `print' and `prin1' will
     escape (using backslashes). Possible values are:

    `()'
          Only escape double-quote and backslash characters.

    `newlines'
          Only escape double-quote, backslash, newline, `TAB', and
          formfeed characters.

    `t'
          Escape double-quote, backslash, and all control characters
          (anything with a numeric value less than 32, or greater than
          126).

 - Variable: print-length
     This variable, if true, limits the number of elements printed from
     lists.

 - Variable: print-level
     This variable, if true, limits the recursion depth when printing
     lists.

Formatted Output
----------------

 - Function: format stream template #!rest values
     Writes to a stream, STREAM, a string constructed from the format
     string, TEMPLATE, and list of arguments VALUES.

     If STREAM is false the resulting string will be returned, not
     written to a stream.

     TEMPLATE is a template for the output string, any `%' characters
     introduce a substitution, using the next unused argument.  The
     substitutions have the following syntax,

          %[INDEX$][FLAGS][FIELD-WIDTH]CONVERSION

     INDEX is an optional decimal number specifying exactly which of
     the VALUES this conversion refers to (with the first at position
     one), and is usually used when translating messages; by default the
     next value is used.

     FIELD-WIDTH is a positive decimal integer, defining the size in
     characters of the substitution output.

     CONVERSION is a character defining how to convert the
     corresponding argument value to text. The default options are:

    `s'
          Write the printed representation of the value without quoting
          (as if from the `princ' function).

    `S'
          Write the printed representation _with_ quoting enabled (like
          the `prin1' function).

    `d'
          Output the value as a decimal number.

    `o'
          Write the value in octal.

    `x'
    `X'
          In hexadecimal.

    `c'
          Write the character specified by the value.

    `%'
          Print a literal percent character. None of the VALUES are
          used.

     FLAGS is a sequence of zero or more of the following characters,

    `_'
          Left justify the substitution within the field.

    `^'
          Truncate the substitution at the size of the field.

    `0'
          Pad the field with zeros instead of spaces.

    `+'
          For `d', `x', and `o' conversions, output a leading plus sign
          if the argument is positive.

    ` ' (a space)
          For `d', `x', and `o' conversions, if the result doesn't
          start with a plus or minus sign, output a leading space.

     The list of CONVERSIONS can be extended through the
     `format-hooks-alist' variable; the strings created by these extra
     conversions are formatted as if by the `s' conversion.

     Note that the FIELD-WIDTH and all flags currently have no effect
     on the `S' conversion, (or the `s' conversion when the argument
     isn't a string).

     If STREAM isn't false (in which case the created string is
     returned) the value of STREAM is returned.

          (format nil "foo %S bar 0x%x" '(x . y) 255)
              => "foo (x . y) bar 0xff"

          (format standard-output "The %2$s is %1$s!" "purple" "dog")
              -| The dog is purple!
              => #<buffer *jade*>

 - Variable: format-hooks-alist
     This variable is an association-list, each element being `(CHAR .
     FUNCTION)', defining extra conversions for the `format' function.

     If a conversion `%X' is given, and the alist contains an element
     whose car is the character X, the the associated function is
     called with one value, the next argument to be formatted. It should
     return the string to be inserted.

Hooks
=====

   A "hook" allows you to wedge your own pieces of Lisp code into the
operation of other functions, enable the extension of that
functionality. These pieces of code are evaluated via the hook and the
result is available to the hook's caller. One hook has already been
encountered, the `format-hooks-alist' variable (see Formatted Output).

Functions As Hooks
------------------

   Some hooks only allow a single piece of code to be hooked in.
Usually a normally-undefined function is used; to install your hook
defined a function with the name of the hook. When the hook is to be
evaluated the function is called.

   Generally the name of the hook's function will end in `-function'.

   An alternative scheme is to use a variable to store the hook, its
value should be the function to call.

Normal Hooks
------------

   This is the standard type of hook, it is a variable whose value is a
list of functions. When the hook is evaluated each of the functions
will be called in turn.

   The names of hooks of this type will normally end in `-hook'.

   These functions are exported by the `rep.system' module.

 - Function: add-hook hook function #!optional at-end
     This function adds a new function FUNCTION to the list of
     functions installed in the (list) hook HOOK (a symbol).

     If AT-END is true the new function is added at the end of the
     hook's list of functions (and therefore will be called last when
     the hook is evaluated), otherwise the new function is added to the
     front of the list.

          text-mode-hook
              => (#<closure fill-mode-on>)
          (add-hook 'text-mode-hook my-function)
              => (#<closure my-function> #<closure fill-mode-on>)

 - Function: remove-hook hook function
     This function removes the function FUNCTION from the list of
     functions stored in the (list) hook HOOK (a symbol).

     _All_ instances of FUNCTION are deleted from the hook.

   There are actually three calling conventions for this type of hook,
differing in how many of the functions in the list actually get called.
In this simplest form, _all_ functions are called. In an `and' type
hook, functions are only invoked while all others have returned true.
As soon as the first function in the hook returns false, no others will
be called. Finally, an `or' type hook aborts when a function returns a
true result.

 - Function: call-hook hook arg-list #!optional type
     Call the hook named by the symbol HOOK, passing all functions the
     arguments in the list ARG-LIST. Note that HOOK may also be the
     actual list of functions to call.

     TYPE defines how the return values of each function in the hook
     are treated. If TYPE is false they are ignored, if TYPE is the
     symbol `and' the hook aborts after a function returns false, if
     TYPE is `or' the hook aborts when a function returns true.

     In all cases the value returned by the last-evaluated function is
     returned.

Files
=====

   `librep' allows you to manipulate files in the operating system's
filing system; a special type of Lisp object, a "file object", is used
to represent files which have been opened for reading or writing
(through the streams mechanism, see Streams).

   Names of files are represented by strings, the syntax of file names
is defined by the underlying operating system: `librep' simply treats
it as a string.

   Unless otherwise stated, all functions and variables described in the
following sections are exported by the `rep.io.files' module.

File Names
----------

   A "file name" is a string identifying an individual file (or
directory) in the filing system (i.e. the disk). The exact syntax of
file names depends on the operating system. There are several functions
for manipulating file names.

 - Function: file-name-absolute-p file-name
     Returns true when FILE-NAME is not specified relative to the
     current directory.

 - Function: file-name-directory file-name
     This function returns the directory part of the file name string
     FILE-NAME. This is the substring of FILE-NAME defining the
     directory containing the file.

          (file-name-directory "/tmp/foo")
              => "/tmp/"

          (file-name-directory "foo")
              => ""

          (file-name-directory "foo/bar/")
              => "foo/bar/"

 - Function: file-name-nondirectory file-name
     Returns the substring of the file name FILE-NAME which is _not_
     the directory part.

          (file-name-nondirectory "/tmp/foo")
              => "foo"

          (file-name-nondirectory "foo")
              => "foo"

          (file-name-nondirectory "foo/bar/")
              => ""

 - Function: file-name-as-directory file-name
     Returns a string through which the item in the file system named by
     FILE-NAME can be referred to as a directory.

          (file-name-as-directory "./foo")
              => "./foo/"

          (file-name-as-directory "./foo/")
              => "./foo/"

 - Function: directory-file-name directory-name
     Returns a string through which the directory named by
     DIRECTORY-NAME can be referred to as a file.

          (directory-file-name "./foo/")
              => "./foo"

          (directory-file-name "./foo")
              => "./foo"

 - Function: expand-file-name file-name #!optional base-dir
     Expands FILE-NAME assuming that it specifies a file relative to
     BASE-DIR. If BASE-DIR is undefined it is taken as the current
     value of the `default-directory' variable. While expanding the
     file name, any obvious simplifications will be performed (e.g. on
     Unix the removal of "." and ".." where possible).

     Note that the returned file name will only be absolute if one of
     the following conditions is met:

       1. BASE-DIR (or `default-directory') is absolute,

       2. FILE-NAME is already absolute.

          (expand-file-name "foo" "./bar")
              => "bar/foo"

     Note for file handler implementors: when a handler is called for
     the `expand-file-name' operation, it will only ever receive one
     argument, the already expanded file name. The only action that may
     be need to be taken is to simplify the file name (e.g. removing `.'
     and `..' entries or whatever).

 - Function: canonical-file-name file-name
     This function returns the canonical name of the file referred to
     by the string FILE-NAME. The canonical name of a file is defined
     such that two files can be compared simply by comparing their
     canonical names; if the names match, they refer to the same file.

     (Note that the opposite isn't always true, if two canonical names
     don't match the files could still be the same, for example via
     hard links. On most operating systems, symbolic links will be
     expanded where possible.

          (canonical-file-name "foo")
              => "/home/john/src/librep/man/foo"

 - Function: local-file-name file-name
     `librep' supports extensible file handling (see File Handlers),
     so file names may refer to files not residing in the
     system's local file structure, and thus which are unavailable to
     other programs.

     This function returns either the absolute name of the file
     FILE-NAME, if it is found in the local system, or false, if the
     file does not.

          (local-file-name "foo")
              => "/home/john/src/librep/man/foo"

          (local-file-name "/john@tango:foo")
              => ()

 - Function: make-temp-name
     This function returns the name of a file which, when created, may
     be used for temporary storage. Each time this function is called a
     unique name is computed.

          (make-temp-name)
              => "/tmp/00088aaa"

          (make-temp-name)
              => "/tmp/00088baa"

 - Variable: default-directory
     This variable names the current working directory. All relative
     file names are interpreted starting from this location in the file
     system.

File Objects
------------

   A file object is a Lisp object which represents an open file in the
filing system. Any file object may be used as a stream (either input or
output) to access the contents of the file (see Streams).

 - Function: filep object
     This function returns true when its argument is a file object.

Creating File Objects
.....................

 - Function: open-file file-name mode
     This function opens the file called FILE-NAME (see File Names)
     and returns the new file object.

     The MODE argument is a symbol defining the access modes used to
     open the file with, the options are:

    `read'
          Open an existing file for reading only.

    `write'
          Open the file for writing only, if the file exists it is
          truncated to zero length. Otherwise a new file is created.

    `append'
          Open the file for appending to, i.e. writing to the end of
          the file. If the file doesn't exist it is created.

   The three standard I/O streams are also available as file handles.

 - Function: stdin-file
     Return a file object representing the interpreters standard input.

 - Function: stdout-file
     Return a file object representing the interpreters standard output.

 - Function: stderr-file
     Return a file object representing the interpreters standard error.

   Attempting to close any of these files will result in the associated
stream being connected to `/dev/null'.

Destroying File Objects
.......................

   The easiest way to close a file is simply to eliminate all
references to it, subsequently the garbage collector will close it for
you. It is better to close files explicitly though since only a limited
number of files may be opened concurrently.

 - Function: close-file file-object
     This function closes the file pointed to by the file object
     FILE-OBJECT.

     Subsequently, any stream accesses FILE-OBJECT are illegal and will
     signal an error.

Functions on File Objects
.........................

 - Function: seek-file file #!optional offset where
     When called as `(seek-file FILE)', returns the distance in bytes
     from the start of the file that the next character would be read
     from.

     When called as `(seek-file FILE OFFSET [WHERE])' alters the
     position from which the next byte will be read. WHERE can be one
     of the values:

    `()'
          OFFSET bytes after the current position.

    `start'
          OFFSET bytes after the beginning of the file.

    `end'
          OFFSET bytes before the end of the file.

     Note that not all files may be seekable; if `(seek-file FILE)'
     returns false, indicating that the current position is unknown,
     any attempts to set the current position will also fail.

 - Function: flush-file file
     This function flushes any buffered output to the file object FILE
     to disk.

 - Function: file-binding file
     Returns the name of the file which the file object FILE is
     currently bound to. Returns false if the file is currently unbound
     (i.e. `close-file' was called on it).

   The next three functions are used when non-local files are being
accessed. See File Handlers for more details.

 - Function: file-bound-stream file
     If the file object FILE doesn't refer to a file in the local
     filing system, return the stream that it is bound to (allowing the
     file's contents to be accessed), this may or may not be another
     file object.

 - Function: file-handler-data file
     Return the file-handler-specific data associated with the file
     object FILE.

 - Function: set-file-handler-data file data
     Set the handler-specific data of file object FILE to DATA.  This
     should only be done by the handler owning the file.

   It's also possible to register a callback function to be invoked when
input is available on a file,

 - Function: set-input-handler local-file function
     Arrange for FUNCTION to be called whenever pending input is
     available on LOCAL-FILE, a file object bound to a file in the
     local file space.

     Note that this makes LOCAL-FILE subsequently do non-blocking input.

     This function is normally only useful when LOCAL-FILE represents a
     pipe or socket.

File Information
----------------

   A number of functions exist which when given the name of a file
return one of the attributes relating to that file.

 - Function: file-exists-p file-name
     Returns true when a file FILE-NAME exists.

 - Function: file-regular-p file-name
     Returns true when the file FILE-NAME is a `normal' file. This means
     that it isn't a directory, device, symbolic link or whatever.

 - Function: file-directory-p file-name
     Returns true when the file FILE-NAME is a directory.

 - Function: file-symlink-p file-name
     Returns true when the file FILE-NAME is a symbolic link.

 - Function: file-readable-p file-name
     Returns true when the file FILE-NAME is readable.

 - Function: file-writable-p file-name
     Returns true when the file FILE-NAME is writable.

 - Function: file-owner-p file-name
     Returns true when the ownership of the file FILE-NAME is the same
     as that of any files written by the editor.

 - Function: file-size file-name
     Returns the number of bytes stored in the file named FILE-NAME.

 - Function: file-nlinks file-name
     Returns the number of hard links pointing to the file FILE-NAME. If
     FILE-NAME has only one name the number will be one.

 - Function: file-modes file-name
     This function returns the access permissions of the file FILE-NAME.
     This will be an integer whose format is undefined; it differs from
     operating system to operating system.

 - Function: file-modes-as-string file-name
     Returns a ten-character string describing the attibutes of the file
     called FILE-NAME

          (file-modes-as-string ".")
              => "drwxr-sr-x"

 - Function: set-file-modes file-name modes
     This function sets the access permissions of the file FILE-NAME to
     the integer MODES (as returned by the `file-modes' function).

 - Function: file-modtime file-name
     Returns the system time at the last modification to the file
     FILE-NAME, this will be in the usual timestamp format, see
     Timestamps.

 - Function: file-newer-than-file-p file-name1 file-name2
     This function returns true if the file FILE-NAME1 was modified
     more recently than the file FILE-NAME2 was.

Manipulating Files
------------------

 - Command: delete-file file-name
     This function deletes the file called FILE-NAME. When called
     interactively FILE-NAME is prompted for.

 - Command: rename-file file-name new-name
     This function attempts to change the name of the file NEW-NAME to
     NEW-NAME.

     This won't work from one file system to another or if a file called
     NEW-NAME already exists, in these cases an error is signalled.

     This prompts for its arguments when called interactively.

 - Command: copy-file file-name destination-name
     Creates a new copy of the file FILE-NAME with the name
     DESTINATION-NAME.

     The access modes of the new file will be the same as those of the
     original file.

     The arguments are prompted for when this function is called
     interactively.