Wednesday, February 6, 2008

CL web adventures

I've been scratching up on Common Lisp, and what better way to do that than to try building a few web applications. Nothing complicated at the moment, just following a few tutorials online, but I did manage to pull together a simple guest-book in about a page of CL code.

Here's what I've done so far:

  1. Learned how to use Swank as a server for SLIME, so I know how to connect to a Lisp instance running remotely now.
  2. Installed Hunchentoot, CL-WHO, and cl-markdown.
  3. Compiled, installed and configured mod_lisp for Apache.
  4. Started learning to use git.

Getting Swank running once you have SLIME installed is pretty easy. What I've been doing so far is firing up my Common Lisp implementation in a terminal (SBCL for those interested), and then run the following commands:

(require 'swank)
(setf swank:*use-dedicated-output-stream* nil
swank:*communication-style* :fd-handler)
(swank:create-server :dont-close t)

I've memorised the above by heart, but you can just as easily put it in a script and run Lisp in the background.

Thanks to ASDF-Install, grabbing Hunchentoot, CL-WHO and cl-markdown was a breeze. It really is as simple as doing this:

(require 'asdf-install)
(asdf-install:install 'name-of-package-here)

ASDF-Install is awesome enough to download dependencies automatically. Initially, it may complain about GPG keys. You can ignore it, but I decided to look into it anyway, because the message that the debugger raised didn't look too hard.

First I needed to make my own public-private key pair:

gpg --gen-key

I just went with the default values for most of the prompts. Then I generated my public key:

gpg --armor --output pubkey.txt --export 'Tung Nguyen'

Then, whenever ASDF-Install complained about not having a key, I'd do something like:

gpg --recv-keys KEY_ID_FROM_CONDITION_MESSAGE
gpg --sign-key KEY_ID_FROM_CONDITION_MESSAGE

If I was happy that the key was from the author of whatever I was downloading at the time, I'd confirm the prompt at the second command. Unfortunately, the "retry" restart for ASDF-Install at that point won't let you go through, but it's a simple matter of aborting the process and retrying the same installation command to get through.

Next, I had mod_lisp to deal with. I've never installed an Apache module before, heck, I barely knew what one was before this. First I had to download the C source file. The instructions at the mod_lisp site mentioned a tool called "apxs", that would handle the compilation of the C source file into a shared object and then install it. It took me a while to figure out that on my Ubuntu setup, it's not included with the 'apache2' package, but in 'apache2-threaded-dev', which totally isn't obscure at all. Then when I ran this command from the mod_lisp site and restarted Apache, the thing still didn't work.

sudo apxs2 -c -i -a mod_lisp2.c

As it so happens, Apache on my Ubuntu Linux system has its modules arranged into directories for small files at /etc/apache2/mods-available, and enabled modules at /etc/apache2/mods-enabled, which just symlinks into some of the files in the previous directory. I copied one of the existing .load files, referring to the new mod_lisp.so file, and after a bit of trial and error, got the thing running.

From there, configuring mod_lisp was easy. I put this in /etc/apache2/httpd.conf:

# Hunchentoot stuff!
LispServer 127.0.0.1 3000 "hunchentoot"

<Location>
SetHandler lisp-handler
</Location>

I initially had a different path for Location, but the Hunchentoot demo is hard-wired to use that particular path, so I changed it back to "/hunchentoot" so I could try it out. Going back to Swank, I fired up Emacs, ran M-x slime-connect, went with the default values at the prompts, and entered the following:

(asdf:operate 'asdf-load-op 'hunchentoot-test)
(hunchentoot:start-server :port 3000 :mod-lisp-p t)

Pointing my browser to http://localhost/hunchentoot showed the demo, which was good enough for me.

From there, I tried out a couple of web applications from tutorials linked from the Hunchentoot website, before trying a simple guestbook application of my own, which brings me up to this point.

I'm learning git so that I can manage the development of a simple centralised issue tracking system, but I haven't gotten very far yet. I've found it easier to simply enter the git commands directly from shell prompts than from the Emacs hooks, so some reading into how to effectively use the version management facilities in the editor is probably in order. We'll see how things pan out.

Despite how old Lisp is as a language, it's quite surprising how active the Common Lisp community is, and how many useful libraries there are available. Even just scratching the surface like I have, there is no way that anybody can claim that Common Lisp is outdated.

2 comments:

Slobodan Blazeski said...

Hunchentoot is very nice, but if you need some widgety thing try weblock, web framework based on hunchentoot and continuations.
common-lisp.net/project/cl-weblocks/

tung said...

Thanks. I've heard of weblocks, but I never felt I had the time to learn how to use it. I really should at some point though.