\begin{document}
\section{Preliminaries}
\subsection{Primitive Data Types}
\begin{Type}{integer}
Integer numbers:
Integers are also called "fixed" numbers. The magnitude of
an integer is unrestricted. Integers in the LISP input stream are
an arbitrary number of integer digits, eventually preceded by
a plus or minus sign.
\begin{Examples}
22\\
-31415926585\\
\end{Examples}
\end{Type}
\begin{Type}{floating}
Floating point numbers: The precision of floating point
numbers is determined solely by the implementation. In BNF floating
point numbers are recognized by the grammar:
\begin{verbatim}
<base> ::= <unsigned-integer>.|.<unsigned-integer>|
<unsigned-integer>.<unsigned-integer>
<unsigned-floating> ::= <base>|
<base>E<unsigned-integer>|
<base>E-<unsigned-integer>|
<base>E+<unsigned-integer>
<floating> ::= <unsigned-floating>|
+<unsigned-floating>|-<unsigned-floating>
\end{verbatim}
\begin{Examples}
3.1415\\
17.0\\
-22e100\\
1.1e-5
\end{Examples}
\end{Type}
\begin{Type}{id}
An identifier is a string of characters which may have the
following items associated with it.
print name: The characters of the identifier.
flags: An identifier may be tagged with a flag. Access is
by the \nameref{flag}, \nameref{remflag}and
\nameref{flagp} functions.
properties: An identifier may have an indicator-value pair
associated with it. Access is by the
\nameref{put}, \nameref{get}, and \nameref{remprop}
functions.
values: An identifier may have a value associated with
it. Access to values is by \nameref{set} \nameref{setq}
The method by which the value
is attached to the identifier is known as the binding
type, being one of
\nameref{Local Binding}, \nameref{Global Binding},
or \nameref{Fluid Binding}.
functions:
An identifier may have a function or macro associated with
it. Access is by the
\nameref{putd}, \nameref{getd}, and \nameref{remd} functions.
An identifier may not have both a function and a value
associated with it.
\name{oblist} entry: An identifier may be entered and removed from a
structure called the \nameref{oblist}. Its presence on the \name{oblist}
does not directly affect the other properties. Access to
the \name{oblist} is by the
\nameref{intern}, \nameref{remob}, and \nameref{read}
functions.
The maximum length of a Standard LISP identifier is 24
characters (excluding occurrences of the escape character !)
but an implementation may allow more. Special characters
(digits in the first position and punctuation) must be prefixed
with an escape character, an ! in Standard LISP. In BNF
identifiers are recognized by the grammar:
\begin{verbatim}
<special-character> ::= !<any-character>
<alphabetic> ::=
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|
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
<lead-character> ::= <special-character>|<alphabetic>
<regular-character> ::= <lead-character>|<digit>
<last-part> ::= <regular-character> |
<last-part><regular-character>
<id> ::= <lead-character>|<lead-character><last-part>
Note: Using lower case letters in identifiers may cause
portability problems. Lower case letters are automatically
converted to upper case when the \nameref{!*RAISE} flag is T.
\end{verbatim}
\begin{Examples}
a\\
Hugo\\
!1!-otto\\
!*raise\\
this!-is!-a!-long!-id\\
!U!P!P!E!R!-and!-!l!o!w!e!r\\
\end{Examples}
\end{Type}
\begin{Type}{string}
A set of characters enclosed in double quotes as
in "THIS IS A STRING". A quote is included by doubling it as in "HE
SAID, ""LISP""". The maximum size of strings is 80 characters but an
implementation may allow more. Strings are not part of the \nameref{oblist} and
are considered constants like \nameref{number}s, \nameref{vector}s,
and \nameref{function-pointer}s.
\end{Type}
\begin{Type}{dotted-pair}
\index{car}\index{cdr}
A dotted pair is a primitive structure which has a left and right part.
A notation called {\em dot-notation} is used for dotted pairs and
takes the form:
\begin{verbatim}
(<left-part> . <right-part>)
\end{verbatim}
The <left-part> is known as the \nameref{car} portion and the
<right-part> as the \nameref{cdr} portion. The left and right parts may be of any type.
Spaces are used to resolve ambiguity with floating point numbers.
When <left-part> or <right-part> are dotted-pairs themselves,
the \nameref{list-notation} is often more convenient.
\end{Type}
\begin{Type}{vector}
A vector is a primitive uniform structure in which
an integer index is used to access random values in the structure. The
individual elements of a vector may be of any type. Access to vectors
is restricted to functions \nameref{putv}, \nameref{getv}, and
\nameref{upbv}.
A notation for vectors, vector-notation, has the
elements of a vector surrounded by square brackets
\begin{verbatim}
<elements> ::= <any>|<any> <elements>
<vector> ::= [<elements>]
\end{verbatim}
\begin{Examples}
[1 2 3 5 7 11 13 17 19 23]\\
[nil (a) (a . a)]\\
[[1 2 3 4 5][2 4 6 8 10][3 6 9 12 15]]\\
\end{Examples}
\end{Type}
\begin{Type}{function-pointer}
An implementation may have functions which deal
with specific data types other than those listed. The use
of these entities is to be avoided with the exception of a
restricted use of the \name{function-pointer}, an access method to
compiled EXPRs and FEXPRs (see \nameref{Function Types}).
A particular
\name{function-pointer} must
remain valid throughout execution. Systems which change the
location of a function must use either an indirect reference or
change all occurrences of the associated value. There are two
classes of use of function-pointers, those which are supported
by Standard LISP but are not well defined, and those which are
well defined.
\end{Type}
\subsection{Classes of Primitive Data Types}
\begin{Introduction}{Type Classes}
The classes of primitive types are a notational convenience for
describing the properties of functions.
\end{Introduction}
\begin{Type}{boolean}
The set of global variables \{\nameref{T}, \nameref{NIL}\}, or their respective
values, \{T, NIL\}.
\end{Type}
\begin{Type}{extra-boolean}
Any value in the system. Anything that is not \nameref{NIL} has
the boolean interpretation T.
\end{Type}
\begin{Type}{ftype}
The class of definable function types. The set of ids \{EXPR,
FEXPR, MACRO\}. See \nameref{Function Types}.
\end{Type}
\begin{Type}{number}
The set of \{\nameref{integer}, \nameref{floating}\}.
\end{Type}
\begin{Type}{constant}
The set of \{\nameref{integer}, \nameref{floating}, \nameref{string},
\nameref{vector}, \nameref{function-pointer} \}.
Constants evaluate to themselves (see \nameref{eval})
\end{Type}
\begin{Type}{any}
The set of \{\nameref{integer}, \nameref{floating}, \nameref{string},
\nameref{id}, \nameref{dotted-pair}, \nameref{vector},
\nameref{function-pointer}\}. An S-expression is another term for any.
All Standard LISP entities have some value unless an \nameref{error}
occurs during evaluation or the function causes transfer of
control (such as \nameref{go} and \nameref{return}).
\end{Type}
\begin{Type}{atom}
The set \nameref{any} - \{\nameref{dotted-pair}\}. Any item wich is not a \name{dotted-pair}
is considered as \name{atom}.
\end{Type}
\subsection{Structures}
\begin{Introduction}{Structures}
Structures are entities created out of the primitive types by the
use of dotted-pairs. Lists are structures very commonly required
as actual parameters to functions. Where a list of homogeneous
entities is required by a function this class will be denoted
by <xxx-list> where xxx is the name of a class of primitives or
structures. Thus a list of ids is an id-list, a list of integers an
integer-list and so on.
\end{Introduction}
\begin{Concept}{List-Notation}
A \name{list} is recursively defined as \nameref{nil} or the dotted-pair
(\nameref{any} . list). A special notation called list-notation is used
to represent lists. List-notation eliminates extra parentheses
and dots. The structure (a . (b . (c . nil))) in list notation
is (a b c). List-notation and dot-notation may be mixed as in
(a b . c) or (a (b . c) d) which are (a . (b . c)) and (a .
((b . c) . (d . nil))). In BNF lists are recognized by the
grammar:
\begin{verbatim}
<left-part> ::= ( | <left-part> <any>
<list> ::= <left-part>) | <left-part> . <any>)
\end{verbatim}
Note: () is an alternate input representation of nil.
\end{Concept}
\begin{Concept}{alist}
An association list; each element of the list is a
dotted-pair, the CAR part being a key associated with the value
in the CDR part.
\begin{Examples}
((a . 17)(b . (expt x 2))(q . nil))\\
\end{Examples}
Here a is associated with 17 while b is linked to the square of x
and q points to nil.
\end{Concept}
\begin{Concept}{cond-form}
A cond-form is a list of 2 element lists of the form:
(ANTECEDENT:any CONSEQUENT:any)
The first element will henceforth be known as the antecedent
and the second as the consequent. The antecedent must have a
value. The consequent may have a value or an occurrence of
\nameref{go} or \nameref{return}.
\begin{Examples}
((greaterp x 0) 1)\\
(t 0)\\
\end{Examples}
\end{Concept}
\begin{Concept}{lambda}
A LAMBDA expression which must have the form (in list
notation):
(LAMBDA <parameters> <body>).
<parameters> is a
list of formal parameters for <body> an S-expression to be
evaluated. The semantics of the evaluation are defined with
the \nameref{eval}.
\begin{Examples}
(lambda(x y)(cons (car x)(cddr y)))
\end{Examples}
\end{Concept}
\begin{Concept}{function}
A LAMBDA expression or a function-pointer to a function. A
function is always evaluated as an EVAL, SPREAD form.
(see \nameref{Function Types}).
\end{Concept}
\section{Notation}
\begin{Introduction}{Function Descriptions}
Each function is provided with a prototypical header line. Each formal
parameter is given a name and suffixed with its allowed type. Lower
case, italic tokens are names of classes and upper case, bold face,
tokens are parameter names referred to in the definition. The type of
the value returned by the function (if any) is suffixed to the
parameter list.
If it is not commonly used the parameter type
may be a specific set enclosed in brackets {...}. For example:
\begin{verbatim}
PUTD(FNAME:id, TYPE:ftype, BODY:{lambda, function-pointer}):id
\end{verbatim}
PUTD is a function with three parameters. The parameter FNAME is
an id to be the name of the function being defined. TYPE is the
type of the function being defined and BODY is a lambda expression
or a function-pointer. PUTD returns the name of the function being
defined.
Functions which accept formal parameter lists of arbitrary length
have the type class and parameter enclosed in square brackets
indicating that zero or more occurrences of that argument are
permitted. For example:
\begin{verbatim}
AND([U:any]):extra-boolean
\end{verbatim}
AND is a function which accepts zero or more arguments which may be
of any type.
\end{Introduction}
\begin{Introduction}{Function Types}
\index{eval type}\index{noeval type}
\index{spread type}\index{nospread type}
\index{expr type}\index{macro type}
EVAL type functions are those which are invoked with evaluated
arguments. NOEVAL functions are invoked with unevaluated arguments.
SPREAD type functions have their arguments passed in one-to-one
correspondence with their formal parameters. NOSPREAD functions
receive their arguments as a single list. EVAL, SPREAD functions
are associated with EXPRs and NOEVAL, NOSPREAD functions with
FEXPRs. EVAL, NOSPREAD and NOEVAL, SPREAD functions can be
simulated using NOEVAL, NOSPREAD functions or MACROs.
EVAL, SPREAD type functions may have a maximum of 15 parameters.
There is no limit on the number of parameters a NOEVAL, NOSPREAD
function or MACRO may have.
In the context of the description of an EVAL, SPREAD function, then
we speak of the formal parameters we mean their actual values.
However, in a NOEVAL, NOSPREAD function it is the unevaluated actual
parameters.
A third function type, the MACRO, implements functions which create
S-expressions based on actual parameters. When a macro invocation
is encountered, the body of the macro, a lambda expression, is
invoked as a NOEVAL, NOSPREAD function with the macro's invocation
bound as a list to the macros single formal parameter. When the
macro has been evaluated the resulting S-expression is reevaluated.
The description of \nameref{eval} and \nameref{expand} provide precise
details.
\end{Introduction}
\begin{Introduction}{Messages}
\index{error}\index{warning}
Many functions detect errors. The description of such functions
will include these error conditions and suggested formats for
display of the generated error messages. A call on the
\nameref{error}
function is implied but the error number is not specified by
Standard LISP. In some cases a warning message is sufficient. To
distinguish between errors and warnings, errors are prefixed with
five asterisks and warnings with only three.
Primitive functions check arguments that must be of a certain
primitive type for being of that type and display an error message
if the argument is not correct. The type mismatch error always
takes the form:
\begin{verbatim}
***** PARAMETER not TYPE for FN
\end{verbatim}
Here PARAMETER is the unacceptable actual parameter, TYPE is the
type that PARAMETER was supposed to be. FN is the name of the
function that detected the error.
\end{Introduction}
\begin{Introduction}{Comments}
The character \% signals the start of a comment, text to be ignored during
parsing. A comment is terminated by the end of the line it is on. The
function \nameref{readch}must be able to read a comment one character at a
time. Comments are transparent to the function READ. The percent sign
may occur as a character in identifiers by preceding it with the escape
character.
(setq a 17) \% this is a comment
\end{Introduction}
%-----------------------------------------------------------------
\section{Elementary Predicates}
%-----------------------------------------------------------------
\begin{Introduction}{Elementary Predicates}
Functions in this section return \nameref{T} when the condition defined is met
and \nameref{NIL} when it is not. Defined are type checking functions and
elementary comparisons.
\end{Introduction}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{atom}
\begin{verbatim}
ATOM(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is not a \nameref{dotted-pair}.
\begin{verbatim}
EXPR PROCEDURE ATOM(U);
NULL PAIRP U;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{codep}
\begin{verbatim}
CODEP(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is a \nameref{function-pointer}.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{constantp}
\begin{verbatim}
CONSTANTP(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is a constant (a \nameref{number},
\nameref{string}, \nameref{function-pointer}, or \nameref{vector}).
\begin{verbatim}
EXPR PROCEDURE CONSTANTP(U);
NULL OR(PAIRP U, IDP U);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{eq}
\begin{verbatim}
EQ(U:any, V:any):boolean eval, spread
\end{verbatim}
Returns T if U points to the same object as V. EQ is not a
reliable comparison between numeric arguments.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{eqn}
\begin{verbatim}
EQN(U:any, V:any):boolean eval, spread
\end{verbatim}
Returns T if U and V are EQ or if U and V are
\nameref{number}s and have the same value and type.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{equal}
\begin{verbatim}
EQUAL(U:any, V:any):boolean eval, spread
\end{verbatim}
Returns T if U and V are the same. Dotted-pairs are
compared recursively to the bottom levels of their trees.
Vectors must have identical dimensions and EQUAL values in
all positions. Strings must have identical characters.
Function pointers must have \nameref{eq} values. Other atoms must be
\nameref{eqn} equal.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{fixp}
\begin{verbatim}
FIXP(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is an \nameref{integer}.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{floatp}
\begin{verbatim}
FLOATP(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is a \nameref{floating} point number.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{idp}
\begin{verbatim}
IDP(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is an \nameref{id}.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{minusp}
\begin{verbatim}
MINUSP(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is a number and less than 0. If U is not a
\nameref{number} or is a positive number, NIL is returned.
\begin{verbatim}
EXPR PROCEDURE MINUSP(U);
IF NUMBERP U THEN LESSP(U, 0) ELSE NIL;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{null}
\begin{verbatim}
NULL(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is NIL.
\begin{verbatim}
EXPR PROCEDURE NULL(U);
U EQ NIL;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{numberp}
\begin{verbatim}
NUMBERP(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is a \nameref{number}.
\begin{verbatim}
EXPR PROCEDURE NUMBERP(U);
IF OR(FIXP U, FLOATP U) THEN T ELSE NIL;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{onep}
\begin{verbatim}
ONEP(U:any):boolean eval, spread.
\end{verbatim}
Returns T if U is a \nameref{number} and has the value 1 or 1.0.
Returns NIL otherwise.
\begin{verbatim}
EXPR PROCEDURE ONEP(U);
IF EQN(U,1) OR EQN(U,1.0) THEN T ELSE NIL;
\end{verbatim}
The definition in the published report is incorrect as it
does not return T for U of 1.0.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{pairp}
\begin{verbatim}
PAIRP(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is a \nameref{dotted-pair}.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{stringp}
\begin{verbatim}
STRINGP(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is a string.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{vectorp}
\begin{verbatim}
VECTORP(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is a vector.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{zerop}
\begin{verbatim}
ZEROP(U:any):boolean eval, spread.
\end{verbatim}
Returns T if U is a number and has the value 0 or 0.0.
Returns NIL otherwise.
The definition in the published report is incorrect as it
does not return T for U of 0.0.
\end{Function}
\section{Functions on Dotted-Pairs}
\begin{Introduction}{Function on Dotted-Pairs}
\index{dotted-pair}
The following are elementary functions on dotted-pairs. All functions
in this section which require dotted-pairs as parameters detect a type
mismatch error if the actual parameter is not a dotted-pair.
\end{Introduction}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{car}
\begin{verbatim}
CAR(U:dotted-pair):any eval, spread
\end{verbatim}
CAR(CONS(a, b)) -> a. The left part of U is returned. The
type mismatch error occurs if U is not a dotted-pair.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{cdr}
\begin{verbatim}
CDR(U:dotted-pair):any eval, spread
\end{verbatim}
CDR(CONS(a, b)) -> b. The right part of U is returned. The
type mismatch error occurs if U is not a dotted-pair.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{caar}
\index{CAAAAR}\index{CAAAR}\index{CAAADR}\index{CAADR}
\index{CADR}\index{CAADAR}\index{CADAR}\index{CDAR}\index{CAADDR}
\index{CADDR}\index{CDDR}\index{CADAAR}\index{CDAAR}\index{CADADR}
\index{CDADR}\index{CADDAR}\index{CDDAR}\index{CADDDR}\index{CDDDR}
\index{CDAAAR}\index{CDAADR}\index{CDADAR}\index{CDADDR}\index{CDDAAR}
\index{CDDADR}\index{CDDDAR}\index{CDDDDR}
The composites of CAR and CDR are supported up to 4 levels, namely:
CAAAAR CAAAR CAAR CAAADR CAADR CADR
CAADAR CADAR CDAR CAADDR CADDR CDDR
CADAAR CDAAR CADADR CDADR CADDAR CDDAR
CADDDR CDDDR CDAAAR CDAADR CDADAR CDADDR
CDDAAR CDDADR CDDDAR CDDDDR
Here e.g. (cdar x) is equivlaent to (cdr (car x)).
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{cons}
\begin{verbatim}
CONS(U:any, V:any):dotted-pair eval, spread
\end{verbatim}
Returns a dotted-pair which is not \nameref{eq} to anything and has U
as its \nameref{car} part and V as its nameref(cdr) part.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{list}
\begin{verbatim}
LIST([U:any]):list noeval, nospread, or macro
\end{verbatim}
A list of the evaluation of each element of U is returned.
The order of evaluation nead not be first to last as the
following definition implies.
\begin{verbatim}
FEXPR PROCEDURE LIST(U);
EVLIS U;
\end{verbatim}
The published report's definition implies a specific
ordering.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{rplaca}
\begin{verbatim}
RPLACA(U:dotted-pair, V:any):dotted-pair eval, spread
\end{verbatim}
The \nameref{car} portion of the dotted-pair U is replaced by V. If
dotted-pair U is (a . b) then (V . b) is returned. The type
mismatch error occurs if U is not a dotted-pair.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{rplacd}
\begin{verbatim}
RPLACD(U:dotted-pair, V:any):dotted-pair eval, spread
\end{verbatim}
The \nameref{cdr} portion of the dotted-pair U is replaced by V. If
dotted-pair U is (a . b) then (a . V) is returned. The
type mismatch error occurs if U is not a dotted-pair.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Functions for Identifiers}
\begin{Concept}{oblist}
The following functions deal with identifiers and the \nameref{oblist},
the structure of which is not defined.
The \name{oblist} is an internal stucture where \nameref{id}s
are kept. The function of the \name{oblist} is
to provide a symbol table for identifiers created during input.
Identifiers created by \nameref{read} which have the same characters will
therefore refer to the same object (see the \nameref{eq} function).
Identifiers created by \nameref{gensym} or \nameref{compress} are
not member of the \name{oblist} and therefore they are not
unique even if they are represented by the same character
sequence on output. The function \nameref{intern} is used
to create an equivalent unique \name{id} which then is
member of the \name{oblist}.
\end{Concept}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{compress}
\begin{verbatim}
COMPRESS(U:id-list):{atom-vector} eval, spread
\end{verbatim}
U is a list of single character identifiers which is built
into a Standard LISP entity and returned. Recognized are
\nameref{number}s, \nameref{string}s,
and identifiers (see \nameref{id}) with the \name{escape} character
prefixing special characters. Function pointers
may be compressed but this is an undefined use. If an entity
cannot be parsed out of U or characters are left over after
parsing an error occurs:
\begin{verbatim}
***** Poorly formed atom in COMPRESS
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{explode}
\begin{verbatim}
EXPLODE(U:{atom}-{vector}):id-list eval, spread
\end{verbatim}
Returned is a list of interned characters representing the
characters to print of the value of U. The primitive data
types have these formats:
\nameref{integer}: Leading zeroes are suppressed and a minus sign
prefixes the digits if the integer is negative.
\nameref{floating}: The value appears in the format [-]0.nn...nnE[-]mm
if the magnitude of the number is too large or small to
display in [-]nnnn.nnnn format. The crossover point is
determined by the implementation.
\nameref{id}: The characters of the print name of the identifier
are produced with special characters prefixed with the
escape character.
\nameref{string}: The characters of the string are produced surrounded
by double quotes "...".
\nameref{function-pointer}: The value of the function-pointer is created
as a list of characters conforming to the conventions of
the system site.
The type mismatch error occurs if U is not a number,
identifier, string, or function-pointer.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{gensym}
\begin{verbatim}
GENSYM():identifier eval, spread
\end{verbatim}
Creates an identifier which is not interned on the \nameref{oblist} and
consequently not \nameref{eq} to anything else.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{intern}
\begin{verbatim}
INTERN(U:{id,string}):id eval, spread
\end{verbatim}
INTERN searches the \nameref{oblist} for an identifier with the same
print name as U and returns the identifier on the \name{oblist} if a
match is found. Any properties and global values associated
with U may be lost. If U does not match any entry, a
new one is created and returned. If U has more than the
maximum number of characters permitted by the implementation
(the minimum number is 24) an error occurs:
\begin{verbatim}
***** Too many characters to INTERN
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{remob}
\begin{verbatim}
REMOB(U:id):id eval, spread
\end{verbatim}
If U is present on the \nameref{oblist} it is removed. This does not
affect U having properties, flags, functions and the like. U
is returned.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Property List Functions}
\begin{Introduction}{Property List Functions}
With each id in the system is a \name{property list}, a set of entities
which are associated with the id for fast access. These entities are
called \nameindex{flags} if their use gives the id a single valued
property, and \nameindex{properties} if the id is to have a multivalued
attribute: an indicator with a property.
Flags and indicators may clash, consequently care should be taken to
avoid this occurrence. Flagging X with an id which already is an
indicator for X may result in that indicator and associated property
being lost. Likewise, adding an indicator which is the same id as a
flag may result in the flag being destroyed.
\end{Introduction}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{flag}
\begin{verbatim}
FLAG(U:id-list, V:id):NIL eval, spread
\end{verbatim}
U is a list of ids which are flagged with V. The effect of
\name{flag} is that \nameref{flagp} will have the value T for those ids of U
which were flagged. Both V and all the elements of U must be
identifiers or the type mismatch error occurs.
\begin{Examples}
flag('(u v),'symmetric)\\
\end{Examples}
Note: If you want to flag a single \name{id} you must put it into
a list before calling the function \name{flag}. A flag is removed
by \nameref{remflag}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{flagp}
\begin{verbatim}
FLAGP(U:any, V:any):boolean eval, spread
\end{verbatim}
Returns T if U has been previously flagged (see \nameref{flag}}
with V, else NIL. Returns NIL if either U or V is not an \nameref{id}.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{get}
\begin{verbatim}
GET(U:any, IND:any):any eval, spread
\end{verbatim}
Returns the property associated with indicator IND from the
property list of U. If U does not have indicator IND, NIL is
returned. GET cannot be used to access functions (use GETD
instead). For setting a property use the function \nameref{put}.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{put}
\begin{verbatim}
PUT(U:id, IND:id, PROP:any):any eval, spread
\end{verbatim}
The indicator IND with the property PROP is placed on the
property list of the id U. If the action of PUT occurs, the
value of PROP is returned. If either of U and IND are not
ids the type mismatch error will occur and no property will
be placed. PUT cannot be used to define functions
(use \nameref{putd} instead). The values stored on the property
list can be retrieved using \nameref{get}. \nameref{remprop}
removes a property.
\begin{Examples}
put('otto,'hugo,'(a))\\
get('otto,'hugo) & (a)\\
put('otto,'hugo,'(b))\\
get('otto,'hugo) & (b)\\
remprop('otto,'hugo)\\
get('otto,'hugo) & nil\\
\end{Examples}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{remflag}
\begin{verbatim}
REMFLAG(U:any-list, V:id):NIL eval, spread
\end{verbatim}
Removes the flag V from the property list of each member of
the list U. Both V and all the elements of U must be ids or
the type mismatch error will occur (see \nameref{flag}).
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{remprop}
\begin{verbatim}
REMPROP(U:any, IND:any):any eval, spread
\end{verbatim}
Removes the property with indicator IND from the property
list of U. Returns the removed property or NIL if there was
no such indicator (see \nameref{put}}.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Function Definition}
\begin{Introduction}{Function Definition}
Functions in Standard LISP are global entities. To avoid
function-variable naming clashes no variable may have the same name as
a function.
\end{Introduction}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{de}
\index{expr}
\begin{verbatim}
DE(FNAME:id, PARAMS:id-list, FN:any):id noeval, nospread
\end{verbatim}
The function FN with the formal parameter list PARAMS is
added to the set of defined functions with the name FNAME.
Any previous definitions of the function are lost. The
function created is of type EXPR (see \nameref{Function Types}). If \nameref{*COMP} is
non-NIL, the EXPR is first compiled. The name of the defined
function is returned.
\begin{verbatim}
FEXPR PROCEDURE DE(U);
PUTD(CAR U, 'EXPR, LIST('LAMBDA, CADR U, CADDR U));
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{df}
\index{fexpr}
\begin{verbatim}
DF(FNAME:id, PARAM:id-list, FN:any):id noeval, nospread
\end{verbatim}
The function FN with formal parameter PARAM is added to the
set of defined functions with the name FNAME. Any previous
definitions of the function are lost. The function created
is of type FEXPR (see \nameref{Function Types}). If \nameref{*COMP} is T the FEXPR
is first compiled. The name of the defined function is
returned.
\begin{verbatim}
FEXPR PROCEDURE DF(U);
PUTD(CAR U, 'FEXPR, LIST('LAMBDA, CADR U, CADDR U));
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{dm}
\index{macro}
\begin{verbatim}
DM(MNAME:id, PARAM:id-list, FN:any):id noeval, nospread
\end{verbatim}
The macro FN with the formal parameter PARAM is added to the
set of defined functions with the name MNAME. Any previous
definitions of the function are overwritten. The function
created is of type MACRO (see \nameref{Function Types}).
The name of the macro is returned.
\begin{verbatim}
FEXPR PROCEDURE DM(U);
PUTD(CAR U, 'MACRO, LIST('LAMBDA, CADR U, CADDR U));
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{getd}
\begin{verbatim}
GETD(FNAME:any):{NIL, dotted-pair} eval, spread
\end{verbatim}
If FNAME is not the name of a defined function, NIL
is returned. If FNAME is a defined function then the
dotted-pair
\begin{verbatim}
(TYPE:ftype . DEF:{function-pointer, lambda})
\end{verbatim}
is returned.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{putd}
\begin{verbatim}
PUTD(FNAME:id, TYPE:ftype, BODY:function):id eval, spread
\end{verbatim}
Creates a function with name FNAME and definition BODY of
type TYPE. If PUTD succeeds the name of the defined function
is returned. The effect of PUTD is that GETD will return a
dotted-pair with the functions type and definition. Likewise
the \nameref{globalp} predicate will return T when queried with the
function name.
If the function FNAME has already been declared as a GLOBAL
or FLUID variable the error:
\begin{verbatim}
***** FNAME is a non-local variable
\end{verbatim}
occurs and the function will not be defined. If function
FNAME already exists a warning message will appear:
\begin{verbatim}
*** FNAME redefined
\end{verbatim}
The function defined by PUTD will be compiled before
definition if \nameref{*COMP} variable is non-NIL.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{remd}
\begin{verbatim}
REMD(FNAME:id):{NIL, dotted-pair} eval, spread
\end{verbatim}
Removes the function named FNAME from the set of defined
functions. Returns the (ftype . function) dotted-pair or
NIL as does \nameref)getd}. The global/function attribute of FNAME is
removed and the name may be used subsequently as a variable.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Variables and Bindings}
\begin{Introduction}{Scope}
\index{variables}
A variable is a place holder for a Standard LISP entity which is said
to be bound to the variable. The scope of a variable is the range over
which the variable has a defined value. There are three different
binding mechanisms in Standard LISP:
\nameref{Local Binding}, \nameref{Global Binding}, and
\nameref{Fluid Binding}.
\end{Introduction}
\begin{Concept}{Local Binding}
\index{variables}
This type of binding occurs
only in compiled functions. Local variables occur as formal parameters
in \nameref{lambda} expressions (function arguments)
and as \nameref{prog} form variables. The binding occurs
when a lambda expression is evaluated or when a \name{prog} form is executed.
The scope of a local variable is the body of the function in which it
is defined.
\end{Concept}
\begin{Concept}{Global Binding}
\index{variables}
Only one binding of a
global variable exists at any time allowing direct access to the value
bound to the variable. The scope of a global variable is universal.
Variables declared \nameref{global} may not appear as parameters
in \nameref{lambda} expressions (function arguments)
or as \nameref{prog} form variables. A variable must be declared
\name{global} prior to its use as a global variable since the default type
for undeclared variables is \nameref{fluid}.
\end{Concept}
\begin{Concept}{Fluid Binding}
\index{variables}
Fluid variables are global
in scope but may occur as \name{fluid} formal parameters or
\nameref{prog} form variables. In interpreted functions all formal parameters
and \name{prog} form variables are considered to have fluid binding until
changed to local binding by compilation. When \name{fluid} variables are
used as parameters (\nameref{lambda} expressions}
they are rebound in such a way that the previous
binding may be restored. All references to \name{fluid} variables are to the
currently active binding.
\end{Concept}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{fluid}
\index{variables}
\begin{verbatim}
FLUID(IDLIST:id-list):NIL eval, spread
\end{verbatim}
The ids in IDLIST are declared as FLUID type variables (ids
not previously declared are initialized to NIL). Variables
in IDLIST already declared FLUID are ignored. Changing a
variable's type from GLOBAL to FLUID is not permissible and
results in the error:
\begin{verbatim}
***** ID cannot be changed to FLUID
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{fluidp}
\index{variables}
\begin{verbatim}
FLUIDP(U:any):boolean eval, spread
\end{verbatim}
If U has been declared by \nameref{fluid} T is
returned, otherwise NIL is returned.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{global}
\index{variables}
\begin{verbatim}
GLOBAL(IDLIST:id-list):NIL eval, spread
\end{verbatim}
The ids of IDLIST are declared global type variables. If
an id has not been declared previously it is initialized to
NIL. Variables already declared GLOBAL are ignored. Changing
a variables type from FLUID to GLOBAL is not permissible and
results in the error:
\begin{verbatim}
***** ID cannot be changed to GLOBAL
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{globalp}
\index{variables}
\begin{verbatim}
GLOBALP(U:any):boolean eval, spread
\end{verbatim}
If U has been declared GLOBAL or is the name of a defined
function, T is returned, else NIL is returned.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{set}
\index{variables}
\begin{verbatim}
SET(EXP:id, VALUE:any):any eval, spread
\end{verbatim}
EXP must be an identifier or a type mismatch error occurs.
The effect of SET is replacement of the item bound to
the identifier by VALUE. If the identifier is not a local
variable or has not been declared GLOBAL it is automatically
declared FLUID with the resulting warning message:
\begin{verbatim}
*** EXP declared FLUID
\end{verbatim}
EXP must not evaluate to T or NIL or an error occurs:
\begin{verbatim}
***** Cannot change T or NIL
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{setq}
\index{variables}
\begin{verbatim}
SETQ(VARIABLE:id, VALUE:any):any noeval, nospread
\end{verbatim}
If VARIABLE is not local or GLOBAL it is by default declared
FLUID and the warning message:
\begin{verbatim}
*** VARIABLE declared FLUID
\end{verbatim}
appears. The value of the current binding of VARIABLE is
replaced by the value of VALUE. VARIABLE must not be T or NIL
or an error occurs:
\begin{verbatim}
***** Cannot change T or NIL
\end{verbatim}
\begin{verbatim}
MACRO PROCEDURE SETQ(X);
LIST('SET, LIST('QUOTE, CADR X), CADDR X);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{unfluid}
\index{variables}
\begin{verbatim}
UNFLUID(IDLIST:id-list):NIL eval, spread
\end{verbatim}
The variables in IDLIST that have been declared as \nameref{fluid}
variables are no longer considered as fluid variables.
Others are ignored. This affects only compiled functions
as free variables in interpreted functions are automatically
considered fluid.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Program Feature Functions}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{go}
\index{program control}
\index{label}
\begin{verbatim}
GO(LABEL:id) noeval, nospread
\end{verbatim}
GO alters the normal flow of control within a \nameref{prog} function.
The next statement of a PROG function to be evaluated is
immediately preceded by LABEL. A GO may only appear in the
following situations:
1. At the top level of a \nameref{prog} referencing a label which
also appears at the top level of the same prog.
2. As the consequent of a \nameref{cond} item of a \name{cond} appearing on
the top level of a \nameref{prog}.
3. As the consequent of a \nameref{cond} item which appears as the
consequent of a \name{cond} item to any level.
4. As the last statement of a \nameref{progn} which appears at
the top level of a \nameref{prog} or in a \name{progn} appearing in
the consequent of a \nameref(cond} to any level subject to the
restrictions of 2 and 3.
5. As the last statement of a \nameref{progn}
within a \name{progn} or as
the consequent of a \nameref{prog}in a \name{progn}to any level subject
to the restrictions of 2, 3 and 4.
If LABEL does not appear at the top level of the \name{prog} in
which the \name{go} appears, an error occurs:
\begin{verbatim}
***** LABEL is not a known label
\end{verbatim}
If the \name{go} has been placed in a position not defined by rules
1-5, another error is detected:
\begin{verbatim}
***** Illegal use of GO to LABEL
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{prog}
\index{program control}
\begin{verbatim}
PROG(VARS:id-list, [PROGRAM:{id, any}]):any noeval, nospread
\end{verbatim}
VARS is a list of ids which are considered fluid when the
PROG is interpreted and local when compiled (see ``Variables
and Bindings'', section 3.6 on page 22). The PROGs variables
are allocated space when the PROG form is invoked and are
deallocated when the PROG is exited. PROG variables are
initialized to NIL. The PROGRAM is a set of expressions to be
evaluated in order of their appearance in the PROG function.
Identifiers appearing in the top level of the PROGRAM are
labels which can be referenced by GO. The value returned by
the PROG function is determined by a \nameref{return} function or NIL
if the PROG falls through.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{progn}
\index{program control}
\begin{verbatim}
PROGN([U:any]):any noeval, nospread
\end{verbatim}
U is a set of expressions which are executed sequentially.
The value returned is the value of the last expression.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{prog2}
\index{program control}
\begin{verbatim}
PROG2(A:any, B:any)any eval, spread
\end{verbatim}
Returns the value of B.
\begin{verbatim}
EXPR PROCEDURE PROG2(A, B);
B;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{return}
\index{program control}
\begin{verbatim}
RETURN(U:any) eval, spread
\end{verbatim}
Within a \nameref{prog}, RETURN terminates the evaluation of a PROG
and returns U as the value of the PROG. The restrictions on
the placement of RETURN are exactly those of nameref{go}. Improper
placement of RETURN results in the error:
\begin{verbatim}
***** Illegal use of RETURN
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Error Handling}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{error}
\index{error handling}
\begin{verbatim}
ERROR(NUMBER:integer, MESSAGE:any) eval, spread
\end{verbatim}
NUMBER and MESSAGE are passed back to a surrounding \nameref{errorset}
(the Standard LISP reader has an ERRORSET). MESSAGE is placed
in the global variable \nameref{emsg*} and the error number becomes
the value of the surrounding ERRORSET. \nameref{fluid} variables and
local bindings are unbound to return to the environment
of the ERRORSET. Global variables are not affected by the
process.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{errorset}
\index{error handling}
\begin{verbatim}
ERRORSET(U:any, MSGP:boolean, TR:boolean):any eval, spread
\end{verbatim}
If an error occurs during the evaluation of U, the value
of NUMBER from the \nameref{error} call is returned as the value of
ERRORSET. In addition, if the value of MSGP is non-NIL,
the MESSAGE from the ERROR call is displayed upon both the
standard output device and the currently selected output
device unless the standard output device is not open. The
message appears prefixed with 5 asterisks. The MESSAGE list
is displayed without top level parentheses. The MESSAGE
from the ERROR call will be available in the global variable
\nameref{emsg*}. The exact format of error messages generated by
Standard LISP functions described in this document are not
fixed and should not be relied upon to be in any particular
form. Likewise, error numbers generated by Standard LISP
functions are implementation dependent.
If no error occurs during the evaluation of U, the value of
(LIST (EVAL U)) is returned.
If an error has been signaled and the value of TR is non-NIL
a traceback sequence will be initiated on the selected output
device. The traceback will display information such as
unbindings of \nameref{fluid} variables, argument lists and so on in an
implementation dependent format.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Functions for Vectors}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{getv}
\index{vector}
\begin{verbatim}
GETV(V:vector, INDEX:integer):any eval, spread
\end{verbatim}
Returns the value stored at position INDEX of the \nameref{vector} V.
The type mismatch error may occur. An error occurs if the
INDEX does not lie within 0... UPBV(V) inclusive:
\begin{verbatim}
***** INDEX subscript is out of range
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{mkvect}
\index{vector}
\begin{verbatim}
MKVECT(UPLIM:integer):vector eval, spread
\end{verbatim}
Defines and allocates space for a \nameref{vector} with UPLIM+1
elements accessed as 0... UPLIM. Each element is initialized
to NIL. An error will occur if UPLIM is < 0 or there is not
enough space for a vector of this size:
\begin{verbatim}
***** A vector of size UPLIM cannot be allocated
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{putv}
\index{vector}
\begin{verbatim}
PUTV(V:vector, INDEX:integer, VALUE:any):any eval, spread
\end{verbatim}
Stores VALUE into the \nameref{vector} V at position INDEX. VALUE is
returned. The type mismatch error may occur. If INDEX does
not lie in 0... UPBV(V) an error occurs:
\begin{verbatim}
***** INDEX subscript is out of range
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{upbv}
\index{vector}
\begin{verbatim}
UPBV(U:any):NIL,integer eval, spread
\end{verbatim}
Returns the upper limit of U if U is a \nameref{vector}, or NIL if it
is not.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Boolean Functions, Conditionals}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{and}
\index{boolean}
\begin{verbatim}
AND([U:any]):extra-boolean noeval, nospread
\end{verbatim}
AND evaluates each U until a value of NIL is found or the end
of the list is encountered. If a non-NIL value is the last
value it is returned, or NIL is returned.
\begin{verbatim}
FEXPR PROCEDURE AND(U);
BEGIN
IF NULL U THEN RETURN NIL;
LOOP: IF NULL CDR U THEN RETURN EVAL CAR U
ELSE IF NULL EVAL CAR U THEN RETURN NIL;
U := CDR U;
GO LOOP
END;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{cond}
\index{boolean}
\begin{verbatim}
COND([U:cond-form]):any noeval, nospread
\end{verbatim}
The antecedents of all U's (\nameref{cond-form}s) are evaluated in order of their
appearance until a non-NIL value is encountered. The
consequent of the selected U is evaluated and becomes the
value of the COND. The consequent may also contain the
special functions \nameref{go} and \nameref{return} subject to the restraints
given for these functions. In these cases COND does not have
a defined value, but rather an effect. If no antecedent is
non-NIL the value of COND is NIL. An error is detected if a U
is improperly formed:
\begin{verbatim}
***** Improper cond-form as argument of COND
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{not}
\index{boolean}
\begin{verbatim}
NOT(U:any):boolean eval, spread
\end{verbatim}
If U is NIL, return T else return NIL (same as function
NULL).
\begin{verbatim}
EXPR PROCEDURE NOT(U);
U EQ NIL;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{or}
\index{boolean}
\begin{verbatim}
OR([U:any]):extra-boolean noeval, nospread
\end{verbatim}
U is any number of expressions which are evaluated in order
of their appearance. When one is found to be non-NIL it is
returned as the value of OR. If all are NIL, NIL is returned.
\begin{verbatim}
FEXPR PROCEDURE OR(U);
BEGIN SCALAR X;
LOOP: IF NULL U THEN RETURN NIL
ELSE IF (X := EVAL CAR U) THEN RETURN X;
U := CDR U;
GO LOOP
END;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Arithmetic Functions}
\begin{Introduction}{Conversion}
\index{mixed-mode arithmetic}
Conversions between numeric types are provided explicitly by the
\nameref{fix} and \nameref{float} functions and implicitly by any
multi-parameter arithmetic function which receives mixed types of arguments. A
conversion from fixed to floating point numbers may result in a loss
of precision without a warning message being generated. Since
integers may have a greater magnitude that that permitted for floating
numbers, an error may be signaled when the attempted conversion cannot
be done.
Because the magnitude of integers is unlimited the conversion
of a floating point number to a fixed number is always possible, the
only loss of precision being the digits to the right of the decimal
point which are truncated. If a function receives mixed types of
arguments the general rule will have the fixed numbers converted to
floating before arithmetic operations are performed. In all cases an
error occurs if the parameter to an arithmetic function is not a
number:
\begin{verbatim}
\errormessage{***** XXX parameter to FUNCTION is not a number}
\end{verbatim}
XXX is the value of the parameter at fault and FUNCTION is the name of
the function that detected the error. Exceptions to the rule are noted
where they occur.
\end{Introduction}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{abs}
\index{arithmetic}
\begin{verbatim}
ABS(U:number):number eval, spread
\end{verbatim}
Returns the absolute value of its argument.
\begin{verbatim}
EXPR PROCEDURE ABS(U);
IF LESSP(U, 0) THEN MINUS(U) ELSE U;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{add1}
\index{arithmetic}
\begin{verbatim}
ADD1(U:number):number eval, spread
\end{verbatim}
Returns the value of U plus 1 of the same type as U (fixed or
floating).
\begin{verbatim}
EXPR PROCEDURE ADD1(U);
PLUS2(U, 1);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{difference}
\index{arithmetic}
\begin{verbatim}
DIFFERENCE(U:number, V:number):number eval, spread
\end{verbatim}
The value U - V is returned.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{divide}
\index{arithmetic}
\begin{verbatim}
DIVIDE(U:number, V:number):dotted-pair eval, spread
\end{verbatim}
The dotted-pair (quotient . remainder) is returned. The
quotient part is computed the same as by QUOTIENT and the
remainder the same as by REMAINDER. An error occurs if
division by zero is attempted:
\begin{verbatim}
***** Attempt to divide by 0 in DIVIDE
\end{verbatim}
\begin{verbatim}
EXPR PROCEDURE DIVIDE(U, V);
(QUOTIENT(U, V) . REMAINDER(U, V));
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{expt}
\index{arithmetic}
\begin{verbatim}
EXPT(U:number, V:integer):number eval, spread
\end{verbatim}
Returns U raised to the V power. A floating point U to an
integer power V does not have V changed to a floating number
before exponentiation.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{fix}
\index{arithmetic}
\begin{verbatim}
FIX(U:number):integer eval, spread
\end{verbatim}
Returns an integer which corresponds to the truncated value
of U. The result of conversion must retain all significant
portions of U. If U is an integer it is returned unchanged.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{float}
\index{arithmetic}
\begin{verbatim}
FLOAT(U:number):floating eval, spread
\end{verbatim}
The floating point number corresponding to the value of the
argument U is returned. Some of the least significant
digits of an integer may be lost do to the implementation of
floating point numbers. FLOAT of a floating point number
returns the number unchanged. If U is too large to represent
in floating point an error occurs:
\begin{verbatim}
***** Argument to FLOAT is too large
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{greaterp}
\index{arithmetic}\index{boolean}
\begin{verbatim}
GREATERP(U:number, V:number):boolean eval, spread
\end{verbatim}
Returns T if U is strictly greater than V, otherwise returns
NIL.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{lessp}
\index{arithmetic}\index{boolean}
\begin{verbatim}
LESSP(U:number, V:number):boolean eval, spread
\end{verbatim}
Returns T if U is strictly less than V, otherwise returns
NIL.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{max}
\index{arithmetic}
\begin{verbatim}
MAX([U:number]):number noeval, nospread, or macro
\end{verbatim}
Returns the largest of the values in U. If two or more values
are the same the first is returned.
\begin{verbatim}
MACRO PROCEDURE MAX(U);
EXPAND(CDR U, 'MAX2);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{max2}
\index{arithmetic}
\begin{verbatim}
MAX2(U:number, V:number):number eval, spread
\end{verbatim}
Returns the larger of U and V. If U and V are the same value
U is returned (U and V might be of different types).
\begin{verbatim}
EXPR PROCEDURE MAX2(U, V);
IF LESSP(U, V) THEN V ELSE U;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{min}
\index{arithmetic}
\begin{verbatim}
MIN([U:number]):number noeval, nospread, or macro
\end{verbatim}
Returns the smallest of the values in U. If two or more
values are the same the first of these is returned.
\begin{verbatim}
MACRO PROCEDURE MIN(U);
EXPAND(CDR U, 'MIN2);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{min2}
\index{arithmetic}
\begin{verbatim}
MIN2(U:number, V:number):number eval, spread
\end{verbatim}
Returns the smaller of its arguments. If U and V are the
same value, U is returned (U and V might be of different
types).
\begin{verbatim}
EXPR PROCEDURE MIN2(U, V);
IF GREATERP(U, V) THEN V ELSE U;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{minus}
\index{arithmetic}
\begin{verbatim}
MINUS(U:number):number eval, spread
\end{verbatim}
Returns -U.
\begin{verbatim}
EXPR PROCEDURE MINUS(U);
DIFFERENCE(0, U);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{plus}
\index{arithmetic}
\begin{verbatim}
PLUS([U:number]):number noeval, nospread, or macro
\end{verbatim}
Forms the sum of all its arguments.
\begin{verbatim}
MACRO PROCEDURE PLUS(U);
EXPAND(CDR U, 'PLUS2);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{plus2}
\index{arithmetic}
\begin{verbatim}
PLUS2(U:number, V:number):number eval, spread
\end{verbatim}
Returns the sum of U and V.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{quotient}
\index{arithmetic}
\begin{verbatim}
QUOTIENT(U:number, V:number):number eval, spread
\end{verbatim}
The quotient of U divided by V is returned. Division of
two positive or two negative integers is conventional. When
both U and V are integers and exactly one of them is negative
the value returned is the negative truncation of the absolute
value of U divided by the absolute value of V. An error
occurs if division by zero is attempted:
\begin{verbatim}
***** Attempt to divide by 0 in QUOTIENT
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{remainder}
\index{arithmetic}
\begin{verbatim}
REMAINDER(U:number, V:number):number eval, spread
\end{verbatim}
If both U and V are integers the result is the integer
remainder of U divided by V. If either parameter is floating
point, the result is the difference between U and V*(U/V)
all in floating point. If either number is negative the
remainder is negative. If both are positive or both are
negative the remainder is positive. An error occurs if V is
zero:
\begin{verbatim}
***** Attempt to divide by 0 in REMAINDER
\end{verbatim}
\begin{verbatim}
EXPR PROCEDURE REMAINDER(U, V);
DIFFERENCE(U, TIMES2(QUOTIENT(U, V), V));
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{sub1}
\index{arithmetic}
\begin{verbatim}
SUB1(U:number):number eval, spread
\end{verbatim}
Returns the value of U less 1. If U is a FLOAT type number,
the value returned is U less 1.0.
\begin{verbatim}
EXPR PROCEDURE SUB1(U);
DIFFERENCE(U, 1);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{times}
\index{arithmetic}
\begin{verbatim}
TIMES([U:number]):number noeval, nospread, or macro
\end{verbatim}
Returns the product of all its arguments.
\begin{verbatim}
MACRO PROCEDURE TIMES(U);
EXPAND(CDR U, 'TIMES2);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{times2}
\index{arithmetic}
\begin{verbatim}
TIMES2(U:number, V:number):number eval, spread
\end{verbatim}
Returns the product of U and V.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{MAP Composite Functions}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{map}
\begin{verbatim}
MAP(X:list, FN:function):any eval, spread
\end{verbatim}
Applies FN to successive CDR segments of X. NIL is returned.
\begin{verbatim}
EXPR PROCEDURE MAP(X, FN);
WHILE X DO << FN X; X := CDR X >>;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{mapc}
\begin{verbatim}
MAPC(X:list, FN:function):any eval, spread
\end{verbatim}
FN is applied to successive CAR segments of list X. NIL is
returned.
\begin{verbatim}
EXPR PROCEDURE MAPC(X, FN);
WHILE X DO << FN CAR X; X := CDR X >>;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{mapcan}
\begin{verbatim}
MAPCAN(X:list, FN:function):any eval, spread
\end{verbatim}
A concatenated list of FN applied to successive CAR elements
of X is returned.
\begin{verbatim}
EXPR PROCEDURE MAPCAN(X, FN);
IF NULL X THEN NIL
ELSE NCONC(FN CAR X, MAPCAN(CDR X, FN));
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{mapcar}
\begin{verbatim}
MAPCAR(X:list, FN:function):any eval, spread
\end{verbatim}
Returned is a constructed list of FN applied to each CAR of
list X.
\begin{verbatim}
EXPR PROCEDURE MAPCAR(X, FN);
IF NULL X THEN NIL
ELSE FN CAR X . MAPCAR(CDR X, FN);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{mapcon}
\begin{verbatim}
MAPCON(X:list, FN:function):any eval, spread
\end{verbatim}
Returned is a concatenated list of FN applied to successive
CDR segments of X.
\begin{verbatim}
EXPR PROCEDURE MAPCON(X, FN);
IF NULL X THEN NIL
ELSE NCONC(FN X, MAPCON(CDR X, FN));
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{maplist}
\begin{verbatim}
MAPLIST(X:list, FN:function):any eval, spread
\end{verbatim}
Returns a constructed list of FN applied to successive CDR
segments of X.
\begin{verbatim}
EXPR PROCEDURE MAPLIST(X, FN);
IFNULL X THEN NIL
ELSE FN X . MAPLIST(CDR X, FN);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Composite Functions}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{apend}
\begin{verbatim}
APPEND(U:list, V:list):list eval, spread
\end{verbatim}
Returns a constructed list in which the last element of U is
followed by the first element of V. The list U is copied, V
is not.
\begin{verbatim}
EXPR PROCEDURE APPEND(U, V);
IF NULL U THEN V
ELSE CAR U . APPEND(CDR U, V);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{assoc}
\begin{verbatim}
ASSOC(U:any, V:alist):{dotted-pair, NIL} eval, spread
\end{verbatim}
If U occurs as the CAR portion of an element of the \nameref{alist} V,
the dotted-pair in which U occurred is returned, else NIL is
returned. ASSOC might not detect a poorly formed alist so an
invalid construction may be detected by CAR or CDR.
\begin{verbatim}
EXPR PROCEDURE ASSOC(U, V);
IF NULL V THEN NIL
ELSE IF ATOM CAR V THEN
ERROR(000, LIST(V, "is a poorly formed alist"))
ELSE IF U = CAAR V THEN CAR V
ELSE ASSOC(U, CDR V);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{deflist}
\begin{verbatim}
DEFLIST(U:dlist, IND:id):list eval, spread
\end{verbatim}
A "dlist" is a list in which each element is a two element
list: (ID:id PROP:any). Each ID in U has the indicator
IND with property PROP placed on its property list by the
PUT function. The value of DEFLIST is a list of the first
elements of each two element list. Like \nameref{put}, DEFLIST may not
be used to define functions.
\begin{verbatim}
EXPR PROCEDURE DEFLIST(U, IND);
IF NULL U THEN NIL
ELSE << PUT(CAAR U, IND, CADAR U);
CAAR U >> . DEFLIST(CDR U, IND);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{delete}
\begin{verbatim}
DELETE(U:any, V:list):list eval, spread
\end{verbatim}
Returns V with the first top level occurrence of U removed
from it.
\begin{verbatim}
EXPR PROCEDURE DELETE(U, V);
IF NULL V THEN NIL
ELSE IF CAR V = U THEN CDR V
ELSE CAR V . DELETE(U, CDR V);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{digit}
\begin{verbatim}
DIGIT(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is a digit, otherwise NIL.
\begin{verbatim}
EXPR PROCEDURE DIGIT(U);
IF MEMQ(U, '(!0 !1 !2 !3 !4 !5 !6 !7 !8 !9))
THEN T ELSE NIL;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{length}
\begin{verbatim}
LENGTH(X:any):integer eval, spread
\end{verbatim}
The top level length of the list X is returned.
\begin{verbatim}
EXPR PROCEDURE LENGTH(X);
IF ATOM X THEN 0
ELSE PLUS(1, LENGTH CDR X);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{liter}
\begin{verbatim}
LITER(U:any):boolean eval, spread
\end{verbatim}
Returns T if U is a character of the alphabet, NIL
otherwise.
\begin{verbatim}
EXPR PROCEDURE LITER(U);
IF MEMQ(U, '(!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
!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))
\end{verbatim}
The published report omits escape characters. These are
required for both upper and lower case as some systems
default to lower.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{member}
\begin{verbatim}
MEMBER(A:any, B:list):extra-boolean eval, spread
\end{verbatim}
Returns NIL if A is not a member of list B, returns the
remainder of B whose first element is A.
\begin{verbatim}
EXPR PROCEDURE MEMBER(A, B);
IF NULL B THEN NIL
ELSE IF A = CAR B THEN B
ELSE MEMBER(A, CDR B);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{memq}
\begin{verbatim}
MEMQ(A:any, B:list):extra-boolean eval, spread
\end{verbatim}
Same as \nameref{member} but an \nameref{eq} check is used for comparison.
\begin{verbatim}
EXPR PROCEDURE MEMQ(A, B);
IF NULL B THEN NIL
ELSE IF A EQ CAR B THEN B
ELSE MEMQ(A, CDR B);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{nconc}
\begin{verbatim}
NCONC(U:list, V:list):list eval, spread
\end{verbatim}
Concatenates V to U without copying U. The last CDR of U is
modified to point to V.
\begin{verbatim}
EXPR PROCEDURE NCONC(U, V);
BEGIN SCALAR W;
IF NULL U THEN RETURN V;
W := U;
WHILE CDR W DO W := CDR W;
RPLACD(W, V);
RETURN U
END;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{pair}
\begin{verbatim}
PAIR(U:list, V:list):alist eval, spread
\end{verbatim}
U and V are lists which must have an identical number of
elements. If not, an error occurs (the 000 used in the \nameref{error}
call is arbitrary and need not be adhered to). Returned is a
list where each element is a dotted-pair, the CAR of the pair
being from U, and the CDR the corresponding element from V.
\begin{verbatim}
EXPR PROCEDURE PAIR(U, V);
IF AND(U, V) THEN (CAR U . CAR V) . PAIR(CDR U, CDR V)
ELSE IF OR(U, V) THEN ERROR(000,
"Different length lists in PAIR")
ELSE NIL;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{reverse}
\begin{verbatim}
REVERSE(U:list):list eval, spread
\end{verbatim}
Returns a copy of the top level of U in reverse order.
\begin{verbatim}
EXPR PROCEDURE REVERSE(U);
BEGIN SCALAR W;
WHILE U DO << W := CAR U . W;
U := CDR U >>;
RETURN W
END;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{sassoc}
\begin{verbatim}
SASSOC(U:any, V:alist, FN:function):any eval, spread
\end{verbatim}
Searches the \nameref{alist} V for an occurrence of U. If U is not in
the alist the evaluation of function FN is returned.
\begin{verbatim}
EXPR PROCEDURE SASSOC(U, V, FN);
IF NULL V THEN FN()
ELSE IF U = CAAR V THEN CAR V
ELSE SASSOC(U, CDR V, FN);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{sublis}
\index{substitution}
\begin{verbatim}
SUBLIS(X:alist, Y:any):any eval, spread
\end{verbatim}
The value returned is the result of substituting the CDR of
each element of the alist X for every occurrence of the CAR
part of that element in Y.
\begin{verbatim}
EXPR PROCEDURE SUBLIS(X, Y);
IF NULL X THEN Y
ELSE BEGIN SCALAR U;
U := ASSOC(Y, X);
RETURN IF U THEN CDR U
ELSE IF ATOM Y THEN Y
ELSE SUBLIS(X, CAR Y) .
SUBLIS(X, CDR Y)
END;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{subst}
\index{substitution}
\begin{verbatim}
SUBST(U:any, V:any, W:any):any eval, spread
\end{verbatim}
The value returned is the result of substituting U for all
occurrences of V in W.
\begin{verbatim}
EXPR PROCEDURE SUBST(U, V, W);
IF NULL W THEN NIL
ELSE IF V = W THEN U
ELSE IF ATOM W THEN W
ELSE SUBST(U, V, CAR W) . SUBST(U, V, CDR W);
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Interpreter}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{apply}
\begin{verbatim}
APPLY(FN:{id,function}, ARGS:any-list):any eval, spread
\end{verbatim}
APPLY returns the value of FN with actual parameters
ARGS. The actual parameters in ARGS are already in the
form required for binding to the formal parameters of FN.
Implementation specific portions described in English are
enclosed in boxes.
\begin{verbatim}
EXPR PROCEDURE APPLY(FN, ARGS);
BEGIN SCALAR DEFN;
IF---------------------------------------------
-Spread the actual parameters in ARGS-
-following the conventions: for calling-
-functions, transfer to the entry point of;
- -
-the function, and return the value returned-
----------------------------------------------
IF IDP FN THEN RETURN
IF NULL(DEFN := GETD FN) THEN
ERROR(000, LIST(FN, "is an undefined function"))
ELSE IF CAR DEFN EQ 'EXPR THEN
APPLY(CDR DEFN, ARGS)
ELSE ERROR(000,
LIST(FN, "cannot be evaluated by APPLY"));
IF OR(ATOM FN, NOT(CAR FN EQ 'LAMBDA)) THEN
ERROR(000,
LIST(FN, "cannot be evaluated by APPLY"));
RETURN
-Bind-the--actual-parameters--in-ARGS--to-the-
- -
-formal parameters of the lambda expression.-
-If the two lists are not of equal length-
-then ERROR(000, "Number of parameters do not-
-match"); The value returned is EVAL CADDR-
----------------------------------------------
END;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{eval}
\begin{verbatim}
EVAL(U:any):any eval, spread
\end{verbatim}
The value of the expression U is computed. Error numbers
are arbitrary. Portions of EVAL involving machine specific
coding are expressed in English enclosed in boxes.
\begin{verbatim}
EXPR PROCEDURE EVAL(U);
BEGIN SCALAR FN;
IF CONSTANTP U THEN RETURN U;
IF IDP U THEN RETURN
-U-is-an-id.--Return-the-value-most-currently-
-bound to U or if there is no such binding:-
- -
----------------------------------------------
IF PAIRP CAR U THEN RETURN
IF CAAR U EQ 'LAMBDA THEN APPLY(CAR U, EVLIS CDR U)
ELSE ERROR(000, LIST(CAR U,
"improperly formed LAMBDA expression"))
ELSE IF CODEP CAR U THEN
RETURN APPLY(CAR U, EVLIS CDR U);
FN := GETD CAR U;
IF NULL FN THEN
ERROR(000, LIST(CAR U, "is an undefined function"))
ELSE IF CAR FN EQ 'EXPR THEN
RETURN APPLY(CDR FN, EVLIS CDR U)
ELSE IF CAR FN EQ 'FEXPR THEN
RETURN APPLY(CDR FN, LIST CDR U)
ELSE IF CAR FN EQ 'MACRO THEN
RETURN EVAL APPLY(CDR FN, LIST U)
END;
\end{verbatim}
see also \nameref{constantp}, \nameref{idp}, \nameref{pairp},
\nameref{evlis}, nameref{apply}, nameref{getd}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{evlis}
\begin{verbatim}
EVLIS(U:any-list):any-list eval, spread
\end{verbatim}
EVLIS returns a list of the evaluation of each element of U.
\begin{verbatim}
EXPR PROCEDURE EVLIS(U);
IF NULL U THEN NIL
ELSE EVAL CAR U . EVLIS CDR U;
\end{verbatim}
see also \nameref{eval}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{expand}
\index{macro}
\begin{verbatim}
EXPAND(L:list, FN:function):list eval, spread
\end{verbatim}
FN is a defined function of two arguments to be used in the
expansion of a \name{macro} defined by \nameref{dm}. EXPAND returns a list in the form:
\begin{verbatim}
(FN L (FN L ...(FN L L ) ... ))
0 1 n-1 n
\end{verbatim}
where n is the number of elements in L, Li is the ith element
of L.
\begin{verbatim}
EXPR PROCEDURE EXPAND(L,FN);
IF NULL CDR L THEN CAR L
ELSE LIST(FN, CAR L, EXPAND(CDR L, FN));
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{function}
\begin{verbatim}
FUNCTION(FN:function):function noeval, nospread
\end{verbatim}
The function FN is to be passed to another function. If
FN is to have side effects its free variables must be \nameref{fluid}
or \nameref{global}. FUNCTION is like \nameref{quote} but its argument may be
affected by compilation. We do not consider \nameindex{FUNARG}s in this
report.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{quote}
\begin{verbatim}
QUOTE(U:any):any noeval, nospread
\end{verbatim}
Stops evaluation and returns U unevaluated.
\begin{verbatim}
FEXPR PROCEDURE QUOTE(U);
CAR U;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{Input and Output}
\begin{Introduction}{IO}
The user normally communicates with Standard LISP through
\nameindex{standard devices}. The default devices are selected in accordance
with the conventions of the implementation site. Other input and
output devices or files may be selected for reading and writing using
the functions described herein.
\end{Introduction}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{close}
\begin{verbatim}
CLOSE(FILEHANDLE:any):any eval, spread
\end{verbatim}
Closes the file with the internal name FILEHANDLE writing
any necessary end of file marks and such. The value of
FILEHANDLE is that returned by the corresponding OPEN. The
value returned is the value of FILEHANDLE. An error occurs if
the file can not be closed.
\begin{verbatim}
***** FILEHANDLE could not be closed
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{eject}
\begin{verbatim}
EJECT():NIL eval, spread
\end{verbatim}
Skip to the top of the next output page. Automatic EJECTs
are executed by the print functions when the length set by
the \nameref{pagelength} function is exceeded.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{linelength}
\begin{verbatim}
LINELENGTH(LEN:{integer, NIL}):integer eval, spread
\end{verbatim}
If LEN is an integer the maximum line length to be printed
before the print functions initiate an automatic nameref{terpri} is
set to the value LEN. No initial Standard LISP line length is
assumed. The previous line length is returned except when
LEN is NIL. This special case returns the current line length
and does not cause it to be reset. An error occurs if the
requested line length is too large for the currently selected
output file or LEN is negative or zero.
\begin{verbatim}
***** LEN is an invalid line length
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{lposn}
\begin{verbatim}
LPOSN():integer eval, spread
\end{verbatim}
Returns the number of lines printed on the current page. At
the top of a page, 0 is returned.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{open}
\index{input}\index{output}
\begin{verbatim}
OPEN(FILE:any, HOW:id):any eval, spread
\end{verbatim}
Open the file with the system dependent name FILE for output
if HOW is \nameref{eq} to OUTPUT, or input if HOW is \name{eq} to INPUT. If
the file is opened successfully, a value which is internally
associated with the file is returned. This value must be
saved for use by \nameref{wrs} and \nameref{rds}. An error occurs if HOW is
something other than INPUT or OUTPUT or the file can't be
opened.
\begin{verbatim}
***** HOW is not option for OPEN
***** FILE could not be opened
\end{verbatim}
Use the \nameref{close} function to close a file.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{pagelength}
\begin{verbatim}
PAGELENGTH(LEN:{integer, NIL}):integer eval, spread
\end{verbatim}
Sets the vertical length (in lines) of an output page.
Automatic page \nameref{eject}s are executed by the print functions
when this length is reached. The initial vertical length
is implementation specific. The previous page length is
returned. If LEN is 0, no automatic page ejects will
occur.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{posn}
\begin{verbatim}
POSN():integer eval, spread
\end{verbatim}
Returns the number of characters in the output buffer. When
the buffer is empty, 0 is returned.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{princ}
\begin{verbatim}
PRINC(U:id):id eval, spread
\end{verbatim}
U must be a single character id such as produced by \nameref{explode}
or read by \nameref{readch} or the value of \nameref{$eol$}. The effect is
the character U displayed upon the currently selected output
device. The value of \name{!$EOL!$} causes termination of the
current line like a call to \nameref{terpri}.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{print}
\begin{verbatim}
PRINT(U:any):any eval, spread
\end{verbatim}
Displays U in \nameref{read} readable format and terminates the print
line. The value of U is returned.
\begin{verbatim}
EXPR PROCEDURE PRINT(U);
<< PRIN1 U; TERPRI(); U >>;
\end{verbatim}
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{prin1}
\begin{verbatim}
PRIN1(U:any):any eval, spread
\end{verbatim}
U is displayed in a \nameref{read} readable form. The format
of display is the result of \nameref{explode} expansion; special
characters are prefixed with the escape character !, and
strings are enclosed in "... ". Lists are displayed in
list-notation and vectors in vector-notation.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{prin2}
\begin{verbatim}
PRIN2(U:any):any eval, spread
\end{verbatim}
U is displayed upon the currently selected print device
but output is not \nameref{read} readable. The value of U is
returned. Items are displayed as described in the \nameref{explode}
function with the exceptions that the escape character does
not prefix special characters and strings are not enclosed in
"... ". Lists are displayed in list-notation and vectors in
vector-notation. The value of U is returned.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{rds}
\begin{verbatim}
RDS(FILEHANDLE:any):any eval, spread
\end{verbatim}
Input from the currently selected input file is suspended
and further input comes from the file named. FILEHANDLE is
a system dependent internal name which is a value returned
by \nameref{open}. If FILEHANDLE is NIL the standard input device is
selected. When end of file is reached on a non-standard
input device, the standard input device is reselected. When
end of file occurs on the standard input device the Standard
LISP reader terminates. RDS returns the internal name of the
previously selected input file.
\begin{verbatim}
***** FILEHANDLE could not be selected for input
\end{verbatim}
The function name RDS goes back to "read select";
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{read}
\begin{verbatim}
READ():any
\end{verbatim}
The next expression from the file currently selected for
input. Valid input forms are: vector-notation, dot-
notation, list-notation, numbers, function-pointers, strings,
and identifiers with escape characters. Identifiers are
interned on the \name{oblist} (see \nameref{intern})
READ returns the
value of \nameref{\$eof\$} when the end of the currently selected input
file is reached.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{readch}
\begin{verbatim}
READCH():id
\end{verbatim}
Returns the next interned character from the file currently
selected for input. Two special cases occur. If all the
characters in an input record have been read, the value of
\nameref{\$eol\$} is returned. If the file selected for input has
all been read the value of \nameref{\$eof\$} is returned. Comments
delimited by % and end-of-line are not transparent to \nameref{readch}.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{terpri}
\begin{verbatim}
TERPRI():NIL
\end{verbatim}
The current print line is terminated. The following output
begins on a new line.
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\begin{Function}{wrs}
\begin{verbatim}
WRS(FILEHANDLE:any):any eval, spread
\end{verbatim}
Output to the currently active output file is suspended and
further output is directed to the file named. FILEHANDLE is
an internal name which is returned by \nameref{open}. The file named
must have been opened for output. If FILEHANDLE is NIL the
standard output device is selected. WRS returns the internal
name of the previously selected output file.
\begin{verbatim}
***** FILEHANDLE could not be selected for output
\end{verbatim}
The function name WRS goes back to "write select".
\end{Function}
%- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\section{LISP Reader}
\begin{Introduction}{LISP Reader}
An EVAL read loop has been chosen to drive a Standard LISP system to
provide a continuity in functional syntax. Choices of messages and the
amount of extra information displayed are decisions left to the
implementor.
\end{Introduction}
\begin{Function}{quit}
\begin{verbatim}
QUIT()
\end{verbatim}
Causes termination of the LISP reader and control to be transferred
to the operating system.
\end{Function}
\section{System GLOBAL Variables}
\begin{Variable}{*comp}
\index{expr}
The value of the global variable !*comp controls whether or not
\nameref{putd} compiles the
function defined in its arguments before defining it. If !*comp is NIL
the function is defined as an \name{expr}. If !*comp is something else the
function is first compiled. Compilation will produce certain changes
in the semantics of functions particularly \nameref{fluid} type access.
\end{Variable}
\begin{Variable}{emsg*}
Will contain the MESSAGE generated by the last \nameref{error} call.
\end{Variable}
\begin{Variable}{$eof$}
The value of !\$eof!\$ is returned by all input functions when the
end \index{end of file}
of the currently selected input file is reached.
\end{Variable}
\begin{Variable}{$eol$}
The value of !\$eol!\$ is returned by \nameref{readch} when it reaches the end
of \name{readch} \index{end of line}
a logical input record. Likewise \nameref{princ} will terminate its current line
(like a call to \nameref{terpri}) when !\$eol!\$ is its argument.
\end{Variable}
\begin{Variable}{*gc}
\index{garbage collector}
!*gc controls the printing of garbage collector messages. If NIL no
indication of garbage collection may occur. If non-NIL various system
dependent messages may be displayed.
\end{Variable}
\begin{Variable}{nil}
\name{nil} is a special global variable. It is protected from being modified
by \nameref{set} or \nameref{setq}. Its value is \name{nil}.
\end{Variable}
\begin{Variable}{*raise}
If \name{!*raise} is non-NIL all characters input through Standard LISP
input/output functions will be raised to upper case. If \name{!*RAISE} is NIL
characters will be input as is.
\end{Variable}
\begin{Variable}{t}
\name{t} is a special global variable. It is protected from being modified
by \nameref{set} or \nameref{setq}. Its value is \name{t}.
\end{Variable}
\end{document}