This is a read-only archive!

Clojure: 1, Common Lisp: 0

Waaaay back in January 2008 I finished my origami gallery photo-blog, written from scratch in Common Lisp. It took me about a month and half of struggling to get it going.

Shattered Dreams

Ah, to be young again. I was very enthusiastic about learning a Lisp, and Common Lisp was just about the best in town. I'd recently read Practical Common Lisp and maybe I hadn't imbibed the Kool-Aid yet, but I'd sipped it quite a bit.

Then reality came a'knocking. SBCL couldn't run on my server's VPS without hacking and recompiling it (many times) to fix memory-mapping issues and get threading working. Cleanly installing all the necessary libraries via ASDF was a problem and a half. Learning Emacs and SLIME was just about the most painful computer experience I've ever been through.

And those were the big things. There were so many little things. Dealing with pathnames in a language that was written before modern-day pathnames were semi-standardized. Destructive vs. safe list operations. Crappy hash-table support, to the point where I gave up and used lists for everything. CL-SQL, which is pretty good but whose syntax and verbosity and quirkiness leaves much to be desired. (I never got the CLOS stuff in CL-SQL working.)

Trying to wrap my head around macros enough to use CL-WHO effectively (never did get it right). Trying to wrap my brain around CL packages and setting up ASDF to work with my own code (I got this working, but I couldn't tell you how at this point). The list goes on and on.

Once I finished the site, I was proud of slogging through it, but I was also exhausted. Common Lisp is language that looks great on paper but it never clicked with me. I set up some Debian init scripts on my server to make sure SBCL would start if my server restarted, and then I tried my best to forget about it. I was burned out.

Sometime a few weeks ago, my origami gallery stopped working. Nothing but 404's. I'm not sure when or why. I tried running my script to restart the SBCL background process and it died with a Bible-and-a-half worth of errors in SBCL. Sigh. I didn't have the patience or the desire to fix it.

Clojure to the rescue

So, today on a whim I decided to re-write the site in Clojure to get it back up and running, using Compojure, a nice new Clojure web framework.

I'm happy to say I'm already done. My newly-Clojure-powered origami gallery, up and running. Cheerfully untested in Internet Explorer, but works in Firefox and Opera.

Start to finish the whole thing took me 8 hours. That includes time writing that little thumbnail-scrolling strip at the bottom in JQuery, a bit of Javascript to hide and show the comments pane, a new stylesheet, and also a bit of time to resize and touch up a couple of new photos of new models to post. The whole site weighs in at 350 lines of Clojure code, which includes an ORM-ish database layer, all of the HTML (s-exp style) and all the controller code.

It was such a joy to write, compared to my first slog through Common Lisp. But why? I don't feel appreciably smarter than I was a year ago. Why did it take me 8 hours this time but 2 months last time? Probably thanks to Clojure itself.

Deploying SBCL was one of my biggest roadblocks last time. By contrast, installing Clojure is easy, even in its infancy where there are sometimes quirks with SLIME compatibility and such. These problems are always minor and the mailing list is always on top of them.

Installing libs is easy, you throw a jar into a directory and you're done. I deployed everything to my Debian server in 15 minutes, which included installing the JVM for the first time, fetching Clojure and all required libs, compiling them, and setting up an environment. (Pro-tip, there's a new bash launcher script in clojure-contrib now, which makes starting Clojure a bit easier and more standard.)

How do you install MySQL support for Clojure? You don't; you install it for Java. There is official documentation on the MySQL website about getting it to work. It's a single jar file you download and throw into your CLASSPATH. Then get the SQL lib from clojure-contrib; 5 minutes of documentation reading, and I was done. When's the last time you saw official documentation on a vendor's website for a Lisp?

That's how it is with Clojure. Compojure uses Jetty as its HTTP server. Jetty is mature, stable, widely used and very well documented. If we had to wait for someone to write an HTTP server for Clojure from scratch, where would we be? I can't say enough times how great it is to be able to slurp up all the Java resources in the world and play with them in a Lisp.

But it's the little things too, that make Clojure such a joy. How do you concatenate strings in Clojure? (str string1 string2 string3). How do I access the name of a "comment" object? (:name comment). How do I set up Compojure so that when someone accesses the url "/" it calls a function called index-page? (defservlet my-servlet (GET "/" (index-page))).

The Compojure HTML-generating library takes full advantage of Clojure literal syntax so that you can do things like [:a {:href ""} (str "Goo" "gle")] to output an HTML link, using a mixture of vector and hash literals and function calls. This alone makes it far more pleasant to use than CL-WHO (and much nicer than writing raw HTML).

And so on. Easy easy easy.

Example one: What time is it?

Here is an issue that exemplifies the kind of hassle I went through in Common Lisp, that I never hope to go through again. How can you get Common Lisp to tell you the current time, and store it in your database? I use this when people post comments, to capture the time the comment was posted. And some other things.

You can read all about getting the current time in Common Lisp here or here. Ignoring that there are two representations of time to choose from (universal vs. internal), the important thing to note is that neither is easily used for anything. CL-SQL meanwhile has types "wall-time" and "universal-time".

So we'll go with universal time. This seemed to be the most popular way to store a time in a database field, back when I researched it. Universal time is a count of milliseconds since 1900. How do you turn this into something a database can understand as a timestamp, or turn it into something readable for human beings? Many languages stores times in a similar way as a huge integer, but most also give you really easy ways to turn millisecond counts into something legible. Not in Common Lisp. Instead, it's as simple as

    (second minute hour date month year day-of-week dst-p tz)
    (format t "It is now ~2,'0d:~2,'0d:~2,'0d of ~a, ~d/~2,'0d/~d (GMT~@d)"
          (nth day-of-week *day-names*)
          (- tz)))

