This is librep.info, produced by makeinfo version 4.2 from librep.texi.

INFO-DIR-SECTION Programming Languages
START-INFO-DIR-ENTRY
* librep: (librep).		A flexible Lisp environment
END-INFO-DIR-ENTRY

   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.


File: librep.info,  Node: Building Lists,  Next: Accessing List Elements,  Prev: List Structure,  Up: Lists

Building Lists
..............

   It has already been described how you can create lists using the Lisp
reader; this method does have a drawback though: the list created is
effectively static. If you modify the contents of the list and that
list was created when a function was defined the list will remain
modified for all future invocations of that function. This is not
usually a good idea, consider the following function definition,

     (defun bogus-function (x)
       "Return a list whose first element is nil and whose second element is X."
       (let
           ((result '(nil nil)))     ;Static list which is filled in each time
         (rplaca (cdr result) x)     ; the function is called
         result))

This function does in fact do what its documentation claims, but a
problem arises when it is called more than once,

     (setq x (bogus-function 'foo))
         => (nil foo)
     (setq y (bogus-function 'bar))
         => (nil bar)               ;The first result has been destroyed
     x
         => (nil bar)               ;See!

   This example is totally contrived--no one would ever write a
function like the one in the example but it does demonstrate the need
for a dynamic method of creating lists.

 - Function: list #!rest elements
     This function creates a list out of its arguments, if zero
     arguments are given the empty list, `()', is returned.

          (list 1 2 3)
              => (1 2 3)
          
          (list (major-version-number) (minor-version-number))
              => (3 2)
          
          (list)
              => ()

 - Function: list* arg1 arg2 ... argn-1 argn
     Creates a new list `(ARG1 ARG2 ... ARGN-1 .  ARGN)'.

          (list* 1 2 '(3 4))
              => (1 2 3 4)

 - Function: make-list length #!optional initial-value
     This function creates a list LENGTH elements long. If the
     INITIAL-VALUE argument is given it defines the value of all
     elements in the list, if it is not defined they are all `()'.

          (make-list 2)
              => (() ())
          
          (make-list 3 t)
              => (t t t)
          
          (make-list 0)
              => ()

 - Function: append #!rest lists
     This function creates a new list with the elements of each of its
     arguments (which must be lists). Unlike the function `nconc' this
     function preserves the structure of all its arguments.

          (append '(1 2 3) '(4 5))
              => (1 2 3 4 5)
          
          (append)
              => ()

     What actually happens is that all arguments but the last are
     copied, then the last argument is linked on to the end of the list
     (uncopied).

          (setq foo '(1 2))
              => (1 2)
          (setq bar '(3 4))
              => (3 4)
          (setq baz (append foo bar))
              => (1 2 3 4)
          (eq (nthcdr 2 baz) bar)
              => t

     The following diagram shows the final state of the three variables
     more clearly,

          foo--> +-----+-----+   +-----+-----+
                 |  o  |  o----> |  o  |     |
                 +--|--+-----+   +--|--+-----+
                    |               |
                    o--> 1          o--> 2   bar
                    |               |          ->
          baz--> +--|--+-----+   +--|--+-----+   +-----+-----+   +-----+-----+
                 |  o  |  o----> |  o  |  o----> |  o  |  o----> |  o  |     |
                 +-----+-----+   +-----+-----+   +--|--+-----+   +--|--+-----+
                                                    |               |
                                                     --> 3           --> 4

     Note how `foo' and the first half of `baz' use the _same_ objects
     for their elements--copying a list only copies its cons cells, its
     elements are reused. Also note how the variable `bar' actually
     references the mid-point of `baz' since the last list in an
     `append' call is not copied.

 - Function: remove elt list
     Return a copy of LIST, with all elements the same as ELT discarded
     (using the `equal' function to compare).

 - Function: remq elt list
     Similar to the `remove' function, except that comparisons are made
     using `eq'.

 - Function: reverse list
     This function returns a new list; it is made from the elements of
     the list LIST in reverse order. Note that this function does not
     alter its argument.

          (reverse '(1 2 3 4))
              => (4 3 2 1)

   As a postscript to this section, the function used as an example at
the beginning could now be written as,

     (defun not-so-bogus-function (x)
       (list nil x))

   Also note that the `cons' function can be used to create lists by
hand and to add new elements onto the front of a list. For example:

     (setq x (list 1 2 3))
         => (1 2 3)
     (setq x (cons 0 x))
         => (0 1 2 3)


File: librep.info,  Node: Accessing List Elements,  Next: Modifying Lists,  Prev: Building Lists,  Up: Lists

Accessing List Elements
.......................

   The most flexible method of accessing an element in a list is via a
combination of the `car' and `cdr' functions. There are other functions
which provide an easier way to get at the elements in a flat list.
These will usually be faster than a string of `car' and `cdr'
operations.

 - Function: nth count list
     This function returns the element COUNT elements down the list,
     therefore to access the first element use a COUNT of zero (or even
     better the `car' function). If there are too few elements in the
     list and no element number COUNT can be found `()' is returned.

          (nth 3 '(0 1 2 3 4 5))
              => 3
          
          (nth 0 '(foo bar)
              => foo

 - Function: nthcdr count list
     This function takes the cdr of the list LIST COUNT times,
     returning the last cdr taken.

          (nthcdr 3 '(0 1 2 3 4 5))
              => (3 4 5)
          
          (nthcdr 0 '(foo bar))
              => (foo bar)

 - Function: last list
     This function returns the last element in the list LIST. If the
     list has zero elements `()' is returned.

          (last '(1 2 3))
              => 3
          
          (last '())
              => ()

 - Function: member object list
     This function scans through the list LIST until it finds an element
     which is `equal' to OBJECT. The tail of the list (the cons cell
     whose car is the matched object) is then returned. If no elements
     match OBJECT then the empty list `()' is returned.

          (member 'c '(a b c d e))
              => (c d e)
          
          (member 20 '(1 2))
              => ()

 - Function: memq object list
     This function is similar to `member' except that comparisons are
     performed by the `eq' function not `equal'.


File: librep.info,  Node: Modifying Lists,  Next: Association Lists,  Prev: Accessing List Elements,  Up: Lists

Modifying Lists
...............

   The `nthcdr' function can be used in conjunction with the `rplaca'
function to modify an arbitrary element in a list. For example,

     (rplaca (nthcdr 2 '(0 1 2 3 4 5)) 'foo)
         => foo

sets the third element of the list `(0 1 2 3 4 5)' to the symbol called
`foo'.

   There are also functions which modify the structure of a whole list.
These are called "destructive" operations because they modify the actual
structure of a list--no copy is made. This can lead to unpleasant side
effects if care is not taken.

 - Function: nconc #!rest lists
     This function is the destructive equivalent of the function
     `append', it modifies its arguments so that it can return a list
     which is the concatenation of the elements in its arguments lists.

     Like all the destructive functions this means that the lists given
     as arguments are modified (specifically, the cdr of their last
     cons cell is made to point to the next list). This can be seen
     with the following example (similar to the example in the `append'
     documentation).

          (setq foo '(1 2))
              => (1 2)
          (setq bar '(3 4))
              => (3 4)
          (setq baz (nconc foo bar))
              => (1 2 3 4)
          foo
              => (1 2 3 4)                ;`foo' has been altered!
          (eq (nthcdr 2 baz) bar)
              => t

     The following diagram shows the final state of the three variables
     more clearly,

          foo-->                           bar-->
          baz--> +-----+-----+   +-----+-----+   +-----+-----+   +-----+-----+
                 |  o  |  o----> |  o  |  o----> |  o  |  o----> |  o  |     |
                 +--|--+-----+   +--|--+-----+   +--|--+-----+   +--|--+-----+
                    |               |               |               |
                     --> 1           --> 2             --> 3           --> 4

 - Function: nreverse list
     This function rearranges the cons cells constituting the list LIST
     so that the elements are in the reverse order to what they were.

          (setq foo '(1 2 3))
              => (1 2 3)
          (nreverse foo)
              => (3 2 1)
          foo
              => (1)                      ;`foo' wasn't updated when the list
                                          ; was altered.

 - Function: delete object list
     This function destructively removes all elements of the list LIST
     which are `equal' to OBJECT then returns the modified list.

          (delete 1 '(0 1 0 1 0))
              => (0 0 0)

     When this function is used to remove an element from a list which
     is stored in a variable that variable must be set to the return
     value of the `delete' function. Otherwise, if the first element of
     the list has to be deleted (because it is `equal' to OBJECT) the
     value of the variable will not change.

          (setq foo '(1 2 3))
              => (1 2 3)
          (delete 1 foo)
              => (2 3)
          foo
              => (1 2 3)
          (setq foo (delete 1 foo))
              => (2 3)

 - Function: delq object list
     This function is similar to the `delete' function, the only
     difference is that the `eq' function is used to compare OBJECT
     with each of the elements in LIST, instead of the `equal' function
     which is used by `delete'.

 - Function: sort list #!optional predicate
     Destructively sorts (i.e. by modifying cdrs) the list of values
     LIST, to satisfy the function PREDICATE, returning the sorted
     list. If PREDICATE is undefined, the `<' function is used, sorting
     the list into ascending order.

     PREDICATE is called with two values, it should return true if the
     first is considered less than the second.

          (sort '(5 3 7 4))
              => (3 4 5 7)

     The sort is stable, in that elements in the list which are equal
     will preserve their original positions in relation to each other.


File: librep.info,  Node: Association Lists,  Next: Infinite Lists,  Prev: Modifying Lists,  Up: Lists

Association Lists
.................

   An "association list" (or "alist") is a list mapping keys to to.
Each element of the alist is a cons cell, the car of which is the
"key", the cdr the value that it associates to. For example an alist
could look like,

     ((fred . 20)
      (bill . 30))

this alist has two keys, `fred' and `bill' which both associate to an
integer (20 and 30 respectively).

   It is possible to make the associated values lists, this looks like,

     ((fred 20 male)
      (bill 30 male)
      (sue  25 female))

in this alist the symbol `fred' is associated with the list `(20 male)'.

   There are a number of functions which let you interrogate an alist
with a given key for its association.

 - Function: assoc key alist
     This function scans the association list ALIST for the first
     element whose car is `equal' to KEY, this element is then
     returned. If no match of KEY is found false is returned.

          (assoc 'two '((one . 1) (two . 2) (three . 3)))
              => (two . 2)

 - Function: assq key alist
     Similar to the function `assoc' except that the function `eq' is
     used to compare elements instead of `equal'.

     It is not usually wise to use `assq' when the keys of the alist
     may not be symbols--`eq' won't think two objects are equivalent
     unless they are the _same_ object!

          (assq "foo" '(("bar" . 1) ("foo" . 2)))
              => ()
          (assoc "foo" '(("bar" . 1) ("foo" . 2)))
              => ("foo" . 2)

 - Function: rassoc association alist
     This function searches through ALIST until it finds an element
     whose cdr is `equal' to ASSOCIATION, that element is then returned.
     false will be returned if no elements match.

          (rassoc 2 '((one . 1) (two . 2) (three . 3)))
              => (two . 2)

 - Function: rassq association alist
     This function is equivalent to `rassoc' except that it uses `eq'
     to make comparisons.


File: librep.info,  Node: Infinite Lists,  Prev: Association Lists,  Up: Lists

Infinite Lists
..............

   Sometimes it is useful to be able to create `infinite' lists--that
is, lists which appear to have no last element--this can easily be done
in Lisp by linking the cdr of the last cons cell in the list structure
back to the beginning of the list.

      -----------------------------------
     |                                   |
      --> +-----+-----+   +-----+-----+  |
          |  o  |  o----> |  o  |  o-----
          +--|--+-----+   +--|--+-----+
             |               |
              --> 1           --> 2

   The diagram above represents the infinite list `(1 2 1 2 1 2 ...)'.

   Infinite lists have a major drawback though, many of the standard
list manipulation functions can not be used on them. These functions
work by moving through the list until they reach the end. If the list
has _no_ end the function may never terminate and the only option is to
send the interpreter an interrupt signal.

   The only functions which may be used on circular lists are: the cons
cell primitives (`cons', `car', `cdr', `rplaca', `rplacd'), `nth' and
`nthcdr'.

   Also note that infinite lists can't be printed. But note the
`print-length' and `print-level' variables, see *Note Output
Functions::.


File: librep.info,  Node: Vectors,  Next: Strings,  Prev: Lists,  Up: Sequences

Vectors
-------

   A vector is a fixed-size sequence of Lisp objects, each element may
be accessed in constant time--unlike lists where the time taken to
access an element is proportional to the position of the element.

   The read syntax of a vector is an opening square bracket, followed
by zero or more space-separated objects, followed by a closing square
bracket. For example,

     [zero one two three]

   In general it is best to use vectors when the number of elements to
be stored is known and lists when the sequence may grow or shrink.

 - Function: vectorp object
     This function returns true if its argument, OBJECT, is a vector.

 - Function: vector #!rest elements
     This function creates a new vector containing the arguments given
     to the function.

          (vector 1 2 3)
              => [1 2 3]
          
          (vector)
              => []

 - Function: make-vector size #!optional initial-value
     Returns a new vector, SIZE elements big. If INITIAL-VALUE is
     defined each element of the new vector is set to INITIAL-VALUE,
     otherwise they are all `()'.

          (make-vector 4)
              => [() () () ()]
          
          (make-vector 2 t)
              => [t t]


File: librep.info,  Node: Strings,  Next: Array Functions,  Prev: Vectors,  Up: Sequences

Strings
-------

   A string is a vector of characters (*note Characters::), they are
generally used for storing and manipulating pieces of text.  `librep'
puts no restrictions on the values which may be stored in a
string--specifically, the null character (`^@') may be stored with no
problems.

   The read syntax of a string is a double quote character, followed by
the contents of the string, the object is terminated by a second double
quote character. For example, `"abc"' is the read syntax of the string
`abc'.

   Any backslash characters in the string's read syntax introduce an
escape sequence; one or more of the following characters are treated
specially to produce the next _actual_ character in the string.

   The following escape sequences are supported (all are shown without
their leading backslash `\' character).

`n'
     A newline character.

`r'
     A carriage return character.

`f'
     A form feed character.

`t'
     A TAB character.

`a'
     A `bell' character (this is Ctrl-g).

`\'
     A backslash character.

`^C'
     The `control' code of the character C. This is calculated by
     toggling the seventh bit of the _upper-case_ version of C.

     For example,

          \^C             ;A Ctrl-c character (ASCII value 3)
          \^@            ;The NUL character (ASCII value 0)

`012'
     The character whose ASCII value is the octal value `012'. After the
     backslash character the Lisp reader reads up to three octal digits
     and combines them into one character.

`x12'
     The character whose ASCII value is the hexadecimal value `12', i.e.
     an `x' character followed by one or two hex digits.

 - Function: stringp object
     This function returns true if its argument is a string.

 - Function: make-string length #!optional initial-character
     Creates a new string containing LENGTH characters, each character
     is initialised to INITIAL-CHARACTER (or to spaces if
     INITIAL-CHARACTER is not defined).

          (make-string 3)
              => "   "
          
          (make-string 2 ?$)
              => "$$"

 - Function: concat #!rest args
     This function concatenates all of its arguments, ARGS, into a
     single string which is returned. If no arguments are given then
     the null string (`') results.

     Each of the ARGS may be a string, a character or a list or vector
     of characters. Characters are stored in strings modulo 256.

          (concat "foo" "bar")
              => "foobar"
          
          (concat "a" ?b)
              => "ab"
          
          (concat "foo" [?b ?a ?r])
              => "foobar"
          
          (concat)
              => ""

 - Function: substring string start #!optional end
     This function creates a new string which is a partial copy of the
     string STRING. The first character copied is START characters from
     the beginning of the string. If the END argument is defined it is
     the index of the character to stop copying at, if it is not defined
     all characters until the end of the string are copied.

          (substring "xxyfoozwx" 3 6)
              => "foo"
          
          (substring "xyzfoobar" 3)
              => "foobar"

 - Function: string= string1 string2
     This function compares the two strings STRING1 and STRING2--if
     they are made from the same characters in the same order then true
     is returned.

          (string= "one" "one")
              => t
          
          (string= "one" "two")
              => ()

     Note that an alternate way to compare strings (or anything!) is to
     use the `equal' function.

 - Function: string-equal string1 string2
     Returns true if STRING1 and STRING2 are the same, ignoring
     differences in character case.

 - Function: string< string1 string2
     This function returns true if STRING1 is `less' than `string2'.
     This is determined by comparing the two strings a character at a
     time, the first pair of characters which do not match each other
     are then compared with a normal `less-than' function.

     In `librep' the standard `<' function understands strings so
     `string<' is just a macro calling that function.

          (string< "abc" "abd")
              => t
          
          (string< "abc" "abb")
              => ()

 - Function: string-lessp string1 string2
     Similar to `string<' but ignores character case in comparisons.

   See *Note String Functions:: for a few more string manipulating
functions, and *Note Regular Expressions:: for a method of pattern
matching in strings.


File: librep.info,  Node: Array Functions,  Next: Sequence Functions,  Prev: Strings,  Up: Sequences

Array Functions
---------------

 - Function: arrayp object
     This function returns true if OBJECT is an array.

 - Function: aref array position
     Returns the element of the array (vector or string) ARRAY POSITION
     elements from the first element (i.e. the first element is
     numbered zero).  If no element exists at POSITION in ARRAY, false
     is returned.

          (aref [0 1 2 3] 2)
              => 2
          
          (aref "abcdef" 3)
              => 100                      ;`d'

 - Function: aset array position value
     This function sets the element of the array ARRAY with an index of
     POSITION (counting from zero) to VALUE. An error is signalled if
     element POSITION does not exist. The result of the function is
     VALUE.

          (setq x [0 1 2 3])
              => [0 1 2 3]
          (aset x 2 'foo)
              => foo
          x
              => [0 1 foo 3]


File: librep.info,  Node: Sequence Functions,  Prev: Array Functions,  Up: Sequences

Sequence Functions
------------------

 - Function: sequencep arg
     Returns true if ARG is a sequence, i.e. a list or an array.

 - Function: length sequence
     This function returns the length (an integer) of the sequence
     SEQUENCE.

          (length "abc")
              => 3
          
          (length '(1 2 3 4))
              => 4
          
          (length [x y])
              => 2

 - Function: copy-sequence sequence
     Returns a new copy of the sequence SEQUENCE. Where possible (in
     lists and vectors) only the `structure' of the sequence is newly
     allocated: the same objects are used for the elements in both
     sequences.

          (copy-sequence "xy")
              => "xy"
          
          (setq x '("one" "two"))
              => ("one" "two")
          (setq y (copy-sequence x))
              => ("one" "two")
          (eq x y)
              => ()
          (eq (car x) (car y))
              => t

 - Function: elt sequence position
     This function returns the element of SEQUENCE POSITION elements
     from the beginning of the sequence.

     This function is a combination of the `nth' and `aref' functions.

          (elt [0 1 2 3] 1)
              => 1
          
          (elt '(foo bar) 0)
              => foo


File: librep.info,  Node: Symbols,  Next: Evaluation,  Prev: Sequences,  Up: The language

Symbols
=======

   Symbols are objects with a name (almost always a unique name). They
are one of the most important data types in Lisp since they are used to
provided named variables (*note Variables::) and functions (*note
Functions::).

 - Function: symbolp arg
     This function returns true when its argument is a symbol.

* Menu:

* Symbol Syntax::               The read syntax of symbols
* Symbol Attributes::           The objects stored in a symbol
* Obarrays::                    Vectors used to store symbols
* Creating Symbols::            Allocating new symbols
* Interning::                   Putting a symbol into an obarray
* Property Lists::              Each symbol has a set of properties
* Keyword Symbols::             Self-evaluating keywords


File: librep.info,  Node: Symbol Syntax,  Next: Symbol Attributes,  Up: Symbols

Symbol Syntax
-------------

   The read syntax of a symbol is usually its name; however, if the name
contains any meta-characters (whitespace or any from `()[]'";|\') they
will have to be entered specially. There are two ways to tell the
reader that a meta-character is actually part of the symbol's name:

  1. Precede the meta-character by a backslash character (`\'), for
     example:

          xy\(z\)                 ;the symbol whose name is `xy(z)'

  2. Enclose part of the name in vertical bars (two `|' characters).
     All characters after the starting vertical line are copied as-is
     until the closing vertical line is encountered. For example:

          xy|(z)|                 ;the symbol `xy(z)'

   Here are some example read syntaxes.

     setq                    ; `setq'
     |setq|                  ; `setq'
     \s\e\t\q                ; `setq'
     1                       ; the _number_ 1
     \1                      ; the _symbol_ `1'
     |!$%zf78&|              ; `!$%zf78&'
     foo|(bar)|              ; `foo(bar)'
     foo\(bar\)              ; `foo(bar)'


File: librep.info,  Node: Symbol Attributes,  Next: Obarrays,  Prev: Symbol Syntax,  Up: Symbols

Symbol Attributes
-----------------

   All symbols have two basic attributes: print name and property list.
Most important is the "print name" of the symbol. This is a string
naming the symbol, after it has been defined (when the symbol is first
created) it may not be changed.

 - Function: symbol-name symbol
     This function returns the print name of the symbol SYMBOL.

          (symbol-name 'unwind-protect)
              => "unwind-protect"

   The symbol's "property list" (or plist) is similar to an alist
(*note Association Lists::), though stored differently, and provides a
method of storing arbitrary extra values in each symbol. *Note Property
Lists::.

   Although not strictly an attribute of the symbol, symbols also
provide a means of associating values with names (i.e. variables).
Within a defined context, a symbol may have a "binding", this binding
associates the symbol with a memory location within which a value may
be stored. When writing Lisp programs, the value of a symbol's current
binding is accessed by writing the print name of the symbol. Similarly
the binding may be modified by using the `setq' special form.  *Note
Variables::.


File: librep.info,  Node: Obarrays,  Next: Creating Symbols,  Prev: Symbol Attributes,  Up: Symbols

Obarrays
--------

   An "obarray" is the structure used to ensure that no two symbols
have the same name and to provide quick access to a symbol given its
name. An obarray is a vector, each element of the vector is a chain of
symbols whose names share the same hash-code (a "bucket"). These
symbols are chained together through links which are invisible to Lisp
programs: if you examine an obarray you will see that each bucket looks
as though it has at most one symbol stored in it.

   The normal way to reference a symbol is simply to type its name in
the program, when the Lisp reader encounters a name of a symbol it looks
in the default obarray for a symbol of that name. If the named symbol
doesn't exist it is created and hashed into the obarray--this process
is known as "interning" the symbol, for more details see *Note
Interning::.

 - Variable: obarray
     This variable contains the obarray that the `read' function uses
     when interning symbols.

 - Function: make-obarray size
     This function creates a new obarray with SIZE hash buckets (this
     should probably be a prime number for the fewest hash collisions).

     This is the only way of creating an obarray. `make-vector' is _not
     suitable_.

 - Function: find-symbol symbol-name #!optional obarray
     This function scans the specified obarray (OBARRAY or the value of
     the variable `obarray' if OBARRAY is undefined) for a symbol whose
     name is the string SYMBOL-NAME. The value returned is the symbol
     if it can be found or false otherwise.

          (find-symbol "setq")
              => setq

 - Function: apropos regexp #!optional predicate obarray
     Returns a list of symbols from the obarray OBARRAY (or the
     default) whose print name matches the regular expression REGEXP
     (*note Regular Expressions::). If PREDICATE is true, each symbol
     which matches REGEXP is applied to the function PREDICATE, if the
     value is true it is considered a match.

     The PREDICATE argument is useful for restricting matches to a
     certain type of symbol, for example only commands.

          (apropos "^yank" 'commandp)
              => (yank-rectangle yank yank-to-mouse)


File: librep.info,  Node: Creating Symbols,  Next: Interning,  Prev: Obarrays,  Up: Symbols

Creating Symbols
----------------

   It is possible to allocate symbols dynamically, this is normally only
necessary when the symbol is to be interned in a non-default obarray or
the symbol is a temporary object which should not be interned (for
example: labels in a compiler).

 - Function: make-symbol print-name
     This function creates and returns a new, uninterned, symbol whose
     print name is the string PRINT-NAME. Its value cell is void
     (undefined) and it will have an empty property list.

          (make-symbol "foo")
              => foo

 - Function: gensym
     This function returns a new, uninterned, symbol that has a unique
     print name.

          (gensym)
              => G0001
          
          (gensym)
              => G0002


File: librep.info,  Node: Interning,  Next: Property Lists,  Prev: Creating Symbols,  Up: Symbols

Interning
---------

   "Interning" a symbol means to store it in an obarray so that it can
be found in the future: all variables and named-functions are found
through interned symbols.

   When a symbol is interned a hash function is applied to its print
name to determine which bucket in the obarray it should be stored in.
Then it is simply pushed onto the front of that bucket's chain of
symbols.

   Normally all interning is done automatically by the Lisp reader. When
it encounters the name of a symbol which it can't find in the default
obarray (the value of the variable `obarray') it creates a new symbol
of that name and interns it. This means that no two symbols can have
the same print name, and that the read syntax of a particular symbol
always produces the same object (unless the value of `obarray' is
altered).

     (eq 'some-symbol 'some-symbol)
         => t

 - Function: intern symbol-name #!optional obarray
     This function uses `find-symbol' to search the OBARRAY (or the
     standard obarray) for a symbol called SYMBOL-NAME. If a symbol of
     that name is found it is returned, otherwise a new symbol of that
     name is created, interned into the obarray, and returned.

          (intern "setq")
              => setq
          
          (intern "my-symbol" my-obarray)
              => my-symbol

 - Function: intern-symbol symbol #!optional obarray
     Interns the symbol SYMBOL into the obarray OBARRAY (or the
     standard one) then returns the symbol. If SYMBOL is currently
     interned in an obarray an error is signalled.

          (intern-symbol (make-symbol "foo"))
              => foo
          
          (intern-symbol 'foo)
              error--> Error: Symbol is already interned, foo

 - Function: unintern symbol #!optional obarray
     This function removes the symbol SYMBOL from the obarray OBARRAY
     then returns the symbol.

     Beware! this function should be used with _extreme_ caution--once
     you unintern a symbol there may be no way to recover it.

          (unintern 'setq)                ;This is extremely stupid
              => setq


File: librep.info,  Node: Property Lists,  Next: Keyword Symbols,  Prev: Interning,  Up: Symbols

Property Lists
--------------

   Each symbol has a property list (or "plist"), this is a structure
which associates an arbitrary Lisp object with a key (usually a
symbol). The keys in a plist may not have any duplications (so that
each property is only defined once).

   The concept of a property list is very similar to an association list
(*note Association Lists::) but there are two main differences:

  1. Structure; each element of an alist represents one key/association
     pair. In a plist each pair of elements represents an association:
     the first is the key, the second the property. For example, where
     an alist may be,

          ((one . 1) (two . 2) (three . 3))

     a property list would be,

          (one 1 two 2 three 3)

  2. Plists have their own set of functions to modify the list. This is
     done destructively, altering the property list (since the plist is
     stored in only one location, the symbol, this is quite safe).

 - Function: get symbol property
     This function searches the property list of the symbol SYMBOL for
     a property `equal' to PROPERTY. If such a property is found it is
     returned, otherwise false is returned.

          (get 'if 'lisp-indent)
              => 2
          
          (get 'set 'lisp-indent)
              => ()

 - Function: put symbol property new-value
     `put' sets the value of the property PROPERTY to NEW-VALUE in the
     property list of the symbol SYMBOL. If there is an existing value
     for this property (using `equal' to compare keys) it is
     overwritten. The value returned is NEW-VALUE.

          (put 'foo 'prop 200)
              => 200

 - Function: symbol-plist symbol
     Returns the property list of the symbol SYMBOL.

          (symbol-plist 'if)
              => (lisp-indent 2)

 - Function: setplist symbol plist
     This function sets the property list of the symbol SYMBOL to PLIST.

          (setplist 'foo '(zombie yes))
              => (zombie yes)


File: librep.info,  Node: Keyword Symbols,  Prev: Property Lists,  Up: Symbols

Keyword Symbols
---------------

   Keywords are a special class of symbols. They evaluate to themselves,
and have the read syntax `#:SYMBOL', where SYMBOL is anything
satisfying the usual symbol syntax. These objects are normally used to
mark keyword parameters in function applications (*note Lambda
Expressions::).

 - Function: make-keyword symbol
     Return the keyword symbol that could be used to mark an argument
     value for the keyword parameter SYMBOL.

          (make-keyword 'x)
              => #:x

 - Function: keywordp arg
     Returns true if ARG is a keyword symbol.


File: librep.info,  Node: Evaluation,  Next: Variables,  Prev: Symbols,  Up: The language

Evaluation
==========

   So far only the primitive data types have been discussed, and how the
Lisp reader converts textual descriptions of these types into Lisp
objects. Obviously there has to be a way of actually computing
something--it would be difficult to write a useful program otherwise.

   What sets Lisp apart from other languages is that in Lisp there is no
difference between programs and data: a Lisp program is just a sequence
of Lisp objects which will be evaluated as a program when required.

   The subsystem which does this evaluation is called the "Lisp
evaluator" and each expression to be evaluated is called a "form".  The
evaluator (the function `eval') examines the structure of the form that
is applied to it and computes the value of that form within the current
Lisp environment.

   A form can be any type of data object; the only types which the
evaluator treats specially are symbols (which describe variables) and
lists (subroutine applications), anything else is returned as-is (and
is called a "self-evaluating form").

 - Function: eval form
     This function computes and returns the value of FORM within the
     current module and dynamic environment, and a null lexical
     environment.

   However, `eval' is rarely explicitly invoked, except in the
read-eval-print loop. Lisp provides many other methods of evaluation
that are usually much more suitable within a program.

 - Variable: max-lisp-depth
     This variable limits the number of nested calls to `eval'. If more
     than this many nested calls to `eval' exist, an error is
     signalled. The intention is to detect infinite recursion before
     hitting the stack size limit (causing a segmentation fault).

* Menu:

* Symbol Forms::                How variables are accessed
* List Forms::                  Subroutine calls
* Self-Evaluating Forms::       Forms which don't get evaluated
* Quoting::                     How to prevent evaluation of forms


File: librep.info,  Node: Symbol Forms,  Next: List Forms,  Up: Evaluation

Symbol Forms
------------

   When the evaluator is applied to a symbol the computed value of the
form is the value associated with the symbol in the current
environment. Basically this means that to get the value of a variable
you simply write its name. For example,

     rep-version
         => "1.0"

this extract from a Lisp session shows the read syntax of a form to get
the value of the variable `rep-version' and the result when this form
is evaluated.

   Since forms are evaluated within the current environment the value
of a variable is its most-recent extant binding (with slight
differences for lexical and special variables). *Note Variables::.

   If an evaluated symbol has no current binding, an error is signalled.


File: librep.info,  Node: List Forms,  Next: Self-Evaluating Forms,  Prev: Symbol Forms,  Up: Evaluation

List Forms
----------

   Forms which are lists are used to invoke a subroutine. The first
element of the list defines the subroutine to be called; all further
elements are arguments to be applied to that subroutine invocation.

   There are several different types of subroutines available:
functions, macros, special forms and autoloads. When the evaluator
finds a form which is a list it tries to classify the form into one of
these four types.

   First of all it evaluates the first element of the list; the computed
value of this element decides how the rest of the elements in the list
are treated. For example, if the first element is a symbol whose value
is a function, then that function is called with the other values in
the list.

* Menu:

* Function Call Forms::         `Normal' subroutines
* Macro Call Forms::            Source code expansions
* Special Forms::               Abnormal control structures
* Autoload Forms::              Loading subroutines from files on the fly


File: librep.info,  Node: Function Call Forms,  Next: Macro Call Forms,  Up: List Forms

Function Call Forms
...................

   When the first element of a list form evaluates to a function object
(either a primitive subroutine or a closure), all other elements in the
list are evaluated sequentially from left-to-right, then these values
are applied to the function definition. The result returned by the
function is then taken as the value of the whole list form.

   For example, consider the form `(/ 100 (1+ 4))'. This is a function
call to the function stored in the variable `/'. First the `/' form is
evaluated, it is a variable containing a data value representing the
primitive subroutine for integer division. Then the `100' form is
evaluated: it is a number, so self-evaluates to the value `100'. Next
the form `(1+ 4)' is evaluated. This is also a function call and
computes to a value of `5' which becomes the second argument to the `/'
function. Now the `/' function is applied to its evaluated arguments of
`100' and `5', and returns the value `20'. This then becomes the value
of the form `(/ 100 (1+ 4))'.

     (/ 100 (1+ 4))
     == (/ 100 5)
     => 20

   Or another example,

     (+ (- 10 (1- 7)) (* (1+ 2) 4)
     == (+ (- 10 6) (* (1+ 2) 4)
     == (+ 4 (* (1+ 2) 4)
     == (+ 4 (* 3 4))
     == (+ 4 12)
     => 16

   The system is also capable of eliminating tail calls where possible,
allowing tail-recursive function definitions to run with bounded space
requirements.

   A "tail-call" is a function call that occurs immediately before
exiting the containing function. Since the containing function need not
receive the result of the function call, it is possible to, in effect,
exit from the containing function before invoking the called function.

   Note however, that this is only possible where none of the dynamic
features of the language (i.e. bindings to special variables,
`unwind-protect', `condition-case', `catch', etc...)  are currently
active in the containing function.

   Consider, for example, the following function:

     (defun print-list (l)
       (unless (null l)
         (format standard-output "%s\n" (car l))
         (print-list (cdr l))))

the call to `print-list' occurs in the "tail-position" of the function.
This means that the call may be made after removing the previous call
to `print-list' from the interpreter's stack of active functions.

   [ XXX currently the interpreter is incapable of eliminating tail
calls to subrs, i.e. Lisp functions implemented in C ]


File: librep.info,  Node: Macro Call Forms,  Next: Special Forms,  Prev: Function Call Forms,  Up: List Forms

Macro Call Forms
................

   Macros are source code expansions, the general idea is that a macro
is a function which using the unevaluated arguments applied to it,
computes another form (the expansion of the macro and its arguments)
which is then evaluated to provide the value of the form.

   Macros are generally used to implement control-flow operations, where
not all arguments may be evaluated, or evaluated in an unusual order.
For more details see *Note Macros::.


File: librep.info,  Node: Special Forms,  Next: Autoload Forms,  Prev: Macro Call Forms,  Up: List Forms

Special Forms
.............

   Special forms are built-in subroutines which the evaluator knows must
be handled specially. The main difference between a special form and a
function is that the arguments applied to a special form are _not_
automatically evaluated--if necessary the special form will evaluate
arguments itself. This will be noted in the documentation of the
special form.

   Special forms are generally used to provide control structures, for
example, the primitive conditional constructs are special forms (if all
of their arguments, including the forms to be conditionally evaluated,
were evaluated automatically this would defeat the object of being
conditional!).

   The special forms supported by `librep' are: `cond', `defvar',
`progn', `quote', `setq'.

 - Function: special-form-p arg
     Returns true if ARG is a special form.

          (special-form-p quote)
              => t


File: librep.info,  Node: Autoload Forms,  Prev: Special Forms,  Up: List Forms

Autoload Forms
..............

   Not all parts of `librep' are needed at once, autoload forms provide
a means of marking that a function (or macro) is contained by a
specific Lisp library. The first time that the function is accessed the
autoload form will be evaluated; this loads the file containing the
function, then re-evaluates the original form. By then the autoload
form will have been overwritten in the symbol's function slot by the
true function (when it was loaded) so the form will execute properly.

   For more details see *Note Autoloading::.


File: librep.info,  Node: Self-Evaluating Forms,  Next: Quoting,  Prev: List Forms,  Up: Evaluation

Self-Evaluating Forms
---------------------

   The computed value of any form which is not a symbol or a list will
simply be the form itself and the form is said to be a "self-evaluating
form".

   Usually the only forms to be evaluated in this way will be numbers,
strings and vectors (since they are the only other data types which
have read syntaxes) but the effect is the same for other types of data.

   This means that forms you know are self-evaluating do not have to be
quoted to be used as constants (like lists and symbols do).

     "foo"
         => "foo"


File: librep.info,  Node: Quoting,  Prev: Self-Evaluating Forms,  Up: Evaluation

Quoting
-------

   As the above sections explain some types of Lisp object have special
meaning to the Lisp evaluator (namely the symbol and list types) this
means that if you want to refer to a symbol or a list in a program you
can't because the evaluator will treat the form as either a variable
reference or a function call respectively.

   To get around this Lisp uses an idea called "quoting". The special
form `quote' simply returns its argument without evaluating it.  For
example,

     (quote my-symbol)
         => my-symbol

the `quote' form prevents the `my-symbol' being treated as a
variable--it is effectively `hidden' from the evaluator.

   Writing `quote' all the time would be a bit time-consuming so there
is a shortcut: the Lisp reader treats any form X preceded by a single
quote character (`'') as the form `(quote X)'. So the example above
would normally be written as,

     'my-symbol
         => my-symbol

   The general way to prevent evaluation of a form is to simply precede
it by a single quote-mark.

 - Special Form: quote form
     This special form returns its single argument without evaluating
     it. This is used to "quote" constant objects to prevent them from
     being evaluated.

   For another form of quoting, see *Note Backquoting::.


File: librep.info,  Node: Variables,  Next: Functions,  Prev: Evaluation,  Up: The language

Variables
=========

   In Lisp, symbols are used to represent variables. Each symbol
contains a "value" slot that is used to contain the value of the symbol
when it used as a variable.

   The normal way to obtain the current value of a variable is simply to
evaluate the symbol of the same name (i.e. write the name of the
variable in your program). The `symbol-value' function can be used to
evaluate variables whose names not known statically.

 - Function: symbol-value variable
     This function returns the value of the symbol VARIABLE in the
     current environment.

* Menu:

* Local Variables::             Creating temporary variables
* Setting Variables::           Altering a variable's value
* Scope and Extent::            Technical jargon
* Void Variables::              Some variables have no values
* Defining Variables::          How to define a variable before
                                  using it
* Fluid Variables::             Another dynamic bindingd methodb

