Clojure Review

On May the 4th, the 1.0 version of Clojure was released [1]. I don't use that lanugage anymore, but I was happy to hear about it. I decided to write this review, in order to present that language to other people, who are (starting to be) fed up with Java, and are dreaming about a better tool to use.

[1] http://clojure.blogspot.com/2009/05/clojure-10.html

Introduction

One of the very first questions I always ask myself when I consider using (learning, etc.) a new programming language is "why should I use X instead of Y?". This question might seem to be naive: we know, that there is no such thing, like a perfect language. Each language has its advantages and disadvantages, and a good programmer should realize that, and should be able to choose a right tool for the task. I could also ask "why should I eat an apple instead of an orange?".

However, I find this question an important one. If the language designers, enthusiasts and users are unable to answer it, I think there are no reasons to choose that language. Are they really unable to tell me, what problems were easily solved with that language, while it would much more complicated with some another tool?

So, now I'll ask the question: why should anyone use Clojure instead of Java, Python, C#, C++, or X (your favourite language)? Let's take a look at the answer, provided by Rich Hickey, the Clojure designer.

Clojure rationale

The first thing Rich has to tell us, is that Lisp is a good thing. He points many things, and I will write about two of them only. The sentences in " are cites from Rich Hickey, the comments are mine.

"Almost no syntax": Lisp has a simple syntax, very easy to generate programatically. If you want to write code, that writes (generates) code, that writes code, Lisp is the language for you. Lisp allows you to automate the process of writing code to the level that is simply impossible in languages like Java, C#, C++ or Python.

"Core advantage still code-as-data and syntactic abstraction": In Python, people use dictionaries to write their data. In Java, Java properties and XML files are used. In Lisp, data has the same form, as code. The advantage: code can be passed as easy, as data. (It can also be *generated* as easy, as data!)

The first tip: if you don't like Lisp, you probably won't like Clojure.

Rich also asked the question: "Why not choose a "standard" Lisp (Common Lisp or Scheme)?".

"Core data structures mutable, not extensible.": I find it an advantage, since it doesn't make me to solve problems using the one and only way (in some particular language). However, I understand, that other people might find this feature a disadvantage. Well, Clojure might be the right choice for them.

"Standard Lisps are their own platforms": True. When I decided to give up with Java, Scala and Clojure, and to go further with Scheme, I also decided to quit the JVM platform. There are some projects, though, which aim to provide standards Lisps to the JVM platform.

The second tip: if you are happy with some standard Lisp, you probably won't need Clojure.

According to Rich, "Functional programming is a good thing".

"Immutable data + first-class functions": A great advantage, in many classes of problems. (Just try to count the number of errors caused by wrong *assignements* in your code!)

"Pure functional languages tend to strongly static types": As Rich wrote, this solution is "not for everyone, or every task".

In general, when I was using Clojure, my code was written in much more FP-way, than when I was using Java or Python. Clojure just "rewards" FP-style of coding. It's like using dictionaries in Python: the more you use them, the cleaner your code is.

The third tip: if you don't like FP, you won't like Clojure.

Rich also claims, that "VMs, not OSes, are the platforms of the future". I fully agree. There are growing number of different systems, so the value of portable software also grows. The more portable software, the more flexible, the more valuable it is.

Using Clojure, you have access to any Java library. Do I really have to write more?

So far, all the statements could've been taken without any emotions. Some people might agree with them, some might oppose, but nothing new nor controversial was said. The next statement might be much more interesting to discuss about: "Object Orientation is overrated".

Rich says, "Born of simulation, now used for everything, even when inappropriate".

If you have a hammer, everything starts to look like a nail. The problem is that it only *seems* to look like a nail, while it's not a nail! Sometimes it's much better to use a different tool, than a hammer.

My private practice showed (to me), that since I gave up on OOP, I don't miss its features. I can use encapsulation without OOP!

The fourth tip: if you're happy with OOP, you won't like Clojure.

Clojure is just not a tool meant to be used to develop OOP software. If you need OOP, you might use Java. Clojure comes where OOP is not a good solution. It doesn't give you an another opportunity to use OOP. It frees you from using just this one tool to solve each kind of problem.

How does the Clojure world look at the second sight?

So far, so good. If you're fed up with Java, all that OOP culture, you like FP, and you like Lisp (or, at least, you're not scared of the parenthesis), you might be interested in Clojure. Now, let's take a closer look at the Clojure world. What this world has to offer you?

No, I asked the wrong question here. You probably have now some idea on what Clojure has to offer you. What you need to know is what you won't be offered.

