http://t3x.org/lispxv/manual.html   (light|dark)

The LISP XV Manual


The   L I S P  X V   M a n u a l

By Nils M Holm, 2019, 2020, 2025


0 QUICK SUMMARY

For the impatient LISP user:

LISP XV is a purely symbolic LISP system that
implements a subset of LISP 1.5. The only data
types are the atom (symbol) and the pair/list.

The following special forms (FSUBRs and FEXPRs
exist):

AND CONC COND CSETQ FUNCTION LABEL OR PROG QUOTE
SELECT SETQ

(Note the absence of LAMBDA!)

The following functions (SUBRs and EXPRS) are
predefined:

APPEND APPLY ATOM ATTRIB CAAR...CDDDR CAR CDR
CONS COPY DEFINE DEFLIST DUMP EQ EQUAL ERROR EVAL
GENSYM GET GO LIST LOAD MAP MAPCON MAPLIST MEMBER
NCONC NOT NULL PAIR PRIN1 PRINT PROG2 PROP READ
RECLAIM REMOB REMPROP RETURN REVERSE RPLACA
RPLACD SASSOC SEARCH SUBLIS SUBST TERPRI TRACE
UNTRACE

There is no syntactic sugar, so 'X is NOT short
for (QUOTE X).

% is the EOT. This is not compatible to LISP 1.5.

There are some deviations from LISP 1.5, which
will be marked with ***** in the following text.


1 S-EXPRESSIONS

A Symbol is any combination of no more than 30 of
these characters:

A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 0 -

A Symbol is also called an Atom.

Although not documented in the LISP 1.5 manual,
"unusual" characters can be included in symbols
using the $$-artifact:

$$<delim>symbol characters<delim>

where <delim> is a delimiting character. For
example: $$*HELLO? ^_^*

A Pair is an ordered pair of two S-expressions:

(car-part . cdr-part)

***** The spaces before and after the dot are
optional, i.e.

(A . B)  =  (A.B)

A pair may contain other pairs:

((A . B) . C)
(A . (B . C))
((A . B) . (C . D))

An S-Expression is either an atom or a pair.

A nested pair of the form

(A . (B . C))   may be written as   (A B . C)

and

(A . NIL)       may be written as   (A)

The rules apply inductively, so

(A . (B . (C . NIL)))  =  (A B C)


1.1 LISTS

A list is an S-expression that is either NIL or a
pair whose cdr part is a list:

List  =  NIL  or  (S-expression . List)

These are Lists:

NIL
(FOO)
(FOO BAR BAZ)
(FOO (A . B) (NESTED LIST))

A list whose innermost/rightmost cdr part is a
symbol is called a Dotted List. These are dotted
lists:

(A B . C)
((FOO BAR) . BAZ)

The pair is a two-element dotted list.

An Association List (or Alist) is a list of pairs
(associations), where the car part of each
association is called the Key and the cdr part
the Value of the association:

((<key1> . <value1>) ... (<keyN> . <valueN>))

See section on ASSOCIATION LIST FUNCTIONS for
details.


1.2 SPACE CHARACTERS

The Comma (',', 44) is a space character, so the
S-expressions (A,B,C) and (A B C) are equal. The
comma can be used for clarity, e.g. in

((A B), (B C), (C D))

or

(EVAL X, A)

but it is generally equivalent to the blank, so
even

QUOTE,,,((A,B,C))

is a valid program.

***** In addition to the blank and the comma,
LISP XV treates the following as white space
characters: the TAB (HT, 9), the Carriage Return
(CR, 13), and the Line Feed (LF, 10).


1.3 ***** COMMENTS

A comment may be inserted anywhere (even inside
of a form, but not inside of an atom) by
including a semicolon (;). Comments extend to the
end of the current line.

Example:

CSETQ (FOO  ; THIS IS A COMMENT
  (QUOTE BAR))


1.5 UNREADABLE FORMS

A form that contains characters other than those
listed in the previous sections are unreadable,
i.e. they cannot be read by the LISP parser.

Unreadable forms are sometimes output by the
system to represent data that have no unambiguous
textual representation.


1.6 CONSTANT SYMBOLS

The following symbols are predefined in the
system. Using them for a different purpose will
lead to unexpected results (because APVAL
precedes the global Alist). In particular, use
FN instead of F to denote function arguments.

Symbol  Value   Description
T       *TRUE*  canonical "true" value
F       NIL     canonical "false" value
NIL     NIL     end of a list
BLANK           blank character
LPAR    (       left parenthesis character
RPAR    )       right parenthesis character
PERIOD  .       dot character
STAR    *       star character

The symbol OBLIST is bound to a list of all atoms
that are currently known to the system.


2 EXPRESSIONS

An Expression or a Form is an S-expression with
a meaning.

x => y     denotes that x evaluates to y;
           y is the Value of x.

undefined  denotes an undefined value.

There are four kinds of expressions:

Variables
Lambda Abstraction
Function Application
Special Forms


2.1 PROPERTIES

Each symbol has a list of Properties attached to
it. A Property List is a list of the form

(<ind1> <prop1> ... <indN> <propN>)

