next up previous
Next: J. INDEX TO FUNCTION Up: LISP 1.5 Programmer's Manual Previous: H. RECURSION AND THE

I. LISP FOR SHARE DISTRIBUTION

The Artificial Intelligence Project at Stanford University has 
produced a version of LISP 1.5 to be distributed by SHARE. In 
the middle of February 1965 the system is complete and is 
available from Stanford. The system should be available from 
SHARE by the end of March 1965.

SHARE LISP differs somewhat from the LISP 1.5 system described in 
the LISP 1.5 Programmer's Manual, but only in (generally) 
inessential details. It is hoped that the changes will be widely 
hailed as improvements.

Verbos and the Garbage CollectorThe garbage collector now prints its message in a single-spaced 
format; thus, the amount of paper generated by a program with 
many cons'es is somewhat less than formerly. Furthermore, the 
garbage collector printout may be suspended by executing 
"VERBOS(NIL)"; and the printout may be reinstated by executing 
"VERBOS(*T*)".

Flap TrapEvery now and then a state of affairs known as floating-point 
trap occurs - this results when a floating-point arithmetic 
instruction generates a number whose exponent is too large in 
magnitude for the eight-bit field reserved for it. When this 
trap occurs and the offending exponent is negative, the obvious 
thing to do is to call the result zero. The old system, however, 
simply printed out a "FLAP TRAP" error message and went on to the 
next pair of S-expressions to be evaluated. The new system 
stores a floating-point zero in the accumulator when an underflow 
occurs. (There has, as yet, been no request to have "infinity" 
stored in the accumulator when an overflow occurs.)

TimeThe new system prints the time upon entering and leavingevalquote. In fact, two times are printed, but in a neat, 
concise, impersonal manner which, it is felt, is more suitable to 
the "age of automation" than the quote from Lewis Carroll. The 
times are printed in minutes and milliseconds; the first time is 
the age of the packet - by definition, this is zero whenevalquote is first entered - and the second time is the age of 
the system being used. Thus, when evalquote is left, the time 
printout tells how much time was spent in the execution of the 
packet and how much time has been spent in execution of SET or 
SETSET packets since the birth of the system plus the time spent 
in the packet being finished. This time printout, to be 
meaningful, requires the computer to have a millisecond clock in 
cell 5 (RPQ F 89349, with millisecond feature).

It is also possible to determine how much time is required to 
execute a given function "TIME1( )" initializes two time cells 
to zero and prints out, in the same format that is used for theevalquote time printout, two times, and these are both zero. 
"TIME()" prints (again in the evalquote time printout format) the 
time since the last execution of "TIME()" and the time since the 
last execution of "TIME1()". The use of the time and time1functions has no effect on the times recorded by evalquote.

Lap and SymtabHeretofore, lap has not only returned the symbol table as its 
value but has printed it out as well. This phenomenon is 
familiar to those who have much at all to do with lap or thecompiler. The lap in the new system always prints the function 
name and the octal location in which the first word of the 
assembled function is stored. (If the assembled function is not 
a SUBR or FSUBR, then only the octal origin of the assembled code 
is printed.) The printout is left-Justified on the output page 
and has the form "<function name> (ORIGIN xxxxxQ)".

The value of lap is still the symbol table, but the printing of 
the symbol table may be suspended by executing "SYMTAB(NIL)", and 
the printing may be restored by executing "SYMTAB(*T*)".

Non-Printing CompilerThe problem of the verbosity of the compiler is only slightly 
abated by the symtab function. The remainder of the trouble may 
be cured by executing "LISTING(NIL)". This turns off the 
printout of the lap code generated by the compiler. And, of 
course, the printout may be reinstated by executing 
"LISTING(*T*)". Thus, for a perfectly quiet compilation (except 
for the origin printout by lap), one need only execute 
"SYMTAB(NIL)" and "LISTING(NIL)" before compiling.

Tracecount (Alarm-Clock Trace)The trace feature of LISP is quite useful, but, with very little 
encouragement, it can be made to generate wastebaskets full of 
useless output. Often a programmer will find that his output 
(without tracing) consists of many lines of garbage collector 
printout, an error message, and a few cryptic remarks concerning 
the condition of the push-down list at the time the error 
occurred. In such a situation, one wishes he could begin tracing 
only a short time before the occurrence of the error. The 
tracecount function permits exactly this. "TRACECOUNT(x)" causes 
the tracing (of those functions designated to be traced by the 
trace function call) to begin after x number of function 
entrances. Furthermore, when the tracecount mechanism has been 
activated, by execution of "TRACECOUNT(x)", some of the blank 
space in the garbage collector printout will be used to output 
the number of function entrances which have taken place up to the 
time of the garbage collection; each time the arguments or value 
of a traced function are printed the number of function entrances 
will be printed; and if an error occurs, the number of function 
entrances accomplished before the error will be printed.

