Common Lisp vs Clojure

10
4081

I started tinkering with Lisp when I was in college and was easily tempted by the possibilities.  The relationship didn’t last because it simply took too much coding to match the capabilities of the modern programming languages at the time, C++, Pascal and Perl.  When I was hired to work on a Clojure project I was excited to see that Clojure was a Lisp technology that could leverage off of modern technologies.  This relationship soured when I discovered that Clojure not only doesn’t conform to any standard, but has no intention of ever conforming to a standard.  Many will argue that Clojure isn’t proprietary because it is open source, but with a single company controlling it’s development, and no established standard, I argue that Clojure is indeed a proprietary technology that can at any point make fundamental changes which break the functionality of business applications.

Being disappointed with the proprietary nature of Clojure I started looking for a JVM based Common Lisp implementation and found ABCL, Armed Bear Common lisp.  While I didn’t particularly like the name of the application, I could see that this technology appears to be on the verge of being usable for modern applications.  There were two immediate issues I ran into with ABCL, performance and conformance.  Instead of wasting time complaining about these problems I took an active role in trying to repair them.  The performance issues were relatively easy to identify. The system runs with  a giant call-stack and makes excessive use of the java “instanceof” operator which is a very slow operator that can be easily refactored out of code. I also discovered some issues with file IO, specifically regarding the handling of jar files. What I discovered was that it didn’t take a great deal of work to improve the performance of the language.

If the advantage of Common Lisp over Clojure is that Common Lisp is an established standard than conformance to that standard would be a prerequisite to choosing A JVM based Common Lisp implementation over Clojure.  This is the tragic flaw of Common Lisp, and in some ways a well-guarded secret.  ‘Secret’ probably isn’t the best word to describe the situation because many of the developers know that their implementation doesn’t conform 100% to the standard, but instead of solutions to the conformance problems the only thing you will find are excuses.  Even SBCL which is the most commonly used implementation of Common Lisp fails over 50 of the official ansi common lisp conformance tests. ABCL performs somewhat better on these tests but how far is it from 100% conformance? If passing the remaining tests is any indicator I found that it wasn’t very difficult to get ABCL to pass most of the tests. There were 3 tests that I didn’t solve. Two of the failures are because ABCL doesn’t do strict CLOS type checking, which probably isn’t too difficult to solve, but the third failure is with the pretty-printer, and that is the conformance issue that is unbelievably complex.  The complexity of the problem alone can explain why Common Lisp implementations don’t conform to the standard.  Digging deeper into the issue I discovered that some flaws in pretty-printer implementations date back over 20 years.

The most fundamental difference between Common Lisp and Clojure is that Clojure is a Lisp-like language, and Common Lisp is an established standard.  Choosing a standardized technology over a proprietary one is a fair decision if there is actually an implementation that both meets your needs and conforms to that standard.  While ABCL proves that it is possible to implement Common Lisp in JVM and therefore utilize the modern facilities provided by Java, it doesn’t fully conform to the Common Lisp standard.  As far as I can tell, none of the freely available common lisp implementations do fully conform to the standard.  Sure they are accepted as conformant with the help of documented exceptions, but the reality is none of them comply with 100% of the rules established by the standard. Because of this I must exclude the existence of a standard as grounds for choosing Common Lisp over Clojure. Once standards compliance is excluded, what remains is that Clojure provides an easier to use syntax, better performance, and better integration with modern applications.  Common Lisp implementations have a single advantage of being based on a standard, but that advantage is lost by the fact that no implementation conforms to that standard, and without the standard there is no remaining reason to choose Common Lisp over Clojure. At this point at least, it seems Clojure is the clear winner.

 

 