In other words, it's not simple. At all. Sure it's just a couple of utility functions (and learning the magic, cryptic FORMAT language) away, but multiply a couple of utility functions by the dozens upon dozens of times I have to do this kind of crap for a simple 300-line website, and it turns out I'm not making a website any longer, instead I'm ad-hoc re-writing Common Lisp to do what any language invented in the past two decades can do out of the box. (e.g., in Ruby it's

I never did get this working entirely right for my site. Timestamps worked and were stored in the DB, but they were never in the proper timezone for some reason. I could've fixed it, but it was a low-priority problem below sundry other problems.

So how do you do this in Clojure? When I use the SQL lib from clojure-contrib, TIMESTAMP values in the database end up as Java Timestamp objects in Clojure by the time I see them. You can read about it here in simple, easily-navigable javadoc. I call (.toString timestamp) and it gives me a human-readable version of the time. Or I can just do (str timestamp). Or I can use .toLocaleString (deprecated) or use a DateFormat object if I want anything fancier. The end. Because Java can do it, Clojure can do it.

Example two: Filenames

How do I get a list (or vector) of all the files in a directory? For my photo-blog I use this to get lists of thumbnails for the photos. In Clojure it was simple enough that I wrote it out myself; there may be a shorter way.

(defn glob [dirname] (into [] (.list (new dirname))))

For Common Lisp you probably want to asdf-install CL-FAD, which "Returns a 'fresh' list of pathnames corresponding to the truenames of all files within the directory named by the non-wild pathname designator dirname." What the hell does that even mean? In fact I do know what it means, but only after plenty of reading. Completely unnecessary reading, if I was using any other language.

Just be careful with filenames, because CL has two ways of representing directories, and this also varies between implementations. This is enough of a problem that a whole chapter of PCL is devoted to writing a library to fix it.

I think the reason I got this project done so much more quickly this time is mostly because I'm using a better language for the job.

Update: hi Reddit. Thanks for DDOS-murdering my server. :)

January 18, 2009 @ 6:56 PM PST
Cateogory: Programming


Quoth Alex on January 18, 2009 @ 7:44 PM PST

I can see many places where Clojure can be a better choice than common lisp, but to tell you the truth i think that apart from the fact that you now have the experience in building such website which you didn't the first time you developed it in Common Lisp, if you wanted you could develop that site from scratch in common lisp in the same 8 hrs. I do believe that after one year of playing (even if in and out like me) with common lisp you should be a better programmer overall. Just my 2 cents anyway...

Quoth Basu on January 18, 2009 @ 7:50 PM PST

I'm just learning Lisp properly having spent some time dabbling in Scheme. I've been trying to pick a Lisp to use and I had decided on CL because it's probably the most popular one (and also because of good books). However I do intend to look into Clojure as soon as I'm fairly conversant in the basic Lisp idioms and ideas.

Quoth Troels on January 18, 2009 @ 8:21 PM PST


Quoth Lars on January 18, 2009 @ 8:47 PM PST

Ah, so you figured you'd pretty much jump straight to Common Lisp without having done much programming before.

Ah, so you figured that'd make everything easier/better.

Ah, but you see -- it only makes things easier/better/possible for people who already have hard earned experience.

..and since you don't have it, you must earn it at the same time as you're learning and doing Common Lisp and that's hard no matter what.

You're another clueless kid troll; you should join comp.lang.lisp and help destroy and water out the already small community of lispers. There seem to be plenty of people willing to do this, so don't hesitate to join in.

Frank Shearar
Quoth Frank Shearar on January 18, 2009 @ 9:05 PM PST

I'm new to lisping, myself. I've felt some of the pain Brian's felt (I'd already been using emacs for a while so at least I didn't have THAT to deal with).

I found myself wanting to justify CL while reading this post but you know, in a way Brian's right. It feels "unfair" that Clojure can simply call out to Java (thus leveraging all those lovely libraries) but hey, that's life.

And you know, if I had to choose between working in Clojure or working in Delphi (my dayjob language), I'll take Clojure, thanks.

Quoth e-tate on January 18, 2009 @ 10:15 PM PST

@Lars: I've used CL for the past 4 years, sometimes in real-time critical production code. To be honest, the CL nuances that the OP doesn't like, I almost agree with him. E.g: SBCL does have limited threading capabilities and sometimes requires compilation. The Edi Weitz branch of web libraries are not IMO very clean (dispatches stored in a global list?? etc), compare the code to AllegroServe for example. There is no precise timing function(SBCL internal-time-units = 1000) that is available save as a compiler hack / C binding (as in gettimeofday). And pathnames are still sometimes odd to work with (completely portable - rarely).

Where I disagree with the OP is in his conclusion: "I think the reason I got this project done so much more quickly this time is mostly because I'm using a better language for the job."

You probably got it done quicker because Java has many more libs than SBCL, and SBCL is not supported by a major company in the way the JVM is. Clojure is still lisp, it just has very nice concurrency, and a flowery-eyed newb tailored website. Try using AllegroCL and I can guarantee you a better experience.

Quoth Lars on January 18, 2009 @ 10:21 PM PST

@e-tate: If you can't figure out a way to work your way around the dispatch mechanism of Hunechntoot to do things the way you want to do them (say, "less global'ish") you're screwed by-default.

Quoth Lars on January 18, 2009 @ 10:22 PM PST

heck .. it's not even about "working around" .. it's explained in plain english in the hunchentoot docs (as i suspected while writing the first post but did not check until now..)

Quoth Lars on January 18, 2009 @ 10:26 PM PST


go back to comp.lang.lisp, retards .. none of you are unable to do anything but troll troll and troll .. and bitch and complain .. sheesh .. you could have written your own http server in common lisp in 2-3 evenings that do exactly what you want with no problems at all some time within those 4 years, e-tate .. (i did this -- anyone can do this) .. it's friggin' hopeless ..

Quoth GT on January 18, 2009 @ 10:33 PM PST

"I think the reason I got this project done so much more quickly this time is mostly because I'm using a better language for the job." I'm not so sure. I think the reason has more to do with experience (reimplementation is always a lot faster than implementing something for the first time) and familiarity with the toolchain (perhaps lack of it for CL, but I suppose you have decent knowledge of Java, and I guess you've run up the obligatory hours of messing around with CLASSPATH and build.xml and whatnot while learning that language/toolchain, like everyone else.)

None of your comments apply to the CL language per se, but rather to the standard library. Of course it is dated, and I really should wish the CL community got its act together and made a set of officially sanctioned high-quality libraries for common purposes: dates/times/calendars, files/directories, XML, networking, SQL (with pluggable drivers, perhaps split between low and high-level functionality)...

I know libraries exist for a lot of stuff, but most seem to be hobby projects done in someone's spare time... Perhaps could be used to standardise interfaces and get people involved in projects - just like RFCs and SRFIs have worked for other communities?

Another Alex
Quoth Another Alex on January 18, 2009 @ 10:43 PM PST