The tracecount feature (or alarm-clock trace, as it is called by 
Marvin Minsky of M. I. T.) enables a programmer to run a job 
(preceding the program by "TRACE -COUNT(O)"), estimate the number 
of function entrances that occur before the program generates an 
error condition or a wrong answer, and then run the job again, 
tracing only the pertinent portion of the execution.

Space and EjectA small amount of additional control over the form of the data 
printed by LISP has been provided in the space and ejectfunctions.

"SPACE(*T*)" causes all output to be double-spaced. "SPACE(NIL)" 
restores the spacing to its original status, in particular, the 
output of the print routine reverts to single-spacing, and the 
"END OF EVALQUOTE OPERATOR" printout again ejects the page before 
printing.

"EJECT()" causes a blank line with a carriage control character 
of 1 to be printed on the output tape. The result is a skip to 
the top of the next page of output.

UntimeThis routine is not available to the programmer, but its mention 
here may prevent some anxiety. In the event that the program 
time estimate is exceeded during system I/O, using the old 
system, one finds himself in the position of having part of one 
system and part of another stored in core or on the SYSTMP. This 
situation would be intolerable if the programmer were trying to 
save some definitions so that he could use them later. To avoid 
this unpleasantness, the system I/O routines have been modified 
so that the clock is, in essence, turned off during system I/O 
and three seconds is automatically added to the elapsed time at 
the conclusion of the read or write operation (in a machine with 
a millisecond core clock this is the case - machines with 1/60 
second core clocks add 50 seconds, but this is easily changed). 
A clock trap that would normally have occurred during the 
execution of the read or write will be executed before the I/O 
operation takes place.

TapeA few programmers with very large programs have long bemoaned the 
inability of LISP to communicate between different systems. The 
functions tape, rewind, mprmt, mread, andbackspace have been designed to alleviate this difficulty. "TAPE(s)", 
where s is a list, allows the user to specify up to ten scratch tapes; 
if more than ten are specified, only the first ten are used. The value 
of tape is its argument. The initial tape settings are, from one 
to ten, A4, A5, A6, A7, A8, B2, B3, B4, B5, B6. The tapes must 
be specified by the octal number that occurs in the address 
portion of a machine-language instruction to rewind that tape; 
that is, a four-digit octal number is required - the first 
(high-order) digit is a 1 if channel A is desired, 2 if channel B 
is desired; the second digit must be a 2; the third and fourth 
are the octal representation of the unit number. Thus, to 
specify that scratch tapes one, two, and three are to be tapes 
A4, Bl, and A5, respectively, execute "TAPE ((1204Q 2201Q 
1205Q))". Only the low-order fifteen bits of the numbers in the 
tape list are used by the tape routines, so it is possible to use 
decimal integers or floating-point numbers in the tape list 
without generating errors.

Rewind"REWIND(x)" rewinds scratch tape x, as specified in the most 
recently executed tape function. For example, if the last tape 
function executed was "TAPE ((1204Q 2201Q))", then "REWIND(2)" 
will cause tape B1 to be rewound. The value of rewind is NIL.

Mprint"MPRINT(x s)" prints the S-expression s on scratch tape x. The 
format of the output is identical to the normal LISP output, 
except that sequence numbers are printed in the rightmost eight 
columns of the output line and the output line is only 80 
characters long (the scratch tape output is generated by the 
punch routine), and is suitable for punching or being read bymread. The value of mprint is the list printed.

Mread"MREAD(x)" reads one S-expression from scratch tape x. The value 
of mread is the S-expression read.

Backspace"BACKSPACE(x)" causes scratch tape x to be backspaced one record. 
Caution in the use of this function is recommended, for if an 
S-expression to be read from tape contains more than 72 
characters, then it will occupy more than one record on the tape, 
and single backspace will not move the tape all the way back to 
the beginning of the S-expression. The value of backspace is 
NIL.

EvalquoteEvalquote is available to the programmer as a LISP function - 
thus, one may now write "(EVALQUOTE APPEND ((A)(B C D)))", rather 
than "(EVAL (QUOTE (APPEND (A)(B C D))) NIL)", should one desire 
to do so.

BacktraceThis function was copied (not quite literally) from M. I. T.'s 
LISP system on the time-shared 7094. Backtrace is a function of 
no arguments in which the manner of specifying the no arguments 
constitutes, in effect, an argument. The first call ofbacktrace, with any argument, or with none, suspends backtrace 
printouts when errors occur. Thereafter, the value of "BACKTRACE 
NIL" is the backtrace for the most recent error; and "BACKTRACE 
x", for x not NIL, restores the backtrace printout to the error 
routine. Backtrace should always be evaluated by evalquote.

