perm filename LSPMAN[206,LSP]1 blob sn#306070
filedate 1977-09-23 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00007 PAGES
C REC PAGE DESCRIPTION
C00002 00002 .IF FALSE THEN BEGIN "title"
C00003 00003 .<< Organization of Manual >>
C00011 00004 .<< Using LISP at LOTS >>
C00022 00005 .IF FALSE THEN START "hide i/o"
C00071 00006 .IF FALSE THEN START "hide editor"
C00093 00007 .<< Correspondence about Maclisp Manual >>
.IF FALSE THEN BEGIN "title"
.<<Title page for MACLISP at LOTS manual>>
.PAGE FRAME 52 HIGH 80 WIDE;
.evenleftborder ← oddleftborder ← 1000;
.area text lines 4 to 52;
.sname ← SSNAME ← NULL
.FONT 1 "NGR40L"
.FONT 2 "SIGN57"
.FONT 3 "SGN114"
.BEGIN CENTER SELECT 3
Edited by Carolyn Talcott
.END "title" ;;
.<< Organization of Manual >>
.require "lsp.pub[1,clt]" source_file;
.sname ← ssname ← null
.count subsection in section
.cb Organization of the Manual
This manual is collected from several sources and aims to document
those features of MACLISP that are available in the student version of
MACLISP implemented at LOTS by R._Gabriel.
The various sections of the manual are described below.
.ss LISP at LOTS
How to invoke the student LISP system at LOTS. Special I/O features.
The log of a sample session.
.ss MACLISP Reference Manual.
Contains parts 1, 2, 3 and the indices of the manual currently
in production at MIT under the direction of Ellen Lewis. The initial
page gives an index for the entire proposed manual.
.ss Input and Output.
This section is taken from the I/O section of the old MACLISP
Reference Manual (written by D. Moon at MIT). It includes mainly information
that pertains to "Old I/O" which is the available form.
.ss The LISP Editor.
This section contains the documentation for the Editor written
by R. Gabriel and T. Finin.
.<< Using LISP at LOTS >>
.count subsection in section
.sname ← "LISP at LOTS"
.ss Using LISP at LOTS
The following is a brief introduction to the use of the "student"
version of MACLISP at LOTS.
This version can be run at LOTS by typing LISP to the "@" prompt.
of the Editor and other useful things are done automatically.
As with other LISP interpreters, the top level is a
read-eval-print loop. Type in an S-expression and LISP returns the value.
To exit LISP type ↑C. (↑ in front of a character means to depress the
<control> key while typing the character.)
This version of MACLISP has the I/O functions DSKIN and DSKOUT
which are similar to the functions of the same name in LISP1.6.
To input a file named FOO.BAR on your directory say (DSKIN_FOO_BAR).
If the file resides on one of the additional directories known to LISP
then (DSKIN_FOO_BAR_<name>) will read <name>FOO.BAR. One such directory
is CS206. Ask a LISP hacker to find out others.
If the file resides on a directory unknown to LIPS then the form of
the instruction is (DSKIN_FOO_BAR_DSK_(m_n)) where (m_n) is the system
account information for the directory concerned.
The Editor functions SAVE and REFILE can be used to save or update
The function DSKOUT can be used to write the result of a computation on a file.
For example if FF is a function name and X is and S-expression then
(DKSOUT_(PRINC_(FF_X))_FOO_BAR) creates a file FOO.BAR on your directory and
PRINC's the result of evaluating (FF X) on that file.
but flexible I/O functions are the usual MACLISP "old I/O" functions
UREAD/UWRITE together with the appropriate control switches. These
are described in the I/O section of the manual. The syntax for these
functions is (UREAD_<name>_<ext>) for a file on your directory or
(UREAD_<name>_<ext>_DSK_(m_n)) for a file on the directory with
account numbers (m_n).
Sometimes you may encounter an error and a breakpoint will occur.
The system will type a message preceded by a ";" and perhaps
give you the option of correcting the error on the fly.
Usually the information that is typed will alert you to the
cause of the error; if not, you should read about errors and debugging
aids in the manual. In any case, to get back to
the toplevel of MACLISP you type: ↑G or (IOC_G).
.ss A Sample Session with LISP at LOTS.
Things typed by the user appear in ⊗THIS_FONT and things typed by LISP
appear in $THIS_FONT. Instructions typed to the Editor are preceded by
a "←" which is the prompt used by the Editor. Messages from the LISP system
(such as error messages) are preceded by ";". Comments are preceded by
the character "#".
$$Student MacLisp Interpreter$
# Type in an S-expression
⊗⊗(QUOTE (A B C))⊗
# LISP returns the value
$$(A B C) $
# Try another. Note that 'A is short for (QUOTE A).
⊗⊗(EQ 'A 'B)⊗
# Define a function
⊗⊗(DEFUN FOO (X) (COND ((ATOM X) XX ) (T (FOO (CAR X)))))⊗
# Try it out
$$;XX Unbound variable. Either type a value to use or ↑G:$ ⊗X
# Oops! a misprint. Tell LISP that you really meant X and it will finish the evaluation.
# Now use the Editor to fix the mistake.
# First prettyprint the current expression (CE).
$$(DEFUN FOO (X) (COND ((ATOM X) XX) (T (FOO (CAR X)))))$
# Now point to the 2nd element of the 4th element of the CE
← ⊗⊗4 2⊗
$$((ATOM X) XX)$
# Replace the XX by the intended X
← ⊗⊗(R XX X)⊗
$$((ATOM X) X) $
# Return to the top of the expression
# Print the "skeleton" of the expression
$$DEFUN FOO (X) (COND # #)) $
# Save the definition on the file FOODEF.LSP in your directory
$$(DSK (4 1381)) $
# Leave the Editor and return to LISP
# This mode of leaving the Editor forgets about the changes made to FOO, so
# read in the definition written on FOODEF.LSP
# (There are ways of getting the Editor to redefine the function using REMEMBER or OK)
⊗⊗(DSKIN FOODEF LSP)⊗
# Try it
⊗⊗(FOO '(A B))⊗
# Read from a previously created file on your directory called FOO.BAR.
# It contains function definitions for ALT and ZEQUAL.
⊗⊗(DSKIN FOO BAR)⊗
⊗⊗(ALT '(A B C D E))⊗
$$(A C E) $
# Sesson is over. Return to EXEC
.IF FALSE THEN START "hide i/o"
.<< Input and Output >>
.sname ← "Input and Output"
.BEGIN "i/o" VERBATIM SELECT 6
***** ROUGH DRAFT #9905 *****
13. Input and Output
13.1 Basic I/O
Input and output can be done in LISP in terms of S-expressions or
in terms of characters. Operations may also be performed on certain
devices, such as displays, robot arms, etc., in terms which are
peculiar to the particular device, using the so-called "moby I/O"
Initially we will discuss just I/O on the user's terminal.
S-expressions can be input by using the function read. (read)
reads one S-expression, which is either a list enclosed in matching
parentheses or an atom delimited by a special character such as a
space or a parenthesis. (A parenthesis would be saved up and used on
the next call to read.) Read returns the S-expression which it read,
converting it from the external representation as characters to LISP
internal form. See Chapter 2 and section 13.1.2.
(readch) reads in one character and returns it as a character
(tyi) reads in one character and returns a number which is the
ascii code for the character.
(print x) prints out the S-expression x in a form which is readable
by humans but which could also be read back into LISP if it was
printed to a file rather than to the terminal. See section 13.2.3 for
an explanation of how to do this.
The expression printed out is preceded by a newline and followed by
a space. If special characters are used with other than their normal
meanings, for example if a parenthesis appears in the pname of an
atom, they are preceded by slashes so that the output could be read
back in. Strings are enclosed in double quotes for the same reason.
(prin1 x) is the same as (print x) except that the leading newline
and trailing space are omitted. Prin1 can be used to print multiple
items on a line, but spacing between the items must be provided for
explicitly, for example by evaluating (tyo 40).
(princ x) is like (prin1 x) except that special characters are not
slashified and strings are not quoted. This makes the output more
pleasing in certain situations, however it cannot be read back into
(terpri) types out a newline.
Output of characters can be accomplished using either tyo or princ.
(tyo n) outputs a character whose ascii code is given by the number n.
princ may be used to output character objects.
As implied above, these functions can also be used to do I/O on
devices other than the terminal. The ways to do this will be
explained in section 13.2.3.
Note that what LISP does when it is at its "top level," that is
when you first start talking to it, is first to call read, then to
call eval on what was read, then to print the result and advance the
terminal to a new line on which the next piece of input may be typed.
This may be expressed as repeated evaluation of:
(print (eval (read))) )
I/O in LISP consists of communication between the LISP environment
and sequences of characters called files, located in the external
world. LISP refers to these files by using "file objects," which are
special objects within the LISP environment which serve as
representatives of, or symbols for, the files in the external world.
Because there is a one-to-one correspondence between files and file
objects, it is often convenient to confuse the two and call them both
The LISP system includes functions which can manipulate files in
various ways: A file may be "opened," that is a file object may be
created and associated with a named file in the external world.
A file may be "closed," that is the association between the
file-object and the external file may be broken and the file-object
The file-accessing information contained in a file-object may be
examined or changed; for example, the line length of an output file
may be adjusted.
The characters of information in the external file may be read or
The attributes of the external file, such as its name, may be
In order to "open" a file, the external file and the file object
must be named so that a connection may be established between them.
The problem of naming file objects is solved trivially by making the
rule that whenever a file object is created its name is decided by the
system and returned as the value of the function that created it.
File objects are then referred to in the same way as any S-expression.
Note that the name of a file object does not have a printable form, so
that if you want to manipulate the file object by typing from the
terminal (rather than from a program), you must keep the file object
as the value of an atomic symbol.
The naming of files in the outside world is more difficult because
MACLISP has to operate with several different outside worlds, that is,
under several different operating systems. It was thought undesirable
to build too many assumptions about the operating system into the
language, because that would restrict the transporting of programs
between MACLISP implementations.
The assumptions that are built in are that the operating system
provides named files located in named directories or on named devices,
which may be accessed sequentially as streams of characters. The
function filepos makes the additional assumption that simple
random-access facilities are available. An interactive environment is
also assumed. Some of the I/O functions assume that the names of
files may be broken up into an arbitrary number of components, so that
names take on a form such as "foo.bar.lisp" or "moby mess". However,
it is possible for a MACLISP to operate with somewhat reduced
effectiveness under an operating system which does not satisfy all of
The user of a program or a subsystem written in LISP wants to be
able to type in file names in the form customary in the particular
operating system being used, and he wants to see them typed out in the
same form. But if a program wants to do more with the file name
supplied by the user than simply pass it on to the system I/O
functions, it needs to have that name translated to a uniform internal
format, in which the interesting components of the name are seperate
atoms in a list, not buried inside a character string whose format is
not even known to the program. To resolve this conflict, two forms
for file names have been defined, and functions are provided to make
the implementation-dependent translation from one form to the other.
The forms of a file name are called the namelist and the namestring.
The namestring is the implementation dependent form. Namestrings
are represented as LISP character strings, however atomic symbols may
also be used, in which case the pname of the atomic symbol is used as
the character string. The contents of a namestring is just a sequence
of characters which have meaning to the user and to the function
"namelist," which converts a namestring to a namelist. Namestrings
should be read in using the "readstring" function and printed out
using "princ," so that no quotes will appear around them.
A namelist is a list whose car somehow specifies the device and/or
directory which contains the file, and whose cdr specifies the name of
the file. The exact way in which the car specifies the
device/directory is implementation-dependent. It should not be of
concern to programs. The cdr of a namelist is a list of names which
are the components of the file name if the operating system uses
multi-component file names. Each name is represented as an atomic
symbol, which is "interned" so that it may be tested with the function
An additional feature of namelists is the "star convention," by
which a namelist may contain unspecified components, which are
indicated by the atom *. Certain other constructions, explained in
section 13.3, may also be used. The star convention allows a single
namelist to specify a class of files, and allows programs to apply
defaults to their file-name arguments in a straightforward fashion.
Some additional information about file objects has been collected
here. It is in brief form and will be elaborated in later sections.
There is no way to input file objects to the reader, because they
do not have pnames or anything of that sort, but for convenience in
error messages and debugging the printer will print a file object as a
sharp sign (#), followed by the namestring of the external file to
which the file object is attached. # is the character which is used
to indicate that an object of unknown type is being printed.
The information contained within a file object is here described
Namelist the namelist for the external file of which the
file object is a representative.
Eoffn a function which is applied when the end of an
input file is reached.
Endpagefn a function which is applied when the end of a page is
reached (on an output file.)
Linel the number of characters per line on an output
Charpos the horizontal position on the line, where 0 is the left
Chrct the number of character positions remaining on the
current line of an output file,
Pagel the number of lines per page.
Linenum the number of the current line, with 0 being the top of the
Pagenum the number of the current page, with the first page being 0.
Filepos the position within the file of the character
currently being accessed. (Not necessarily
meaningful for all kinds of files.)
Other internal information used by the LISP I/O
functions in transactions with the operating
Note that as a special case nil is considered to be a file object
which represents the terminal. This is in addition to nil's other
identities as an atomic symbol and as a list.
13.2.3 Specifying the Source or Destination for I/O
When an I/O function is called, the source (file) from which it is
to take its input or the destinations (files) on which it is to put
its output may be specified directly as an argument to the function,
or they may be specified by default. The default input source and
output destinations are specified by several system variables, which
may be setq'ed or lambda-bound by the user. They are described below.
infile is the default input source, if the switch ↑q is t. If ↑q
is nil the terminal is used as the default input source.
outfiles is a list of default output destinations. Output is sent
to all of these files if the ↑r switch is t. Output also goes to the
terminal unless the ↑w switch is t.
Note that in the values of infile and outfiles nil means the
terminal, any anything other than nil must be a file object.
The value of infile is a file object which is the default input
source if ↑q is non-nil. Infile can also be nil which specifies
that input will be from the terminal even if ↑q is not nil. The
initial value of infile is nil.
If the value of ↑q is non-nil, the default input source is the
value of the atom infile. If ↑q is nil, the default input source
is nil, i.e. the terminal.
The value of instack is a list of pushed-down values of infile.
It is managed by the function inpush. The initial value is nil.
The value of outfiles is a list of file objects which are output
destinations if ↑r is not nil. Elements of the list outfiles may
be either file objects created by openo or opena, or nil meaning
output to the terminal. Note that output goes to the terminal
anyway if ↑w is nil, so it is possible to get double characters
If the value of ↑r is non-nil, the default output destinations
include the files in the list which is the value of the atom
If the value of ↑w is non-nil, the default output destinations do
not include the terminal. (Unless ↑r is on and nil is a member
of the outfiles list.)
Now the basic I/O functions can be explained in full detail:
read LSUBR 0 to 2 args
This is the S-expression input function.
(read) reads an S-expression from the default input source.
(read f), where f is a file or nil meaning the terminal, reads an
S-expression from f. During the reading, infile and ↑q are bound
so that evaluation of (read) within a macro-character function
will read from the correct input source.
(read x), where x is not a file and not nil, passes x as an
argument to the end-of-file function of the input source if the
end of the file is reached. Usually this means that read will
return x if there are no more S-expressions in the file.
(read t) suppresses the calling of the end-of-file function if
the end of the file is reached. Instead, read just returns t.
(read x f) or (read f x) specifies the end-of-file value x and
selects the input source f.
readch LSUBR 0 to 2 args
Readch reads in one character and returns a character object.
The arguments are the same as for read.
readline LSUBR 0 to 2 args
readline reads in a line of text, strips off the newline
character or characters at the end, and returns it in the form of
a character string. The arguments are the same as for read. The
main use for readline is reading in file names typed by the user
at his terminal in response to a question.
tyi LSUBR 0 to 2 args
Tyi inputs one character and returns a fixnum which is the ascii
code for that character. The arguments are the same as for read.
tyipeek LSUBR 0 or 1 arg
(tyipeek) is like (tyi) except that the character is not eaten;
it is still in the input stream where the next call to an input
function will find it. Thus (= (tyipeek) (tyi)) is t. If the
end of the file is reached, tyipeek returns 3, (the ascii code
for "end of text.") The end of file function is not called.
(tyipeek n), where n is a fixnum < 200 octal, skips over
characters of input until one is reached with an ascii code of n.
That character is not eaten.
(tyipeek n), where n is a fixnum > 1000 octal, skips over
characters of input until one is reached whose syntax bits from
the readtable, logically anded with (lsh n -9.), are nonzero.
(tyipeek t) skips over characters of input until the beginning of
an S-expression is reached. Splicing macro characters, such as
";" comments, are not considered to begin an object. If one is
encountered, its associated function is called as usual (so that
the text of the comment can be gobbled up or whatever) and
tyipeek continues scanning characters.
prin1 LSUBR 1 or 2 args
(prin1 x) outputs x to the current output destination(s), in a
form suitable for reading back in.
(prin1 x f) outputs x on the file f, or the terminal if f is
print LSUBR 1 or 2 args
Print is like prin1 except that the output is preceded by a
newline and followed by a space. This is the output function
most often used.
(print x) prints x to the default output destinations.
(print x f) prints x to the file f, or to the terminal if f is
princ LSUBR 1 or 2 args
Princ is like prin1 except that special characters are not
slashified and strings are not quoted.
(princ x) outputs x to the current output destination(s).
(princ x f) outputs x to the file f, or the terminal if f is nil.
tyo LSUBR 1 or 2 args
(tyo n) types out the character whose ascii code is n on the
current output destination(s).
(tyo n f) types out the character whoe ascii code is n on the
file f or on the terminal if f is nil. Tyo returns its first
terpri LSUBR 0 or 1 arg
(terpri) sends a newline to the current output destination(s).
(terpri x) sends a newline to x, where x may be an output file or
nil meaning the terminal.
inpush SUBR 1 arg
(inpush x), where x is a file object open for input or nil to
specify the terminal, pushes the current input source onto the
input stack and selects x as the current input source. This is
(setq instack (cons infile instack))
(setq infile x)
x is returned.
(inpush 0) just returns infile.
(inpush -1) pops a new input source off of the input stack:
(setq infile (car instack)
instack (cdr instack))
The above code is wrong in the case where instack is nil, i.e.
empty. In this case inpush leaves instack nil and makes infile
nil, which means the terminal.
(inpush -n) does (inpush -1) n times.
(inpush 1) does (inpush (inpush 0)), (inpush +n) does that n
The value of inpush is the newly selected input source. If
inpush causes infile to be set to nil, ↑q is set to nil since the
terminal has become the input source.
13.2.4 Handling End of File
Calls to the input functions read, readch, readstring, and tyi
specify an argument called the "eofval." If this argument is omitted
nil is assumed. If the end of the input file is reached during the
execution of the function, the eofval argument is used by the
Each file object has an end-of-file handler, its eoffn. When an
end of file occurs while input is being taken from this file, the
eoffn is examined. (Eof on the terminal cannot occur.) If the eoffn
is nil, then the following default action is taken: If eofval on the
call to read was not supplied, then the input file is closed and read
continues taking characters from a new input file popped off the input
stack. If the input stack is empty, (setq ↑q nil) is done and read
continues reading from the terminal. If an eofval was supplied on the
call to read, then read immediately returns it. The input file is not
This is not strictly true in the case where the input function is
read or readstring and it is in the middle of an object. In this
case, rather than allowing the object to cross files, a fail-act error
occurs. The argument passed to the user interrupt service function is
the list (read-eof). If the interrupt service function returns an
atom (such as nil), read errs out; but if it returns a list, read
goes on reading from the new input source as if there had not been any
If the eoffn for the input file is not nil, then it is a function
and it is applied with two arguments. The first argument is the file
object that eof'ed. The second argument is the eofval on the call to
read, or, if an eofval was not supplied, nil. If the eoffn returns
nil, the file is closed and reading continues from the input source
popped off the input stack. The above prohibition of objects crossing
eofs applies. If the eoffn returns t, reading continues from whatever
input source was made the current default one by the eoffn. If the
eoffn returns something other than t or nil, then read immediately
returns whatever the eoffn returned, and the file is not closed unless
the eoffn closes it.
eoffn LSUBR 1 or 2 args
(eoffn x), where x is an input file, gets x's end-of-file
function. The end-of-file function is called if the end of the
file is reached during input.
(eoffn nil) gets the default end-of-file function.
(eoffn x f) sets x's end-of-file function to f.
(eoffn nil f) sets the default end-of-file function to f.
f may be nil, which means that no end-of-file function is to be
13.5 The Old "Uread" I/O System
The functions uread, uwrite, ufile, ukill, and crunit are part
of an older LISP I/O system. They are retained for
compatibility. Various "status" functions are also part of this
older I/O system. (See section 12.7)
These five functions name files in a different way from the
other I/O functions. A file is named by a 4-list,
(name1 name2 dev dir)
Name1 and name2 together make up the "filename," dev is the
"device," and dir is the "directory." In the ITS implementation
of MACLISP, these go together to make up the ITS file name:
DEV: DIR; NAME1 NAME2
In the DEC-10 implementation, dev is the device name, name1 is
the file name, name2 is the extension, and dir is a list of two
fixnums, the project number and the programmer number. Thus the
(name1 ext dev (proj prog))
represents the file
In the Multics implementation, dev is ignored and dir is the
directory pathname. The entry-name is name1.name2. Thus the
Multics filename is:
These five functions maintain their own set of defaults, which
are updated every time one of these functions is called, so that
the defaults correspond to the last file that was used. The
defaults may be examined with (status crfile), which returns the
first two elements of the default 4-list, and (status crunit)
which returns the last two.
It is not necessary to specify all four parts of the 4-list
when one of these five functions is used. Any omitted parts are
taken from the defaults.
These functions are fsubrs which do not evaluate their
arguments. They may be applied to a 4-list, e.g.
(apply 'uread '(foo bar dsk comlap))
or they may be called with the 4-list as four arguments, which is
convenient when calling them from top level.
This function selects an input file. The argument list is a
4-list as described above. The specified file is made the
default input source. Note that the ↑q switch mst be turned
onbefore input will be automatically taken from this file.
Uwrite opens an output file. When done with this file, ufile
must be used to close it and give it a name. The arguments are
the last two elements of a 4-list, specifying the device and
directory on which the file is to be written. The first two
parts of the 4-list are not specified until the file is ufile'd.
(ufile name1 name2) closes the uwrite output file and gives it
the name name1.name2. (ufile) takes name1 and name2 from the
(crunit) gets the current device and directory.
(crunit dev dir) sets the device and directory and returns it.
The arguments are not evaluated. Example:
(crunit) => (dsk >udd>Bar>Foo>subdirectory)
(ukill -args-), where -args- are like uread, deletes the
The value of uread is a file object being used for input
initiated by the uread function, or nil if no file is currently
The value of uwrite is a file object being used for output
initiated by the uwrite function, or nil if no file is currently
There are also some status/sstatus functions associated with these.
These are (status crunit), (status crfile), (status uread), and
.END "hide i/o" ;;
.IF FALSE THEN START "hide editor"
.<< The LISP Editor>>
.sname ← "The LISP Editor"
.BEGIN "editor" VERBATIM SELECT 6
The following is a very brief introduction to the use
of the LISP Editor.
Loading the Editor
------- --- ------
1). To run the LISP Editor, one simply types (EDIT)
or (EDIT FOO) to edit the in-core function "FOO" or
(EDIT FOO FOO BAR DSK (COM RPG)) to edit the function
"FOO" in file FOO.BAR in the directory of COM,RPG.
2). (EDIT) or (EDIT FOO) or (EDIT FOO FOO BAR) or (EDIT FOO
FOO BAR DSK (COM RPG)) can be done in LISP's that have
an autoload property for EDIT. Typing (EDIT) causes the
Editor to be initialized and entered. (EDIT1 <exp>) will make
<exp> the toplevel editable expression. (EDIT2 <var>) will
make (PROG2 (SETQ <var> <current value of var>) T) the
toplevel while (EDIT2 (GET <var> <indicator>)) will make it:
(DEFPROP <var> <value> <indicator>).
How to Look at the Current Expression (CE)
--- -- ---- -- --- ------- ---------- --
P prints the CE using the current print depth
(sublist cutoff) and print length (length cutoff)
PP pretty-prints the entire CE
PS pretty-prints the CE using the print depth cutoff
W prints the "window" surrounding the CE. Thus if
window size is 2, it prints the 2 preceeding and 2 following
tokens around the CE, where "token" means expression or
changes the window size to n.
(PL n) changes the print length to n (initially 5)
(PD n) changes the print depth to n (initially 2)
Changing the CE
-------- --- --
(CR E1...En) changes the CE to E1...En (i.e. splices in
E1...En), and makes the CE E1.
(n E1...En) n>0, changes the n-th element of the CE to
(n E1...En) n<0 changes the n-th element of the CE from the
end to E1...En
(n) n>0 deletes the n-th element of the CE
(n) n<0, deletes the n-th element from the end
RI moves the right parenthesis in one expression
RO moves the right parenthesis out one expression
LI similar to RI
LO similar to RO
DELETE deletes the CE (if the CE is the toplevel
expression, the Editor assumes that the user
wants to edit a different function and requests:
(function name <file specifications>):
The answer can be of several forms; examples:
1) FOO - loads FOO from core
2) (FOO FOO BAR) - loads FOO from FOO.BAR
3) (FOO BAR DSK (COM RPG)) - loads FOO from FOO.BAR in
the directory of COM,RPG.
4) NEW - gives a fresh top-level expression
5) cntrl-G - quits back to the Editor command decoder
6) UNDO - <see below>.
Moving around within the Expression
------ ------ ------ --- ----------
n n>0 makes the new CE the n-th element of the CE
n n<0, makes the new CE the n-th element from the end
of the CE
↑ makes the CE the immediate parent of the CE
TOP makes the CE the toplevel expression
NX makes the CE the next one after the CE
BK makes the CE the one before the CE
MARK marks the current location so that it can be JUMPed
to by the command JUMP. Note: MARKing and JUMPing
is not guaranteed to work in all cases, since
modification of the thing being edited can render
the MARK meaningless.
JUMP jumps to the last MARKed location
UNMARK forgets where the last MARK was set (speeds
(A n E1...En) puts E1...En after the n-th element of the CE
(B n E1...En) puts E1...En before the n-th element of the CE
(AI E1...En) puts E1...En after the CE and makes E1 the new CE
(BI E1...En) puts E1...En before the CE and makes E1 the new CE
(R exp1 exp2) replaces all occurrences of exp1 with exp2 in the CE, viewed
as a list, returns nil? if no occurrences found
(TR exp1 exp2)replaces all occurrences of exp1 with exp2 in the CE, viewed
as a tree
Finding Expressions (i.e. changing the CE)
------- ----------- --- -------- --- --
(F pat) finds the next occurrence of pat, searching in
(BF pat) finds the next occurrence of pat, searching in
inverse print order
(F pat T) finds the next occurrence of pat but looks at the
topmost elements of the CE first (useful for
getting to PROG tags)
(BF pat T) similar to above
(F pat n) finds the n-th occurrence of pat
(BF pat n) similar to above
F finds the next occurrence of the last search
BF similar to above
Pat, as used above, can contain any of the following:
Element of pat What it matches
------- -- --- ---- -- -------
atom atoms EQ to it
list calls matcher recursively
? any atom or single list
(i.e. an s-expression)
?X any element; binds ?X to
whatever it matched
* any non-empty string of
*X matches as *, but binds *X to
the list of elements it matched
=?X whatever ?X matched last time
=*X whatever *X matched last time
(RESTRICT ? P1...Pn) any element satisfying the
($R ? P1...Pn) same as above.
(RESTRICT ?X P1...Pn) similar to above but binds ?X
to what it matched.
($R ?X P1...Pn) same as above.
Note: (A ?X IS A ?X) matches (a word is a word) but
not (a word is a sentence). Simlarly for (*X is a *X).
Invoking the Matcher
-------- --- -------
(MATCH pat) attempts to match pat against the CE
(MATCH pat var1 ... varn) attempts to match pat against the
CE while retaining the values of the
variables var1,..., varn. (E.g.
(MATCH (* *A *B ?A) *A ?A).
MATCH attempts to match the last pat against the
CE. Like F and BF above.
REMATCH attempts to get the next match of pat against
the CE. Usually this only makes sense if
pat contains some * variables.
(REMATCH var1 ... varn) rematches but will retain var1,...,varn.
Hairy Matching Uses
----- -------- ----
(PR pat) replaces the CE with the instantiation of
pat (substitutes the values of ?-variables
(PA n P1...Pn) similar to (A n E1...En)
(PB n P1...Pn) similar to (B n E1...En)
(PAI P1...Pn) similar to (AI E1...En)
(PRA exp1 pat) similar to (R exp1 exp2)
(TPRA exp1 pat) similar to (TR exp1 exp2)
(SAVE <file specs>) saves the toplevel expression
in the file given by the file
specs (will create files not
SAVE saves the toplevel expression
in the file last saved in. If
there was none, the file spec.
(REFILE FOO <file specs>) replaces the function FOO in
the file given by the file
specs with that found under
the "draft" property of FOO
(REFILE (FOO1...FOOn)<file specs>)
similar to above but refiles
(REFILE (FOO1...FOOn)<infile specs><outfile specs>)
(REFILE * <infile><optional outfile>) updates every function
similar to above but files the
result in the outfile
REMEMBER puts the toplevel expression
under the "draft" property
(preserves DEFUN format and
OK REMEMBER's and EVAL's the
(i.e. defines the function as
well as remembers it)
(COMMENT T) allows comments to be in the
toplevel expression (uses the
(COMMENT NIL) disables above
HELP either provides helpful
information or confuses you
The Undo Feature
--- ---- -------
The Editor allows the user to "undo" any editing he has
done. Thus if he has made a mistake or simply is
experimenting, he can invoke the undo feature to undo each
step. However the undoer requires a history of the edit to
be kept and so uses a lot of space. Be warned!
(UNDO T) enables undoing
(UNDO n) enables undoing with only the last undoable
commands being saved (initially 6.)
(UNDO NIL) disables undoing and flushes the undoqueue (the
UNDO undoes the last command. Successive UNDO's will
undo prior edit commands.
The following commands can be undone:
↑ TOP RI RO LI LO NX BK BF DELETE F OK REMEMBER (COMMENT
-) (A -) (B -) (R -) (PA -) (PB -) (PAI -) (PBI -) (PL -)
(PD -) (PRA -) (BF -) (F -) (CR -) (PR -) (AI -) (BI -)
(N -) (N) N (EDPROG -).
Programming the Editor
----------- --- ------
***** Flushed 12/4/76 *****
(EDPROG T) enables the " read-macro
(EDPROG NIL) disables above
***** End Of Flush *****
(EDITCOMMAND A B) a FEXPR which allows the atom A to mean
B in the Editor. For instance,
(EDITCOMMAND LEN (LENGTH %#CE))
tells the Editor that when you type LEN
to it, the length of the CE is to be
It is possible to write LISP programs to do editing:
one can cause the editor to evaluate a command by saying:
(%EVALUATE exp), where exp must EVAL to a valid edit
command. A simple way to abbreviate these calls to the
editor is to define a read macro which expands to the
One may also have an initialization file called
EDIT.INI which will be read when the Editor is being loaded.
This file can either contain functions like any other LISP
file or LINKTO statements, which are of the form:
This statement will cause the Editor to read the files
specified in order. Functions and LINKTO statements may be
interspersed. No FASLOADs may occur in the initialization
file nor in any of the files LINKTOed.
A nice subset of an EDIT.INI file can be seen in
EDIT.IN[AID,RPG] which is documented in
FASMAC.DOC[AID,RPG]. Basically it uses a hoakey fast read
macro facility and allows one to use the control/meta keys
as fast macros to do atomic edit commands with a minimum of
The following global variables are useful:
%#CE contains the CE (munging the CE must be done
using the Editor)
%TOP-EDIT-EXP contains the toplevel expression
%#UNDOLIST contains the undolist
%#UNDOFLAG tells whether or you you are in the undo mode
Exiting and Etc.
------- --- ---
EXIT exits the Editor (to the LISP toplevel)
(EDIT) gets you back to the Editor
(REMEDIT) flushes the Editor.
Any other command is handed to LISP to be EVAL'ed.
.END "hide editor";;
.<< Correspondence about Maclisp Manual >>
.IF FALSE THEN BEGIN "mumble"
∂06-Sep-77 2048 FTP:GLS at MIT-MC (Guy L. Steele, Jr.)
Date: 6 SEP 1977 2231-EDT
From: GLS at MIT-MC (Guy L. Steele, Jr.)
To: CLT at SU-AI
CC: GLS at MIT-MC, ELLEN at MIT-MC
Date: 6 Sep 1977 1318-PDT
From: CLT at SU-AI (Carolyn Talcott)
To: gls at MIT-MC
I am working for JMC putting together notes and manuals for his LISP course
this fall. The manual usd spring quarter contains a copy of part 3 of the
MACLISP Reference Manual dated Feb 1977. I have not been able to locate this
online here and I wonder if you know whether it exists here online and, if so,
on what file. (RPG is away on holiday, so I can't ask him.) Thanx!
Carolyn Talcott (CLT)
The person who is (theoretically) working on the MacLISP manual
is Ellen Lewis (ELLEN@MIT-MC). I'm quite certain that it is all
on-line, and Ellen can probably tell you where. Some parts
have been updated since last spring, and others not.
I can also provide on-line copies of the two papers I presented
at the MACSYMA Users Conference, which dealt with data representations
and fast arithmetic in MacLISP, if you are interested.
∂06-Sep-77 2127 CLT MACLISP Manuals
To: ellen at MIT-MC
Regarding our conversation this morning, We have online
parts 1 , 2 and the Indices from the Draft of the
MACLISP REFERENCE MANUAL dated March 6,1976. The manual assembled for spring term
also contains part 3 dated Feb. 10, 1977. I have not beem able to locate the
latter online here. (RPG is away on vacation now, and no one else seems to know.)
Perhaps you could send any parts that we don't seem to have, or which have been
updated. We need to have things ready for the printer by the end of this week
Thanx a lot,
Carolyn Talcott (CLT)
∂08-Sep-77 1242 FTP:ELLEN at MIT-MC (V. Ellen Lewis) Part 3 of Lisp Manual
Date: 8 SEP 1977 1542-EDT
From: ELLEN at MIT-MC (V. Ellen Lewis)
Subject: Part 3 of Lisp Manual
To: clt at SU-AI
The third part of the LISP Manual, not complete but in much better
shape than that you had for last spring, lives on
as an ascii file. There are a few PUB randomnesses I didn't bother to
sort out (some undefined labels for cross references which at this point
are only cross, they don't reference...), but hopefully nothing too
drastic. You may FTP it, or if you tell me where you want it, I'll
FTP it to you.
∂08-Sep-77 2351 CLT MACSYMA Conf. papers
To: gls at MIT-MC
Thanx for the info on MacLISP the manual. I would like to have copies of
the papers you presented at the MACSYMA Users Conference. Perhaps you
could just send me the file names and I can FTP them.
∂09-Sep-77 0007 CLT MacLISP Manual Part 3
To: ellen at MIT-MC
I have FTPed Part 3 of the MacLISP manual and spooled a hard copy.
Everything seems in order (altho I haven't read the whole thing yet!).
Thanks so much.
∂16-Sep-77 1338 RPG Maclisp Manual
If you are going to re-print the LOTS Maclisp manual,
then you ought to use help.doc[aid,rpg] to update the sections on the
editor and debugging stuff.
∂16-Sep-77 1350 CLT Maclisp Manual
I have copied the Editor section of HELP.DOC[aid,rpg] to include in
the manual. I didn't include the rest as none of those packages
seem to work in the student version of LISP at LOTS and that is
all the manual is intended to document. If you think I should include
the rest let me know.
Also I renamed LSPMAN.PT3[1,clt] to LISPMAN.PT3[aid,rpg] but it dissappeared.
I reFTPed the file and it is again on my directory. Perhaps you could
copy it whereever you would like it and let me know. Then I will delete my copy.
.END "mumble" ;;