where each IND is called an indicator and each
PROP is the indicated property, i.e. indicators
appear at odd and properties at even positions in
a property list.

The PNAME property specifies the name that will
be displayed when printing a symbol.

The property list is attached to a symbol via its
CDR field. (This is not documented in the LISP
manual, but generally works in LISP 1.5.)


2.2 VARIABLES AND FUNCTION NAMES

A Variable is a symbol that is bound to a Value.
A Function Name is a symbol that is bound to a
function.

Variables evaluate to their values.

Variable  =>  Value

References to unbound symbols (symbols that are
not bound to any value) are undefined:

unbound-symbol  =>  undefined

There are different ways to bind a symbol to a
data object. Functions names are bound to
functions via the SUBR, FSUBR, EXPR, and FEXPR
properties. The values of constants are bound
via the APVAL property.

Function bindings are created by a variety of
definition forms, like DEFINE and DEFLIST.
Constants are created by the CSETQ special form.

Variables are bound to values by applying a
functions to values, thereby creating bindings
in the global Alist, or by using the PROG
facility and the SETQ special function. No
distinction is made between variables and
function names in the global Alist.

If both a binding via a property and a binding
via the global Alist exist for the same symbol,
the property will always take precedence.

A Constant is a variable that is bound to its
value via the APVAL field. It normally does not
change at program runtime (but it can).

For instance, the canonical "true" value, T, is a
constant:

T  =>  *TRUE*


2.3 LAMBDA ABSTRACTION

(LAMBDA <vars> <expr>)

is a Lambda Abstraction or Lambda Function.

Names enclosed in angle brackets are
Meta-Syntactic Variables. They are not part of
LISP, but describe parts of expressions.

<Vars> is a list of variables of a function and
<expr> is the Term or Body of a function.

Examples: (LAMBDA (X) X)
          (LAMBDA (FN X) (FN X))
          (LAMBDA () (PRINT (QUOTE HELLO)))

The variables of a function are created by
binding their names to the arguments of the
function. This happens when the function is
being applied to some arguments.

Note that LAMBDA itself is neither a function nor
a special function, so a lambda abstraction by
itself has no value. To pass it as a value to
another function or even to apply it in situ, it
must either be quoted by QUOTE or converted to a
FUNARG by using FUNCTION. (Q.v.)


2.4 FUNCTION APPLICATION

A variable X is Bound in an expression E, if

- E is a lambda function
AND
- X is a variable of E

Examples:

X  is     bound in  (LAMBDA (X) (F X))
F  is not bound in  (LAMBDA (X) (F X))

When a variable X is not bound in an expression E,
X is Free in E; X is a free variable of E.

A function is Applied to Arguments using the
syntax

(<function> <argument> ...)

The following steps are involved in the
application:

(1) the function is looked up in the SUBR and
    EXPR properties of the function symbol and
    in the global Alist

(2) each argument in the application is
    evaluated

(3) the global Alist is saved

(4) each argument is bound to the corresponding
    variable in the global Alist

(5) the body of the function is evaluated

(6) the saved global Alist is restored

(7) the value of the body is returned

When a function has both the SUBR and EXPR
property set, the property that appears first in
the property list of the function symbol will be
used. Only when none of these properties is
given, the Alist will be searched.

Variables are associated with arguments by
position, i.e. the first argument is bound to
the first variable, etc.

For instance:

((FUNCTION (LAMBDA (X Y) (CONS X Y)))
 (QUOTE A) (QUOTE B))

; evaluate arguments:
; (QUOTE A) => A,  (QUOTE B) => B
((LAMBDA (X Y) (CONS X Y)) A B)

; create variables and store 1 in X and 2 in Y,
; giving the body
(CONS A B)

; evaluate the body, giving the value
(A . B)

There has to be exactly one argument per variable.


3 SPECIAL FORMS

A Special Form has the same outer appearance as
the function application:

(<function> <argument> ...)

There are some difference, though: none of the
<argument>s will be evaluated and a list of all
arguments will be passed to the function. The
function may then evaluate some or all of the
arguments by calling EVAL.

Special form functions are bound to function
names via the FSUBR and FEXPR properies of the
function symbol. They are usually defined using
the DEFLIST function. (Q.v.)

A special function receives two arguments: the
list of all (unevaluated) arguments passed to it
and the global Alist that is in effect *before*
the special function is called. When a special
function calls EVAL, this Alist should be passed
to it (unless you are trying something really
weird.)


4 ELEMENTARY FUNCTIONS

4.1 SUBR ATOM (OBJ)  =>  T or NIL

Return T, if OBJ is an atom.

Examples: ATOM (FOO)  =>  *TRUE*
          ATOM (NIL)  =>  *TRUE*
          ATOM ((X))  =>  NIL


4.2 EXPR CAAR (PAIR)   =>  OBJ
    ...
    EXPR CDDDR (PAIR)  =>  OBJ

These functions extract elements from nested
pairs. These elements are extracted by the C??R
functions:

((CAAR . CDAR) . (CADR . CDDR))

And these elements by C???R:

 (  ((CAAAR . CDAAR) . (CADAR . CDDAR))
  . ((CAADR . CDADR) . (CADDR . CDDDR))  )

