Clojure


I know I’ve mentioned Clojure now and again in this blog, but I haven’t actually talked that much about it. I feel it’s time to change that right now – Clojure is in the air and it’s looking really interesting. More and more people are talking about it, and after the great presentation Rich gave at the JVM language summit I feel that there might be some more converts in the world.

So what is it? Well, a new Lisp dialect for the JVM. It was originally targeting both the JVM and .NET but Rich ended up not going through with that (a decision I can understand after seeing the efforts Fan have to expend to continue providing this feature).

It’s specifically not an implementation of either Common Lisp nor Scheme, but instead a totally new language that’s got some interesting features. The most striking feature of it is the way it embraces functional programming. In comparison to Common Lisp who I characterize as being a multiparadigm language, Clojure has a heavy bent towards functional programming. This includes a focus on immutable data structures and support for good concurrency models. He’s even got an implementation of STM in there, which is really cool.

So what do I think about it? First of all, it’s definitely a very interesting language. It’s also taken the ideas of Lisp and twisting them a bit, adding some new ideas and refining some old ones. If I wanted to do concurrency programming for the JVM I would probably lean more towards Clojure than Scala, for example.

All that said, I am in two minds about the language. It is definitely extremely cool and it looks very useful. The libraries specifically have lots to say for them. But the other side of it for me is from the point of Lisp purity. One of the things I really like about Lisps is that they are very simple. The syntax is extremely small and in most cases everything will just be either lists or atoms and nothing else. Common Lisp can handle other syntax with reader macros – which end up with results that are still only lists and atoms. This is extremely powerful. Clojure has this to a degree, but adds several basic composite data structures that are not lists, such as sets, arrays and maps. From a pragmatic standpoint I can understand that, but the fact that they are basic syntax instead of reader macros mean that if I want to process Clojure code I will end up having to work with several kinds of composite data structures instead of just one.

This might seem like a small thing, and it’s definitely not something that would stop me from using the language. But the Lisp lover in me cringes a bit at this decision.

All in all Clojure is really cool and I recommend people to take a look at it. It’s getting lots of attention and people are writing about it. Stu Halloway is currently in the process of porting Practical Common Lisp to Clojure, and I recently saw a blog post about someone porting On Lisp to Clojure, so there is absolutely an interest in it. The question is how this will continue. As I’ve started saying more and more: these are interesting times for language geeks.


