Trailing-Edge
-
PDP-10 Archives
-
decus_20tap1_198111
-
decus/20-0004/02lisp.doc
There are no other files named 02lisp.doc in the archive.
SECTION 2
USING INTERLISP
2.1 Using the INTERLISP Manual - Format, Notation, and Conventions
The INTERLISP manual is divided into separate, more or less independent
sections. Each section is paginated independently, to facilitate
issuing updates of sections. Each section contains an index to key
words, functions, and variables contained in that section. In addition,
there is a composite index for the entire manual, plus several
appendices and a table of contents.
INTERLISP is currently implemented on (or implementations are in
progress for) at least four different computers. This manual purports
to be a reference manual for all implementations of INTERLISP, both
present and future. However, since the largest user cummunity is still
that of INTERLISP-10, the original implementation for the DEC PDP-10,
the manual does contain some implementation dependent material. Where
this is the case, the text refers to INTERLISP-10, and is indicated as
such.
Throughout the manual, terminology and conventions will be offset from
the text and typed in italics, frequently at the beginning of a section.
For example, one such notational convention is:
The names of functions and variables are written in lower case and
underlined when they appear in the text. Meta-LISP notation is used for
describing forms.
Examples: member[x;y] is equivalent to (MEMBER X Y), member[car[x];FOO]
is equivalent to (MEMBER (CAR X) (QUOTE FOO)). Note that in meta-LISP
notation lower case variables are evaluated, upper case quoted.
. notation is used to distinguish between cons and list.
e.g., if x=(A B C), (FOO x) is (FOO (A B C)), whereas (FOO . x) is
(FOO A B C). In other words, x is cadr of (FOO x) but cdr of (FOO . x).
Similarly, y is caddr of (FOO x y), but cddr of (FOO x . y). Note that
this convention is in fact followed by the read program,
i.e., (FOO . (A B C)) and (FOO A B C) read in as equal structures.
Other important conventions are:
2.1
TRUE in INTERLISP means not NIL.
The purpose of this is to allow a single function to be used both for
the computation of some quantity, and as a test for a condition. For
example, the value of member[x;y] is either NIL, or the tail of y
beginning with x. Similarly, the value of or is the value of its first
TRUE, i.e., non-NIL, expression, and the value of and is either NIL, or
the value of its last expression.
Although most lists terminate in NIL, the occasional list that ends in
an atom, e.g., (A B . C) or worse, a number or string, could cause
bizarre effects. Accordingly, we have made the following implementation
decision:
All functions that iterate through a list, e.g., member, length, mapc,
etc. terminate by an nlistp check, rather than the conventional
null-check, as a safety precaution against encountering data types which
might cause infinite cdr loops, e.g., strings, numbers, arrays.
Thus,
member[x;(A B . C)] = member[x;(A B)]
reverse[(A B . C)] = reverse[(A B)]
append[(A B . C);y] = append[(A B);y]
1
For users with an application requiring extreme efficiency, we have
provided fast versions of memb, last, nth, assoc, and length which
compile open and terminate on NIL checks, and therefore may cause
infinite cdr loops if given poorly formed arguments. However, to help
detect these situations, fmemb, flast, fnth, fassoc, and flength all
generate errors when interpreted if their argument ends in a non-list
other than NIL, e.g., BAD ARGUMENT - FLAST.
Most functions that set system parameters, e.g., printlevel,linelength,
radix, etc., return as their value the old setting. If given NIL as an
argument, they return the current value without changing it.
All SUBRS, i.e., hand coded functions, such as read, print, eval, cons,
etc., have "argument names" selected from U, V, W, X, Y, Z, as described
under arglist, Section 8. However, for tutorial purposes, more
suggestive names are used in the descriptions of these functions in the
text.
Most functions whose names end in p are predicates, e.g., numberp,
tailp, exprp; most functions whose names end in q are nlambda's, i.e.,
do not require quoting their arguments, e.g., setq, defineq, nlsetq.
------------------------------------------------------------------------
1
A NIL check can be executed in only one instruction, an nlistp on
INTERLISP-10 requires about 12, although both generate only one word
of code.
2.2
"x is equal to y" means equal[x;y] is true, as opposed to "x is eq to y"
meaning eq[x;y] is true, i.e., x and y are the same identical LISP
pointer.
When new literal atoms are created (by the read program, pack, or
mkatom), they are provided with a function definition cell initialized
to NIL (Section 8), a value cell initialized to the atom NOBIND (Section
16), and a property list initialized to NIL (Section 7). The function
definition cell is accessed by the functions getd and putd described in
Section 8, the value cell by the functions gettopval and settopval
(Section 5), and the property list by the functions getproplist and
setproplist, (Section 7).
car of NIL and cdr of NIL are always NIL, and the system will resist
attempts to change them.
The term list refers to any structure created by one or more conses,
i.e., it does not have to end in NIL. For example, (A . B) is a list.
The function listp, Section 5, is used to test for lists. Note that not
being a list does not necessarily imply an atom, e.g., strings and
arrays are not lists, nor are they atoms. See Section 10.
Many system functions have extra optional arguments for internal use
that are not described in the writeups. For example, readline is
described as a function of one argument, but arglist[READLINE] returns
(RDTBL LINE LISPXFLG). In such cases, the user should just ignore the
extra arguments.
INTERLISP departs from LISP 1.5 and other LISP dialects in that car of a
form is never evaluated. In other words, if car of a form is not an
atom with a function definition, and not a function object, i.e., a list
car of which is LAMBDA, NLAMBDA, or FUNARG, an error is generated.
apply or apply* (Section 8) must be used if the name of a function is to
be computed as for example, when functional arguments are applied.
2.2 Using the INTERLISP-10 System on TENEX - An Overview
Call INTERLISP-10 by typing LISP followed by a carriage return.
INTERLISP will type an identifying message, the date, and a greeting,
followed by a "_". This prompt character indicates that the user is
"talking to" the top level INTERLISP executive, called evalqt, (for
historical reasons), just as "@" indicates the user is talking to Tenex.
evalqt calls lispx which accepts inputs in either eval or apply format:
if just one expression is typed on a line, it is evaluated; if two
expressions are typed, the first is apply-ed to the second. eval and
apply are described in Section 8. In both cases, the value is typed,
followed by _ indicating INTERLISP is ready for another input.
INTERLISP is normally exited via the function logout, i.e., the user
types LOGOUT(). However, typing control-C at any point in the
computation returns control immediately to Tenex. The user can then
continue his program with no ill effects with the Tenex CONTINUE
command, even if he interrupted it during a garbage collection. Or he
can reenter his program at evalqt with the Tenex REENTER command. The
latter is DEFINITELY not advisable if the Control-C was typed during a
garbage collection. Typing control-D at any point during a computation
2.3
will return control to evalqt. If typed during a garbage collection,
the garbage collection will first be completed, and then control will be
returned to INTERLISP's top level, otherwise, control returns
immediately.
When typing to the INTERLISP read program, typing a control-Q will cause
INTERLISP to print "##" and clear the input buffer, i.e., erase the
entire line up to the last carriage return. Typing control-A erases the
last character typed in, echoing a \ and the erased character. Control-
A will not back up beyond the last carriage return. Typing control-W
within a call to read or readline will erase the last expression typed,
echoing a \\. Control-W will back up to previous lines. Control-O can
be used to immediately clear the output buffer, and rubout to
2
immediately clear the input buffer. In addition, typing control-U (in
most cases) will cause the INTERLISP editor (Section 9) to be called on
the expression being read, when the read is completed. Appendix 3
contains a list of all control characters, and a reference to that part
of the manual where they are described. Section 16 describes how the
system's interrupt characters can be disabled or redefined, as well as
how the user can define his own interrupt characters.
Since the INTERLISP read program is normally line-buffered to make
3
possible the action of control-Q, the user must type a carriage return
before any characters are delivered to the function requesting input,
e.g.,
4
_E TC
T
However, the read program automatically supplies (and prints) this
carriage return when a matching right parenthesis is typed, making it
unnecessary for the user to do so, e.g.,
_CONS(A B)
(A . B)
The INTERLISP read program treats square brackets as "super-
parentheses": a right square bracket automatically supplies enough right
parentheses to match back to the last left square bracket (in the
------------------------------------------------------------------------
2
The action of control-Q takes place when it is read. If the user has
"typed ahead" several inputs, control-Q will only affect at most the
last line of input. Rubout however will clear the entire input
buffer as soon as it is typed, i.e., even during a garbage
collection.
3
Except following control[T], see Section 14.
4
'C' is used throughout the manual to denote carriage-return.
2.4
expression being read), or if none has appeared, to match the first left
parentheses, e.g.,
(A (B (C]=(A (B (C))),
(A [B (C (D] E)=(A (B (C (D))) E).
% is the universal escape character for read. Thus to input an atom
containing a syntactic delimiter, precede it by %, e.g., AB% (C or %%.
See Section 14 for more details.
^V (control-V) can be used to type a control character that would
otherwise interrupt the input process, e.g., control-D, control-C, etc.
If the character following ^V is A, B, ... or Z, the corresponding
control character is input, e.g., ^VA^VB^VC is the atom
control-Acontrol-Bcontrol-C. ^V followed by any other character has no
effect, i.e., FOO^V1 and FOO1 are identical. For more details, see
Appendix 3.
Typing ' immediately in front of any expression has the effect of
quoting the expression, i.e., (A 'B C) is read as (A (QUOTE B) C). See
Section 14.
At any point during input, the user can type ?= followed by carriage-
return and be given the argument names and corresponding values (if any)
of the expression (form) being typed. Typing just ? carriage-return
will cause the user to receive information from the INTERLISP manual
about the expression or command being typed. In the following example
underlined characters were typed by the user.
_(SETQ FOO (ELT 3 ?=C
A = 3
N =
(ELT 3 ?C
elt[a;n] Value is nth element of the array a.
elt generates an error, ARG NOT ARRAY,
if a is not the beginning of an array.
(ELT 3 ^W\\3 A 3]
? is also a programmer assistant command for use following an error. In
many cases, the programmer's assistant can analyze the cause of the
error (see example below). If not, the programmer's assistant simply
presents information about the error from the manual.
Example
Most of the "basics" of on-line use of INTERLISP, e.g., defining
functions, error handling, editing, saving your work, etc., are
illustrated in the following brief console session. Underlined
characters were typed by the user.
1. The user calls INTERLISP from Tenex, INTERLISP prints a date, and a
2.5
greeting. The prompt character _ indicates the user is at the top
level of INTERLISP.
2. The user defines a function, fact, for computing factorial of n. In
INTERLISP, functions are defined via DEFINE or DEFINEQ, (Section 8).
Functions may independently evaluate arguments, or not evaluate
them, and spread their arguments, or not spread them (Section 4).
The function fact shown here is an example of an everyday run-of-
the-mill function of one argument, which is evaluated. The function
definition uses CLISP (Conversational LISP, Section 23). The CLISP
will automatically be converted to LISP when the function is run.
3. The user "looks" at the function definition. Function definitions
in INTERLISP are stored in a special cell called the function
definition cell, which is associated with the name of the function
(Section 8). This cell is accessible via the two functions, getd
and putd, (define and defineq use putd). Note that the user typed
an input consisting of a single expression, i.e., (GETD (QUOTE
FACT)), which was therefore interpreted as a form for eval. The user
could also have typed GETD(FACT).
4. The user runs his function. Two errors occur and corrections are
offered by DWIM (Section 17). In each case, the user indicates his
approval, DWIM makes the correction, i.e., actually changes the
definition of fact, and then continues the computation.
5. An error occurs that DWIM cannot handle, and the system goes into a
break. At this point, the user can type in expressions to be eval-
ed or apply-ed exactly as at the top level. The prompt character
":" indicates that the user is in a break, i.e., that the context of
his computation is available. In other words, the system is
actually "within" or "below" the call to itimes in which the error
occurred.
6. The user types in the break command, BT, which calls for a backtrace
to be printed. In INTERLISP, interpreted and compiled code (see
Section 18 for discussion of the compiler) are completely
compatible, and in both cases, the name of the function that was
called, as well as the names and values of its arguments are stored
on the stack. The stack can be searched and/or modified in various
ways (see Section 12).
Break commands are discussed in Section 15, which also explains how
the user can "break" a particular function, i.e., specify that the
system go into a "break" whenever a certain function or functions
are called. At that point the user can examine the state of the
computation. This facility is very useful for debugging.
2.6
@LISPC 1
INTERLISP-10 11-17-73 ...
GOOD EVENING.
_DEFINEQ((FACT (LAMBDDA (N) (IF N=0 THEN NIL ELSE N*(FACTT N-1] 2
(FACT)
_(GETD 'FACT) 3
(LAMBDDA (N) (IF N=0 THEN NIL ELSE N*(FACTT N-1))
_FACT(3) 4
LAMBDDA {IN FACT} -> LAMBDA ? YESC
FACTT {IN FACT} -> FACT ? YESC
NON-NUMERIC ARG 5
NIL
IN ITIMES
(BROKEN)
:BTC 6
ITIMES
COND
FACT
COND
FACT
COND
FACT
**TOP**
:NC 7
1
:?C 8
BECAUSE ITIMES REQUIRES THAT EACH OF ITS ARGUMENTS BE A NUMBER
BUT IN (ITIMES N (FACT (SUB1 N))) {IN FACT},
THE VALUE OF (FACT (SUB1 N)) IS NIL WHEN N=1
:EDITF(FACT) 9
EDIT
*(R NIL 1) 10
*OKC 11
FACT
:RETURN 1C 12
'BREAK' = 1
6
_PP FACTC 13
(FACT
[LAMBDA (N)
(COND
((EQ N 0)
1)
(T (ITIMES N (FACT (SUB1 N])
FACT 14
_PRETTYDEF((FACT) FACT) 15
FACT.;1
2.7
7. The user asks for the value of the variable n, i.e., the most recent
value, or binding. The interpreter will search the stack for the
most recent binding, and failing to find one, will obtain the top
level value from the atom's value cell, which is car of the atom
(Section 3). If there are no bindings, and the value cell contains
the atom NOBIND, an unbound atom error is generated (Section 16).
8. The user types ?, a command to the programmer's assistant (Section
22). The p.a. looks at the error and the context and using its
information about ITIMES, "explains" the error.
9. The user realizes his error, and calls the editor to fix it. (Note
that the system is still in the break.) The editor is described at
length and in detail in Section 9. It is an extremely useful
facility of INTERLISP. Section 9 begins with a simple introduction
designed for the new user.
10. The user instructs the editor to replace all NIL's (in this case
there is only one) by 1. The editor physically changes the
expression it is operating on so when the user exits from the
editor, his function, as it is now being interpreted, has been
changed.
11. The user exits from the editor and returns to the break.
12. The user specifies the value to be used by itimes in place of NIL by
using the break command RETURN. This causes the computation to
continue, and 6 is ultimately returned as the value of the original
input, fact(3).
13. The user prettyprints (Section 14) fact, i.e., asks it be printed
with appropriate indentations to indicate structure. Prettyprint
also provides a comment facility. Note that both the changes made
to fact by the editor and those made by DWIM are in evidence.
14. The user writes his function on a file by using prettydef
(Section 14), creating a Tenex file, FACT.;1, which when loaded into
INTERLISP at a later date via the function load (Section 14), will
cause fact to be defined as it currently is. There is also a
facility in INTERLISP for saving and restoring an entire core image
via the functions sysout and sysin (Section 14).
15. The user logs out, returning control to Tenex. However, he can
still continue his session by re-entering INTERLISP via the Tenex
REENTER or CONTINUE command.
2.8