As I follow the exercises in Practical Common Lisp (PCL) by Peter Seibel, I’ll post the experiences here. Let’s get started.
The Book Itself
is available in dead-tree format and as a series of HTML files. My new Nook is hungry for ePubs, so I downloaded each PCL chapter, dragged and dropped into Sigil, and tweaked the resulting ePub. Sigil has a horrible bug which shoves code blocks way down pages, so my copy of PCL isn’t looking too great. But I plan to write a CL program to restore its former glory.
is an introduction designed to welcome programmers to Lisp. A short summary would be: DON’T PANIC. The intro is humorous and intriguing.
Shit just got real. Now PCL ushers the reader to install Lisp in a box (really Lispbox). Back in 2005, Lispbox was surely a godsend for the budding Common Lisper, but in 2010 it’s not only aged, it’s broken. I’ve already blogged about the pain and agony of setting up a CL system, and I won’t repeat myself. Suffice to say MacPorts is only half a saving grace for Mac users. I’m currently using Aquamacs and Aquamacs SLIME with MacPorts CLISP and Quicklisp besides. My .emacs is pastebinned.
PCL covers the basics of Emacs shortcut keys then jumps to the Lisp interpreter. SLIME is quite helpful in this endeavor, compiling, running, debugging my code for me. I like the PCL’s Hello World is not a program but an expression entered into the REPL. Since half the work will be done there, it’s a good idea to get acquainted with ol’ Reppy.
PCL dives into writing defun’s; introduces the debugger; details the proper loading of source files and optional compilation of same, and ends with a NASA anecdote. A geek such as I couldn’t hope for much more than this chapter.
The first practical chapter. PCL invites the reader to construct a simple music database, introducing Lisp syntacs and semantics along the way. I completed save-db, load-db, … up to update and delete-rows. I’m happy to report that Seibel’s code is clear and concise. PCL suggests using a combination of select and where to simulate a SQL query, with the effect that I almost believe I’m using a real database.
The section, “Removing Duplication and Winning Big” is not easy to skim over, so I’m stuck there for now. It covers Lisp macros, a topic I’ve only heard in reverent whispers.
I’ll let you in on a secret: I’m concurrently reading Real World Haskell. There are notable differences between Haskell and Common Lisp.
Haskell vs Common Lisp
Haskell has one official version (GHC) available on multiple platforms, free, and open source. Common Lisp has no official version. There are Windows-only versions, commercial versions, Linux-only versions with broken makefiles, and CL install kits that once served a purpose but now only serve to mock the senseless diversity of CL implementations.
Installing a complete Haskell environment is simple and painless. Installing Common Lisp took me on a journey.
GHC incorporates new features in each version. Common Lisp’s lack of an official version means that each flavor includes and omits important features. E.g., some come with multithreading, some don’t. ANSI can’t be as responsive as the Haskell community, so the Common Lisp standard will likely not benefit from new features anytime soon.
Haskell stores functions and variables in the same space. Common Lisp does not; it requires ' and #' to pass functions around.
Haskell syntax is light and uniform. By PCL Ch. 3, Common Lisp syntax is starting to slow me down.
Haskell has monads. Common Lisp has macros. More on that when I learn precisely what they are and how to use them.
Haskell’s error messages are somewhat esoteric. Common Lisp’s are more readable.
GHCi’s REPL has enough features to satisfy most programmers. Common Lisp REPLs often fail to include expression history, backspace functionality, and other obvious REPL features. CL REPLs are so crippled that Emacs/SLIME is a necessity.
Both Haskell and Common Lisp syntax are unique, requiring special effort to understand. I believe this is because BASIC syntax is more natural. STEP 1 STEP 2 STEP 3 is intuitive for humans. On the other hand, linear procedures aren’t very powerful. Functional languages have power because they break out of the STEP 1 STEP 2 STEP 3 routine: Spaghetti code is the result of a procedural programmer attempting to do more complex work.
Back to PCL
I’m not sure exactly when I need to #' functions in Common Lisp. While following the PCL exercises, I’ve left out #' for lambdas, and my code gives the same results as Seibel’s. It stands to reason that lambdas don’t need to be #'ed since they self-evaluate. Allegro and CLISP don’t need #' for lambdas, but I’m not sure about other CLs. In any case, I’d like to see a note about this in PCL. Also, I wonder why multiple quote syntaxes exist: ', `, and quote.
Common Lisp Syntax
Look at the code for generating a database query. There are SIX different symbols, each with their own purpose and usage.
(defmacro where (&rest clauses)
(and ,@(make-comparison-expr-list clauses))))
The ampersand in &rest is CL’s way of handling function arguments. &key would interpret the arguments as a property list, while &rest stores all the arguments in clauses.
The #' references the lambda without evaluating it. That is, pound (#) references an unevaluated (') lambda object.
The comma (,) and at (@) work together to force evaluation inside the unevaluated (`#') lambda expression. The lambda would have been prefaced with '#', but ,@ only works inside the backtick quote (`).