I don't want to quibble about installation issues and how much ASDF sucks (for which there are many reasons), but I do take issue with your timestamp example. The issue is, essentially, that you don't like that there isn't a languge-supplied way to go from an internal representation of the current time to a human-readable string, and so you need to write a routine to do the conversion. (I understand it's only an example; my response applies to the whole family of objections.) But, to my mind at least, that's a ridiculous objection: I almost never want exactly the timestamp format that some canned routine gives me. Sure, if I'm using a database, it'd be handy for the database library to provide a utility routine to generate SQL timestamps, but there's absolutely no reason for a generic "toString" method to do what I want in any given circumstance. What CL does is exactly the right thing: provide a primitive that gives easy access to a parsed representation (multiple values are much nicer to work with than nine seperate accessors), and provides a powerful, general-purpose formatting language for turning it into whatever kind of string you want. I'll grant that FORMAT strings can get hairy, but in the simple case (as in the example you provided) they're not any worse than C's printf, and in the complex cases (e.g., iteration, conditionals, etc.) they can replace a dozen or so lines of code with a single call.

The point is that CL takes this approach in almost all cases: provide powerful operations that can be easily composed to produce the desired result. I'm not saying that Clozure doesn't do the same: it's a nice Lisp, and takes a similar tact. But what I am saying is that complaining that the language provides primitives that you don't like because they're unfamiliar but doesn't provide a utility routine that will produce results that may be acceptable in some particular case but not in many others is not useful. Java takes the latter approach constantly; it's a symptom of poor design and lack of vision. "I need to solve this exact problem right now," says the Java developer, "but I won't bother generalizing the underlying issue because that seems hard." The CL approach may be unfashionable, but to those of us who have learned to live with its eccentricities, it's exactly the right thing, because once we've learned the primitives, we can construct the particular solution with almost no effort. (And really, your timestamp example counts as almost no effort; it's two forms.)

As for pathnames, one could (and someday probably should) write an entire book on the CL pathname system, and how it's been completely misinterpreted and misunderstood. I don't really want to do that right now, so I'll simply say this: if you're happy working with a piece of structured data (and pathnames are structured, unless you don't have directories, not to mention types, versions, etc.) exclusively in serialized string form, then go to it. Those of us that like structure in our data structures will be over here, happily hacking in CL.

Quoth pete on January 18, 2009 @ 10:48 PM PST

Such vitriol coming from the CL enthusiasts! My experience roughly matches Brian's. I am fond of Lisp but Common Lisp is more of a pain to use than it should be. Clojure keeps the Lisp feel while stepping around most of CL's shortcomings and bringing the language into modernity, and I expect it will become very popular as a result.

Quoth Smalltalk on January 18, 2009 @ 11:18 PM PST

I tried lisp, wasn't my thing. Then I really tried lisp, built interesting stuff and got fairly competent at it. In the end I went back to smalltalk because it's ugly bits are less than the ugly bits of lisp and I can be as or more productive in that environment as I can be in lisp. Even without macros.

Quoth Neonsquare on January 18, 2009 @ 11:19 PM PST

Well - your real point seems to be that its nice that you can use Java libraries when lisping in Clojure. But that has nothing to do with Common Lisp. Clojure is an implementation defined language - so you could compare it with particular implementations. You've compared it to SBCL. Actually your title should be Clojure 1 : SBCL 0 I actually use LispWorks - this implementation makes it easy to call-out to all those fine Cocoa-Frameworks on my Mac. The same is possible with the free ClozureCL. If you want to use Java-Frameworks: Take a look at ABCL a Common Lisp implementation for the JVM. ABCL development has got some momentum again. Having said that: I think SBCL is a better implementation than your article suggested - maybe one has to invest more work in learning this environment than learning a small one like Clojure.

Quoth Kerrisian on January 18, 2009 @ 11:26 PM PST

I believe that people should be given a choice not to use Emacs. ;)

Quoth Lars on January 19, 2009 @ 12:03 AM PST

