Where to Go Next
So, that’s it. Welcome to the wonderful world of Lisp. The best thing you can do now—if you haven’t already—is to start writing your own Lisp code. Pick a project that interests you, and do it in Common Lisp. Then do another. Lather, rinse, repeat.
However, if you need some further pointers, this section offers some places to go. For starters, check out the Practical Common Lisp Web site at http://www.gigamonkeys.com/book/
, where you can find the source code from the practical chapters, errata, and links to other Lisp resources on the Web.
In addition to the sites I mentioned in the “Finding Lisp Libraries” section, you may also want explore the Common Lisp HyperSpec (a.k.a. the HyperSpec or CLHS), an HTML version of the ANSI language standard prepared by Kent Pitman and made available by LispWorks at http://www.lispworks.com/documentation/HyperSpec/index.html
. The HyperSpec is by no means a tutorial, but it’s as authoritative a guide to the language as you can get without buying a printed copy of the standard from ANSI and much more convenient for day-to-day use.12
If you want to get in touch with other Lispers, comp.lang.lisp
on Usenet and the #lisp
IRC channel or the Freenode network (http://www.freenode.net
) are two of the main online hang- outs. There are also a number of Lisp-related blogs, most of which are aggregated on Planet Lisp at http://planet.lisp.org/
.
And keep your eyes peeled in all those forums for announcements of local Lisp users get-togethers in your area—in the past few years, Lispnik gatherings have popped up in cities around the world, from New York to Oakland, from Cologne to Munich, and from Geneva to Helsinki.
If you want to stick to books, here are a few suggestions. For a nice thick reference book to stick on your desk, grab The ANSI Common Lisp Reference Book edited by David Margolies (Apress, 2005).13
For more on Common Lisp’s object system, you can start with Object-Oriented Programming in Common Lisp: A Programmer’s Guide to CLOS by Sonya E. Keene (Addison-Wesley, 1989). Then if you really want to become an object wizard or just to stretch your mind in interesting ways, read The Art of the Metaobject Protocol by Gregor Kiczales, Jim des Rivi�res, and Daniel G. Bobrow (MIT Press, 1991). This book, also known as AMOP, is both an explanation of what a metaobject protocol is and why you want one and the de facto standard for the metaobject protocol supported by many Common Lisp implementations.
Two books that cover general Common Lisp technique are Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp by Peter Norvig (Morgan Kaufmann, 1992) and On Lisp: Advanced Techniques for Common Lisp by Paul Graham (Prentice Hall, 1994). The former provides a solid introduction to artificial intelligence techniques while teaching quite a bit about how to write good Common Lisp code, and the latter is especially good in its treatment of macros.
If you’re the kind of person who likes to know how things work down to the bits, Lisp in Small Pieces by Christian Queinnec (Cambridge University Press, 1996) provides a nice blend of programming language theory and practical Lisp implementation techniques. While it’s primarily focused on Scheme rather than Common Lisp, the same principles apply.
For folks who want a little more theoretical look at things—or who just want to know what it’s like to be a freshman comp sci student at M.I.T.—Structure and Interpretation of Computer Programs, Second Edition, by Harold Abelson, Gerald Jay Sussman, and Julie Sussman (M.I.T. Press, 1996) is a classic computer science text that uses Scheme to teach important programming concepts. Any programmer can learn a lot from this book—just remember that there are important differences between Scheme and Common Lisp.
Once you’ve wrapped your mind around Lisp, you may want to place it in a bit of context. Since no one can claim to really understand object orientation who doesn’t know something about Smalltalk, you might want to start with Smalltalk-80: The Language by Adele Goldberg and David Robson (Addison Wesley, 1989), the standard introduction to the core of Smalltalk. After that, Smalltalk Best Practice Patterns by Kent Beck (Prentice Hall, 1997) is full of good advice aimed at Smalltalkers, much of which is applicable to any object-oriented language.
And at the other end of the spectrum, Object-Oriented Software Construction by Bertrand Meyer (Prentice Hall, 1997) is an excellent exposition of the static language mind-set from the inventor of Eiffel, an oft-overlooked descendant of Simula and Algol. It contains much food for thought, even for programmers working with dynamic languages such as Common Lisp. In particular, Meyer’s ideas about Design By Contract can shed a lot of light on how one ought to use Common Lisp’s condition system.
Though not about computers per se, The Wisdom of Crowds: Why the Many Are Smarter Than the Few and How Collective Wisdom Shapes Business, Economies, Societies, and Nations by James Surowiecki (Doubleday, 2004) contains an excellent answer to the question, “If Lisp’s so great how come everybody isn’t using it?” See the section on “Plank-Road Fever” starting on page 53.
And finally, for some fun, and to learn about the influence Lisp and Lispers have had on hacker culture, dip into (or read from cover to cover) The New Hacker’s Dictionary, Third Edition, compiled by Eric S. Raymond (MIT Press, 1996) and based on the original The Hacker’s Dictionary edited by Guy Steele (Harper & Row, 1983).
But don’t let all these suggestions interfere with your programming—the only way to really learn a language is to use it. If you’ve made it this far, you’re certainly ready to do that. Happy hacking!
1The combination of Common Lisp’s read-time conditionalization and macros makes it quite feasible to develop portability libraries that do nothing but provide a common API layered over whatever API different implementations provide for facilities not specified in the language standard. The portable pathname library from Chapter 15 is an example of this kind of library, albeit to smooth over differences in interpretation of the standard rather than implementation-dependent APIs.
2A Foreign Function Interface is basically equivalent to JNI in Java, XS in Perl, or the extension module API in Python.
3As of this writing, the two main drawbacks of UFFI are the lack of support for callbacks from C into Lisp, which many but not all implementations’ FFIs support, and the lack of support for CLISP, whose FFI is quite good but different enough from the others as to not fit easily into the UFFI model.
4Knuth has used the saying several times in publications, including in his 1974 ACM Turing Award paper, “Computer Programming as an Art,” and in his paper “Structured Programs with goto Statements.” In his paper “The Errors of TeX,” he attributes the saying to C.A.R. Hoare. And Hoare, in an 2004 e-mail to Hans Genwitz of phobia.com, said he didn’t remember the origin of the saying but that he might have attributed it to Dijkstra.
5CL-PPCRE also takes advantage of another Common Lisp feature I haven’t discussed, compiler macros. A compiler macro is a special kind of macro that’s given a chance to optimize calls to a specific function by transforming calls to that function into more efficient code. CL-PPCRE defines compiler macros for its functions that take regular expression arguments. The compiler macros optimize calls to those functions in which the regular expression is a constant value by parsing the regular expression at compile time rather than leaving it to be done at runtime. Look up **DEFINE-COMPILER-MACRO**
in your favorite Common Lisp reference for more information about compiler macros.
6The word premature in “premature optimization” can pretty much be defined as “before profiling.” Remember that even if you can speed up a piece of code to the point where it takes literally no time to run, you’ll still speed up your program only by whatever percentage of time it spent in that piece of code.
7Declarations can appear in most forms that introduce new variables, such as **LET**
, **LET***
, and the **DO**
family of looping macros. **LOOP**
has its own syntax for declaring the types of loop variables. The special operator **LOCALLY**
, mentioned in Chapter 20, does nothing but create a scope in which you can make declarations.
8The FASL files produced by **COMPILE-FILE**
are implementation dependent and may or may not be compatible between different versions of the same Common Lisp implementation. Thus, they’re not a very good way to distribute Lisp code. The one time they can be handy is as a way of providing patches to be applied to an application running in a known version of a particular implementation. Applying the patch simply entails **LOAD**
ing the FASL, and because a FASL can contain arbitrary code, it can be used to upgrade existing data as well as to provide new code definitions.
9ASDF was originally written by Daniel Barlow, one of the SBCL developers, and has been included as part of SBCL for a long time and also distributed as a stand-alone library. It has recently been adopted and included in other implementations such as OpenMCL and Allegro.
10On Windows, where there are no symbolic links, it works a little bit differently but roughly the same.
11Another tool, ASDF-INSTALL, builds on top of ASDF and MK:DEFSYSTEM, providing an easy way to automatically download and install libraries from the network. The best starting point for learning about ASDF-INSTALL is Edi Weitz’s “A tutorial for ASDF-INSTALL” (http:// www.weitz.de/asdf-install/
).
12SLIME incorporates an Elisp library that allows you to automatically jump to the HyperSpec entry for any name defined in the standard. You can also download a complete copy of the HyperSpec to keep locally for offline browsing.
13Another classic reference is Common Lisp: The Language by Guy Steele (Digital Press, 1984 and 1990). The first edition, a.k.a. CLtL1, was the de facto standard for the language for a number of years. While waiting for the official ANSI standard to be finished, Guy Steele—who was on the ANSI committee—decided to release a second edition to bridge the gap between CLtL1 and the eventual standard. The second edition, now known as CLtL2, is essentially a snapshot of the work of the standardization committee taken at a particular moment in time near to, but not quite at, the end of the standardization process. Consequently, CLtL2 differs from the standard in ways that make it not a very good day-to-day reference. It is, however, a useful historical document, particularly because it includes documentation of some features that were dropped from the standard before it was finished as well as commentary that isn’t part of the standard about why certain features are the way they are.