< Previous | Next >
January 8, 2010 12:21 AM CST by psilord in category Lisp

Absinthe and Lisp

Suppose one wants to write a helluva a lot of code in Common Lisp while drinking Absinthe and wishing his life went a different way in some respects.

Now stop supposing.

There are quite a few different implementations of Common Lisp out there. I'm pretty sure they have serious advocates and detailed pros and cons and yadda yadda yadda.... Know what? I don't care. I picked SBCL simply because some nice guy on a mailing list somewhere said a tool called clbuild will help me keep it and a lot of common usage CL libraries up to date and that Emacs' SLIME mode uses it natively. Good enough for me, but initially I'm using vim with Limp instead of Emacs for now.

clbuild is a funny thing. It is pretty damned useful. If you wanted to start from scratch and check it out, this is what you'd do. I'd recommend messing about in a /tmp directory for a while before making a real install so you can learn what happens. Some of this follows the clbuild page, but there is a little more detail one needs to know almost right away that I'll specify. Here is what you initially do:

Linux > cd /tmp
Linux > darcs get http://common-lisp.net/project/clbuild/clbuild
Linux > cd ./clbuild
Linux > chmod +x clbuild
Linux > ./clbuild check

At this point, I would recommend you actually find all of the source control programs clbuild wants and install them into your linux distro. It'll just make the next steps easier because various CL libraries use various source control programs. Let's keep going, first we'll get all of the stable projects, then we'll get and compile sbcl.

Linux > ./clbuild update --main-projects 
Linux > ./clbuild update sbcl
Linux > ./clbuild compile-implementation sbcl

At this point, you're almost done, now comes the fiddly parts. For example, sbcl requires a core file that it unexecs into memory and it has to be told where that core file is. If you do this:

Linux > ./clbuild lisp

then clbuild will know how to invoke sbcl so that it finds the correct core file. If, however, you want to run sbcl on the command line, you should write a little shell script that invokes the right sbcl with the right core file using the --core argument. Due to the semantics of the SBCL command line, this script is slightly harder to write than one thinks, but if you zen the SBCL manual for command line arguments a bit you'll figure it out.

Ok, now, what about other libraries in the wnnp section of the projects? To install these, and I recommend installing them individually as needed, you'd do (for example, iolib):

Linux > ./clbuild install iolib

Here are where things get tricky. The install will go fine, but if you try to (require 'iolib) into your running sbcl--which means sbcl will compile it on the fly, you'll get an error about an unreadable character. It turns out that the iolib library has UTF-8 encoded into its source and it appears the default of sbcl is to accept only 7-bit ASCII input. What to do?

In my case, I haven't started hacking on lisp yet, so I don't have any lisp projects in my .sbcl/systems/ directory to intermix with the sbcl just compiled from clbuild. So, we're going to copy the file clbuild.conf.default to clbuild.conf and comment out the first and second unsets in the new file in order to utilize my fledgling $HOME/.sbclrc file.

Then add this entry into your $HOME/.sbclrc file:

(setf sb-impl::*default-external-format* :utf-8)

This has the effect of telling sbcl upon start up that I wanted a utf-8 reader. After these steps were done it loaded iolib just fine. Since I'm new to Common Lisp and sbcl, this took a bit to figure out.

You probably want a few more things in your .sbclrc file as well, here is what I have in mine:

;; Allow reading of utf-8
(setf sb-impl::*default-external-format* :utf-8)

;; Allow higher precision with floats
(setf *read-default-float-format* 'double-float)

;; Tell ASDF where clbuilds central repository is.
(require :asdf)
(setf asdf:*central-registry* 
	'(#p"/home/psilord/content/code/lisp/clbuild/systems/"))

;; If a fasl was stale, try to recompile and load (once).
;; This fixes the situation when I recompile sbcl with a new revision.
(defmethod asdf:perform :around ((o asdf:load-op)
  (c asdf:cl-source-file))
  (handler-case (call-next-method o c)
                ;; If a fasl was stale, try to recompile and load (once).
                (sb-ext:invalid-fasl ()
                                     (asdf:perform (make-instance 'asdf:compile-op) c)
                                     (call-next-method))))

If you're an emacs user, you can probably do:

Linux > ./clbuild slime

and get a copy of emacs up and running with slime automatically set up and working in it. If you do this method DO NOT follow the setup directions concerning your .emacs file in the SLIME manual. There is some kind of conflict I wasn't arsed to figure out which causes an insane keymapping in your emacs session.

While Limp for vim is actually pretty good (except for what happens when you want to run a personally installed copy of SBCL...), it deviates a little bit in the cultural indention rules for Common Lisp and every person to whom I show my code comments on it and wants to correct it. So, I'm learning emacs for the sole purpose of writing Common Lisp in it just so it'll do the indenting correctly. Emacs was a bit of a bother in the beginning since the non-modal editing commands actually cause more keys to be typed while doing command-like things instead of editing-like things, but I'll get over it.

At this point, you can write some Common Lisp and see things work. I'd recommend going over to this blog post to learn how to use ASDF which describes how your source is organized and is quite useful and commonly applied. I'd also recommend carefully understanding how Common Lisp's packaging system works and how you move into, move out of, and use packages.

Three very useful books are "ANSI Common Lisp" by Paul Graham, which I luckily owned, "Practical Common Lisp", and "Successful Lisp". They are all beginner-ish books in Common Lisp. They overlap somewhat, but in the places they don't it is very instructive.

If you happen to not know much about functional programming, then you should read the Structure and Interpretation of Computer Programs. This wonderful book will give you the knowledge you need. It happens to be written for Scheme, which is a dialect of Lisp, but all of the main ideas of functional programming still apply, there are just some fiddly bits with #' (sharp-quote), argument evaluation order semantics, a very different standard library of functions, and macros of which one needs to be aware.

*sigh* my bottle has an end, my pain doesn't.

End of Line.

< Previous | Next >