Friday, December 23, 2011

Does Clojure fix "Fundamental problems with the Common Lisp language (citation)"?

I was looking for some Common Lisp libraries to implement an idea of mine. For lots of reasons I was considering not using Python or Clojure and going directly with Common Lisp (in fact, I think it is going to be Scheme... but it is hard to tell).

As it often happens when following semi-random links on Google, I stumbled on something quite interesting:
Fundamental problems with the Common Lisp language

Nothing extremely new, indeed. The only point that really surprised me was the "hard to compile efficiently" thing. I would have said that in general SBCL is a pretty fast environment. Not as fast as C++, perhaps not even as Java (but I believe that this depends from the specific benchmarks used), but still fast.

However I was mostly interested in the other claimed problems:

  1. Too many concepts; irregular
  2. Hard to compile efficiently
  3. Too much memory
  4. Unimportant features that are hard to implement
  5. Not portable
  6. Archaic naming
  7. Not uniformly object-oriented
May seem like a lame argument... but I think that clojure actually addresses all the problems but number 2 and 3. Please notice that I'm not claiming that clojure is a memory hog or that it is slow. Simply put, right now my impression is that common lisp is still faster than clojure. I believe that this is due to Clojure being an additional layer over Java. Java is itself probably marginally faster than SBCL (though your mileage may vary). With marginally faster I mean that really depends on what you are doing and one or the other may result faster.

Alioth benchmarks are, like all benchmarks, not extremely relevant. Still, this is my general impression. SBCL does a wonderful job, in that CL is much higher level than Java and there are many more engineers optimizing the JVM. However, Clojure takes its toll, in that, according to my tests (and to alioth as well) there is quite a lot of work to do to make it catch up with Java.

Probably for high level stuff or specific problems (where in Java there would be essentially some part of clojure runtime/libraries to be re-implemented) they are on par.

About the memory, my feeling is that JVM is a rather memory intensive business, and Clojure can't do much about it. E.g., Python programs usually run using much less memory when confronted with similar data-sets.

I'm not saying that we should drop CL and switch to clojure. However, I believe that clojure addressed some of the problem that many (some?) in the CL community feel CL has.

2 comments:

rara avis said...

I disagree. In order:

1."Too many concepts; irregular". Clojure has actually *more* concepts than CL, and way more than Scheme.
2."Hard to compile efficiently". As mentioned above, Clojure is much slower than CL; and good CL compilers do in my opion an amazing job, by generating code that is about 2x slower than C. I can't recall speed being a problem in Lisp.
3."Too much memory". CL is a memory hog for small sources, but marginal memory consumption is not high; any JVM-based language has high sunk memory costs *and* high marginal costs.
4."Unimportant features that are hard to implement." Point taken, and advantage Clojure. That's a problem for the writers of compilers though. The final user doesn't care.
5."Not portable".Point taken, and advantage Clojure. The flip side of this is that Clojure is not standard-defined, and there is only one implementation. Do you want to write critical code for the long run in such a language? I think Perl and the health perils of Larry Wall should serve as a cautionary tale. One the other side, clean Common Lisp written today will run with minor modifications in 50 years. Guaranteed.
6."Archaic naming". This seems a very minor annoyance. Just a handful of names, which become soon familiar. On the other side, Clojure is guilty of *renaming* a lot of functions, which seems downright stupid.
7."Not uniformly object-oriented". I think it's much more conform to the spirit of Lisp to build an object system on top of the language rather than in the language; and CLOS has very consistent syntax, and (personal preference) better than Clojure. On top of that, objects in functional languages are vastly overrated.

As you, I am not saying that there is a strict ordering between Clojure, Scheme, and Common Lisp. Clojure has brought people closer to functional programming, and it's a Lisp. It's not growing at the expense of the other dialects, but rather it may increase their user base. However, this goes both ways. Clojure has shortcomings of its own. Simply put, one should select the Lisp dialect based on the project at hand.

Unknown said...

1. I agree that scheme has way less concepts than Clojure and CL. I am not entirely sure how we should "count" the concepts.
However, I kind of think that Clojure has still less stuff than Common Lisp. Of course both being Lisps this should be taken carefully, it is entirely possible that most CL concepts have been ported to Clojure, thus making Clojure actually bigger, for example.

What I mean is that Clojure is a relatively simple language. Common Lisp has a lot of legacy, there are many ways to do things, and, at least to me, it is not entirely clear which one is the correct one. The main problem I feel in Clojure (and that is probably what makes you say that clojure has more concepts) is that it borrows lots of stuff from Java.

Stuff that really look out of place sometimes and does not seem to play nice with Lisp. Moreover, Java interactions led to some concepts which would not have necessary otherwise. I don't particularly like that part of Clojure. The thing is, we need that to have it play not too bad with Java.

In fact, one of the reasons I especially liked Joy of Clojure was that it leaves Java interaction out for most of the book, and that way the language is really small and clean.

2. I tended to agree. However, the points were not mine. I just reported them. I do not know how they are widely acknowledged in CL community. Besides, I would like to know what do you mean with 2x slower than C.

If for example we consider Alioth, your claim is true. But then also Clojure looks like 2 times slower than CL (while I would have said that it is an order of magnitude slower).

In fact, I really do not have precise ideas on this. My gut feeling was that SBCL is fast. So I do not understand that point myself.

3. This is of course true.

4. Usually it is so. However, sometimes this kind of features pose severe constraints on the implementation, thus barring possible good and fast ones. Really, CL is an old language, I expect that stuff to exist.

5. I have to say I basically do not care about standard-defined. I have written critical code in not-standard defined languages for the last ten years without any kind of problem. In fact, I may say that the experience has been much more pleasant than writing code for standard defined languages such as C++. About CL, it is true that there is a standard, but it is also true that it leaves out important stuff. That is something I've heard many timidly complain.

I may say that I wrote some cross-platform C code for Prolog (with ffi) and having it work for the major implementations was just a big PITA.

6. Yes it is minor. And I fact I like those names. + caddr is better than first rest rest. Perhaps with a different syntax it would have been possible.

7. This is complex to answer. I don't think that the point is where you build the object system. The problem the author indicates is that it does not interact with the lower levels. For example, in Clojure all the collections work with some basic functions. That makes it transparent with regard to the specific implementation. I think that it is the "good" part of OOP. For the rest, I would not dub Clojure object oriented.

And yes, I agree that OOP is overrated. Still CL does it and does it excellently. It is a pity that some stuff cannot be done (while in principle they could).

And I agree one should choose the dialect based on the project. However, it would be nice if we could choose on our preference about defining features, because otherwise all the dialects are good for every project.