Winter 91 - THE VETERAN NEOPHYTE
THE VETERAN NEOPHYTE
LISP, COLOR ICONS, AND LAYERS
I recently started learning Lisp, in order to write
a color icon editor for a project in ACOTSM (that's Apple Classroom of Tomorrow). The people
behind ACOT are creating an environment in which kids can build and explore simulated
ecologies, and I wanted to help, but didn't know Lisp well enough to be of much use. A color
icon editor was needed, and it seemed like a straightforward and painless little project to cut
my Lisp teeth on. Hah.
I did learn lots of Lisp, but I spent a disproportionate amount of time learning the low-level system
interface in Macintosh Allegro Common Lisp (MCL) and wrestling Color QuickDraw to the ground.
For you CopyBits fans, did you know that CopyBits always assumes that the destination PixMap is
on the current GDevice? I guess I already knew this--it's documented all over the place--but the
implications never affected me before. I needed to convert a 4-bit PixMap to 8 bits, so hey, let's use
CopyBits, right? Wrong. The colors got munged every time, because color mapping kicked in and
the source's color table didn't match the GDevice's. For the gory details, see Technical Note #277,
especially the section on color mapping. If you like CopyBits, you'lllove this tech note.
I was curious what others thought of Lisp, so I asked around a little. Here are some of the responses I
Functional languages are cool if you have good libraries, but all those parentheses are a pain
in the ass.
-- Bryan "Beaker" Ressler, C programmer.
It's the shortest distance between conception and realization.
-- Matthew MacLaurin, self-admitted Lisp junkie.
I hate it.
-- Neil Day, who was forced to write the
Tower of Hanoi iteratively in an introductory Lisp course.
It's a great productivity tool, and Common Lisp provides a rich (though perhaps Byzantine)
--Gregg Williams, technical writer and sometime Lisper.
-- Natty, my dog.
There are several immediately apparent things about Lisp that are foreign to people used to C or
Pascal. Data typing is nonexistent unless you want it: Any variable can hold any type of data at
any time. Functions can be data, too, and can be passed around all over the place. Everything is
cozily wrapped in parentheses many levels deep (after a while, this is somehow comforting).
Context is all important and omnipresent. Changes can be immediately tried out, so forprototyping (and for those of us who thrive on immediate gratification) it's a joy to work in. For
those lacking in discipline, Lisp can help to create a real mess (of course, any language can do
that for you, it's just easier in Lisp). Because it is so forgiving, it encourages my own built-in
strategy, which in the long run isn't terribly efficient, although lots of fun. With a little
self-control, of course, this problem would go
away (left as an exercise for the reader).
Writing Lisp code that is QuickDraw intensive is kind of a pain at first. MCL provides great libraries
for basic QuickDraw tasks, but if you want to get fancy, you have to do it yourself. For the icon
editor, I needed lots of little utility routines to do stuff like find a particular color's pixel value in the
color table, add a color to a color table, copy a cicn, change the depth of a cicn, build new cicns
from scratch. Nearly half my code consists of these little utilities. They'd be needed regardless of
the language, I guess, but writing them in Lisp required me to learn the low-level system interface
much more thoroughly than I originally intended. This made me grumble a little, but after I'd gotten
over the initial syntactical hump, low-level access became transparent and largely effortless.
The other half of the code was much Lispier. I used the built-in object system (Object Lisp, since I
was using MCL 1.3.2. Now, in MCL version 2.0, it's the Common Lisp Object System, or CLOS),
and I found that it successfully isolated me from most of the grungy system details like events and
window handling (that's what it's supposed to do, right?).
I haven't done a lot of object programming, so I can't make incisive comparisons with other
object systems, but I liked it.
The sort of layered, threaded structure of Lisp, and the continual "level switching" I had to do
during development, got me thinking about how the machine is getting progressively more distant
from the software I write. It seems that I write software to live on top of other software, not
software to live on a machine. Object programming is a kind of layer creation, in that a well-
designed object hides lots of details from the user of the object. MacApp is a layer (a thick one),
HyperCard is also a layer
(a really thick one), the Mac ® Toolbox is a layer, and so on.
More and more, programmers need to be comfortable stuffed between these layers. Here's the
hard truth: YOU NO LONGER HAVE TOTAL CONTROL OF THE MACHINE. Once upon a time, in
the dim and distant past, programmers had absolute power over every aspect of the computer.
There wasn't even any such thing as a user! A programmer was God in a monotheistic universe.
Now there are all sorts of software smoke screens between your code and the machine itself. You
are no longer God; at best, you are a minor demigod in charge of shoes, or something. A long
time ago I read a discussion of Macintosh programming, and one person compared it to sitting in
a dark closet by yourself, and occasionally answering a note that is passed under the door from
the outside. I think that's exaggerating a little, but the point is valid. You no longer need to know
everything that's going on in the house; you can just be responsible for your own room. At least,
that's the idea . . .
One persistent problem is that you have to depend on the reliability of the other code. When my
icon editor was almost done, I found a memory leak. Two tiny handles were left on the heap after
closing the editor. It took me almost a week (and some expert help) to track it down to a bug in the
MCL object system. Obviously, this diluted the benefits gained by using the system.
Overall, though, I really do think that this division
of labor, this layering, is a good thing. It lets people find the niche they like best, and ignore much
of the rest if they want to. Often it is an incredible time-saver to learn to use others' code rather than
learning to do what they did from scratch. Ideally, the layers will insulate you completely from
irrelevant detail, and allow you to focus on your task. We're not there yet, but someday, maybe,
you can actually stop inventing the wheel.