This is a read-only archive!

Emacs continued; Lisp explorations

Thanks to ruben who posted some helpful comments on how to make Emacs buffer switching better in my latest ramblings. My blog like so many others isn't conducive to posting source code in comments, but I googled up a page about iswitch which provides code for enabling and configuring it. It definitely makes switching between buffers nicer.

I also noticed today that Emacs keeps giving me odd errors ever since I put my Lisp code into a Bazaar repo. Again google to the rescue; turns out Emacs is trying to do some funky crap involving my bzr info. You can turn this off in ~/.emacs via

(setq vc-handled-backends (remq 'Bzr vc-handled-backends))

Another annoying thing about Emacs is how it dumps backup files into directories where you're editing files, so you end up with lost~ of~ screwy~ filenames~ all over your filesystem. You can make it put all backup files into a single directory like so:

(defun make-backup-file-name (file)
  (concat "~/.emacs.d/_backups/" (file-name-nondirectory file) "~"))

To be fair, Vim has the same ugly behavior by default, so to make Vim do the same, you need to put this into ~/.vimrc:

set backupdir=~/.vim/_backups

So yeah, the main reason I'm using Emacs at all is that I'm writing Common Lisp, and if you write Lisp you're almost chained to Emacs. Well, you are if you consider your only options to be Vim and Emacs, which I largely do. I'm too much attached to Vim to want to use anything that isn't largely keyboard-driven.

I'm also using Emacs for bragging rights, of course. How many people can say they're good at Vim AND Emacs? I'll have adoring fans lined up by the hundreds just to watch me write code, in awe and wonder. (Yeah, let me keep believing that.)

My goal as previously stated is to write a photoblog website in Common Lisp. I gave this a good try yesterday. I'm largely handicapped by the fact that I don't know Lisp very well, but I got to the point where it could read a directory tree of photos, categorize them and display them in a browser window. I have a lot of work left, but I'm hopeful I'll get this done. It turns out that things I thought would be hard about this were pretty easy, and things I thought would be easy weren't so much.

One thing I thought would be hard was getting Apache2 to talk to Lisp. Given the absolute nightmare involved in getting Apache to work with Ruby on Rails, I was very worried. But using mod_lisp2 turned out to be extremely easy. I have mod_lisp2 talking to Hunchentoot. Both are in Portage:

emerge mod_lisp2 hunchentoot

Then edit /etc/conf.d/apache2 to add the customary -D LISP to APACHE2_OPTS.

Then find a directory that Apache can see, and add this to .htaccess:

LispServer 55555 "hunchentoot"
SetHandler lisp-handler

Replacing the IP and port number if needed. That's all the Apache setup needed. All that's left is to fire up Lisp and start the hunchentoot server from the REPL:

CL-USER> (hunchentoot:start-server :port 55555 :mod-lisp-p t)

And that's it. Now Apache will forward requests to Lisp and render the results. Couldn't be easier.

That just gives you a way for Lisp to serve web pages though; it doesn't give you any kind of framework for building the pages. There's a very interesting series of webcasts involving setting up a web page using Lisp. He uses CL-WHO to produce HTML, which is very similar to the HTML-compiler-interpreter that Peter Seibel goes through in PCL.

So I ended up writing a bunch of code using that library, and a few other helper libraries like CL-FAD to help with pathname manipulation (one area in which Common Lisp is sorely lacking in ease of use, in my opinion). Here's where I started to have difficulties though: loading / requiring libraries in my code. Compile time vs. load time vs. runtime is very blurry in Lisp. Every time I closed Emacs and reopened it and tried to run my file, I'd get all kinds of errors about libraries not being loaded. What I probably need to do is use ASDF to manage all this for me. I must say that even though this is a hassle, it's nowhere near the hassle of trying to resolve dependencies in, say, C++.

Another problem I ran into was that some of my macros were bombing at load time because of functions not being defined soon enough for the macros to use. What I think I need to do there is use EVAL-WHEN as per chapter 21 of PCL.

So yeah, something as simple as loading and running a file full of source code isn't exactly trivial in Common Lisp. For someone like me who's used to writing a Ruby script, and then running the thing from the command line and having Ruby start and load my script and run it and stop, it takes a lot of getting used to a persistent environment like Lisp gives you. But there are also advantages. Being able to fiddle with the guts of your program while it's running is a lot of fun and very powerful if you know how to use it properly, which I largely suspect I don't, but hopefully I'll learn.

December 16, 2007 @ 11:38 AM PST
Cateogory: Programming