E.g., CAAR extracts the car field of a car field,
CADR the car field of a cdr field, etc. The most
commonly used variants are these:

CADR   the second element of a list
CDDR   the tail of a list after the second elt.
CADDR  the third element of a list
CDDDR  the tail of a list after the third element

Examples: CADR ((1 2 3 4))  =>  2
          CDDR ((1 2 3 4))  =>  (3 4)

          CADAR ((LAMBDA (X) T) NIL)  =>  (X)


4.3 SUBR CAR (PAIR)  =>  OBJ
    SUBR CDR (PAIR)  =>  OBJ

CAR extracts the CAR part and CDR the cdr part of
a pair. When applied to an atom CAR and CDR will
not return any meaningful value, but informally,
the cdr part of most atoms will be their property
list.

Examples: CAR ((1 . 2))  =>  1
          CAR ((1))      =>  1
          CAR ((1 2 3))  =>  1
          CDR ((1 . 2))  =>  2
          CDR ((1))      =>  NIL
          CDR ((1 2 3))  =>  (2 3)


4.4 SUBR CONS (OBJ1 OBJ2)  =>  PAIR

Create a fresh pair with OBJ1 as its car part
and OBJ2 as its cdr part. The following
equations hold for all values of X and Y:

      (CAR (CONS X Y))  =  X
      (CDR (CONS X Y))  =  Y

The following holds for any pair X:

(CONS (CAR X) (CDR X))  =  X

Examples: CONS (1 2)      =>  (1 . 2)
          CONS ((1 2) 3)  =>  ((1 2) . 3)
          CONS (1 (2 3))  =>  (1 2 3)
                           =  (1 . (2 3))


4.5 SUBR EQ (OBJ1 OBJ2)  =>  T or F

Return T, if OBJ1 and OBJ2 are the same object.
This is the case, if OBJ1 and OBJ2 are both

- the same symbol
or
- bound to the same variable

In particular,

(EQ (CONS X NIL)
    (CONS X NIL))  =>  NIL

for any S-expression X, and, given that Y is
bound to some value,

(EQ Y Y)           =>  *TRUE*

Examples: EQ (FOO FOO)  =>  *TRUE*
          EQ (FOO BAR)  =>  NIL
          EQ (FOO NIL)  =>  NIL
          EQ (T T)      =>  *TRUE*


4.6 EXPR EQUAL (OBJ1 OBJ2)  =>  T or F

Return T, if OBJ1 and OBJ2 are structurally
equal. This is the case, if 

- (EQ OBJ1 OBJ2) => *TRUE*

  or

- (EQUAL (CAR OBJ1) (CAR OBJ2)) => *TRUE*
  and
  (EQUAL (CDR OBJ1) (CDR OBJ2)) => *TRUE*

(EQ A B) implies (EQUAL A B), but the converse is
not true.

Informally, two S-expressions are equal, if PRINT
emits the same output for them (but this is only
true, if both S-expressions have an unambiguous
textual representation).

Examples: EQUAL ((A (B) C) (A (B) C))  =>  *TRUE*
          EQUAL ((A (B) C) (A (X) C))  =>  NIL


4.7 SUBR LIST (OBJ ...)  =>  LIST

Create a fresh list containing the values of the
given expressions.

***** Note that LIST has to be implemented as
an FSUBR in LISP 1.5, because it has a variable
number of arguments. LISP XV has SUBRS with a
variable number of arguments internally.

Examples: LIST ()       =>  NIL
          LIST (1 2 3)  =>  (1 2 3)

          (LIST (CONS (QUOTE 1) (QUOTE 2))
                (ATOM NIL)
                (NULL (QUOTE X)))
                              =>  ((1 . 2) T NIL)


4.8 EXPR NULL (OBJ)  =>  T or F

Return T, if OBJ is NIL. This function is used
to test if the end of a list has been reached.

Example: (NULL (CDR (QUOTE (X))))  =>  *TRUE*


4.9 SUBR RPLACA (PAIR OBJ)  =>  PAIR
    SUBR RPLACD (PAIR OBJ)  =>  PAIR

RPLACA replaces the car part and RPLACD replaces
the cdr part of the given PAIR with OBJ. The
pair will be *modified*. Both functions return
the modified pair.

Examples: RPLACA ((FOO . BAR) 1)  =>  (1 . BAR)
          RPLACD ((FOO . BAR) 2)  =>  (FOO . 2)

          (CSETQ INF (QUOTE (1)))
          (RPLACD INF INF)  =>  (1 1 1 1 1 1 ...)
                                ; INFINITE LIST


5 INTERPRETER FUNCTIONS

5.1 SUBR APPLY (FUN LIST)  =>  OBJ

        Apply FUN to the given LIST of arguments and
        return the value delivered by the function.

        FUN may be a function (SUBR or EXPR) or lambda
        function, but not a special function (FSUBR or
FEXPR).

        Example: APPLY (CONS (A B))  =>  (A . B)


5.2 FSUBR COND (<clause> ...)  =>  OBJ

Each <clause> has the form (FORM1 FORM2).

COND proceeds as follows:

The predicate FORM1 of the first clause is
evaluated. When its value is not NIL, the
expression FORM2 will be evaluated and the value
of the expression will be returned. No further
clauses will be examined.

When the predicate of the first clause is NIL,
the predicate of the next clause will be
evaluated. Evaluation of COND ends when a
clause with a non-NIL predicate is found.

It is an error for COND to run out of clauses.

Examples:

(COND (NIL (QUOTE A))
      (NIL (QUOTE B))
      (T (QUOTE C)))       =>  C

(COND (T (QUOTE FIRST))
      (T (QUOTE SECOND)))  =>  FIRST


5.3 SUBR EVAL (FORM ALIST)  =>  OBJ

Evaluate the S-expression FORM and return its
value. This is basically an interface to the LISP
system. Any effects caused by evaluating FORM
(such as input, ouput, or changing data objects)
will take place as if the expression was
evaluated at the top level of the system.

ALIST is the global Alist to be used while
evaluating FORM. When evaluating forms at the
top level, NIL may be specified in the place of
ALIST.

Example: EVAL ((ATOM NIL) NIL)  =>  *TRUE*


5.4 FSUBR FUNCTION (FUN)  =>  FUNARG

Package the function FUN and the current global
Alist into a FUNARG and return it. FUN must be a
lambda abstraction. A FUNARG can be applied to
arguments, just like any oher function.

The following program using a MAPLIST-like
function will be used to illustrate the usage
of FUNCTION.

DEFINE ((
  (MAPL (LAMBDA (X FN)
    (COND ((NULL X) NIL)
          (T (CONS (FN X)
                   (MAPL (CDR X) FN))))))
  (TEST (LAMBDA (X)
    (MAPL (QUOTE (1 2 3))
          (QUOTE (LAMBDA (Y) (CONS X Y)))))) ))

Given this definition, the expression

TEST (FOO)

will evaluate to

(((1 2 3) 1 2 3) ((2 3) 2 3) ((3) 3))

instead of the expected result

((FOO 1 2 3) (FOO 2 3) (FOO 3))

This is because the free variable X of the
function (LAMBDA (Y) (CONS X Y)) is bound to a
new value each time MAPL is entered, because
MAPL shares the name X with the lambda function.

To overcome this problem, the FUNARG created by
FUNCTION uses the global Alist that was in
effect when FUNCTION was called instead of the
one that is in effect during the evaluation of
MAPL. When using

(FUNCTION (LAMBDA (Y) (CONS X Y)))

in the above example, the expected value is
returned.

From a modern perspective, FUNCTION creates a
closure and thereby implements lexical scoping.

Example: see above.


5.5 FSUBR GO (SYMBOL)  =>  undefined

Transfer control to the expression following the
label SYMBOL in PROG. See PROG.


5.6 FSUBR LABEL (SYMBOL FUN)  =>  FUNARG

Create a recursive FUNARG where the given SYMBOL
refers to the FUNARG itself in the Alist of the
FUNARG. I.e. create a recursive function.

Yes, a FUNARG created by LABEL is a recursive
structure. Try printing it!

Example: ((LABEL FOO
            (LAMBDA (X)
              (COND ((NULL X) (QUOTE DONE))
                    (T (FOO (CDR X))))))
          (QUOTE (1 2 3 4 5)))           =>  DONE


5.7 FSUBR PROG (LIST FORM ...)  =>  OBJ

The Program Feature or Program Facility.

LIST is a list of symbols and each FORM is any
S-expression.

PROG evaluates as follows:

(1) Every symbol in the LIST is added to the
    global Alist with a value of NIL.

(2) Every FORM that is a symbol is associated
    with the S-expressions that follow it.
    The associations are placed in the so-called
    Go-List.

(3) All non-atomic FORMs are evaluated from top
    to bottom and their values are discarded.

(4) When there are no more forms to evaluate,
    PROG returns NIL.

(5) When a FORM of the form (GO X) is found,
    the symbol X is looked up in the Go-List
    and control is transferred to the FORM that
    follows the symbol X.

(6) When a FORM of the form (RETURN X) is found,
    the expression X is evaluated and the PROG
    facility returns the value of X.

(7) When a COND expression inside of PROG runs
    out of clauses, control is passed to the FORM
    that follows the COND form, if any.

(8) GO and RETURN expressions can be evaluated
    conditionally (using COND) inside of PROG,
    but only if the COND appears directly inside
    of PROG (and in particular not inside of a
    nested COND).

PROG can be nested. In this case, every PROG has
its own Alist and Go-List. An inner PROGs can
access the Alists of outer PROGs, but not their
Go-Lists

Example: DEFINE ((
           (REV (LAMBDA (X)
             (PROG (R)
               A (COND ((NULL X) (RETURN R)))
                 (SETQ R (CONS (CAR X) R))
                 (SETQ X (CDR X))
                 (GO A))))  ))

         REV ((1 2 3))  =>  (3 2 1)


5.8 EXPR PROG2 (FORM1 FORM2)  =>  OBJ2

Return the second argument. The purpose of PROG2
is to evaluate two expressions, usually one for
effect, where only one single expression is
expected.

