John Allen. Anatomy of Lisp. McGraw-Hill. ISBN
0-07-001115-X. 1978.
This is a hard book to characterise. It’s simultaneously an
introduction, a collection of advanced (for the time) programming
techniques, and a guide to some very low-level implementation
details. It contains a lot of the usual introductory material, but
then delves into different representational choices for the basic
data structures – lists, but also arrays and hash tables as well
as Lisp code itself – and for the frames needed to represent
function calls. It the tackles interpretation versus
compilation, and even topics such as cross-compilation and
just-in-time or memoised compilation.
It’s impossible to read this book without thinking of SICP, and
indeed I think in many ways it’s a direct precursor. (It’s
referenced a couple of times in SICP.) It has that same
combination of high-level, semantics-driven programming combined
with descriptions of underlying mechanisms. Where I think it
mainly differs is that it mixes representations, using a more
semantics-driven notation and explicit assembler instructions
rather than sticking with Lisp variants for everything. It’s
only when you see the two approaches side by side that you realise
how clear Lisp can be in radically different contexts..
Another important book was published in 1978: Kernighan and
Ritchie’s The C programming language. The two books share a
certain low-level focus, but come to very different conclusions
about the correct approach to dynamic storage, as the following
footnote by Allen (slightly edited for clarity) illustrates:
Experiments have been performed in which Lisp programmers were
allowed to return “garbage” to the free-space list themselves. The
results were disastrous: list structure thought to be garbage was
returned to the free-space list even though the structure was
still being used by other computations.
C, of course, accepts this “disaster” as a natural consequence of
manual allocation management. It encapsulates the different
attitudes of the two contemporary language communities, though:
one wanting a machine in which to think (and willing to use
computing power to simplify tasks), and those wanting raw
performance from limited hardware (and willing to complicate the
programming task to get it).
Overall, Allen’s book is a great attempt at an end-to-end
discussion of Lisp all the way down to the metal. Many of the
techniques are still relevant, at least as exemplars against
later, more efficient, techniques should be judged.
(Thanks to Paul McJones for pointing me to the free PDF of the book,
which he was responsible for developing. See this post for a history
of how this came about.)