Sunday, February 21, 2010

Common Lisp Pain

I've been looking for the most powerful toolbox to build my own web projects. For me Java and other JVM languages are out. I played the Java game on and off since 2000. I'm set on using a dynamic language. Ruby and Python, while cool and have extremely active communities, both seem crippled version of Lisp to me. So I've been learning Common Lisp (CL) and looking for a CL based web stack.

CL has been a blast to learn. The Practical Common Lisp book is excellently written and fun to work through. Getting SBCL and Aquamacs set up was fairly easy. Getting SLIME going.... took some work.

Then it gets harder.

ASDF. ASDF-INSTALL. What? What's the difference? What's the relationship? So eventually I *get* that ASDF is just the packaging bit, while ASDF-INSTALL is the downloading bit. ASDF-INSTALL is frankly busted. The web of trust chains back to nothing. And I only found that out after I use ASDF-INSTALL to pull down Hunchentoot and CL-WHO. This bombs horribly for many reasons. Eventually I'm pointed to clbuild. This takes a bit of work and for a while my SLIME is dead. Then the guys at #lisp ask if I installed clbuild's SLIME. OK I do that and now clbuild is working. Clbuild isn't terribly sophisticated though. The whole process of putting your own project in a project and exporting symbols is a bit weak. In this respect Java got it right. Heck, Maven (though a *massively* painful tool to use) gets much closer. Clbuild knows how projects are related, but it does not seem to deal with versioning. It only knows how to pull the latest versions down.

But at least I'm running and now I even get how to use asdf:*central-repository* to bring in my own projects, outside of clbuild's directory tree.

Now I finally get the Lisp for the Web example working. Except embedding Parenscript in a CL-WHO with-html-output form doesn't work for me. Next I add in persistence with Rucksack.

That was more pain because Rucksack's with-transaction inside a with-html-output caused an internal error in SBCL (no stack trace). There was nothing for it but to move code around until it worked. Not a happy debugging process.

Using metaclasses to add persistence is just elegant. I'm in. I've seen the the object-oriented persistence problem solved in many ways. I've even worked on a few object-relational mapping tools. The last attempt was in Scala, and even that wasn't ideal. CL and it's meta-object protocol are up to the task though. Rockin'.

So I get Rucksack working with the example and I feel like I'm getting somewhere. Then I find that Rucksack isn't ready for prime-time; the author doesn't recommend it as a primary datastore.

Hunchentoot with CL-WHO and HTML-TEMPLATE seem cool. I'm looking for a higher level of abstraction though.

Then it gets harder.

I take a look at Uncommon Web. Or I try to. It's really just a bunch of source code. So I'm to master a code base before deciding if I even like it? That's just... dumb.

Next up: Weblocks. More documentation. The articles on are very clear and well written. The widget approach sounds promising. The idea building HTML based on object and view definitions sounds really good. Dynamically created and modifiable scaffolding sounds good (as opposed to Rails style one-time created scaffolding). Even better Weblocks installs with clbuild. The demo even fires up right away. Rockin'. Now we're on to something. So today I try to work through the remaining 3 examples. No go. All are busted.

The simple-blog doesn't show blog entries on the main page. That example uses an XML backed store (cl-prevelance), so I'm not interested (why use XML with in a language based on s-expressions?). The weblocks-clsql-demo example tries to use a missing clsql-fluid package. This doesn't come from clbuild; you need to manually patch your copy of CLSQL. Wait so to use Weblocks with CLSQL, I have to make a code change to CLSQL? That's just... dumb. The final weblocks-elephant-demo uses a symbol, drop-instance, which is not exposed in the latest version of Elephant. Busted. This is exactly the sort of version issue with clbuild I mentioned above. Lame. So Weblocks, though promising, is not maintained in a useful way. Sad.

All in all, CL is feeling very fringe. I see blind spots. CL is the Lisper's Blub.


  1. Very similar to my own experience. Your post saved me a lot of time. Thanks!

  2. As someone who is sort of going down a similar path, I get the feeling that you are thrashing around. From my (long) experience, the pain you are feeling is not unusual for many libraries, frameworks, languages, platforms.

    "I'm looking for a higher level of abstraction though."

    No where in your post do you talk about writing Lisp code. You're looking for plug-n-play components. You're probably looking for Rails.

    That's a cute conclusion, but I don't think you are a 'Lisper'.

  3. You have a talent to step into a hornets nest ;-)

    There is some truth in your post and there is also some truth within the last comment about you actually not writing lisp but trying to play plug-and-play with CL.

    First, its really a good idea to think about CL the language and CL the development platform as two different beasts. The former is standardized, stable and a very flexible tool; the latter depends on many things. There are some projects which make plug&play development with CL as a platform much easier (Quicklisp and Lispy are only two which come to my mind). You can think of this projects as being shrink-wrapped distributions, meeting the same purpose like debian, ubuntu, centos and others do for linux. What you actually tried is starting is the CL-equivalent of building your own linux-distribution without prior experience with it. Not a good idea. "CL distributions" like the mentioned ones make your live a lot easier. There still are libraries like UCW (you tried) which are very heavy on dependencies and are actually really more a tool for their maintainers than a marketing campaign for getting lisp newbies. I used UCW for a while and - at that time - one really had to work with the source to get something done. This is not the case for all CL libraries.

    I hope you don't give up on it from your first impressions - it'S really worth the effort - believe me.