Example: ((LABEL FOO
            (LAMBDA (X)
              (COND ((NULL X) NIL)
                    (T (PROG2 (PRINT X)
                              (FOO (CDR X)))))))
          (QUOTE (1 2 3)))

          ; will print (1 2 3), (2 3), and (3).


5.9 FSUBR QUOTE (OBJ) =>  OBJ

Return OBJ unevaluated.

Examples: QUOTE (FOO)      =>  FOO
          QUOTE ((CAR X))  =>  (CAR X)


5.10 FSUBR RETURN (FORM)  =>  undefined

Evaluate the given FORM and return its value from
the innermost PROG facility. See PROG.


5.11 FSUBR SETQ (SYMBOL FORM)  =>  OBJ

Evaluate the given FORM and change the value
bound to the given SYMBOL in the global Alist
to the value of the form.

The SYMBOL must be in the global Alist, so it
must be either a PROG variable or a function
variable.

SETQ CANNOT be used to change the APVAL of a
symbol. Use CSETQ instead.

***** In LISP 1.5 SYMBOL must be a PROG
      variable.

Example: See PROG.


6 LOGICAL CONNECTIVES

6.1 FSUBR AND (FORM ...)  =>  OBJ

Evaluate the given FORMs, from left to right,
until a form evaluates to NIL. In this case
return NIL. When none of the FORMs evaluates
to NIL, return T. When no arguments are given,
return T.

This special function implements the
short-circuit logical AND.

EXAMPLES: (AND)                  =>  *TRUE*

          (AND (QUOTE 1)
               (QUOTE 2)
               (QUOTE 3))        =>  *TRUE*

          (AND NIL (QUOTE FOO))  =>  NIL

          (AND NIL (PRINT T))    =>  NIL
          ; T will never print


6.2 FSUBR OR (FORM ...)  =>  OBJ

Evaluate the given FORMs, from left to right,
until a form evaluates to a value other than NIL.
In this case return T. When none of the FORMs
evaluates to non-NIL, return NIL. When no
arguments are given, return NIL.

This special function implements the
short-circuit logical OR.

Examples: (OR)                  =>  NIL

          (OR F F)              =>  NIL

          (OR (QUOTE 1)
              (QUOTE 2)
              (QUOTE 3))        =>  *TRUE*

          (OR NIL (QUOTE FOO))  =>  *TRUE*

          (OR T (PRINT NIL))    =>  *TRUE*
          ; NIL will never print


6.3 EXPR NOT (OBJ)  =>  T or F

Return T, if OBJ is NIL. This function is used
to test if a truth value is "true".

Example: NOT (T)    =>  NIL
         NOT (F)    =>  *TRUE*
         NOT (NIL)  =>  *TRUE*
         NOT (FOO)  =>  NIL


7 LIST HANDLING

7.1 EXPR APPEND (LIST1 LIST2)  =>  LIST

Create a fresh list containing the elements of
LIST1 and LIST2 in the given order. Both LISTs
must be NIL-terminated.

Examples: APPEND ((A B) (C D))  =>  (A B C D)
          APPEND (NIL (A B))    =>  (A B)
          APPEND ((A B) NIL)    =>  (A B)


7.2 FSUBR CONC (LIST ...)  =>  LIST

Evaluate and concatenate all given LISTs. Each
list will be attached to the next list using
NCONC. Each given LIST except for the last one
will be modified by this function.

All LISTs must be NIL-terminated.

Examples: (CONC)              =>  NIL
          (CONC (QUOTE (A)))  =>  (A)

          (CONC (QUOTE (A))
                (QUOTE (B)))  =>  (A B)

          (CONC (QUOTE (A))
                (QUOTE (B))
                (QUOTE (C)))  =>  (A B C)

          (CONC (QUOTE (A))
                NIL
                (QUOTE (B))
                NIL)          =>  (A B)


7.3 EXPR COPY (LIST)  =>  LIST

Return a fresh copy of the given list. All pairs
of the list will be newly allocated, the new list
will share only its atoms with the given list.

Example: COPY ((A (B) C))  =>  (A (B) C)


7.4 EXPR MEMBER (OBJ LIST)  =>  T or NIL

Find the given OBJ in the given LIST. Return T,
if OBJ appears in LIST. When the expression is
not contained in the list, return NIL.

Examples: MEMBER (C (A B C))      =>  *TRUE*
          MEMBER (X (A B C))      =>  NIL
          MEMBER ((B) ((A) (B)))  =>  *TRUE*


7.5 EXPR NCONC (LIST1 LIST2)  =>  LIST

Attach LIST2 to the end of LIST1 and then return
LIST1, which at this point is the concatenation
of LIST1 and LIST2.

Examples: NCONC ((A B) (C D))  =>  (A B C D)
          NCONC (NIL (A B))    =>  (A B)
          NCONC ((A B) NIL)    =>  (A B)


7.6 EXPR REVERSE (LIST)  =>  LIST

Create a fresh list containing the elements
of LIST in reverse order. LIST must be a
NIL-terminated list.

Examples: REVERSE ((A B C))  =>  (C B A)
          REVERSE (NIL)      =>  NIL