@Kerrisian (post #15): Yeah, but what are you going to do to see this happen? Do you have anything to offer at all? Perhaps one or maybe two free hands, or money?

Nothing? That's right; I did not think so.

In general you and your "people" do not even exist (your "vote" is annoying noise tbh.) to people like Edi Weitz and others who actually provide or try to provide something.

Really, try doing something remotely similar. No matter what language you use you will find that writing libraries is harder than you think and only a few people can do it so shut your mouth unless you can actually do something yourself or have something to offer to enable people to shift focus on fixing hurdles that are not hurdles to themselves anymore.

..because if you struggle with an editor like Emacs you should just forget about programming and computers or go use something very simple like Visual Basic or PHP which is fine as long as you STFU and start dealing with reality and cut the B.S. complaining, bitching and trolling.

PS: Yes, Reddit; you are 99% weak idiots. The votes always land on the most easy and pleasant ("sounding") way out .. you fat, lazy, fucks.

Quoth e-tate on January 19, 2009 @ 12:10 AM PST

@Lars: And there was I thinking that you may not be a blind zealot. So wrong to presume indeed. I did not flesh out my last argument very well, as I thought that having used Lisp, you would understand what I was talking about.

" If you can't figure out a way to work your way around the dispatch mechanism of Hunechntoot to do things the way you want to do them (say, ?less global'ish?) you're screwed by-default. "

Why should I have to work around the way a library is implemented? The library should be implemented so that I do not have to work around its hacky nature. I hardly think writing your own HTTP server is an adequate solution to the problem, I doubt many people have the time to write their own libs from scratch every time they stumble upon bad design. See AllegroServe for a better designed lib. And PLZ use both libraries more than just 2-3 evenings of hobbyist dev before answering this.

" you could have written your own http server in common lisp in 2-3 evenings that do exactly what you want with no problems at all some time within those 4 years, e-tate "

Yeah, I've implemented a HTTP server in CL too. Is that the point? The point is that the OP has chosen to use Clojure instead of CL because a lot of Open Source CL stuff is not as high quality as what is available elsewhere. This includes SBCL itself, and many open source cl libraries.

You can label me a troll if you wish, but its kind of a retarded way of looking at a point of view don't you think? Especially since I'm a CL programmer. Stop being purposely blind because of your love for lisp and admit to yourself that CL IS NOT perfect.

Quoth Lars on January 19, 2009 @ 12:27 AM PST

@e-tate (post #17):

"Why should I have to work around the way a library is implemented?"

By definition a library like Hunchentoot (http server) should be generic enough to fit many possible ways to use it. Can you provide an example of how you'd like the API to look like and at the same time ensure that it is flexible enough depending on what others want? I bet you can't, or I bet I or someone else would be unhappy with it.

The difference is that some try to improve the situation while others do or provide nothing except their lame pathetic "vote" by ways of leeching onto the biggest and easiest, for now, host then posting about it in public as if this was some sort of grand discovery while in reality they will be stuck at the "next step" something is missing on that particular host just as unable to do something about the situation as they are or where when using CL.

..oh, and did you see my next posts? I mean ... it's trivial. Grow a brain or GTFO.

"Yeah, I've implemented a HTTP server in CL too."

Then what is your problem?

"..and admit to yourself that CL IS NOT perfect."

All this has very little to do with CL or its libraries. Most of you guys suck; that's the problem.

Quoth e-tate on January 19, 2009 @ 12:39 AM PST

"All this has very little to do with CL or its libraries. Most of you guys suck; that's the problem."

Maybe this is your problem, maybe you are a social recluse who programs in a cave somewhere in Tibet. That doesn't really concern me.

"The difference is that some try to improve the situation while others do or provide nothing except their lame pathetic ?vote?"

Yeah yeah, so what have you done to try to improve the situation? Some people try to improve the situation, but then when they stumble upon a challenging problem, they go and tell other people that they have met this problem in order to find out how other people would solve it. Then they talk to you and give up, because you just label them retarded instead of trying to help.

You can create code which will incrementally improve the state of CL. You can also be an elitist idiot in the way that you are, and turn people away from using CL. Do you understand now or are you still not listening?

Quoth Radu on January 19, 2009 @ 1:18 AM PST

My experience with CL was very similar. My headaches were with UncommonWeb rather then SBCL, but the the rest is identical. I'm a bit surprised at the heat Clojure receives from lispers. It's as much a Lisp as anything can be. There have been lisps that compiled to C for decades, and I don't think they got the same flak. Anyways, the reaction of the Old Guys was a lot warmer... closer to hot ( )

I don't suppose you could publish the source code for the clojure version? There's not enough Compojure documentation out there, and I guess it could help...

Also, right now seems to be down :)

rik the vik
Quoth rik the vik on January 19, 2009 @ 1:21 AM PST

Ah, a classic flamewar! Go Lars!

Even if I don't agree with some of the details of the article (it's probably better to pick on your CL implementation rather than CL as a whole), I like the tone behind it. These days people want to pick up a language and get work done. It doesn't mean the language needs to be dumbed down to VB, but we want the tools and libraries we use to help us, not slow us down. The author's implementation of CL seemed like more of a pain in the ass than a time-saver. And let's be honest, the first hours you put in with a new tool leave a huge impression.

Lisp has tons of great benefits, and I'm glad to see projects like Clojure bringing Lisp and functional programming to a new audience.

Quoth Mark on January 19, 2009 @ 1:22 AM PST

Lars is just another basement dweller that does nothing productive with CL.

Quoth Gabe on January 19, 2009 @ 1:30 AM PST

Lars, I hope you're just trolling and not really this bitter.

Quoth ulrich on January 19, 2009 @ 1:42 AM PST

Guys like Lars is why I left CL and moved on. Instead of helping, they "bitch and complain" about other people who they think "bitch and complain". What a recursive troll! Hey Lars, have a sense of humor. You'll live longer!

Quoth Lars on January 19, 2009 @ 1:47 AM PST

@e-tate: "Maybe this is your problem, maybe you are a social recluse who programs in a cave somewhere in Tibet. That doesn't really concern me."

lol .. this is your response? Turns out you serve as a good example yourself of what really is the core of the problem then.

I.e., if you do not "program in a cave" once in a while you are not working on anything of much significance. Ask Rich or Edi or anyone who has created something significant if they have "a cave in Tibet"; they do.

"Yeah yeah, so what have you done to try to improve the situation?"

Tbh., I'm very happy with "the situation":

  • Hunchentoot
  • cl-who
  • Postmodern
  • Alexandria / cl-utilities
  • ..and others, but those are the core of what I use and it is good stuff when you know what you're doing or for someone with an actual brain able to learn something (significantly) new.

Again what I'm not happy about is the more people-oriented part of "the situation"; the lazy complainers and the trolls who do nothing no matter what .. but I guess I've made that clear now.

What I'd like to see improve, in general (i.e, this doesn't exist regardless of programming language), is a better or different way of creating web UIs. I have my own weird wild web ongoing effort for this called SymbolicWeb (and SW-HTTP, which was needed for Comet or "reversed http").

