Lazy Lists
Volume Number: 5
Issue Number: 10
Column Tag: Lisp Listener
(Mumble Paul(About Lisp)) 
By Paul Snively, Wheeling, IL
Note: Source code files accompanying article are located on MacTech CD-ROM orsource code disks.
It’s been a while since anyone has written anything about any dialect of Lisp or,
for that matter, anything that has anything to do with Lisp in MacTutor. This might
lead one to the conclusion that nothing of any importance is going on in the Lisp world,
or with Lisp as it relates specifically to the Macintosh. This is somewhat saddening,
because nothing could be further from the truth.
The most obvious and most visible thing that’s happened in the Lisp world
relative to the Macintosh is that Apple Computer, Inc. purchased the assets of Coral
Software, Inc. in a move that appears to have surprised several people, myself
included. It’s quite rare for Apple to out-and-out buy a third-party
software-development house; my interpretation of the acquisition is that it serves to
prove Apple’s corporate commitment to many different kinds of artificial intelligence
research with respect to future system architectures, and it also serves to prove that
Apple uses Allegro CL on the Macintosh a great deal internally (Apple seems to be a
stickler for having control of the development systems that they themselves use
internally, which is why MPW exists in the first place).
I won’t go into great detail in this space about Allegro CL [for details, see
MacTutor, March 1988]. Suffice it to say that the current version, as of this writing,
is 1.2.2, and that when it ships through APDA it will include the base language, the
Foreign Function Interface that will allow linking MPW C or Pascal code into your Lisp
program, and the Standalone-Application Generator that will allow you to turnkey
your Lisp program. Also available from APDA for twenty dollars will be the current
version of Portable CommonLOOPS, about which I’ll have more to say a bit later.
The other big news in the Common Lisp community on the Macintosh is that
ExperTelligence, Inc. has licensed Procyon Common Lisp from Procyon Re search, Ltd.
in the United Kingdom for distribution in the United States of America. The Procyon
implementation has a great deal going for it, not the least of which is an almost
religious adherence to the specification of Common Lisp set forth in Steele’s Common
LISP: The Language, hereafter called CLtL, which is the canonical description of the
language published in 1984. This is a two-edged sword: there is a fair amount of
Common Lisp source out there that presumes a somewhat more liberal interpretation
of CLtL than the Procyon implementation supports. This is rarely, if ever, damaging
(the only example I’ve come across in actual practice is that FIND-SYMBOL wants an
honest-to-goodness package object as its optional second parameter, whereas Allegro
CL, and apparently most Common Lisp implementations, will allow a package name to
be passed).
Another thing that can be considered a plus of the Procyon system is that it seems
to know a fair amount about the Macintosh as far as data structures are concerned. For
example, Procyon includes a pretty nifty structure editor. A structure editor, as
opposed to a text editor, deals with Lisp data structures in the heap, rather than their
textual representation in a file. One of the interesting things that it does is to treat
bit-vectors, one of Common Lisp’s data types, as bitmaps, providing a fatbits-style
editor to modify the contents of the bit-vector. It’s touches like this that make the
Procyon system a pleasure to use.
In terms of system performance, Procyon and Allegro subjectively seem very
close. Both companies, upon hearing that I intended to write about the two systems,
made comments about how performance could be tweaked out of their systems, but I’m
going to adopt here the attitude that there are really only two levels of performance for
any given system: good enough and not good enough. It’s a subjective measurement
anyway; FullWrite Professional’s performance is “good enough” to me, but I know a
great many people who do not use it precisely because its performance is “not good
enough” to them. To me, both Allegro CL and Procyon Common Lisp perform well
enough.
Another thing about Procyon that you may or may not appreciate is the fact that it
comes with a two-volume set of documentation, and that Procyon Common Lisp’s
DOCUMENTATION function is indexed to the printed documentation (although, happily,
lambda lists for functions are still available online). It’s a good thing that Procyon’s
documentation is so comprehensive and large; the implementation offers quite a few
extensions above and beyond CLtL’s standard definition.
Procyon includes several examples, both of generic Common Lisp programming
and of several of the Procyon-specific extensions, such as the so-called “Common
Graphics” system that implements Procyon’s interface to the Macintosh Toolbox and
OS. Oddly, Procyon, an ostensibly complete Common Lisp implementation, does not
ship with CLtL, a must for any Common Lisp programmer, nor does it ship with any of
the standard Common Lisp-based texts such as Winston and Horn. It’s my opinion that
this somewhat mars the educational value of an otherwise well-documented system.
In the 2.0 release that I received for evaluation, Procyon’s text editor is limited
to a maximum of 32K, a limitation that both Procyon and ExperTelligence assure me
will be removed, if it hasn’t been already by the time of this writing, or by the time it
reaches the shelves. I’m also told that some items, such as a file compiler and an
implementation of the forthcoming Common Lisp Object System (CLOS), are under
development and will either be integrated into the system or available separately for a
modest charge.
Speaking of CLOS, Procyon 2.0 does not ship with any kind of object system,
meaning that it can’t easily be extended to support new types of OS and/or Toolbox data
structures and functions. In fact, there is a fair amount of documentation given
describing how to create custom stream types, since most Common Lisp I/O revolves
around streams. Since there is no object system, adding new stream types seems
needlessly complex and unwieldy, at least when compared to Allegro CL, which allows
you to define subclasses of the basic *STREAM* class and then simply define a few
methods to have a new stream type (a good example of this is given in Allegro’s
Serial-Streams.Lisp source file, which defines a stream type that allows Allegro CL to
do stream-oriented I/O through the serial ports).
Both Allegro CL and Procyon Common Lisp are good, solid, reliable
implementations of the Common Lisp standard, a standard which seems to be of
increasing importance in the world at large and the Macintosh world in particular.
Both will at least consider running on a two-megabyte machine, although realism
dictates at least four to get anything accomplished, and, as with all systems, eight is
something of a dream. Procyon offers a few more tools, such as the structure editor,
and seems somehow “Macier.” Allegro offers an object system, easier Toolbox and OS
access, and feels “Lispier.” Allegro CL also now benefits somewhat from being
supported by Apple Computer, Inc. Individual preference will be the final arbiter in
terms of which system you find yourself using.
[In the late-breaking news department, ExperTelligence will have Procyon
Common Lisp 2.1 available by the time you read this. 2.1 will remove the limitations
noted above, and as a product line is divided into three different levels, as shown:
Personal Professional Developer
Retail: $620.00 $1250.00 $2000.00
Education: $445.00 $900.00 $1450.00
Includes: Procyon 2.1 Procyon 2.1 Procyon 2.1
CLOS CLOS
FFI
Runtime
ID
CLOS = Common Lisp Object System, FFI = Foreign Function Interface, Runtime =
Standalone Application Generator, and ID = Interface Designer.
If the Developer’s version of Procyon sounds intriguing, it should. As you may
know, ExperTelligence’s Interface Designer was the precursor to NeXT’s Interface
Builder, which is a significant element in why the NeXT computer is so easy to
program. CLOS answers my criticisms about Procyon lacking a real object system,
and the FFI and Runtime systems are great if you’re doing serious commercial work.
ExperTelligence tells me I’ll receive a review copy of the Developer’s system once all
components of it have cleared customs as they come from the United Kingdom, and I
will report on them once I have them. Procyon 2.0 owners should call ExperTelligence
at (805) 967-1797 for upgrade information.]
A little bit earlier I mentioned Portable CommonLOOPS in passing. For some
time there has been something of a war waging among a variety of object-oriented
programming systems that have been written in Lisp. Lisp Machines, Inc. (now
defunct) had Object Lisp, which survives in Allegro CL. Symbolics, Inc. and MIT have
Flavors, which is offered by a variety of vendors and is available as an option for
Allegro CL. Xerox PARC has Portable CommonLOOPS, the current generation of what
started as LOOPS, became CommonLOOPS when Common Lisp was defined, and was then
made “portable” in the sense that it has been customized for several of the most
popular implementations of Common Lisp, including Allegro CL for the Macintosh.
One reason that I think Portable CommonLOOPS is important is because it’s a
very powerful, flexible object-oriented programming environment that runs very
well in Allegro CL. The other, and perhaps more important, reason is that an ANSI
committee is standardizing the Common Lisp language, and that standard will include
the Common Lisp Object System (CLOS), and each version of Portable CommonLOOPS
that is released by Xerox PARC is a little bit closer to CLOS, which means that it’s a
little bit closer to the future. Also, Portable CommonLOOPS is in the public domain,
which means the price is right, and you get source code. If you’re thinking about
writing a large object-oriented program in Common Lisp, think strongly about
writing it in Portable CommonLOOPS. That way it will stand a much better chance of
surviving the inevitable transition to an ANSI-standard Common Lisp implementation.
The Portable CommonLOOPS sources are available via anonymous FTP from a number
of UNIX sites on the nets, as well as from APDA (my understanding is that they’ll
charge $20.00 or so for the distribution).
One problem with Portable CommonLOOPS is that the source code is the only
documentation, apart from a handful of release notes that are really only of use if
you’re already part of the “intelligentsia” with respect to Portable CommonLOOPS.
Luckily, since Portable CommonLOOPS is moving toward being a CLOS implementation,
you can largely get away with reading CLOS documentation and applying it to Portable
CommonLOOPS (which is the whole point anyway). To that end, I recommend Winston
and Horn Third Edition to the person who needs a complete Common Lisp text that
devotes some space to CLOS, and Object-Oriented Programming in Common Lisp to the
person who already has a working knowledge of Common Lisp but is perhaps a CLOS
tyro. This book, by Sonya Keene, takes the reader through most aspects of CLOS from
the bare basics to advanced subjects, using examples that actually mean something,
such as process locking and implementing I/O streams within CLOS. Keene, an
employee of Symbolics, Inc. and a member of the ANSI committee responsible for the
CLOS standard and specification, obviously knows her subject well and presents it in a
highly coherent manner.
All that has been going on has not necessarily been going on in the Common Lisp
world, however. Since I last wrote about Lisp in MacTutor, Semantic Micro systems,
developers of MacScheme and MacScheme+Toolsmith, have also been busy. As of this
writing, the current version of MacScheme+Toolsmith is 1.51. This version includes
support for much of Inside Macintosh Volume V; a few new items in the menus, such as
“Load,” which allows you to load a Scheme file without first opening it and without
typing the full pathname in the transcript window; and some new contributed code.
The first contribution is a very nice macro called ExtendSyntax that uses a
pattern-matching system to allow the construction of other macros that extend
Scheme’s syntax. This utility is described in The Scheme Programming Language by R.
Kent Dybvig. It makes writing fairly complex macros much less painful than it
normally is in Scheme. As an example, consider the LET special form. As most Scheme
programmers realize, what LET does is to encapsulate the body of the LET in a lexical
environment, which it then applies to the values assigned to the names. With
EXTEND-SYNTAX, you would express this idea like this:
; Here’s how the let macro could have been defined:
(extend-syntax (lett)
((lett ((x e) ...) body ...)
((lambda (x ...) body ...)
e ...)))
In other words, we’re defining a new piece of syntax, LETT, that can accept some
list of pairs (that’s what the “(x e) ” means) and some body of expressions (the
“body ”) and will expand to “(lambda” followed by the list of the first elements of
the pairs (that is, the names), followed by all the expressions of the body, followed by
all of the second elements of the pairs (that is, the values). In other words,
(lett ((x 3) (y 4))
(+ x y))
would expand to:
(lambda (x y)
(+ x y)
3 4)
This is just a simple example, but hopefully you can see how expressing macros
as syntactical patterns that expand to other syntactical patterns makes macro-writing
much easier.
The other major contribution shipped with 1.51 is a MacScheme implementation
of Texas Instruments’ SCOOPS system. This is the object-oriented programming
system that TI wrote for and ships with their own PC-Scheme system, and Semantic
Micro systems’ own John Ulrich did the MacScheme version. If you’ve never tried
your hand at object-oriented programming and you own MacScheme+Toolsmith 1.51
or later, take a look at SCOOPS. The MacScheme version leaves some fairly important
optimizations out, and unfortunately uses EVAL, which means that standalone
applications generated with it will not have any dead code removed, since the routine
that finds dead code can’t rip anything out lest it be needed for EVALing at run-time.
These shortcomings aside, SCOOPS remains a nice example of how object-oriented
programming can be implemented, and seems to be a fairly powerful system.
All of this assumes that you have some Scheme experience. However, it
sometimes seems that only people who went to MIT or Indiana University to study
computer science have even heard of Scheme. Semantic Micro systems must feel the
same way--they recently announced the introduction of Scheme Express, a compact