8 DEFINITIONS AND PROPERTY LISTS

8.1 EXPR ATTRIB (SYMBOL LIST)  =>  LIST

Attach the given LIST to the end of the property
list of the given SYMBOL. The list should be a
list of two arguments. The value of ATTRIB is
the list.

Example: ATTRIB (FOO (APVAL BAR)) =>  (APVAL BAR)
         EVAL (FOO NIL)           =>  BAR


8.2 FSUBR CSETQ (SYMBOL FORM)  =>  OBJ

Evaluate FORM and attach it as the APVAL property
to the given SYMBOL, thereby turning SYMBOL into
a constant. Return the evaluated expression in a
singular list.

Example: (CSETQ FOO (QUOTE BAR))  =>  (BAR)
         (EVAL (QUOTE FOO) NIL)   =>  BAR


8.3 EXPR DEFINE (LIST)  =>  *TRUE*

The LIST must be of the form ((NAME VALUE) ...)
and each VALUE must be a lambda abstraction.

DEFINE adds each VALUE to the property list
of the corresponding NAME under the EXPR
indicator. I.e., it defines funcions.

Note that DEFINE is itself an EXPR, but it is
always used at the top level of a program, which
evaluates expressions using EVALQUOTE, so its
arguments are automatically quoted.

Example:

DEFINE ((
  (GET (LAMBDA (X Y)
         (COND ((NULL X) NIL)
               ((NULL (CDR X)) NIL)
               ((EQ (CAR X) Y) (CADR X))
               (T (GET (CDR X)))))) ))


8.4 EXPR DEFLIST (LIST SYMBOL)  =>  *TRUE*

DEFLIST is a more general variant of DEFINE that
also specifies the indicator of the properties to
add to the given symbols, so it can be used to
define sets of FEXPRs or constants (via APVAL).

Example:

DEFLIST ((
  (IF (LAMBDA (X A)
        (PROG (PRED CNS ALT)
          (SETQ PRED (EVAL (CAR X) A))
          (SETQ CNS (CADR X))
          (SETQ ALT (CADDR X))
          (COND ((EVAL PRED NIL)
                   (RETURN (EVAL CNS A)))
                (T (RETURN (EVAL ALT A))))))) )
  FEXPR)


8.5 EXPR GET (LIST SYMBOL)      =>  OBJ
    SUBR GET (SYMBOL1 SYMBOL2)  =>  OBJ

Return the property stored under the indicator
SYMBOL in the given property list. Return NIL,
if there is no such indicator in the list.

Due to the way property lists are stored in
symbols, the first argument of GET may also be
a symbol.

Example: GET (T APVAL)  =>  *TRUE*


8.6 EXPR PROP (LIST SYMBOL FUN)      =>  OBJ
    EXPR PROP (SYMBOL1 SYMBOL2 FUN)  =>  OBJ

Return the tail of the given property list
starting at the indicator SYMBOL. If there is no
such indicator in the list, call FUN with zero
arguments and return its value.

Due to the way property lists are stored in
symbols, the first argument of PROP may also be
a symbol.

Example: PROP (T APVAL
                 (LAMBDA () NIL))  =>  *TRUE*

         PROP (T NONEXISTENT
                 (LAMBDA () NIL))  =>  NIL


8.7 EXPR REMPROP (LIST SYMBOL)      =>  NIL
    SUBR REMPROP (SYMBOL1 SYMBOL2)  =>  NIL

Remove the indicator SYMBOL and the subsequent
property from the given property list. If there
is no such indicator, do nothing. Return NIL.

Due to the way property lists are stored in
symbols, the first argument of REMPROP may also
be a symbol.

Example: CSETQ (FOO (QUOTE BAR))
         REMPROP (FOO APVAL)
         GET (FOO APVAL)      =>  NIL


9 ASSOCIATION LIST FUNCTIONS

9.1 EXPR PAIR (LIST1 LIST2)  =>  ALIST

Create a new association list by pairing the keys
in LIST1 with the values in LIST2. The lengths of
the lists must be equal. Return the new Alist.

Example: PAIR ((A B C) (1 2 3))
                    =>  ((A . 1) (B . 2) (C . 3))


9.2 EXPR SASSOC (OBJ ALIST FUN)  =>  OBJ

Find an association with the key OBJ in ALIST
and return it. When no association in ALIST has
OBJ as its key, call FUN with no arguments and
return its value.

Examples:

SASSOC (B ((A . 1) (B . 2) (C . 3))
        (LAMBDA () NIL))            =>  (B . 2)

SASSOC (FOO ((A . 1) (B . 2) (C . 3))
        (LAMBDA () (QUOTE NOPE)))   =>  NOPE

SASSOC ((Y) (((X) . 1) ((Y) . 2))
        (LAMBDA () NIL))            =>  ((Y) . 2)


9.3 EXPR SUBLIS (ALIST OBJ)  =>  OBJ

Replace in OBJ every symbol that appears as a key
in ALIST with the corresponding value.

Examples: CSETQ (A (QUOTE (X . PAINTER)
                          (Y . PAINTS)
                          (Z . PAINTING)))
          SUBLIS (A (THE X Y THE Z))
            =>  (THE PAINTER PAINTS THE PAINTING)