I'm not alone; there are others out there who's actually doing something:

  • Hans is working on Hunchentoot; Edi is busy with other stuff.
  • Attila Lendvai is working on something called WUI and he's doing some crazy cool stuff with a DB persistence layer. It's all open source and public.
  • UCW and/or Lisp-on-Lines is still alive; Drew and a a couple of others is working on it. these are of course only web-related libraries (that's what I pay attention to), but there's other stuff going on also.

"Then they talk to you and give up, because you just label them retarded instead of trying to help."

Yes, good. We don't need and we don't want these people around; they are negative. They will always cling to the easy short-term solution or host then stop at the first hurdle unable to solve anything "within that host" and thus be unable to provide anything in return anyway.

"You can create code which will incrementally improve the state of CL."

It is pretty clear that these people will not do this, and it does not only apply to CL in particular; they cannot incrementally improve any remotely significant library.

"You can also be an elitist idiot in the way that you are, and turn people away from using CL. Do you understand now or are you still not listening?"

Yes, and this is exactly what I want. Better SNR, and less people "in the way".

(..which means i should learn to ignore the massive amount of useless meat posting random junk on the internet anyway..)

Dorkus Maximus
Quoth Dorkus Maximus on January 19, 2009 @ 2:08 AM PST

@Another Alex: You've assumed, as so many would-be Lisp proponents have, that Lisp is unpopular because other people are too stupid to appreciate it. I suppose it comforts you to think so.

Warm fuzzies aside, CL is unpopular because it has a LOT of warts which impede getting work done. The timestamp problem and the filename problem are both good examples of CL's major shortcomings: CL is internally an interesting language, but (1) its connection to the outside world is tenuous at best, and (2) because of political forces, not technical problems, there is practically no hope of ever fixing it.

Now why would a mean old dork say such nasty things about poor little CL ?? Because I am helping maintain a large CL program (Maxima) and the holes in the CL spec, coupled with the balkanization of CL implementations, cause endless trouble, wasted time, loss of hair, swearing, etc. Now before you try to tell me I should just find another hobby, let me explain that I'm happy enough to do the work, it's just your fanboy attitude that really yanks my chain.

Quoth deafmetal on January 19, 2009 @ 2:22 AM PST

This ain't exactly an advertisement for it's strengths:

Service Temporarily Unavailable

The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.

Apache/2.2.3 (Debian) PHP/5.2.0-8+etch13 mod_ssl/2.2.3 OpenSSL/0.9.8c mod_perl/2.0.2 Perl/v5.8.8 Server at Port 80

Quoth e-tate on January 19, 2009 @ 2:50 AM PST

"lol .. this is your response? Turns out you serve as a good example yourself of what really is the core of the problem then."

"I.e., if you do not ?program in a cave? once in a while you are not working on anything of much significance. Ask Rich or Edi or anyone who has created something significant if they have ?a cave in Tibet?; they do."

The cave analogy was constructed for a troll like creature. Tibet was perhaps the wrong word to use, Himalayas would have been better. I hear Yetis reside there. So you misunderstood the analogy, which was created to point at your inability to understand social reality. A newb knows only that he does not know much. Are you going to call him an idiot because he says/does something that he thinks is right and gets it wrong?

"the lazy complainers and the trolls who do nothing no matter what .." "Yes, good. We don't need and we don't want these people around; they are negative." "It is pretty clear that these people will not do this, and it does not only apply to CL in particular;" "Yes, and this is exactly what I want. Better SNR, and less people ?in the way?."

What a depressed world you seem to live in. In my world there are people who get things right, and people who get things wrong. I don't think labeling anyone negatively has ever gotten me anywhere, but best of luck with that.

Quoth Lars on January 19, 2009 @ 3:40 AM PST

"A newb knows only that he does not know much. Are you going to call him an idiot because he says/does something that he thinks is right and gets it wrong?"

Perhaps. There are many types of newbs. I'm yelling into the void, if it hits something or someone then it might be because there is some truth in it; it hit the right type of newb and it applies to him/her. If it hits you because you care about the "wrong type of newb" (thinking all newbs are alike; they should be treated equally from the start) then maybe that's not such a good thing, or it might be unclear or a misunderstanding.

What you mention here sounds like a humble newb; "the good type". Note that all newbs can adjust their attitude and deal with reality. People have got to be realistic; most of the "problems with CL" the author and some others point out here are ridiculous and not even presented or explained properly. These are problems with attitude towards learning something new. A problem is having to label yourself as a newb after not being a newb in something (or many things) for a long time.

"What a depressed world you seem to live in. In my world there are people who get things right, and people who get things wrong. I don't think labeling anyone negatively has ever gotten me anywhere, but best of luck with that."

Actually, people label each other like this and in other ways all the time; it just happens internally some of the time. ..and I don't care much about "going anywhere"; I'm doing ok in my little cave.

Quoth Brian on January 19, 2009 @ 4:16 AM PST

Lars: 10/10, bravo.

Another Alex: Java gives you the same access to the primitives (count of milliseconds) that Common Lisp does. The ideal is to give low-level access, but also give a good solid standard way to access things at a higher level. Dates are not an area where anyone is going to revolutionize the world by writing their own formatting functions. There are only so many ways to output a date. If you hit all of those ways (and still give access to the primitives, just in case) then you have things covered.

The alternative is everyone doing their own thing, and then you need to write a cookbook entry about it. Needless constant re-inventing of wheels, and everyone ends up speaking their own slightly different dialect of CL. This isn't an advantage.

Everyone: Yeah, you DDOSed my server. Sorry, wasn't expecting to be reddit-bombed.

Quoth e-tate on January 19, 2009 @ 4:33 AM PST

Maybe you have forgotten how long you've spent programming in CL productively, and how complex it is to begin with. You cannot tell me it took you 2-3 evenings to grok CL and its portability issues(SBCL, CMUCL, CLISP, ACL, ABCL, ECL, GCL, CormanCL, OpenMCL, ...), asdf & defsystem & cffi / uffi, Emacs + SLIME, cl-ppcre & cl-iterate + x open source lib that you care to use. It took me personally a long time to truly understand the language, the implementations and their pitfalls & their real-time performance, the libraries and their levels of completeness/quality; and I would never be so arrogant as to claim to understand it all. Which is why calling any newb an idiot is self defeating at best - if your aim truly is to get code written in CL. A community is an invaluable help in getting people up and running. You can't expect a total newb to start messing with SBCL sources. The path to knowledge has to be constructed in some way. So I guess what I'm trying to say is, why insult people when you can help them out, given the complexity of starting out in CL. If people were always helpful towards newbs, I'm confident that many fine libs would be written - and a lot of them are not that difficult to write. (see any C binding based lib)

"I'm yelling into the void"

Why not just speak to people normally, as a grown up. I'm fairly certain it would work better than trolling.

Anyway I'm done with this, good luck with SymbolicWeb, I hope it succeeds.

Quoth felzix on January 19, 2009 @ 6:35 AM PST

I had the same experience with CL and am likewise looking at Clojure as a possible solution. I'm not ready to give CL up yet, though, since the problems start to go away as you get more used to it. By far, the biggest problem I've had is asdf. So much so that I only use it when an install script or .deb is provided, and then I'm still treating it hackily.

Packages aren't so hard. See this for an explanation. I still refer back to it occasionally when I forget something, but it details things pretty well. The only real problem with CL packages is that they are more powerful than package systems in other languages. Probably they should be taught as if they weren't very powerful so newbies can use them.

Quoth Justin on January 19, 2009 @ 6:52 AM PST

Tarred with the same brush.

You may have found clojure easier than CL, probably because of familiarity with the project and possibly because of familiarity with java, but every negative point you make against CL arms the luddites agains clojure also. Bear that in mind.

Quoth spispopd on January 19, 2009 @ 6:56 AM PST

Uhm. You want to read and print timestamps? You realise there are libraries for that for lisp, right? (there are several, because standards for timestamps vary)

Big Funkin Polar Bear
Quoth Big Funkin Polar Bear on January 19, 2009 @ 7:31 AM PST

Lars, imagine you are programming people. Being rude and boorish is like programming in VB. Being polite and encouraging others is like LISPing.

Get it?

Quoth Lars on January 19, 2009 @ 9:08 AM PST

Big Funking Polar Bear: "Programming people" does not sound like a good thing tbh. :}

