For the past few days I've been reading Paul Graham's classic On Lisp, a book I've wanted to read for a long time but, until now, lacked both the Common Lisp chops to understand it and the time to spare.

It's a wonderful book, supremely relevant to anyone who has learned the "basics" of Lisp and wants to move on to bigger things. The first few chapters are about advanced usage of functions, but most of the book is about the thing that truly makes Lisp special: macros. Macros are a facility for extending the language, allowing the programmer to build "on Lisp", creating utilities, domain-specific languages, and even full-blown implementations of systems like Prolog.

I have tried to implement the various macros presented in the book. Initially, my strategy was to read about a macro, then try to implement it myself without looking at the book's implementation. However, this made for painfully slow reading, so I quickly began to skim the various chapters to get an overview of everything before I doubled down on a particular topic.

Why is trying to implement something yourself painfully slow? Because you're truly learning. Doing it yourself requires understanding every concept and paying attention to every detail. Of course, if you've exhausted your efforts, it's time to take a look at the solution–but not before then.

This is an unfortunate parallel between physical and mental training: you only grow when you've pushed yourself to the limit. Everything up to the limit is previously-trodden ground, and will at best maintain, not improve, your condition.

In this spirit, I have decided to try to implement zippers, based on Gerard Huet's paper, in Emacs Lisp, using Clojure's [[https://github.com/clojure/clojure/blob/master/src/clj/clojure/zip.clj][clojure.zip]] and Daniel Martin's [[https://github.com/danielfm/cl-zipper][cl-zipper]] as guides. By actually trying to implement everything from scratch, I have already found some bugs in cl-zipper.

What this shows, I think, is that code review is truly effective only when two or more individuals try to do the same thing, then review each other's code. If the reviewer hasn't tried to do the task themselves, it's unlikely they'll understand all the intricate details.

There's a snowball's chance in hell this will actually happen at any company, of course, since it's prohibitively costly in time (and therefore money). For projects, in which you've only got one chance to do it right (like landing on the moon), however, this sort of parallel effort, followed by mutual review may be a good way to prevent errors.