9.4 EXPR SUBST (OBJ1 OBJ2 OBJ3)  =>  OBJ

Create a copy of OBJ3 in which every occurrence
of OBJ2 is replaced by OBJ1, i.e. substitute OBJ1
for OBJ2 in OBJ3.

Examples: SUBST (FOO BAR FOO)  =>  BAR

          SUBST (X A (A (B) C (A)))
                               => (X (B) C (X))

          SUBST (X (A) (A (B) C (A)))
                               => (A (B) C X)


10 HIGHER ORDER FUNCTIONS

10.1 EXPR MAP (LIST FUN)      =>  NIL
10.2 EXPR MAPCON (LIST FUN)   =>  LIST
10.3 EXPR MAPLIST (LIST FUN)  =>  LIST

Each of these functions applies the function FUN
to each tail of the given LIST, beginning with
the entire list and progressing toward the
singleton list consisting solely of its last
element.

MAPLIST returns a list of the values of FUN.
MAPCON concatenates the values returned by FUN
using NCONC. Hence the values returned by FUN
must be lists. MAP applies FUN purely for effect
and returns NIL.

Examples: MAPLIST ((A B C) (LAMBDA (X) X))
                          =>  ((A B C) (B C) (C))

          MAPCON ((A B C) COPY)
                          =>  (A B C B C C)

          MAP ((A B C) PRINT)  =>  NIL


10.4 EXPR SEARCH (LIST FUN1 FUN2 FUN3)  => OBJ

Apply the function FUN1 to each tail of the given
LIST, just like MAPLIST and friends. When FUN1
returns a non-NIL value for a sublist, apply FUN1
to that sublist and return its value. When no
tail of LIST has the property tested by FUN1,
return the value of FUN3 applied to NIL.

Example: SEARCH ((A NIL B NIL)
                 (LAMBDA (X) (NULL (CAR X)))
                 COPY
                 ERROR)           =>  (NIL B NIL)


11 INPUT AND OUTPUT

11.1 SUBR READ ()  =>  OBJ

Read the textual representation of one object
from the current input source, convert it to
internal representation and return it.

Note that the value returned by READ on the REPL
will then be printed by PRINT (see below), which
converts it back to textual representation.
Hence the internal representation of an object
will never be visible to the programmer.

READ will skip over leading white space
characters while reading input. It will only
return when a complete S-expression has been
read. When reading lists or pairs, the input
may span multiple lines.

***** READ will also skip over comments.

***** When no input is available on the current
input source, READ will return a special object
called the End of Transmission Marker (or EOT
marker). The EOT marker will print as <EOT> at
the LISP prompt.

***** An EOT marker can normally generated by
pressing "Control" and "d" (control-D) on the
keyboard, even on non-Unix systems, but not in
batch mode (see REPL). LISP XV will also
interpret the "%" character as an EOT marker.

Examples: READ () FOO  =>  FOO

          READ () (A
                   B
                   C)  =>  (A B C)

          READ () %    =>  <EOT>


11.2 SUBR PRIN1 (SYMBOL)  =>  SYMBOL

Print the textual representation of the given
SYMBOL, which is taken from the PNAME property
of the symbol. When the symbol has no PNAME,
print Lxxx instead, where "xxx" is the address
of the symbol in memory. (This is not documented
in the LISP 1.5 manual.) Return the symbol.

Example: PRIN1 (FOO)  =>  FOO


11.3 SUBR PRINT (OBJ)  =>  OBJ

Print the textual representation of any
S-expression and then advance the cursor to the
next line of output. Return the S-expression

Example: PRINT ((FOO BAR))  =>  (FOO BAR)


11.4 SUBR TERPRI ()  =>  NIL

Advance the cursor to the next line of output.
Return NIL.

Example: TERPRI ()  =>  NIL


12 DEBUGGING AND ERROR HANDLING

12.1 SUBR ERROR (OBJ)  =>  undefined
     SUBR ERROR ()     =>  undefined

Abort program execution and report error A 1. If
an object is given, also print that object on a
separate line. This function never returns.

Example: ERROR ()


12.2 SUBR TRACE (LIST)  =>  NIL

LIST is a list of function names. Whenever a
function that is bound to one of these names is
entered, its name and arguments will print. When
one of the functions returns, its value will
print. All functions must be EXPRs. TRACE returns
NIL.

Example: DEFINE (((FOO (LAMBDA (X) T))))
         TRACE ((FOO))  =>  NIL
         FOO (BAR)
         ; Output:
         FUNCTION:  FOO
         ARGUMENTS: (BAR)

         VALUE: *TRUE*


12.3 SUBR UNTRACE (LIST)  =>  NIL

LIST is a list of function names. The functions
will no longer be traced (see TRACE). UNTRACE
returns NIL.

Example: UNTRACE ((FOO))  =>  NIL


13 OTHER FUNCTIONS

13.1 SUBR DUMP (SYMBOL)  =>  *TRUE*

***** The DUMP function has a different meaning
in LISP 1.5.

Write the LISP memory pool and some meta
information to the image file named by SYMBOL.
Return T.

