Let Over Lambda by Doug Hoyte
New Lisp books are rare, so this is a big event in my world (think Christmas, graduation and birthday at once and you're close). Let over Lambda is a self-published book of remarkably high quality. The first three chapters are available online, but in a way that's a shame; it's actually after these chapters that the book really takes of.
The introductory chapter makes clear that this is going to be highly opinionated and potentially flammable material. Doug doesn't shy away from breaking well-established Common Lisp idioms and holds strong opinions on both programming and language design (in Common Lisp, these two areas actually converge). Personally, I find it refreshing. At times it's a good idea to challenge conventional wisdom and get another perspective on how to do things. I may not change my initial believes, but at least it gets me to actively rethink my coding habits. That said, you do have to know Common Lisp pretty good in order to know that to sort out.
The book holds a fast pace. After an introduction to Let over Lambda itself (the name refers to the code pattern used to create a lexical closure), Doug dives into the core of the book: macros. And here's the first gem of the book, a small domain-specific language for macro design. It's simple, elegant and a great example of eliminating repetitive patterns in the code. Each chapter in the book builds on the previous one and re-uses the developed abstractions and utilities. This is an approach that works well and relates to real software development.
The fourth chapter stands as the best introduction to read macros I've ever read. The developed macros are a testimony of Lisp's power; with read macros the syntax of the language is extended to allow Perl-like regular expression shortcuts. Another favorite is chapter 6 on anaphoric macros. An anaphoric macro works by deliberate variable capture, effectively making it possible for the user to refer back to the captured variable. Doug combines several macros to achieve clever code and the synergy effects between the macros are impressive. But combining anaphoric macros is not without consequences; what we get is basically highly compressed code that draws parts of its meaning from the surrounding context. Such code violates the lexical transparency and with several captured variables in scope it gets quite challenging to keep a mental picture of it (the problem gets somewhat harder if you follow Doug's style of dropping the *earmuffs* on special variables). Yet, as Doug points out, this is all about power and powerful it is!
After an interesting chapter on efficiency, the final chapter puts all techniques to work on a larger problem - implementing Forth on top of Lisp. Besides fueling my interest for Forth, this chapter demonstrates, more than anything else, the central theme of the book: Lisp can be anything you want it to be.
With the possible exception of the Forth chapter, I was pleasantly surprised by the practical usability of the code. There's a lot of smart code in Let over Lambda, at times even beautiful. I learned a lot from it, but it shouldn't be the first Lisp book you read; you'll need a working knowledge of Common Lisp and a good language reference as much of the code isn't described in any detail. After that, this book may well take you to the next level.
Reviewed June 2008