On Lisp is a comprehensive study of advanced Lisp
techniques, with bottom-up programming as the unifying theme. It is
intended for anyone who wants to become a better Lisp programmer.
It gives the first complete description of macros and
macro applications. The book also covers important
subjects related to bottom-up programming, including
functional programming, rapid prototyping, interactive development,
and embedded languages.
The final chapter takes a deeper look at object-oriented
programming than previous Lisp books, showing the step-by-step
construction of a working model of the Common Lisp Object System
(CLOS).
Chapters cover:
The Extensible Language
Functions - explains how Lisp and Lisp programs are
both built out of a single raw material: the function. Like any building material, its
qualities influence both the kinds of things we build, and the way we build them
Functional Programming - describes the kind of
construction methods which prevail in the Lisp world
Utility Functions - describes techniques for
extending Lisp with new functions; how the ability to pass functions as
arguments leads to greater possibilities for abstraction
Returning Functions - shows how to write functions
which return other functions. Macros make the task of combining operators much easier
Functions as Representation
Macros - explains how macros work, gives techniques
for writing and testing them, and looks at the issue of macro style
When to Use Macros - identifies when macros bring
advantages
Variable Capture - Macros are vulnerable to a problem
called variable capture. This chapter is about how to foresee and avoid
them
Other Macro Pitfalls - discusses four more problems
to avoid when defining macros: Number of Evaluations, Order of
Evaluation, Non-functional Expanders, and Recursion
Classic Macros - shows how to define the most
commonly used types of macros. They can be divided into three
categories: macros which create context, macros for conditional and
repeated evaluation, and another similarity between conditional and
repeated evaluation
Generalized Variables - looks at the implications of
setf, and then shows some examples of macros which can be built upon it
Computation at Compile-Time - describes a class of
problems which could be solved by functions, but where macros are more efficient
Anaphoric Macros - shows that variable
capture can also be used constructively
Macros Returning Functions - shows how to use macros
to build abstractions which are equivalent to those defined in Chapter
5, but cleaner and more efficient
Macro-Defining Macros - presents three examples of
macro-defining macros: one to define abbreviations, one to define
access macros, and a third to define anaphoric macros
Read-Macros - discusses read-macros, which do their
work at read-time
Destructuring - combines assignment with access:
instead of giving a single variable as the first argument, we give a
pattern of variables, which are each assigned the value occurring in
the corresponding position in some structure
A Query Compiler - describes how to embed in Lisp a
program to answer queries on a database
Continuations - looks at the use of continuations
in Scheme, which has built-in support for them, and how to use
macros to build continuations in Common Lisp programs
Multiple Processes - deals with a model of
computation in which a computer runs not one single program, but a
collection of independent processes
Nondeterminism - describes how macros can make Lisp
handle another important class of details: the details of transforming
a nondeterministic algorithm into a deterministic one
Parsing with ATNs - shows how to write a
nondeterministic parser as an embedded language
Prolog - describes how to write Prolog as an embedded
language
Object-Oriented Lisp - discusses object-oriented
programming in Lisp. Common Lisp includes a set of operators for
writing object-oriented programs.
Collectively they are called the Common Lisp Object System, or CLOS
Performance and Evaluation of Lisp Systems focuses on what determines the performance of a Lisp
implementation and how to measure it. It is the source of the so-called
"Gabriel Benchmarks", which are still in use to benchmark Unix systems.
Chapters cover:
Introduction
The Implementation:
MacLisp - one of the first Lisps written on the
PDP-10
MIT CADR - The CADR is the MIT Lisp machine; it is quite similar to the
Symbolics LM-2. Both machines run a dialect of Lisp called ZetaLisp,
which is a direct outgrowth of the MIT Lisp Machine Lisp
Symbolics - an intellectual descendent of the CADR
and the LM-2 but has more hardware support for Lisp
LMI Lambda - the Lambda is a 32-bit microprogrammed processor with up to
64K 64-bit words of virtual control store and a 200 nanosecond
microcycle time
S-1 Lisp - runs on the S-1 Mark IIA computer, which
is a supercomputer-class complex instruction set computer.
S-1 Lisp is almost entirely written in Lisp
Franz Lisp - written at the University of
California at Berkeley by Richard Fateman and his students.
It was originally intended to be a Lisp that was suitable
for running a version of MACSYMA on a Vax
NIL - New Implementation of Lisp, one of the main
influences on the design of Common Lisp
Spice Lisp - an implementation of Common Lisp
written mostly in Common Lisp and partly in microcode
Vax Common Lisp - the first Common Lisp implemented
on stock hardware
Portable Standard Lisp - a ‘LISP in LISP’ that has
been in development at the University of Utah since 1980 and
at Hewlitt-Packard since 1982
Xerox D-Machine
The Benchmarks:
Tak - a variant of the Takeuchi function that Ikuo
Takeuchi of Japan used as a simple benchmark
Stak - a variant of TAK; it uses special binding to
pass arguments rather than the normal argument-passing mechanism
Ctak - a variant of TAK that uses CATCH and THROW
to return values rather than the function-return mechanism
Takl - very much like TAK, but it does not perform
any explicit arithmetic
Takr - a function that was defined to thwart the
effectiveness of cache memories. TAKR comprises 100 copies of
TAK, each with a different name
Boyer - a rewrite-rulebased simplifier combined with a very dumb
tautology-checker, which has a three-place IF as the basic logical
connective
Browse - it is essentially a theorem-proving
benchmark
Destructive - benchmarks the 'destructive' (hence
the name) list utilities. It does this by constructing a tree that
is a list of lists and then destructively modifying its elements.
This manipulation proceeds by means of a fairly elaborate
iterative control structure
Traverse - tries to measure the performance that
can be expected from the abstract data structure systems provided
by the various Lisp dialects
Derivative - performs a simple symbolic derivative
in which the data representation is the usual S-expression
representation for functions
Data-Driven Derivative - exactly like DERIV except
that functions taking derivatives of specific operators are located
on the property list of the operator rather than buried in a piece of code
Another Data-Driven Derivative - a variant of
DDERIV. It optimizes FUNCALL by using a FUNCALL-like function that
assumes it is being handed compiled code
Division by 2 - this benchmark that divides by 2
using lists of n NIL’s
FFT - a FFT benchmark tests a variety of
floating point operations including array references
Puzzle - solves a search problem that is a
block-packing puzzle invented by John Conway
Triangle - similar in many respects to the Puzzle
benchmark, but it does not use any two-dimensional arrays.
Therefore it provides a differentiator between one-dimensional
and two-dimensional array references
File Print - measures the performance of file
output. The program checks to see whether there is a file with a certain name (there should not
be). Then it creates and opens a new file with that name,
prints a test pattern into that file, and then closes it
File Read - tests file input. It reads the file
produced by FPRINT
Terminal Print - tests terminal output
Polynomial Manipulation - computes powers of
particular polynomials
Conclusions
Performance and Evalution of Lisp Systems is released
under the Creative Commons License.
Common Lisp the Language is intended to be a
language specification rather than an implementation specification
(although implementation notes are scattered throughout the
text).
It defines a set of standard language concepts and
constructs that may be used for communication of data structures
and algorithms in the Common Lisp dialect.
Chapters cover:
Data Types
Scope and Extent
Type Specifiers
Program Structure
Predicates
Control Structure
Macros
Declarations
Symbols
Packages
Numbers
Characters
Sequences
Lists
Hash Tables
Arrays
Strings
Structures
The Evaluator
Streams
Input/Output
File System Interface
Errors
Pretty Printing
CLOS, the Common Lisp Object System, with new
features to support function overloading and object-oriented
programming, plus complete technical specifications
Loops, a powerful control structure for multiple
variables
Conditions, a generalization of the error signaling
mechaniss
Series and generators
Plus other subjects not part of the ANSI standards
but of interest to professional programmers