The image can later be reloaded by passing its
name to the LISP XV interpreter.

Example: DUMP (LXVIMAGE)  =>  *TRUE*


13.2 SUBR GENSYM ()  =>  SYMBOL

Return a new symbol. The symbol will not be added
to the OBLIST and hence will not be permanent.
Reading the symbol back will generate a different
symbol with the same name.

Example: GENSYM ()  =>  G1
                        ; The actual name may
                        ; be different


13.3 SUBR LOAD (SYMBOL)  =>  *TRUE*
     SUBR LOAD (LIST)    =>  *TRUE*

***** The LOAD function has a different meaning
in LISP 1.5.

Load a LISP program from the file named SYMBOL.
Each function/argument pair in the file will be
evaluated as if entered at the LISP system
prompt. LOAD returns *TRUE*.

When a list is passed to LOAD instead of a
symbol, LOAD will construct a relative path name
from the components of the list. E.g. the list
(FOO BAR BAZ) will be translated to the path
name "foo/bar/baz" on a DOS or Unix system.

On systems with case-sensitive file names, the
name of the file to load must be all lower-case.

Example: LOAD (LXVTEST)  =>  *TRUE*


13.4 SUBR RECLAIM ()       =>  SYMBOL
     SUBR RECLAIM (SYMBOL) =>  SYMBOL

Run a garbage collection and return the number
of reclaimed nodes as a transient symbol.

When a non-NIL symbol is passed to RECLAIM, all
subsequent collections will be verbose, i.e. the
number of reclaimed nodes will be printed after
each collection. Passing NIL to RECLAIM will turn
off verbose collections.

A "node" is a rather abstract entity. A CONS
cell consists of a single node, but an atom
conisists a variable number of nodes.

Example: RECLAIM ()  =>  4950
                         ; the actual value may
                         ; be different


13.5 SUBR REMOB (SYMBOL)  =>  NIL

Remove the given symbol from the OBLIST, thereby
removing it from the system. Return NIL.

Example: REMOB (FOO)  =>  NIL


13.6 FSUBR SELECT (OBJ <clause> ...)  =>  NIL

Each clause has the form (OBJn FORM).

First evaluate OBJ and then compare its value to
the object in each clause, from left to right.
Evaluate the FORM associated with the first OBJn
that is EQUAL to OBJ. When no clause matches OBJ,
return OBJ.

Example: (SELECT (QUOTE BAR)
                 (FOO (QUOTE 1))
                 (BAR (QUOTE 2))
                 (BAZ (QUOTE 3)))  =>  2

         (SELECT (QUOTE QUUX)
                 (FOO (QUOTE 1))
                 (BAR (QUOTE 2))
                 (BAZ (QUOTE 3)))  =>  QUUX


14 THE REPL

The Read Eval(quote) Print Loop (REPL) is the
interface to the LISP system. It reads a function
and a list of arguments via READ and evaluates
them via EVALQUOTE. This means that the arguments
will not be evaluated before passing them to the
function.

Some functions (in particular FEXPRs and FSUBRs)
may evaluate some or all of their argument
themselves, though. Therefore, some arguments
still may have to be quoted.

For example, entering

CONS (FOO BAR)

will result in

(FOO . BAR)

However, entering

COND ((T FOO))

will result in an error unless the symbol FOO is
bound via its APVAL property. In this case

COND ((T (QUOTE FOO)))

has to be used instead, because COND evaluates
forms of its clauses conditionally.


14.1 BATCH MODE

When the LISP XV interpreter is started in
batch mode, input is read from SYSIN (stdin)
and output is written to SYSOUT (stdout). Batch
mode is activated by passing the command line
argument "-" to the interpreter.

In batch mode, input and output of the LISP
system can be redirected to files. Command line
editing will not work, and pressing Control-C
will exit the interpreter immediately. The
interpreter will also exit when the end of its
input is reached or an error occurs.


14.2 INTERACTIVE MODE

While the REPL is reading input in interactive
mode, the following keys will have special
functions:

Control-A  move cursor to beginning of line
Control-B  move cursor left
Control-C  abort all input, start over
Control-D  delete character
Control-D  (on empty line) return EOT
Control-E  move cursor to end of line
Control-F  move cursor right
Control-H  delete char. on left (also backspace)
Control-L  clear screen
Control-P  rotate through last three input lines
Control-U  clear current input line

Once a computation is in progress, it can be
aborted by pressing Control-C.

To end the LISP session, press Control-D or enter
a % sign, both on an empty input line with no
lists open.

15 ERROR CODES

A 1     ERROR called
A 3     COND unsatisfied
A 4     Not a program variable
A 6     GO with undefined label
A 8     Undefined variable
A 9     Undefined function
A 10    Type error *****

F 2     Too few function arguments
F 3     Too many function arguments

GC 2    Out of memory

P 2     Print depth exceeded *****

R 1     Right parenthesis or dot out of context
R 2     Malformed pair
R 3     Invalid character
R 4     Unexpected end of file
R 5     Symbol too long
R 6     File I/O error *****
R 7     File access error *****

X 1     Program stopped by user *****

Z 1     Syntax error *****

contact | privacy