Read-In ErrorsA common cause of free-storage or circular list printouts is an 
error (in parenthesis count, usually) during the initial read-in 
of a packet. The new system causes the accumulator to be cleared 
if an error occurs during the initial read-in, so that the 
contents of the accumulator are printed as "NIL".

ObkeepAnyone desperate for a few more words of free storage may make up 
a list, s, of all atom names he wants to retain in his personal 
LISP systems, then execute (in a SET packet) "OBKEEP(s)". All 
atoms except those which are members of s will be eliminated from 
the object list.

Reserved"RESERVED NIL" prints the names of the atoms on the object list 
in alphabetical order, along with the indicators (not 
alphabetized, and flags may be missed) on their property lists. 
This function should help to solve some of the problems that 
arise involving mysterious behavior of compiled functions that 
worked fine when interpreted.

Gensym and SymnamGensym now omits leading zeroes from the numeric portions of the 
print-names of the symbols it generates, thus, what once looked 
like "G00001" now prints as "G1". Furthermore, it is possible to 
specify a heading word of from zero to six characters for thegensym symbols by executing symnam. "SYMNAM(NIL)" causes 
LISP-generated symbols to have purely numeric print-names (but 
they are not numbers). The numeric portions of the print-names 
are truncated from the left so as not to overlap the heading 
characters. Thus, "SYMNAM(AAAAA)" causes gensym to produce 
distinct atoms with the following (not necessarily distinct) 
print-names. AAAAA1, AAAAA2, .... AAAAA9, AAAAAO, AAAAA1, .... 
The argument of symnam must have the indicator PNAME on its 
property list. "SYMNAM(12)" will cause undefined results.

IfFor the convenience of those who find it difficult to get along 
with the "COND" form of the conditional statement, the following 
"IF" forms are provided in the new system. "IF (a THEN b ELSE 
c)" and "IF (a b c)" are equivalent to "COND ((a b) (T c))". "IF 
(a THEN b)" and "IF (a b)" are equivalent to "COND ((a b))".

For"FOR (index $i s u d_{1} \ldots d_{n}$)", 
for n less than 17, sets index 
to the value of i and skips out of the following loop as soon as 
the value of u is not NIL: evaluate u, evaluate $d_{1}, \ldots ,$evaluate $d_{n}$, evaluate s, go to the beginning of the loop. If i, 
s, and u are numbers, then the for statement is similar to the 
ALGOL "for index = i step s until u do begin $d_{1} \ldots d_{n}$ end". The value of thefor statement is the value of $d_{n}$ the last time it 
was evaluated. The final value of index is available outside thefor function because cset is used to set the index.

SublisSublis has been re-hand-compiled so that it behaves as if it were 
defined as follows.

sublis[p;e] = 
label[suba; $\lambda$[[e];[ 
     atom[e] $\rightarrow$         label [subb; $\lambda$[[x];[ 
            null[x] $\rightarrow$ e; 
            eq[caar[x];e] $\rightarrow$cdar[x]; 
            T $\rightarrow$ subb[cdr[x]] 
         ]]][p]; 
     T $\rightarrow$         $\lambda$[[u;v];[ 
            and[equal[car[e];u];equal[cdr[e];v]] $\rightarrow$ e; 
            T $\rightarrow$ cons[u,v] 
         ]][suba[car[e]];suba[cdr[e]]] 
]]][e].

The differences between the new sublis and the old one, as far as 
the programmer is concerned, are that the new model is faster and 
the result shares as much storage as possible with e.

Characteristics of the SystemThe set-up deck supplied with the SHARE LISP system produces a 
system tape with the following properties:

        Size (in words) - 
                Binary Program Space 14000 octal 
                Push-Down List 5000 octal 
                Full-Word Space 4220 octal 
                Free Storage 22400 octal 
        System Tape (SYSTAP) B7 
        System Temporary Tape (SYSTMP) B6 
        System Input Tape (SYSPIT) A2 
        System Output Tape (SYSPOT) A3 
        System Punch Tape (SYSPPT) A3

The console switches may be used to obtain special results:

        SW1 on for LISP input from on-line card reader 
        SW2 has no effect 
        SW3 on for LISP output on on-line printer 
        SW4 has no effect 
        SW5 on to suppress SYSPOT output 
        SW6 on to return to overlord after accumulator printout 
            resulting from error *F 5*. SW6 off for error printout.


next up previous
Next: J. INDEX TO FUNCTION Up: LISP 1.5 Programmer's Manual Previous: H. RECURSION AND THE