10 COMMENTS

  1. It seems to me that the sheer size of the Common Lisp specification and all of its complexity is part of the reason the language hasn’t been popular since the late 1980s.

    Scheme is a much more limited language, of course. But it seems to me that Scheme is the Lisp family language with an open standard and the best options for adoption. There’s even Kawa, which is Scheme R5RS for the JVM.

    • Mike,
      It is too bad I didn’t have this information prior to trying to make ABCL standards compliant. I wasn’t aware that Scheme was standards based. Either way, I spoke to soon. A day after writing this post I was able to find solutions for the remaining 3 tests.

      https://github.com/rritoch/jrelisp

      This was just the first step. I’m now focusing on optimization since the original goal was to make the system OSGI compatible, I was side-tracked by the compliance issue.

      Best Regards,
      Ralph Ritoch

    • Most of the spec is a a set of functions all written in CL. The actual core of the language is extremely tiny. That large set of functions is a plus not a minus. If you were right then Java with its tons of libraries would turn everyone completely off.

  2. I am curious what you meant by the sentence that it “took too much coding to match the capabilities of the modern PL”, especially if you were comparing to Pascal and C++? If anything, Lisp would allow your programs to be substantially shorter than in C++ (or Java if we were to throw in the current enterprise favourtite PL).

    • Christian,
      Limiting to just Pascal and C++ I could start with the most obvious that at the time “Turbo C++” and “Turbo Pascal” which were popular at the time came built with decent graphics support libraries and examples of how to use it. I don’t recall any of the openly available implementations of lisp at the time being distributed with windows graphics support. It was also easy to link in assembly code for the purpose of serial (modem) communication which was quite common at the time and there were various examples available to work with. These were the most fundamental needs of applications at the time, neither of which the openly available versions of Lisp provided and would require a huge amount of library development and quite possibly alteration of the lisp engine itself just to support.

      Best Regards,
      Ralph Ritoch

      • C++ and the entire C derived and Algol family lines are far far more restricted and limited languages than the Lisp family including Clojure.

  3. Ok, so it is/was a library issue more than shortcomings in the languages themselves. Fair enough.

    While I can understand that depending on a single vendor language (such as Clojure) could be a concern I am not entirely sure why the variations in implementation support for the Common Lisp standard is a tragic flaw as you write. I am not sure that there exists any language implementation with an independent specification (ie where the specification is to just the implementation itself as with Clojure) which conforms 100% to that. Not to mention the challenges to just formally agree on what the standard even means.

    In some situations, and that was the case with an earlier version of the scheme standard but variants of this can be found in CL too, you fix problems of agreeing to how a device should look by leaving it out. I think it was R4 of the scheme standard (and perhaps also R5) that left out macros due to disagreement over how to do macros. This may on the surface increase the chances of conformance but since macros is and was deemed a central language feature, every implementation then added their own macro systems leading to quite a mess, even though specifically non conformance violations was not a part of that.

    The CL standard was done in the mid-eighties, strict adherence to a standard that is not continously updated at some level is perhaps not all that interesting anyway.

  4. Almost none of this makes any sense to me. Clojure is very well defined. The main difference between it and Common Lisp is certainly not that CL has a rather old standard. Particularly as that standard includes nothing about far too many things like concurrency. Having a standard, as such, helps not at all for saying what is really better about one language versus another. What is better about CL is that it is lisp all the way down to an extremely tiny bit of C and assembler to bootstrap the thing. It’s actual spec is also very tiny. Expressed in CL the core of it is less than a page. It is also much more syntactically consistent. Basically it has none. 🙂 It produces faster code in modern implementations. Lisp invented JIT and garbage collection long before Java existed. In CL you can do highly functional programming restricting mutation as Clojure does if you wish. Clojure nicely makes much of the heavy lifting for doing that kind of programming relatively invisible. Common Lisp has a much better condition (error handling and more) and more powerful macros and a built in amazing OO systems based on multiple dispatch instead of methods owned by classes. It has a better numeric stack than the one Clojure mostly inherits from Java.

    That said Clojure is very very nice for its more uniform functions across different data types and of course for access to all the JVM (and CLR) implement code. That is a pretty killer advantage. Also clojurescript is a much better supported development tool for frontend work spitting out javascript than parenscript library is in CL. It is much closer to just a plain Clojure subset that happens to spit out javascript. The same or better *could* be done in CL but to me knowledge has not been done yet.

    The Clojure stack traces are a horror show though.

  5. Clojure is to Lisp what Java is to C++, yes Clojure is commercial but so what? You don’t really need a standard to be a success and that is exactly what Clojure seems to be doing under the Java ecosystem.

    Want pure open source projects? Go GNU!

  6. Conformance to a standard is hardly more important than being powerful and fruitful to program in. The CL standard is so old that threading and IPC is not even addressed by it to name only two. Obviously that there is such an out of date standard can be no proof of superiority by itself. We must evolve CL beyond this standard if we want to see any kind of CL renaissance.

LEAVE A REPLY

Please enter your comment!
Please enter your name here