My rants are not very eloquently executed or anything like that, but that's fine. I hope there are some visible points in there anyway.

e-tate: You somewhat missed the point on that http thing I think, but yeah I agree with some of what you say anyway. It might work to some extent but I'm not convinced people really listen much either way, in particular when minor problems (or misunderstandings!) like these are presented as final conclusions instead of questions which would be or lead to something much more constructive. Thanks.

PS: About skill and experience and all that.. I don't know, maybe it'd be a good idea to mention that I view myself as a fairly average Lisper and programmer -- probably a bit on the messy, playful and let's-just-try-and-see-if-it-blows-up side of the scale. I talk sometimes, but I know where I stand and I get annoyed when others don't.

Quoth lawrence on January 19, 2009 @ 9:10 AM PST

Feeding the troll...

Continuing Big Funkin Polar Bear's train of thought: And if you find that you are unable to achieve positive results by being polite and encouraging others and sharing your knowledge: well, that's just because you're a newb, and you should practice more and carefully study the many free examples online. Good luck!

You fail at linux
Quoth You fail at linux on January 19, 2009 @ 9:18 AM PST

Sorry your VPS sucks but if you don't have MMAP you don't have linux.

Quoth Lars on January 19, 2009 @ 9:29 AM PST

@lawrence: Indeed .. think of the poor helpless children!

Probably works wonders in the u-es-end-ayi, true.

Quoth wtf? on January 19, 2009 @ 9:45 AM PST

why aren't you just letting the database tag the column for you with the proper timestamp? even mysql will do that....

Yami King
Quoth Yami King on January 19, 2009 @ 7:36 PM PST

Lol @ Lars, you've got some serious slashing skills..

No really, why the heck would you write a blog post about something this ridiculous. Only one thing can be said about all this and that's: If you can't handle it, don't even try to use it

You can't just go out and tell everyone that CL sucks, because you were to lazy to check why your server came up with 404s. Even the fact that it took you about a month and a half to setup a website, this easy, says enough.

public class Post { public static bool isUseless() { return true; } }

And that's the bottomline.

Quoth Brian on January 20, 2009 @ 2:17 AM PST

@Yami King: You learned CL, Emacs and SLIME from scratch in an afternoon, huh? In fact I could've written the thing in a day in Ruby, Perl, PHP, or (apparently) Clojure, but I wanted the learning experience. If I thought CL sucked I wouldn't have learned it.

In reality I said that CL "didn't click with me", "took a lot of time", "wasn't the right tool for the job". If you read that as "OMG CL SUX" it's your own fault. What's really useless is zealots having a panic attack and starting flamewars on a blog because someone said their religious beli-.... programming language of choice was even slightly less than perfection divinely-bestowed upon mankind.

Being self-righteous on the internet feels good though, I can't say I blame you. Thanks for trying.

@wtf?: Yes, that is what I ended up doing.

Quoth Devin on January 20, 2009 @ 3:15 AM PST

@Lars -- You are the reason most people do not want any part of the lisp community. Seriously, think before you post.

Quoth Lars on January 20, 2009 @ 8:57 AM PST

@devin: Good. Keep away, and spread the word.

Nameless Coward
Quoth Nameless Coward on January 20, 2009 @ 9:43 AM PST

People like Lars is why I don't have an hesitation recommend Scala over OCaml and Clojure over Lisp. I don't see much technical advantage in using OCaml instead of Scala or Lisp instead of Clojure, but Scala and Clojure's community is so much friendlier. Just browse through their usenet postings or idle in their irc channel for a week or two and you'll get a feel for what constitutes as acceptable behaviour in that community.

Nameless Coward
Quoth Nameless Coward on January 20, 2009 @ 9:44 AM PST

s/have an/have any/

Quoth bored on January 20, 2009 @ 9:58 AM PST

so lispers, humor us with your productivity gains, where are the lisp based web applications? I'm bored with the batman metaphors of power in a deep and dark cave unattainable to those not handing over their left nut on entry. Show me the web applications. please, no links to essays.