10 Comments, Comment or Ping

  1. In Lisp parlance, an atom is exactly anything (object, vector, hash table, xapping) that’s not a cons. When you say that macros only have to process lists or atoms, that’s a tautology. The trick is simply that most macros don’t have to destructure anything but lists.

    September 29th, 2008

  2. Paul:

    Well, that’s not entirely true. In Lisps up until Clojure, an atom is anything that isn’t a cons. But in Clojure that’s not really true, which is my point.

    As a typical example, Clojure has a let form – this let form actually takes a vector, not a list of lists.

    September 29th, 2008

  3. The point is that even if the CL let also took a vector, that vector would still be an atom. Your atom/non-list-composite distinction isn’t. Moreover, I don’t see why it is particularly harder to work with a vector of bindings instead of a cons-list of bindings affects the implementation of macros, let-like or otherwise.

    September 29th, 2008

  4. I don’t agree about that. If the let form in CL took a vector, then it would be useful to be able to implement that let form as a macro, in which case it would be necessary to be able to decompose that vector in a macro. But that’s not the way CL does it – and thus a macro generally don’t need to care about anything other than atoms and conses. While in Clojure a macro might potentially have to care about all 5 different types of composites.

    September 29th, 2008

  5. I don’t understand this atom/composite (… where so-called composites are atoms) distinction of yours, nor do I see what makes non-list data structures intrinsically harder to manipulate.

    September 29th, 2008

  6. Well, what I call a composite is something that contains other things. That in CL a hash is an atom is kinda nonintuitive, since it’s really not atomic. (Where I use the word atomic in the english/greek meaning – where something is indivisible).

    But if in a language other composites than composites are used in the syntax, then that means you’ll have to handle them. Say for example that if CL used hashes for optional parameters. Then if you needed to process parameter lists you would have to work with both conses and hashes.

    September 29th, 2008

  7. On Lisp -> Clojure. Perhaps you were referring to my blog posts? I cannot seem to find any other efforts in this arena. So far I’m having a blast, although I fear that I am simply writing common Lisp in Clojure (if that makes any sense).

    http://www.earthvssoup.com/tag/onlisp/

    Thanks for the post, I agree with most of what you say, but not coming from a Lisp background (aside from college and grad school of course) I do not feel the sting of non-Lisp purity.

    -m

    September 30th, 2008

  8. Justin Grant

    Clojure is really cool. I have to side with Ola on this one.

    Having implemented a fairly sizable web project in Clojure earlier this year this is exactly the problem that tends to grow bigger and bigger with the code base.
    Having to keep in mind that the list is not the primary data type in Clojure and to remain aware of what Clojure may be doing under the hood with Java types is a not only a pain but a real issue when using it on real projects.

    Rich has done some great things with Clojure and some of the questions I put back to him a while back about design choices had to do with performance and hence the reason for staying with underlying Java types in many cases.

    Fair enough but I’d love it if Clojure was not put forward as a Lisp-1 instead of just saying that it simply uses Lisp-like syntax instead.
    Recursion in Clojure is far from recursion in Lisp and there are other other differences that prove it’s not a Lisp at all.

    Our team found that any substantial experience with Lisp (beyond simple s-exps) was a drawback and a barrier to learning/using Clojure. No more needs to be said.

    I’m wondering if Rich will continue to call Clojure a Lisp dialect at Lisp50/OOPSLA next month considering he’s an invited speaker alongside Richard Gabriel, Guy Steele, Alan Kay, Kent Pitman and John McCarthy !

    I’ll be there to find out…

    September 30th, 2008

  9. @ola

    Clojure is extremely simple. In particular, all of the data structures can be manipulated as sequences with uniform code, for instance this works on any collection and returns a collection of the same type:

    (into (empty c) (map some-fn c))

    The entire sequence library works on every data structure. Stuart Halloway was working on an example from PCL and I showed him how in Clojure you could swap a vector or set for the list he was using and not change _any_ of the rest of the code, just trading off performance characteristics.

    “While in Clojure a macro might potentially have to care about all 5 different types of composites” is a theoretical argument that vanishes in the face of use of Clojure’s library and destructuring facilities. It is so easy to write code that does not care.

    I don’t consider atom one of the strong abstractions of Lisp, as many of the things for which it returns true are not atomic. Once you recognize it as non-consp, well, it just doesn’t seem so fundamental anymore.

    @justin

    Lisp is a unique concept in that very different languages, e.g. Common Lisp and Scheme, can both arguably be called “a Lisp”. I would argue that any definition of Lisp that included both CL and Scheme (and wasn’t trivially “Lisp means CL or Scheme”) would have to include Clojure. CL doesn’t guarantee TCO. PLT Scheme has just made their conses immutable. Etc.

    If you are going to say something is not a Lisp you’ll first need to say what a Lisp is. Clojure’s recursion is precisely Common Lisp’s recursion.

    I’ve presented Clojure to Pascal Costanza, Guy Steele, Alan Bawden, Gerald Sussman, Dan Weinreb et al and no one has said to me, in public or private, that Clojure is not a Lisp. I don’t think they would have invited me to speak at ECOOP, OOPSLA or ILC if they thought that.

    In the end, the “a Lisp” conversation degenerates – there are those who argue that Scheme isn’t Lisp, that Lisp means Common Lisp or whatever the community of people using Common Lisp decide is Lisp. But if you are going to value the notion of “a Lisp”, you’ll have to allow the concept to apply to things that differ from what already exists.

    @all

    We have to make sure, as Lispers who cringe at the C/Java/xxx programmers who come to Lisp and complain about how different it is from what they are used to, rejecting it offhand before learning about how it works, that we don’t turn around towards new Lisps and do the same.

    October 1st, 2008

  10. Justin Grant

    Rich,

    Thanks for the response.
    You make valid points that oppose my notion of “a Lisp” as you put it. I am very biased in this obviously. You’re also right that this conversation degenerates very quickly. There are things about Scheme and CL that bug me just as much as some things about Clojure. (maybe that qualifies it as “a Lisp” then in some respect ?)

    Let me say though that my opinion will hardly prevent me from continuing to use and recommend Clojure on future projects. It’s truly one of the most impressive and practically useful languages on the JVM that I’ve come across.

    Looking forward to your talk at Lisp50/OOPSLA !

    -Justin

    October 1st, 2008

Reply to “Clojure”