xxx
+-----------------------------------+
| |
| U T I L I S P M A N U A L |
| |
+-----------------------------------+
Takashi Chikayama
Information Engineering Course
University of Tokyo
Modified for MTS by
Michael Alexander
The University of Michigan
Contents Sep. 8, 1981
Table of Contents
1. Introduction ................................... 1
1.1 General Information .......................... 1
1.2 How to Run and Stop the System ............... 1
1.3 Notational Conventions and Notes on Syntax ... 2
1.4 Data Types ................................... 4
1.5 Lambda Lists ................................. 5
2. Predicates ..................................... 7
2.1 Predicates on Data Types ..................... 7
2.2 General Purpose Predicates ................... 8
3. Evaluation ..................................... 9
3.1 The Evaluator ................................ 9
3.2 Various Functions Concerned with Evaluation .. 9
4. Flow of Control ................................ 13
4.1 Conditionals ................................. 13
4.2 Iteration .................................... 15
4.3 Non-local Exits .............................. 18
4.4 Mapping ...................................... 19
5. Manipulating List Structure .................... 22
5.1 Cons manipulation ............................ 22
5.2 List Manipulation ............................ 23
5.3 Alteration of List Structure ................. 25
5.4 Tables ....................................... 26
5.5 Sorting ...................................... 29
5.6 Hashing ...................................... 29
6. Symbols ........................................ 30
6.1 The Value .................................... 30
6.2 The Definition ............................... 31
6.3 The Property List ............................ 32
6.4 The Print Name ............................... 33
6.5 Creation of Symbols .......................... 33
7. Numbers ........................................ 34
7.1 Numeric Predicates ........................... 34
7.2 Conversion Functions ......................... 36
7.3 Arithmetics .................................. 36
7.4 Logical Operations on Numbers ................ 38
8. Strings ........................................ 39
8.1 Characters ................................... 39
8.2 String Manipulation .......................... 40
8.3 Manipulation of Characters in Strings ........ 42
Contents - 1
Sep. 8, 1981 Contents
8.4 Converting Strings and Numbers ............... 43
8.5 Bit String Manipulation ...................... 43
9. Vectors ........................................ 44
9.1 Vector Manipulation .......................... 44
9.2 References ................................... 45
10. Macros ........................................ 47
10.1 Evaluation of Macros ........................ 47
10.2 DEFMACRO Facility ........................... 48
10.3 Backquote Facility .......................... 49
11. Input and Output .............................. 50
11.1 Streams ..................................... 50
11.2 Allocating Files ............................ 52
11.3 Printed Representation ...................... 53
11.3.1 The Printer ............................. 54
11.3.2 The Reader .............................. 56
11.3.3 The Readtable ........................... 58
11.3.4 Setting Readtable ....................... 59
11.4 Input Functions ............................. 60
11.5 Output Functions ............................ 61
11.6 Formatted Printing .......................... 61
11.7 Indented Printing ........................... 62
12. Code Pieces ................................... 64
13. Compilation ................................... 65
13.1 Compiling Functions ......................... 65
13.2 Declaration ................................. 66
13.3 Storing Compiled Objects .................... 67
13.4 Difference from the Interpreter ............. 67
13.5 Providing Space for Compiled Codes .......... 67
14. Errors and Debugging .......................... 68
14.1 The Error System ............................ 68
14.2 Attention Handling .......................... 71
14.3 The Debugger ................................ 71
14.4 The Low-Level Debugger ...................... 72
15. Memory Management System ...................... 73
16. Structure Editor - USE ........................ 75
16.1 Invoking USE ................................ 75
16.2 USE Session ................................. 76
16.3 Scope and Position Numbers .................. 77
16.4 Pattern Matching Rules ...................... 77
16.5 Printing Current Scope ...................... 78
16.6 Changing the Scope .......................... 78
16.7 Searching ................................... 79
Contents - 2
Contents Sep. 8, 1981
16.8 Inserting and Deleting Parentheses .......... 79
16.9 Inserting and Deleting S-expressions ........ 80
16.10 Replacing S-expressions .................... 81
17. Calling External Programs ..................... 82
17.1 Calling TSS Commands ........................ 82
17.2 Calling User-Defined Programs ............... 82
17.3 Manipulating Command Symbols ................ 83
18. Miscellaneous ................................. 84
Contents - 3
May 18, 1981 1. Introduction
1. Introduction
1.1 General Information
The UTILISP (University of Tokyo Interactive LISt Processor)
system is designed for highly interactive programming and
debugging of sophisticated programs.
This document is intended to serve both as a User's Guide and
as a Reference Manual for the language and the system. It is
hoped that those who are familiar with the Lisp language can
acquire a complete knowledge of the system from this manual.
This is a preliminary version. Several sections are missing
and these will be supplied in the near future. Please consult
the author for information concerning these missing sections.
The author's address is as follows:
Takashi Chikayama
ICOT Institute for New Generation Computer Technology
Mita Kokusai Bldg. 21F
4-28 Mita 1-Chome
Minato-ku, Tokyo 108, Japan
Telephone: 03-456-3195
1.2 How to Run and Stop the System
(Note: This section may be altered.)
At present, the system is in operation at the Computer Centre,
University of Michigan, and is organized as a MTS program.
The standard command sequence for running the system is
currently as follows:
#Run *UTILISP
> (Lisp input)
Several optional parameters exist for the command LISP, i.e.:
STACK: STACK=n specifies that the size of the stack area is to
be n pages (1page = 4KB). The default value for n is
16.
FIX: FIX=n specifies that the size of the "fixed heap" area
(for compiled codes) is to be n pages. The default value
for n is 8.
SIZE: SIZE=n specifies that n pages are to be allocated for
use by UTILISP. It will not get more space if this is
not enough. The default value for n is 64.
81-09-07 - 1 - Utilisp Manual
1. Introduction May 18, 1981
If the logical I/O unit 0 has been assigned, the file
associated with it is executed first. This execution is
identical with that of the standard top-level Lisp loop,
except that the results are not displayed.
After the execution of the unit 0 file (if any), the system
enters the top-level loop. Each S-expression read in is
evaluated and the result is displayed. Note that the top-
level evaluator is EVAL, not EVALQUOTE.
The session can be terminated by calling the function QUIT.
If one wishes to terminate the session abnormally, the
function ABEND can be used.
There are cases in which these system functions are not
recognized by the Lisp reader, e.g., when the READTABLE or
OBVECTOR has been destroyed. In such cases, the Utilisp
session can be terminated by ten consecutive exclamation marks
(!!!!!!!!!!) at the beginning of an input line from the
terminal.
In case an endless or unexpectedly long computation should
occur, an attention interrupt from the terminal (usually by
means of the break key) will stop the current computation and
the system enters the BREAK loop. For details, see Chapter 14
(Errors and Debugging).
1.3 Notational Conventions and Notes on Syntax
There are several conventions concerning notation, which
should be understood before reading the manual in order to
avoid confusion.
In this manual, Lisp symbols are printed in upper-case
characters. Lower-case words appearing in S-expressions
represent certain Lisp objects the details of which are
irrelevant or explained elsewhere. They appear between the
symbols "<" and ">", e.g., .
In what follows, a Lisp object whose "car" is and "cdr" is
may sometimes be written in the form (a . b). However,
note that and, especially, are not necessarily atoms.
Thus, a list beginning with the symbol PROGN may be written in
the form (PROGN . body), where is a list following
PROGN. Similarly, in titles of descriptions of functions,
"PLUS . args", for example, indicates a list of
arguments following the function PLUS.
Lisp symbols appearing as titles are followed by a term
indicating its category within curly brackets, "»" and "º",
(if it is not an ordinary function) and a description of its
arguments (if it is not a variable). Specifically, the
categories are "Special Form", "Macro", and "Variable". The
following examples illustrate the manner in which the
arguments are described:
Utilisp Manual - 2 - 81-09-07
May 18, 1981 1. Introduction
QUOTE »Special Formº arg
QUOTE is a "special form" and takes one argument.
CONS x y
CONS is an ordinary function and requires two arguments,
and , and their absence generates an error.
GENSYM (prefix) (begin)
GENSYM may take zero to two arguments; and
are optional.
PLUS . args
PLUS may take arbitrarily many (possibly zero) arguments.
- arg . args
- may take arbitrarily many (but at last one) arguments.
As in the examples, argument names appear between "<" and ">"
in the description of the function.
The symbol "=>" will be used to indicate evaluation in
examples, e.g., "FOO => NIL" means that "the result of
evaluating FOO is NIL".
There are several terms which are widely used in this manual
but will not be rigorously defined. They are: "S-
expression", which means a Lisp object, especially in its
printed representation; "dotted pair", which means a "cons";
and "atom", which means a Lisp object other than a "cons".
Note that an atom does not necessarily mean a symbolic atom;
it may be a number, string, etc. It is recommended that those
who are not familiar with these terms consult an appropriate
Lisp textbook.
Several characters have special meanings in UTILISP, i.e.,
single quote('), double quote("), backquote(`), comma(,),
semicolon(;), and slant(/).
Semicolons are used for comments. When the Lisp reader
encounters a semicolon, it ignores all the characters
remaining on the current line and resumes reading from the
beginning of the next line. In such a case, a blank space is
automatically introduced between the last symbol preceding the
semicolon and the first symbol on the next line. However, a
semicolon can occur as an element of a string (see remarks on
double quotes below).
A single quote "'" has the same effect as the special form
QUOTE (see below). For example, 'FOO is read as (QUOTE FOO),
and '(CONS 'FOO 'BAR) is read as (QUOTE (CONS (QUOTE FOO)
(QUOTE BAR))), etc.
Slants are used for quoting characters possessing special
functions so that they are merely interpreted as normal
alphabetic characters. For example, /'FOO is read as a symbol
whose print name is "'FOO" and not as (QUOTE FOO). Thus, one
must type "//" to convey the symbol "/" to the Lisp reader.
81-09-07 - 3 - Utilisp Manual
1. Introduction May 18, 1981
Double quotes are used for indicating strings. Any characters
occurring between a double quote and the next double quote are
read as a string. Double quotes occurring inside strings
should be typed twice. For example, """" represents a string
consisting of one double quote. A string may extend beyond
the ends of a line.
Concerning backquotes and commas, see Chapter 10 (Macros).
1.4 Data Types
There are nine data types in this system, i.e., symbol, cons,
fixnum, flonum, string, vector, reference, stream, and code
piece.
A symbol has a "print name", a "value" (sometimes called a
"binding"), a definition, and a property list. The "print
name" is a string which is the value of the function PNAME
when applied to the symbol in question; this string serves as
the printed representation of the symbol. The "value" may be
any Lisp object, and is interpreted as the value of the symbol
when the latter is used as a variable. The symbol may also be
in "unbound" state, in which case, it has no value at all.
Access to the value of a symbol is effected by evaluating the
symbol, and the value may be updated by using the function
SET. The definition is functional attributes of the symbol;
access is effected by GETD and updating by PUTD. The property
list contains an even number of elements (possibly zero);
direct access and updating can be effected by PLIST and
SETPLIST, respectively, but it is usually more convenient to
use the functions GET (for access), PUTPROP (for adding and
updating properties), and REMPROP (for removing properties).
SYMBOL is the basic function for creating a new symbol with a
certain print name. All symbols which are normally read in
are registered in a table called "obvector", and any of these
which bear the same name are identified by means of the
function INTERN (for details, see Chapter 11, "Input and
Output"). The function GENSYM serves to generate a sequence
of distinct symbols.
A "cons" is a Lisp object possessing two components, "car" and
"cdr", which can be any Lisp objects. Access to these two
components is effected by the functions CAR and CDR,
respectively, and updating by RPLACA and RPLACD, respectively.
A "cons" may be constructed by means of the function CONS.
There are two kinds of numerical objects in this system, upon
which arithmetical operations may be performed; one is called
"fixnum" which possesses 24-bit signed integer value; the
other is called "flonum" which possesses 64-bit floating point
value with the accuracy of about 15 decimal digits.
A string is a finite sequence of characters. Each character
has an 8-bit code value which is usually interpreted interms
of the EBCDIK code. Independent access to and updating of
these characters can be effected by means of the functions
SREF and SSET, respectively. The length of a string can be
Utilisp Manual - 4 - 81-09-07
May 18, 1981 1. Introduction
obtained by applying the function STRING-LENGTH.
A vector is a finite ordered set of Lisp objects. Vectors can
be created by means of the function VECTOR. The elements of
such a vector may be any Lisp objects; access is effected by
means of the function VREF and updating by the function VSET.
The length of a vector can be obtained by using the function
VECTOR-LENGTH.
A reference is a pointer indicating an element of a vector.
It is often useful to have access to and update elements of
vectors. A reference can be created by the function
REFERENCE; access to and updating of the corresponding element
can be effected by means of the functions DEREF and SETREF,
respectively.
A stream is an object related to I/O. All the I/O operations
in this system are carried out by means of such intermediary
streams, which are created by the function STREAM.
A code piece is a segment of machine code which constitutes
the body of a predefined or a compiled function. Code pieces
have names, normally a symbol, access to which can be effected
by means of the function FUNCNAME.
1.5 Lambda Lists
A lambda-expression is the format specifying an interpreted
function in Lisp, and is of the form
(LAMBDA lambda-list . body)
where is a list of forms. Usually, is a
list of symbols which corresponds to the so-called formal
parameter list in certain other programming languages. When a
lambda-expression is applied to given values of the arguments
(actual parameters), the symbols are bound to these values,
and the forms constituting are evaluated sequentially
and the result of the last of these evaluations is returned as
the final result of the application. The formal parameters
are then unbound and revert the state they were in prior to
the application. If the number of actual arguments is not
equal to the length of , an error is generated.
In UTILISP, an element of can be either a symbol
or a list of the form
(symbol . defaults)
When the number of actual arguments to which the function is
applied is less than the length of , the given
actual arguments are first bound to the corresponding symbols.
The remaining elements of must have the form
(symbol . defaults). Here, is a list of forms
which are evaluated sequentially and the result of the last
one (or NIL in the case when is empty) is bound to
. If an actual argument corresponding to a symbol
associated with a list is supplied, then the symbol
is bound to this actual argument and the associated list
is merely ignored.
81-09-07 - 5 - Utilisp Manual
1. Introduction May 18, 1981
Default values are evaluated after the binding of the
preceding arguments, hence, they may depend upon the results
of the preceding bindings.
Some examples of lambda-lists are as follows:
(A B C) :
A, B, and C are all required.
(A B (C)) :
A and B are required but C is optional; the default value
of C is NIL.
(A B (C 0)) :
A and B are required but C is optional; the default value
of C is 0.
(A B (C (PRINT "Default value is used for C.") 0)) :
A and B are required and C is optional; when the default
value is used, the indicated message is printed.
(A B (C (CONS A B))) :
A and B are required and C is optional; the default value
of C depends upon A and B.
Utilisp Manual - 6 - 81-09-07
May 17, 1981 2. Predicates
2. Predicates
A predicate is a function which tests the validity of some
condition involving its arguments and returns the symbol T if
the condition holds, and the symbol NIL otherwise.
When a Lisp object is used as a logical value, it is
interpreted as "false" if and only if it is NIL; all Lisp
objects other than NIL are interpreted as "true".
2.1 Predicates on Data Types
The following predicates are for testing data types. These
predicates return T if the argument is of the type indicated
by the name of the function, NIL if it is of some other type.
SYMBOLP arg
Returns T if is a symbol, otherwise NIL.
CONSP arg
Returns T if is a "cons", otherwise NIL.
LISTP arg
LISTP is an alias of CONSP. This is incorporated mainly
for compatibility with other Lisp systems.
ATOM arg
Returns T if is not a "cons", otherwise NIL.
FIXP arg
Returns T if is a "fixnum" object, i.e., an integer
number, otherwise NIL.
FLOATP arg
Returns T if is a "flonum" object, i.e., a
floating-point number, otherwise NIL.
NUMBERP arg
Returns T if is a numerical object, i.e., either a
"fixnum" or a "flonum", otherwise NIL.
STRINGP arg
Returns T if is a string, otherwise NIL.
VECTORP arg
Returns T if is a vector, otherwise NIL.
REFERENCEP arg
Returns T if is a reference pointer, otherwise NIL.
STREAMP arg
Returns T if is a stream, otherwise NIL.
81-09-07 - 7 - Utilisp Manual
2. Predicates May 17, 1981
CODEP arg
Returns T if is a code piece, otherwise NIL.
2.2 General Purpose Predicates
The following functions are some other general purpose
predicates.
EQ x y
Returns T if and denote the same Lisp object,
otherwise NIL. Lisp objects which have the same printed
representation are not necessarily identical. However,
the "interning" process ensures that two symbols with the
same print name are identical (see Chapter 11, for
details). Unlike some other Lisp systems, equality of
values of integer numbers ("fixnums") can also be
compared using EQ.
Note: In this manual, the expression "two Lisp objects
are EQ" means that they are the same object.
NEQ x y
(NEQ x y) = (NOT (EQ x y)). This function is
incorporated primarily for convenience in typing.
EQUAL x y
EQUAL returns T if and are "similar" Lisp
objects, otherwise NIL. That is, two strings are EQUAL
if they have the same length and all the characters in
corresponding positions are the same, two "flonums" are
EQUAL if they have the same floating-point value, and,
inductively, two "cons" cells are EQUAL if their
respective "cars" and "cdrs" are EQUAL. In all other
cases, two objects are EQUAL if and only if they are EQ.
If two Lisp objects are EQUAL, they have the same printed
representation, however, the reverse does not necessarily
hold (e.g., for symbols which have not been "interned").
NOT x
NULL x
NOT returns the symbol T if is EQ to NIL, and the
symbol NIL otherwise. NULL is the same as NOT; both
functions are incorporated for the sake of readability.
It is recommended that NULL be used for checking whether
a given value is NIL, and that NOT be used for inverting
a logical value.
The system also includes various predicates in addition to
those introduced in this chapter. These will be described in
the chapters on the various data types accepted by these
predicates; for example, the predicate ZEROP is described in
Chapter 7, "Numbers".
Utilisp Manual - 8 - 81-09-07
May 18, 1981 3. Evaluation
3. Evaluation
3.1 The Evaluator
The process of evaluation of a Lisp form is as follows:
If the form is neither a symbol nor a "cons", i.e., if it is a
"fixnum", "flonum", a string, a code piece, a vector, a
reference or a stream, then the result of its evaluation is
simply the form itself.
If the form is a symbol, then the result is the value to which
that symbol is bound. If the symbol is unbound, an error is
generated.
A so-called "special form" (i.e., a "cons" identified by a
distinguished symbol in its "car") is evaluated in a manner
which depends upon the particular form in question. All of
these special forms will be individually described in this
manual.
If the form in question is not a so-called "special form",
then it requires the application of a function or a macro to
its arguments. The "car" of the form is a lambda-expression
or the name of a function. If the function is not a "macro",
the "cdr" of the form is a list of forms which are evaluated
sequentially, from left to right, and the resulting arguments
are then supplied to the function; the value finally returned
is the result of applying the function to these arguments.
The evaluation process for macro forms is described in Chapter
10, "Macros".
A more detailed and accurate description of the evaluator will
be supplied after various improvements of present
implementation have been carried out.
3.2 Various Functions Concerned with Evaluation
EVAL x
Evaluates , and returns the result. Ordinarily, EVAL
is not often used explicitly, since evaluation is usually
carried out implicitly. EVAL is primarily useful in
programs concerning Lisp itself, rather than in its
applications.
APPLY fn arglist
Applies the function to the set of arguments given
by , and returns the resulting value.
FUNCALL fn . args
Applies the function to the set of arguments ,
and returns the resulting value. Note that the
functional argument is evaluated in the usual way,
81-09-07 - 9 - Utilisp Manual
3. Evaluation May 18, 1981
while function which constitutes the "car" of an ordinary
Lisp application is not.
Example:
(SETQ CONS 'PLUS) => PLUS
(FUNCALL CONS 1 2) => 3
(CONS 1 2) => (1 . 2)
Thus, explicit application using FUNCALL, instead of
simple implicit function application, should be used for
functional arguments, since, the binding of the function
is not examined by the evaluator in simple implicit
function applications, whereas when FUNCALL is used, the
functional argument symbol is evaluated first, yielding a
function which is then applied in the ordinary manner.
QUOTE »Special Formº arg
Simply returns the argument . Its usefulness
largely consists in the fact that its argument is not
evaluated by the evaluator.
Examples:
(QUOTE X) => X
(SETQ X (QUOTE (CONS 1 2))) X => (CONS 1 2)
Since QUOTE is very frequently used, the Lisp Reader
allows the user to reduce the burden of keying in the
program by converting S-expressions preceded by a single
quote character "'" into QUOTEd forms. For example,
(SETQ X '(CONS 1 2))
is converted into
(SETQ X (QUOTE (CONS 1 2)))
FUNCTION »Special Formº fn
The form (FUNCTION x) has precisely the same effect as
(QUOTE x); these alternative forms are available for the
sake of clarity in reading and writing programs. It is
recommended that FUNCTION be used to quote a piece of a
program, and that QUOTE be used for segments of data.
The compiler utilizes this information to generate
efficient object codes.
Note: Function-valued arguments in Lisp functions should
be evoked using FUNCALL. See the description of FUNCALL
(above) for details.
COMMENT »Special Formº . args
COMMENT ignores its arguments and always returns NIL; it
is useful for inserting explanatory remarks.
PROGN »Special Formº . args
The arguments are evaluated sequentially, from
left to right, and the value of the final argument is
returned. This operation is useful in cases where it is
necessary to evaluate a number of forms for the sake of
the concomitant side effects but only the value of the
last form is required. Note that LAMBDA-expressions,
COND forms, and many other control structure forms
Utilisp Manual - 10 - 81-09-07
May 18, 1981 3. Evaluation
incorporate this property of PROGN implicitly (in the
sense that multiple forms are handled in a similar
manner).
PROG1 »Special Formº . args
PROG1 functions in the same manner as PROGN, except that
it returns the value of the first argument rather than
the last. PROG1 is most commonly used to evaluate a
number of expressions, with possible occurrence of the
side effects, and return a value which must be computed
before the side effects occur.
Example:
(SETQ X (PROG1 Y (SETQ Y X)))
This form interchanges the values of the variables X and
Y.
PROG2 »Special Formº . args
The action of PROG2 is the same as that of PROGN and
PROG1, except that it returns the value of its second
argument. It is incorporated mainly for compatibility
with other Lisp systems.
(PROG2 x y . z) is equivalent to (PROGN x (PROG1 y .
z)).
LET »Macroº bindings . body
A LET form has the syntax
(LET ((var1 vform1)
(var2 vform2)
...)
bform1
bform2
...)
which is automatically converted into and effectively
equivalent to the following form:
((LAMBDA (var1 var2 ...)
bform1
bform2
...)
vform1
vform2
...)
It is often preferable to use LET rather than to directly
use LAMBDA, since the variables and the corresponding
forms appear textually close to one another, which
increases the readability of the program.
As LET forms are converted into LAMBDA application forms,
all the values of the 's are computed before
binding any of these values to to the corresponding
's. For example, cannot depend upon
, that is, if appears in , then a
variable named must have been bound somewhere
outside this LET form.
81-09-07 - 11 - Utilisp Manual
3. Evaluation May 18, 1981
LETS »Macroº bindings . body
LETS is similar to LET except that LETS binds its
variables sequentially, one by one, while LET, as
mentioned above, binds them at once. (LETS is a
contraction of "LET Sequentially").
A LETS form has the syntax
(LETS ((var1 . vforms1)
(var2 . vforms2)
...)
bform1
bform2
...)
which is effectively equivalent to:
((LAMBDA ((var1 . vforms1)
(var2 . vforms2)
...)
bform1
bform2
...))
each list constitutes the default value list
for the corresponding , and therefore can depend
upon the preceding 's (see Section 1.5, "Lambda
Lists", for details).
Note: The interpretation of LETS is faster than that of
LET. However, once compiled, their speeds become
identical.
Utilisp Manual - 12 - 81-09-07
Jul. 3, 1981 4. Flow of Control
4. Flow of Control
The present system provides a variety of structures for the
flow of control.
Function application is the basic method for constructing
programs. Moreover, the definition of a function may always
call the function being defined. This process is known as
"recursion".
Both explicit and implicit PROGN structures can be used for
sequential execution of programs. The forms in a PROGN
structure are evaluated sequentially from left to right.
In this chapter, we shall describe some even more flexible
control structures. Conditional constructs are useful for
making decisions, while iteration and mapping constructs may
be convenient for repetition. There are also more flexible
control structures known as non-local exits.
4.1 Conditionals
A conditional construct incorporates a decision in a program,
resulting in the execution of one of several alternatives in
accordance with certain logical conditions.
AND »Special Formº . args
Evaluates the arguments sequentially, from left to right.
If the value of any argument is NIL, then NIL is returned
and the remaining arguments are not evaluated. If the
value of all the arguments are non-NIL, then the value of
the last argument is returned. AND can be interpreted
for logical operation, where NIL stands for "false" and
non-NIL for "true".
Examples:
(AND X Y)
(AND (SETQ TEMP (ASSQ X Y))
(RPLACD TEMP Z))
(AND ERROR-EXISTS (PRINC "There is an error!"))
Note: (AND) => T
OR »Special Formº . args
Evaluates the arguments sequentially, from left to right.
If the value of any argument is NIL, the next argument is
evaluated. If there are no remaining arguments, then NIL
is returned. However, if the value of any argument is
non-NIL, then that value is immediately returned and the
remaining arguments, if any, are not evaluated. OR can
be interpreted as a logical operation, where NIL stands
for "false" and non-NIL for "true".
Note: (OR) => NIL
81-09-07 - 13 - Utilisp Manual
4. Flow of Control Jul. 3, 1981
COND »Special Formº . clauses
The arguments of COND are usually referred to as
"clauses". Each clause consists of a predicate followed
by a number (possibly zero) of forms. The predicate is
called the "antecedent" and the forms are called the
"consequents".
Thus, a COND-form might have the following syntax:
(COND (antecedent consequent consequent ...)
(antecedent)
(antecedent consequent ...)
...)
Each clause represents an alternative which is selected
if its antecedent is satisfied and the antecedents of all
preceding clauses were not satisfied when evaluated.
The clauses are processed sequentially from left to
right. First, the antecedent of the current clause is
evaluated. If the result is NIL, the process advances to
the next clause. Otherwise, the consequents are
evaluated sequentially from left to right (in a PROGN
manner), the value of the last consequent is returned,
and the remaining clauses (if any) are not processed. If
there were no consequents in the selected clause, then
the value of the antecedent is returned. If the clauses
are exhausted, that is, the value of every antecedent is
NIL, then the value of the COND form is NIL.
SELECTQ »Special Formº key-form . clauses
Many programs require multiplex branchings which depend
on the value of some form. A typical example is as
follows:
(COND ((EQ X 'FOO) ...)
((EQ X 'BAR) ...)
((MEMQ X '(BAZ QUUX MUM)) ...)
(T ...))
SELECTQ is incorporated for convenience in such
situations. A SELECTQ form has the following syntax:
(SELECTQ key-form
(pattern consequent consequent ...)
(pattern consequent consequent ...)
(pattern consequent consequent ...)
...)
The first argument is evaluated first (just
once). The resulting value is called the "key". The key
form is followed by a number of "clauses", each of which
consists of a "pattern" followed by a number (possibly
zero) of "consequent" forms. The pattern of each clause
is compared with the key, and if it "matches", the
consequents of this clause are evaluated, and SELECTQ
returns the value of the last consequent. If there are
no "matches", or if there is no consequent in the
Utilisp Manual - 14 - 81-09-07
Jul. 3, 1981 4. Flow of Control
selected clause, then NIL is returned. Note that the
patterns are not evaluated.
The objects which may be used as the patterns and their
"matching" conditions are as follows:
1) Any atom (symbol, number, etc.), except the symbol T
In this case, the key matches if it is EQ to the
atom.
2) A list
In this case, the key matches if it is EQ to one of
the top-level elements of the list.
3) The symbol T
The symbol T constitutes a special pattern which
matches anything.
Example: The preceding example can be expressed as
follows:
(SELECTQ X
(FOO ...)
(BAR ...)
((BAZ QUUX MUM) ...)
(T ...))
Note: The symbol T itself may be used as the first
component of a clause, in a non-trivial manner, by
selecting (T) as the pattern.
4.2 Iteration
PROG »Special Formº locals . body
PROG is a special form which provides temporary
variables, sequential evaluation of forms, and "goto"
operations. A typical PROG form might have, for example,
the following structure:
(PROG (var1 (var2 . inits2) var3 (var4 . inits4))
tag1 statement1
statement2
tag2 statement3
...)
, , ... are temporarily bound variables.
The binding of these variables prior to the execution of
the PROG are recorded, and when the execution of the PROG
has been completed, the original bindings are restored.
If a variable is associated with an initial value list
, then the elements of the list are evaluated
sequentially, from left to right, and the value of the
last one becomes the initial value of the variable. If
there are no initial value forms, then the variable is
initialized to NIL.
Example:
(PROG ((A T)
B
(C (PRINT "C is bound") (CAR '(FOO . BAR))))
81-09-07 - 15 - Utilisp Manual
4. Flow of Control Jul. 3, 1981
. body)
Here, the initial value of A is T, that of B is NIL, and
that of C is the symbol FOO. Before the binding of C is
executed, the indicated message is printed. The bindings
are processed sequentially, and the value of each form
may depend upon previous bindings.
The portion of a PROG which follows the variable list is
called the "body". The elements of may be atoms,
which are called "tags", or "cons" cells, which are
called "statements."
After the temporary variables have been bound, the forms
in the body are processed sequentially. Tags are not
evaluated, whereas statements are evaluated and their
values discarded. If process reaches the end of the
body, then NIL is returned. However, two special devices
(described below) may be used to alter the flow of
control in the body of a PROG.
If (RETURN x1 ... xn) is evaluated, then processing of
the body is terminated and the value of the last argument
is returned as the value of the PROG. If n=0, i.e.,
if no arguments are present, then the value returned will
be NIL. Only those RETURN statements which are
explicitly included in the body of a PROG form can
legitimately used in this manner (for example, a RETURN
statement occurring within the definition of a function
called during the execution of a PROG will generate an
error when the program is compiled.)
If (GO tag) is evaluated, then the evaluation process is
resumed from the statement labelled with (in case
there is no statement associated with , i.e., when
is at the end of a PROG body, the PROG routine is
simply terminated); is not evaluated. If the label
does not occur in the body of the PROG form
currently being executed, the body of the innermost PROG
form properly including the current one is searched, and
so forth; if is found, then the execution sequence
leaves the current PROG form and the program execution is
resumed from the point labelled with . If the label
does not occur in any PROG form which contains (GO
tag), then an error is generated. Any statement of the
form (GO tag) must be explicitly included in the PROG
form containing the destination indicated by .
GO »Special Formº tag
See the explanation under the entry for PROG above.
Note: can be an atom of any type including
symbolic atoms or "fixnums". Since the process of
searching is effected using the equality criterion EQ,
"flonums", strings, vectors, etc. are generally not
appropriate as labels.
Utilisp Manual - 16 - 81-09-07
Jul. 3, 1981 4. Flow of Control
RETURN . args
See the explanation under the entry for "PROG" above.
LOOP »Special Formº . body
LOOP is a special form used for simple iteration. The
arguments of LOOP are evaluated sequentially from left to
right. As long as EXIT is not evoked during these
evaluations, this process is interminably repeated.
However, if an EXIT form is encountered, the inner-most
LOOP containing it is terminated and the value of the
last argument of this EXIT is returned as the value of
that LOOP form.
Example: The top-level loop of the system, although
actually defined in terms of machine language, could have
been defined as follows:
(LOOP (PRINT (EVAL (READ))))
EXIT . args
See the explanation under the entry for LOOP above. EXIT
being an ordinary function, its arguments are evaluated
sequentially, from left to right, in the usual manner.
When a LOOP form is to be compiled, the corresponding
EXIT forms must be explicitly contained in the LOOP.
DO »Macroº index-part exit-part . body
DO is a control form which facilitates iteration using
so-called "index variables." The first argument is a list, the elements of which have the form
(var init next)
where is a symbol employed as an index variable,
is the initial value assigned to , and
is a form which is computed after each iteration,
whereupon the resulting value is assigned to .
The initial values are computed sequentially, and only
after this process is completed are they bound to the
corresponding variables; the same applies to subsequent
assignments arising from the forms.
The second argument has the syntax as
(end-test . exit-forms)
After initially binding the index variables, and after
each round of value assignments, the form is evaluated. If the result is non-NIL, the
termination process begins; the forms constituting the
list are evaluated sequentially, from left
to right, and the value of the last one (or NIL, if the
list is empty) will be returned as the value
of the DO form. The index variables are then unbound,
their original values are restored, and the evaluation of
the DO form terminates.
81-09-07 - 17 - Utilisp Manual
4. Flow of Control Jul. 3, 1981
Otherwise, if the evaluation of yields NIL,
execution of begins; is a list of forms,
which are evaluated sequentially, from left to right, and
the results are discarded. When is exhausted, the
evaluation process proceeds to the evaluation of the
forms.
Any form may be omitted from when no
assignment of the corresponding variable is required
after iteration; in this case, merely serves as an
ordinary local variable. Any initiation form may
also be omitted; in this case, NIL becomes the initial
value of the corresponding .
A DO form, being a macro, is automatically converted into
an equivalent combination of LET and LOOP. Thus, to
depart from a DO form, the function EXIT can be used in
its , , or the forms of its
. It should be borne in mind that, since the
forms are evaluated outside the LOOP, the use of
EXIT in an form will terminate the evaluation of a
still "larger" DO or LOOP form than the one under
consideration.
Examples: Printing all the elements of a list X
separated by a space can be performed by the following
program:
(DO ((L X (CDR L)))
((ATOM L))
(PRIN1 (CAR L))
(PRINC " "))
When each element of a vector V is a number, their sum
can be computed by the following program:
(DO ((I 0 (1+ I))
(L (VECTOR-LENGTH V))
(SUM 0 (PLUS SUM (VREF V I))))
((= I L) SUM))
Note that, in this example, the body of DO is empty.
This is, in fact, the case in many applications, since
the index and exit parts of a DO control form can, in
themselves, be quite powerful. Also note that, when
(VREF V I) is computed, the variable I still retains its
previous value, that is, the value (1+ I) has not
yet been assigned to it. L does not have a part,
and is merely a temporary variable which facilitates the
computation of .
4.3 Non-local Exits
CATCH tag . forms
CATCH is a function primarily utilized for non-local
exits. (CATCH tag . forms) evaluates the elements of
the list and returns the value of the last form,
unless an expression of the form (THROW tag . values)
with the same is encountered during the evaluation
of , in which case the arguments in are
Utilisp Manual - 18 - 81-09-07
Jul. 3, 1981 4. Flow of Control
evaluated, and CATCH immediately returns the last of the
(or NIL when is empty) and performs no
further evaluation.
Note: The argument is evaluated, which is not the
case in some other Lisp systems. However, no repeated
evaluation is applied to the elements of the list
, which are evaluated just once as the normal
arguments of a function. The special action of CATCH
occurs during the evaluation of its arguments, rather
than during the execution of CATCH itself; the function
CATCH, in itself, only returns its last argument (or NIL
when there is only one argument ) if the evaluation
of its arguments is completed without calling THROW.
Example:
(CATCH 'ATOMIC
(MAPCAR L
(FUNCTION (LAMBDA (X)
(COND ((ATOM X) (THROW 'ATOMIC X))
(T (CAR X)))))))
This program returns a list of the "car"'s of the
elements of the list L, if the latter are all non-atomic,
otherwise, the first atomic element of L is returned.
THROW tag . values
As described above, THROW is used in conjunction with
CATCH for (primarily non-local) exits. THROW conveys the
value of the last argument in (or NIL when
is empty) back to the closest preceding CATCH in
the execution sequence which possesses the same and
has not yet been evoked. Any CATCH forms (or other
control forms or functions) which may be nested between
the THROW form under consideration and the corresponding
CATCH are effectively ignored. See the above description
of CATCH for further details.
Note: As in the case of CATCH, both and forms in
are evaluated, unlike the corresponding function
THROW in some other Lisp systems.
Example: The following program returns A rather than B.
(CATCH 'A (CATCH 'B (THROW 'A 'A)) 'B)
4.4 Mapping
Mapping is a type of iteration in which a certain function is
successively applied to portions of a list or a vector given
as an argument. There are several options for the manner in
which the portions of the list or the vector are chosen and
the results returned by the application of the function are
presented.
81-09-07 - 19 - Utilisp Manual
4. Flow of Control Jul. 3, 1981
The table shows the relations between the six map functions on
list structures.
applies function to
| successive | successive |
| sublists | elements |
---------------+--------------+--------------+
its own | | |
first | MAP | MAPC |
argument | | |
---------------+--------------+--------------+
list of the | | |
returns function | MAPLIST | MAPCAR |
results | | |
---------------+--------------+--------------+
nconc of the | | |
function | MAPCON | MAPCAN |
results | | |
---------------+--------------+--------------+
MAP list fn
The function is applied to the successive sublists
of , i.e., first itself, then its "cdr",
then "cddr", etc. The value returned is its original
argument (possibly modified by )..
Example:
(MAP '(A B C) (FUNCTION PRIN1))
This program prints out "(A B C)(B C)(C)" and returns (A
B C).
MAPC list fn
The function is applied to the successive elements
of , i.e., first the "car" of , then its
"cadr", then "caddr", etc. The value returned is its
original argument (possibly modified by )..
Example:
(MAPC '(A B C) (FUNCTION PRIN1))
This program prints out "ABC" and returns (A B C).
MAPLIST list fn
The function is applied to the successive sublists
of , i.e., first itself, then its "cdr",
then "cddr", etc. The value returned is a newly created
list of the results of these applications.
Example:
(MAPC '(A B C) (FUNCTION PRIN1))
This program prints out "(A B C)(B C)(C)" and returns ((A
B C) (B C) (C)).
MAPCAR list fn
The function is applied to the successive elements
of , i.e., first "car" of , then its "cadr",
then "caddr", etc. The value returned is a newly created
list of the results of these applications.
Utilisp Manual - 20 - 81-09-07
Jul. 3, 1981 4. Flow of Control
Example:
(MAPCAR '(A B C) (FUNCTION PRIN1))
This program prints out "ABC" and returns (A B C), which
appears the same as the original arguments, but,
actually, has newly been created.
MAPCON list fn
The function is applied to the successive sublists
of , i.e., first itself, then its "cdr",
then "cddr", etc. The value returned is the results of
these applications concatenated together.
Example:
(MAPCON '(A B C) (FUNCTION NCONS))
This program returns (A B C B C C).
MAPCAN list fn
The function is applied to the successive elements
of , i.e., first "car" of , then its "cadr",
then "caddr", etc. The value returned is the results of
these applications concatenated together.
Example:
(MAPCAN '(A B C) (FUNCTION NCONS))
This program returns (A B C), which appears the same as
the original argument, but, actually, has newly been
created.
MAPV vector fn
MAPV successively applies to all the elements of
, in increasing order of indices. The arguments
presented to the function are "reference" objects
"pointing" to the elements of . See chapter 9,
"Vectors", for further information about "reference".
The value returned by MAPV is simply the original
argument (possibly modified by the execution of
the function ).
Example:
(MAPV (VECTOR 5)
(FUNCTION (LAMBDA (R)
(SETREF R (READ)))))
This will return a vector of five Lisp objects
consecutively read in.
MAPVECTOR vector fn
MAPVECTOR also applies to all the elements of
, in increasing order of indices, however, in
this case, the arguments presented to are the
elements themselves, rather than references "pointing" to
them (see the description of MAPV). MAPVECTOR returns a
new vector the components of which are the corresponding
results of these applications.
81-09-07 - 21 - Utilisp Manual
5. Manipulating List Structure Jul. 28, 1981
5. Manipulating List Structure
5.1 Cons manipulation
CAR x
CAR returns the "car" of . If is an atom, an
error is generated.
CDR x
CDR returns the "cdr" of . If is an atom, an
error is generated.
C...R x
All the compositions of CAR and CDR, upto a total of
four, are defined as, so-called, "built-in" functions.
The names of these functions begin with "C", followed by
a sequence of "A"'s and "D"'s corresponding to the
indicated composition of functions, and end with "R".
Example: (CDDAR x) is effectively the same as (CDR (CDR
(CAR x)))
CR x
CR returns itself, and is the function in the C...R
group for which the total number of "A"'s and "D"'s is
zero. This function is sometimes useful when dealing
with mapping functions. For example, (MAPCAR list
(FUNCTION CR)) may be used to obtain a top-level copy of
.
CONS x y
CONS is a primitive function which creates a new "cons"
cell, the "car" and "cdr" of which are and ,
respectively.
Examples:
(CONS 'A 'B) => (A . B)
(CONS 'A '(B C D)) => (A B C D)
NCONS x
(NCONS x) is effectively the same as (CONS x NIL).
XCONS y x
XCONS (an abbreviation of "eXchange CONS") differs from
CONS only in that the order of the arguments is reversed.
XCONS is useful when the "cdr" part of the result should
be evaluated before the "car" part.
Example:
(XCONS 'A 'B) => (B . A)
COPY x
COPY creates and returns a "copy" of . The atoms
constituting the copy are the same as those constituting
the original argument , but all the "cons" cells of
Utilisp Manual - 22 - 81-09-07
Jul. 28, 1981 5. Manipulating List Structure
the copy are newly created.
Note: List structures in which a non-atomic node is
indicated by more than one pointer are not copied
faithfully; such nodes will be duplicated in the "copy".
"Copying" a cyclic structure in this manner results in an
endless computation.
5.2 List Manipulation
The following section explains some of the basic functions
provided for manipulating lists. A list is defined
recursively as either the symbol NIL, which represents an
empty list, or a "cons" whose "cdr" is a list. However, it
should be noted that, although their arguments are denoted by
the word "list", the functions described below are applicable
whether or not the final atom is NIL.
LAST list
LAST returns the last top-level "cons" of . If
is an atom, an error is generated; if the top-
level structure of is cyclic, then an endless
computation occurs.
Example:
(LAST '(A (B C) D E)) => (E)
LENGTH list
LENGTH returns the length of . The length of a
list is the number of its top-level elements.
As in the case of LAST, if the top-level structure of
is cyclic, an endless computation occurs.
Example:
(LENGTH '(A (B C) D E)) => 4
(LENGTH NIL) => 0
FIRST x
==> (CAR x)
SECOND x
==> (CADR x)
THIRD x
==> (CADDR x)
FOURTH x
==> (CADDDR x)
FIFTH x
==> (CAR (CDDDDR x))
SIXTH x
==> (CADR (CDDDDR x))
81-09-07 - 23 - Utilisp Manual
5. Manipulating List Structure Jul. 28, 1981
SEVENTH x
==> (CADDR (CDDDDR x))
NTH n list
NTH returns the th top-level element of , where
(CAR list) is counted as the zeroth element. If is
negative or not less than the length of , an error
is generated. Note that (NTH 2 x) is actually (THIRD x)
rather than (SECOND x).
Example:
(NTH 2 '(A B C D E)) => C
NTHCDR n list
NTHCDR applies CDR to the second argument for times,
and returns the result; for =0, the result is simply
itself. If is negative or not less than the
length of , an error is generated.
Example:
(NTHCDR 2 '(A B C D E)) => (C D E)
LIST . args
LIST constructs and returns a list of its arguments,
ordered in the same manner as the arguments themselves.
Examples:
(LIST 1 2 (CAR '(3 5)) (+ 2 2)) => (1 2 3 4)
(LIST) => NIL
APPEND . lists
The result of APPEND is essentially a concatenation of
its arguments, however, avoiding physical alteration, the
arguments are copied (except for the last one; see also
the description of NCONC below). The tail of the
resulting list is physically identical with that of the
last argument.
Examples:
(APPEND '(A B C) '(D E) NIL '(F G H))
=> (A B C D E F G H)
(APPEND) => NIL
Note: When several lists are to be APPENDed, and the
order of the resulting list is not essential, the longest
argument should be entered last since it is not copied;
this reduces both computing time and required memory
space.
REVERSE list
REVERSE creates a new list, the top-level elements of
which are the same as those of but arranged in
reverse order. REVERSE, unlike NREVERSE (see below),
does not modify its argument.
Example:
(REVERSE '(A (B C) D)) => (D (B C) A)
Utilisp Manual - 24 - 81-09-07
Jul. 28, 1981 5. Manipulating List Structure
NCONC . lists
NCONC returns a list which is the concatenation of the
arguments. The arguments (except the last one) are
physically altered in the manner of RPLACD rather than
copied (see also the description of APPEND above.)
Example:
(SETQ X '(A B C))
(SETQ Y '(D E F))
(NCONC X Y) => (A B C D E F)
X => (A B C D E F)
Note that the value of X itself has been altered, since
the "cdr" of its last "cons" has been replaced by the
value of Y.
NREVERSE list
NREVERSE reverses its argument , which is altered
in the RPLACD manner throughout the list (see also the
description of REVERSE).
Example:
(SETQ X '(A B C))
(NREVERSE X) => (C B A)
X => (A)
Note that the value of X itself has been altered, since
the original list has been modified in RPLACD fashion.
PUSH »Special Formº item var
(PUSH item var) has the same effect and value as
(SETQ var (CONS item var))
but is more readable. must be a bound variable.
PUSH is useful, along with POP (see below), in
maintaining a list in the manner of a push-down stack.
POP »Special Formº var
(POP var) has the same effect and value as
(PROG1 (CAR var) (SETQ var (CDR var)))
but is more readable. must be a symbol which is
bound to a non-atomic value prior to the execution of
POP. POP is useful, along with PUSH (see above), in
maintaining a list in the manner of a push-down stack.
5.3 Alteration of List Structure
The functions RPLACA and RPLACD serve to alter existing list
structure; that is, to change the "cars" and "cdrs" of
existing "cons" cells.
Since structure is physically altered rather than copied,
caution should be exercised when using these functions, as
unexpected side-effects may occur if portions of the affected
list structures are common to several Lisp objects. The
functions NCONC and NREVERSE also alter list structure,
however, they are not normally used to obtain such side-
effects, rather, the concomitant list-structure modification
is effected purely for the sake of efficiency and
corresponding non-destructive functions are also available.
81-09-07 - 25 - Utilisp Manual
5. Manipulating List Structure Jul. 28, 1981
RPLACA x y
RPLACA replaces the "car" of by and returns
(modified) . must be a "cons", while may be
any Lisp object.
Example:
(SETQ X '(A B C))
(RPLACA X 'N) => (N B C)
X => (N B C)
RPLACD x y
RPLACD replaces the "cdr" of by and returns
(modified) . must be a "cons", while may be
any Lisp object.
Example:
(SETQ X '(A B C))
(RPLACD X 'C) => (A . C)
X => (A . C)
SUBST x y z
(SUBST x y z) substitutes for all occurrences of
in (using EQ for testing equality) and returns the
modified copy of . The original is not altered,
as SUBST recursively copies all the "cons" cells of ,
replacing by all elements which are EQ to .
Example:
(SUBST 'A 'B '(A B (C B)))
=> (A A (C A))
Note: List structures in which a non-atomic node is
designated by more than one pointer are not copied
faithfully; such nodes will be duplicated in the "copy".
Applying SUBST to a cyclic structure results in an
endless computation.
5.4 Tables
The system provides several functions which simplify the
maintenance of several varieties of tabular data structures
assembled from "cons" cells.
The simplest of these structures is just an ordinary list of
items, which represents an ordered set.
An association list is a list the element of which are "cons"
cells. The "car" of each such "cons" is called a "key" and
the "cdr" represents an associated datum.
Although these simple data structures are convenient for small
data bases, their form is such that search time increases
linearly with the size of the data base, and consequently they
are inefficient when handling large amounts of data. Large-
scale data bases are best maintained using vectors and hashing
functions (see the section 5.6 "Hashing" for details).
Utilisp Manual - 26 - 81-09-07
Jul. 28, 1981 5. Manipulating List Structure
MEMQ item list
(MEMQ item list) returns NIL if - is not identical
(with respect to the function EQ) with one of the
elements of
, otherwise, it returns the portion of
beginning with the first occurrence of - .
The procedure searches
on the top-level only.
Since MEMQ returns NIL if - is not found, and a non-
NIL object if it is found, MEMQ can be used as a
predicate.
Example:
(SETQ X '(A B C D E))
(MEMQ 'C X) => (C D E)
(MEMQ 'FOO X) => NIL
MEMBER item list
MEMBER functions in the same manner as MEMQ, except that
EQUAL, rather than EQ, is used for comparison.
MEM predicate item list
MEM functions in the same manner as MEMQ, except that it
takes an additional argument , the latter may
be any predicate taking two arguments. (MEM (FUNCTION
EQ) a b) is effectively identical with (MEMQ a b) and
(MEM (FUNCTION EQUAL) a b) with (MEMBER a b).
Example:
(MEM (FUNCTION (LAMBDA (X Y) (0= (+ X Y))))
13
'(1 3 -4 -13 7 -6))
=> (-13 7 -6)
DELQ item list (n)
When the optional argument is absent, DELQ returns
with all top-level occurrences of - deleted;
EQ is used for comparison. The argument
is
actually altered in the RPLACD manner when occurrences of
- are excised, except that any initial segment of
all the elements of which are EQ to - is not
altered in this manner (see Example below). If is
present, it must be a "fixnum" and only the first
top-level occurrences of
- are deleted. may be
zero, in which case,
itself is returned without
any alteration.
Example:
(SETQ X '(A B A B))
(DELQ X 'B) => (A A)
X => (A A)
Note: DELQ should be used for value, not for effect.
Thus, the two pairs of operations
(SETQ Y '(A B A B))
(SETQ Y (DELQ 'A Y))
and
(SETQ Y '(A B A B))
(DELQ 'A Y)
81-09-07 - 27 - Utilisp Manual
5. Manipulating List Structure Jul. 28, 1981
result in different values of Y. The value returned by
DELQ is (B B) in both cases. However, Y is given the
value (B B) in the former case and (A B B) in the latter.
REMQ item list (n)
REMQ yields the same result as DELQ, except that
itself is not altered; what is returned is a copy of the
original argument with the first top-level
top-level occurrences of - removed, where is the
minimum of and the number of top-level occurrences of
- in
.
EVERY list predicate
EVERY applies , a predicate function of one
argument, to the top-level elements of
sequentially, from left to right. If returns
non-NIL for every element, then EVERY returns T. If any
of these applications yields NIL, then EVERY returns NIL
immediately, and no further applications are executed.
SOME list predicate
SOME applies , a predicate function of one
argument, to the top-level elements of
sequentially, from left to right. If returns
non-NIL for some element, then SOME immediately returns
the portion of beginning with the element which
yielded non-NIL, and no further applications are
executed. If all the applications yield NIL, then SOME
returns NIL.
ASSQ item alist
ASSQ searches for and returns the first element in the
association list the "car" of which is EQ to
- , if such an element exists, otherwise, the value
NIL is returned. The association list may be updated by
applying RPLACD to the result of ASSQ, if the latter is
not NIL.
Example:
(ASSQ 'C '((A B) (C D) (E F)))
=> (C D)
ASSOC item alist
ASSOC functions in the same manner as ASSQ, except that
EQUAL instead of EQ is used for comparison.
ASS predicate item alist
ASS functions in the same manner as ASSQ, except that it
takes an additional argument , a predicate
taking two arguments, which is used for comparison. In
the special case where is EQ, this function
effectively reduces to ASSQ.
Utilisp Manual - 28 - 81-09-07
Jul. 28, 1981 5. Manipulating List Structure
5.5 Sorting
SORT table predicate
The list
is arranged in increasing order, using
the ordering relation corresponding to , and
the resulting ordered list is returned.
should be a function of two arguments, which returns non-
NIL if and only if the first argument is strictly less
than the second in the sense of total ordering relation.
5.6 Hashing
Some hashing scheme is desirable in order to reduce the
computing time required for data retrieval in large-scale data
bases. The search time required for an item remains constant
using hashing, as long as the hash table is large enough,
compared with the number of its entries.
The present system provides a standard hashing function for
Lisp objects to facilitate the maintainance of hashed data
bases.
HASH x
HASH computes hash value for and returns it as an
integer number "fixnum". The result may be positive,
negative, or zero. Its properties guaranteed are:
1) Objects which are EQUAL are hashed to the equal
value.
2) A "fixnum" is hashed to itself.
3) A string is hashed to non-negative value.
4) A symbol is hashed to the same value as its print-
name.
81-09-07 - 29 - Utilisp Manual
6. Symbols Aug. 3, 1981
6. Symbols
Symbolic atoms such as X or CONS are called "symbols" in this
system. A symbol is associated with four Lisp objects; the
"binding" is the value of the symbol when it is used as a
variable; the "definition" is the functional definition of the
symbol when it is used as the name of a function or a macro;
the "property list" is used to retain various Lisp objects
associated with the symbol; the "print name" is used for input
and output operations.
6.1 The Value
A symbol can be associated with its "value", which may be a
Lisp object of any type, and is returned as the result of
evaluating the symbol. The symbol may be in "unbound" state,
in which case the symbol has no value at all; when an
"unbound" symbol is evaluated, an error is generated. Newly
created symbols (by INTERN, GENSYM, etc.) are initially in the
"unbound" state. A symbol is called a "variable" when the
primary concern is its value.
The value of a variable can be changed either by "lambda-
binding" or by "assignment"; when a symbol is "lambda-bound",
its previous value is saved and will be restored later,
whereas "assignment" discards the previous value. "Lambda-
binding" is sometimes called simply "binding" in this manual.
The symbols NIL and T are always bound to themselves; they may
not be assigned nor lambda-bound (The error of changing the
value of T or NIL is not detected!)
SET variable new-value
"Assignment" to can be effected by the
function SET. The value of is changed to
which may be any Lisp object. The previous
value of , if any, is discarded. SET returns
the newly assigned value .
SETQ »Special Formº . args
(SETQ x y) is effectively the same as (SET 'x y).
Additional feature of SETQ is concurrent assignment of
variables without explicit temporary variables. A SETQ
form such as
(SETQ var1 form1 var2 form2 ...)
is used for this purpose. , , ... are all
evaluated first, sequentially, in this order. Then their
resulting values are assigned to , , ....
Example: Values of two variables X and Y can be
exchanged by
(SETQ X Y Y X)
Utilisp Manual - 30 - 81-09-07
Aug. 3, 1981 6. Symbols
BOUNDP variable
BOUNDP returns T if is bound to some value;
otherwise, i.e., if it is unbound, NIL is returned.
MAKE-UNBOUND variable
MAKE-UNBOUND makes unbound. The current value
of , if any, is discarded. MAKE-UNBOUND
returns the symbol as its value.
6.2 The Definition
A symbol can be associated with its "functional definition",
or "definition", for short. When a function is called via its
name, that is, when the first argument of FUNCALL or APPLY is
a symbol, or a symbol appears as the "car" of a form to be
evaluated, the "definition" of that symbol is called as a
function. When a symbol is not defined as a function nor a
macro, the symbol is said to be "undefined"; an error is
generated when an undefined symbol is used as a function.
DEFUN »Macroº name lambda-list . body
DEFUN can be used for defining functions. should
be a symbol. A list
(LAMBDA lambda-list . body)
will be the new definition of . The previous
definition of , if any, is discarded. DEFUN
returns as its value.
MACRO »Macroº name lambda-list . body
MACRO can be used for defining macros. should be
a symbol. A list
(MACRO LAMBDA (arg) . body)
will be the new definition of . The previous
definition of , if any, is discarded. MACRO
returns as its value.
Note: Macros can more elegantly be defined using
DEFMACRO. See Chapter 10, Macros, for detail.
GETD sym
GETD returns the definition of a symbol . If
is undefined, an error is generated.
PUTD sym def
PUTD makes the definition of be