Quoth Lars on January 20, 2009 @ 10:04 AM PST (FF and IE only for now .. i'm working on other stuff while waiting for data from the client) ..and a couple more .. google around

..and a couple of Intranet projects

keep in mind that clojure is also a lisp, morons

i'm tired of getting mail from this blog now, so i'll unsubscribe or tag-as-spam or whatever

Quoth bored on January 20, 2009 @ 10:16 AM PST

lars, just as i thought. thanks for the laughs, or I should say links.

Quoth Lars on January 20, 2009 @ 11:38 AM PST

fuck you, retard

Quoth Justin on January 20, 2009 @ 12:22 PM PST

bored: Way to go, you are exactly what you claim to abhor. You asked for examples, he gave you some and you choose to disparage his work. What kind of person does that make you or are you childish enough to think that because he was mean first you are entitled.

Clojure has at its disposal a set of libraries, via java, that are well understood and accessible to the average programmer. By virtue of its age, the lisp scene hides the wood with the trees, there are absolutely brilliant libraries out there that take advantage of everything that LISP has to offer and truly give the user the OMG that is awesome moment, but you need to hunt.

My personal choices are:

LISP : SBCL, LISPWORKS, ACL PERSISTENCE : postmodern, elephant, prevalence W3 : Weblocks (Hunchentoot), hunchentoot, AllegroServe (portable)

I am looking at clojure as it develops and I am pretty impressed, but to be honest, the main thing it has done is renew my interest in common-lisp. I'm pretty sure RH would think that was pretty cool.

Quoth Justin on January 20, 2009 @ 12:35 PM PST

Lars: Stop mate, just stop, you aren't going to change any minds with that approach, and anything good you have to say is being lost in the noise.

You love LISP, so do I, but Clojure is more approachable to common or garden programmers because it offers a bridge to the OO model, however broken, offered by Java. Even C++ is moving to multiple dispatch. My hope is that Clojure will be a great success in its own right and for some people will be a gateway to CL.

Quoth bored on January 20, 2009 @ 1:04 PM PST


I'm entertained by lars crotchety nature, never said I abhorred it, many of my pets behave in this manner. I'm in sync with your inclination to clojure but prefer the term clojurist, not lisper.

Quoth bored on January 20, 2009 @ 1:23 PM PST


where are these hunters and the web applications they built with the wood they found?

Quoth Justin on January 20, 2009 @ 1:53 PM PST

They are out there.

Personally, I rewriting a small auction APP for my kids school, the original application was in C# (WinForms & NHibernate), over the last couple of weeks I have converted it to Clojure (Compojure & JDBC) and am now porting it to CL using (weblocks & postmodern (I would use Elephant but I need to leverage the existing DB)).

As you might expect the development cycle is shorter and shorter as I am simply re-factoring to a different, and in the case of clojure and CL only very slightly, language. But at no time would I consider this Clojure 0 CL 1.

I have two other nascent projects for which CL and Clojure are in the frame, whether they see the light of day will depend on how much time I can dedicate to them and how well the ideas are received by my, admittedly narrow, focus group (That' my wife and kids)

From the perspective of other web apps written using LISP, there must be nearly as many lame reddit clones written in LISP as in RAILs and Django. But seriously, you are correct, serious examples are few and far between, orbitz engine, but they are there and it is my hope that the number will only grow as a result of Clojure, either in its own right, or as a gateway to CL.

Quoth bored on January 20, 2009 @ 2:30 PM PST


what requirements caused you to migrate from clojure to cl? enjoy the journey with your family.

Quoth Justin on January 20, 2009 @ 2:46 PM PST

I thought you might ask.

There was no hard driver. I really enjoyed using compojure and clojure to refactor the application, but as I said, the more I used clojure the more I wanted to get back into CL.

There was, nee is, absolutely no need to re-factor to CL but I came across weblocks and was very impressed with the idea and implementation (I also looked as lars' symbolicweb.).

I decided that I would like to see how the app would translate to weblocks, it isn't done yet but it looks v. promising.

The next question must be 'How do you have so much time on your hands?', The answer is also why it takes me 5 times as long to code up a simple page as it used to, I am currently on disability and the treatments I am receiving are somewhat, how shall I say, incapacitating, but I am almost through to the other side so should be getting more productive.

Quoth davidC on January 20, 2009 @ 2:47 PM PST

@Justin+Lars: But ehm, why do you wish Clojure to be a gateway to CL? What is so good about CL that warrants it surviving over say Scheme, Dylan or Clojure? (or even at all)

  • Its amazingly static 1000 page spec?
  • Its unhygienic macro system?
  • Its plethora of open source implementations that lack proper support for concurrency / multi threading / GC / Win32 support?
  • Its great type system that mandates beautiful type declarations which make your code look like C?
  • Its friendliest of communities?
  • Its advanced pattern matching capabilities? (destructuring-bind ftw lol)
  • Its relatively superior availability of open source libraries?
  • Its REALLY portable pathnames?
  • ASDF?
  • Paul Graham?

Lars & Justin why not stop and view the world in more than 1D?

Quoth davidC on January 20, 2009 @ 3:05 PM PST

PS: @Brian: Good choice. The only way to write good CL code is to write a function called eval, and another named apply. Then you write an environment structure, a simple GC(see Moon papers), and write your language in that.

But I warn you, it isn't as pretty as using Scheme to begin with.

Quoth Justin on January 20, 2009 @ 3:12 PM PST


As I said I think Clojure deserves to succeed in its own right. For my part I prefer CL.

I have often said, perhaps not here, that my preference would be for Dylan to have succeeded, Obj-C is a nice language but one can't help feeling that the baby was thrown out with the bathwater with regard to Dylan at Apple.

I respect your list and have a few comments.

a. You are correct the language (spec) has been static for a long time, how we move forward from here I am not sure but it is definitely a problem. b. Unhygienic macros can be problematic but they are workable using gensym. c. As to the plethora of open source implementations. I am using sbcl and clozure on the mac and have had no problems porting code between them, although I am very fastidious about using portable LUSP. Yes it's a problem, but its a problem for scheme and Dylan (Gwydion and opendylan are not exaxtly like for like (limited-types, threads, etc...) d. Type system, Fair point, but I don't use it much. e. The community is a problem, almost a big enough problem to drive me away, but amongst the unfriendly people are some nice people. I have seem the same level of antagonism in other forums, especially now that the shine is starting to rub of rails. (My opinion) f. It doesn't purport to have pattern matching, so is this a barb against all languages that don't. BTW I have enjoyed the pattern matching of HASKELL OCAM and ERLANG, but it is not a deal breaker for me. g. Come on, there is crap out there for all languages, LISP has been around a long time and it has it's fair share of crud, but there are some gems. h. I haven't had a problem with pathname to date so I can't comment. i. ASDF is not so bad, I acutally use clbuild as an alternative to asdf-install and mudballs looks intersting. j. Paul Graham. I was pretty disappointed with ARC, although I am reserving judgment for now. PG has definitely been a significant influence on me when I was taking my first steps into LISP but those days are passed. Now I regard him with respect but I would like to think that my own motivation and ideas are what drive me forward.

Quoth davidC on January 20, 2009 @ 3:32 PM PST


Dylan can still succeed, we just need to write a decent implementation, heh.

a. The problem is that no one knows how to move forward from here. This is where the "Lisp is dying" idea began. c. Scheme has PLT Scheme, which is incomparably good. But yes, the code may not be portable to other Schemes depending on which libs you choose to use. Dylan only has two workable implementations, I would certainly not argue that either of them are as good as OpenMCL. e. Paul Graham has created an army of elitist angst teens (ala Lars) fueled by the idea that they are geniuses because OMG THEY CAN CODE IN LIZP LOLZ. Even though it is the language with the simplest syntax and semantics, and the simplest type system. (My opinion) f. Yes. Haskell/ML pattern matching rocks and makes code more concise. g. Okay, there are some good libraries. Which ones are the gems that you are referring to, that eg are not available in every other language? i. mudballs does look like an interesting idea. I think it represents CL quite well.

Quoth Justin on January 20, 2009 @ 11:51 PM PST


I don't disagree with your points and I certainly agree that there are a lot of elitists among the CL community, for my own part I have always taken the view that an expert demonstrates their expertise by admitting the gaps in their knowledge but being prepared to help other when possible. It is the junior and mid level engineers who don't know what they don't know. (You may have noted that I asked Lars to stop. I can't completely flame him out of respect for the fact that he has put himself out there with symbolicweb)

As it stands only the MACRO system, (Scheme / Lisp / Dylan) really sets LISP apart from other languages. The implication is that there is nothing that LISP can do that can't be done in other languages, for instance, WEBLOCKS would be cleaner in scheme because continuations are part of the languages whereas in LISP it uses cl-cont, but to develop weblocks in java / ruby / python would be an imposing (take longer) because of the extensive use of MOP and MACROS.

At the end of the day I love the brevity of lisp ( that includes scheme and clojure ) and for some reason the parentheses dont't bother me in the slightest. I can be incredible productive in LISP although I have experienced similar productivity with HASKEL, the only problem is I have yet to overcome my fear of the mondad.

What does DYLAN need to succeed, well definitely a killer application but probably the following: a. Unification of the distributions. (Nobody knows which to use.) b. Native backends for DUIM for (Windows / Vista, Linux, OS X) c. Port of a webserver / application server, say hunhentoot. d. JDBC like connectivity, ODBC in not good enought, although to be fair someone could throw this together for a specific DB fairly quickly through FFI. 3. Evangelism and this is the key.

David, thanks for the back and forth I am enjoying myself immensely.

David Barker
Quoth David Barker on January 23, 2009 @ 1:34 AM PST

Here's a quick macro to make str for common lisp:

(defmacro str (&rest strings) `(concatenate 'string ,@strings))

With the date stuff I just used the rfc-1123-date function included with Hunchentoot, it takes a universal timestamp and returns it printed as a nice string. (Although to be fair rolling your own function isn't a big deal.)

Three of Coins » Blog Archive » Common Lisp, Clojure, and seriousness.

[...] Brian Carper described a few days ago, how Clojure?is better (for him) than Common Lisp?(actually, SBCL). ?I managed to dig through ensuing flame war, but it seems like nobody in the flame war realized (or it wasn’t stressed enough) that original post is actually comparing apples to oranges, a serious language to a toy language. [...]

Quoth JCG on March 06, 2009 @ 12:12 AM PST

My foreign language preference is French; it took quite a while to learn. Then I was amazed how easy it was to learn Spanish. But then I went back to French and you know what? It was easier too. In parallel, I learned a little Common Lisp, not really up to conversational level. I went to Scheme; it was easier, much easier.... but in returning to Common Lisp, it also had become very much easier and now ditto for Clojure. Meanwhile at my job, I tried and failed to learn Haskell which I imagine to be more like German, but dang it, the Python list comprehensions sure seemed normal afterward, as did the functional things such as map/filter.

My long-winded point is that I agree with those who think that comparing the speed of developing your second web server in Clojure with your first in CL is invalid. The fact is that you'll never again develop your first web server. It might be that you could develop a web server faster in any language. You already know the issues and just as Italian would no doubt be made easier after Spanish after French, so will web sever #3.

I honestly think that Clojure will serve best as a stepping stone to non-Java environments. My gut feel is that the flagrant coupling of Clojure to the JVM rather than using the JVM as more of a library implementation will cost it in years to come when Java falls out of favor. I suspect that old Common Lisp will outlive it. I'll use it in the meantime because I'm either correct that it will be pertinent for the next say five years or that I'm incorrect and it will live a while. Big win / small win - I'll be happy with either.

Bonne chance a tous.

Quoth Martial on March 29, 2009 @ 8:28 PM PDT

Very informative post! About the last comments after davidC's one on the lack of coherent static typing or pattern matching, there's a very good try to renew Lisp in a more functional way with QiII.

It's based on CL so there's no concurrency as in Haskell. I do like the deductive programming and the fact that static typing is optional (start a quick hack is often hard to do with languages from the ML/Miranda family) and proofable. I praise for an implementation of Qi for Clojure.

Quoth Brian on March 30, 2009 @ 7:02 AM PDT

See here for some of Rich's thoughts on OOP and classes/types. Many people are working on type-systems and OOP systems for Clojure including porting CLOS. Not sure if anyone's porting Qi but it'd be interesting.

Quoth Dude on April 06, 2009 @ 8:38 PM PDT

This is not going to be a technical discussion.

To all the communities, and specially @Lars: If you want to bring people to your house, you don't spit on their face. You invite them and offer them your best tea. That's what the rails community did - hey and it worked.

Quoth Curtis on April 07, 2009 @ 10:34 PM PDT

Lars, one of the main reasons to code Lisp instead of Java is that you're trying to avoid doing more work than is necessary. If someone finds Clojure to be less trouble and require less work than CL, then you need to convince them that the amount of work required to do their job using CL is ultimately lower in the long term than it would be using Clojure.

You haven't even tried to do that.

Instead, you seem to be arguing that even if CL is harder to be productive in than Clojure, people should always choose CL because otherwise they're lazy. And stupid.

If you prefer the non-lazy solution as a rule, then you're a shit programmer. Willingness to learn new things, and difficult things, is fine; suggesting that someone with no significant prior investment in either language pick the more troublesome one, even when the power of both is almost exactly equivalent, is just foolish.

I probably won't be taking a second look at CL at all now thanks to your comments (straw that broke the camel's back). The community surrounding (smothering) it appears to be toxic, and I'd never inflict it upon myself when there are other options; I realize most of the people are not like you, but a few rotten apples makes for a pretty shitty pie.

Luckily, asshats like you don't show up too much in the Clojure community, because you're all so damn offended by the fact that Clojure doesn't walk the Lisp party line.

@JCG: I wouldn't hold your breath on that JVM (or Java) going out of favor thing. One need merely take a peek into the business world to see that there's far too much expensive Java code in place to allow the JVM die; even if Java itself gives way, its replacement will have to run on the JVM because of the massive prior investments and interop concerns.

Quoth blah on August 22, 2009 @ 8:06 AM PDT

Curtis: Yeah, going for PHP will save you a lot of time, and when that's done, the next PHP, ad infinitum.

Quoth Jason on February 28, 2011 @ 9:34 AM PST

For time, universal-time is okay (it is about average for built-in time libraries and language), but local-time is the library for handling time:

It solves all the problems you are talking about.