First of all, I'll start with documentation. I find docs a crucial thing. When I'm new to some language, I need a good tutorial. Not even a book (I'm not a newbie, I know how to write a program), but a tutorial, freely available, written to make me fast into a language. An example of a good tutorial might be the Java (official) one.

I found Clojure for the first time in December last year. I became more interested in it in January this year, and I wrote some Clojure code in February. On that time, there wasn't any valuable Clojure tutorial available. Or, perhaps I should write: there wasn't anything, that *I* could find a valuable tutorial. Not only a good quality tutorial (like the Java one), but anything I had to study for more than just an hour or two. (I was studying Java tutorial for about four weeks when I was learning Java.)

Now (the end of May, 2009), the situation is *somewhat* better. I found the "Learning Clojure" [2]. The tutorial is definitelly not so deep as the Java one (yes, I'm quite fond of this Java tutorial!), but it might be a good introduction for someone, who has no knowledge of FP and Lisp into Clojure. It will give you the very first grasp of Clojure. For more, you should refer to the language documentation.

[2] http://en.wikibooks.org/wiki/Learning_Clojure

And here we have another problem…

During my short adventure with Clojure, I often needed a function for some particular task. I hadn't been an experienced Lisper (I'm still not a one), so I was often looking for some function in Clojure docs, without any clue on what I should've been looking for.

Clojure docs, in comparison to Java, are a mess. All the functions are documented (I think), but it's hard to find them. At the first sight docs look to be structured by various topics, like special forms, data structures or sequences. Some names are ambiguous, like "Other functions". But the real problem is that those materials don't contain all the information! If you want to see the full picture, you have to look at "API", which is the alphabetical index of all the functions. And there are a lot of them. Good luck while looking for the one you need. Often the best way to find out what exactly a function does, is to look at its code. (Please note that it's also a good way to learn more about Clojure.)

Well, I understand the fact that Clojure is not donated so much as Java. I'm just pointing that there's a lot to do with documentation yet. I have also to point out, that Clojure docs are poor in comparison to Java docs.

If we are at the documentation topic, I'd like to write about a lack of documentation tool for Clojure. When you get the Java SDK (or JDK, whatever it is called now), you get the standard documentation building tool. You can document your code in your source files, and than just build a nice-looking docs in the form of HTML pages. Unfortunatelly, you have no such a tool in Clojure. Or, at least, I haven't found anything on the net. Clojure is a young language, so you can't rely on tools like Doxygen yet.

Clojure is also not meant to be a Java complete replacement, and you should always have this on your mind. Java is built of classes. If you use Java, you just have to use objects, and therefore you have to use classes. With Clojure, you can make your code use classes in more FP-way, but sometimes you'll need your own Java class. Unfortunatelly, I wasn't able to find a way to declare a Java class (with private, package-private, protected and public fields and/or methods) in pure Clojure. The only way to do it was to write the appropriate Java code, and then to make use of that code (a class declaration) from Clojure.

I have also found an interesting question on the net [3]. Clojure is standarized only by means of the existing Clojure implementation, and it might be regarded as a flaw of this language. (And, in contrary to some people from the Clojure community, I don't find it a hillarious issue.)

[3] http://groups.google.com/group/clojure/browse_thread/thread/4d9b1069d7f9b23a/8a95ae91359acd17?lnk=gst&q=%22serious+language%22#8a95ae91359acd17

At first, it might seem to be a trivial issue. Who cares about official standards? If a technology is good enough, it might be used to solve problems.

Then I found an interesting question: what would happen to Clojure if Rich Hickey was suddenly taken far and away by aliens? (Well, actually the question wasn't about aliens; it was about Rich's death. Since I wish a good health to Rich, I decided to change the question, while leaving its point unchanged.)

So, let's imagine that Rich was taken far and away from us by aliens. Clojure has no leader; no one can answer questions regarding some Clojure behaviour. How can we say the difference between a bug and a feature? We have no reference specification.

That problem can be expressed in another words: Clojure lacks maturity. Maturity already achieved by Common Lisp, Scheme, or Java. Clojure is a young technology, and should be regarded as such.

Conclusion

I hadn't been using Clojure for a long time. The last version I was using was the one from 18th of December, 2008. I don't suppose that the language now is much more mature, as it was then, though. I think the language I was using was quite usable, and could be used in a production environment. As I pointed out, Clojure is not so mature, as is Java, but it doesn't mean that it's too early to use it for something serious.

I have one more thing to say about my experience with Clojure. It was much better to code in Clojure, than to code in Java. I was freed from the Java OOP culture, and I got my first try with Lisp. It was an amazing experience! Now, I can say one thing for sure: if I ever was made to use the Java platform, I would use Clojure as much, as I'd be able to. It seems to be a much better choice, than Java.

Clojure has also very friendly community. There are many people (well, perhaps not so many as in the Java world), who are working on their interesting projects. I learned many things just by reading their posts on the Clojure mailing list.

I hope that in the following years, the meaning of languages different than Java on the JVM will grow, and that Clojure will become an important player there. In my opinion, it's worth it.