Tuesday, September 01, 2009

[Misc] Clojure & Clojure Book Review

It looks like we are living in a fantastic time concerning programming languages. Creating a new language has never been easier then before. With the two great platforms Java and .Net it's not extremely difficult any more to generate intermediate code from the language you are dreaming of. And even the pragmatic bookshelf has a book in writing on "language patterns" to cover this topic.

Thus I assume that nearly every developer is looking out to bet on A) the best horse or to see B) a language from where you can learn the most. Unfortunately the whole world seems to bet on Scala from the sea of hot languages. And indeed Scala is quite cool and might win the race with good reason. Scala is hot stuff for reason. Nevertheless I never got really warm with Scala and it's hard for me to describe why. It's something in the syntax I really can not explain. My dream language must have a code that looks quite perfect. Years ago I had that feeling coding Ruby (and I love Ruby) because the code simply looked great (although I don't like other things in ruby as e.g the clumsy class definitions (there was a project on rubyforge to fix it. Does someone know the name?)).

So I am still constantly looking out for new languages and of course the pragmatic programmers have brought this book into my view:

Stuart Halloway, "Programming Clojure", 2009

So I might share my thoughts on this book and on the language.

For me still Clojure is more attractive then Scala because:

1. It's the toughest edge for your brain.
Perhaps you belong to the same generation as me: I never really used Lisp, Scheme or the dialects alike. But as I am a Java, D and Ruby Coder => Lisp and thus Clojure ("Lisp Reloaded") is the hardest challenge to learn. And according to the last two book reviews you should always go the hard way to learn the most. This might be even true for you.?! For me it turns out that the amount of round brackets is not the problem.

2. Clojure enforces the use of no variables but immutable data structures (as the successful Erlang does!). The code / structures itself mostly is the container for variables you would define use normally. This has two really strong advantages:

1. No variables mean less errors and less to debug
2. No variables and immutable data means no side effects
Hence it's not so easy to write Clojure code with much side effects.

3. Clojure has the strong concurrency concepts - if you really need mutable data - using STM (Software Transactional Memory) / MVCC, Agents, Atoms, giving you ACID Transactions without the "D" (which is only valid for databases).

4. The Java integration is really smart. Have a look:

(new java.util.Random)

simply generates an object you can easily use to work with.

Java and Clojure can call themselves easily vice versa. This might be a really good argument for you to save investments. Clojure doesn't really try to build up all the java libs from scratch; it reuses them in a clever way.

5. Clojure is indeed fast because it generates pure Java byte code.

And of course all the other stuff that a hot language must have:
  • Closures (I still can not believe that they are still discussion this hot feature for Java... it's a shame)
  • List Comprehensions
  • a workaround for tail recursion and currying and other weird stuff as
  • very lazy sequences, trampolining, etc.
What also challenged my mind is that Clojure has only three constructs for flow control (as we learned from Oz a simple and nevertheless powerful language doesn't really need much):
  • An "if" See an example (if (> num 100) "yes" "no"))
  • A "do" which is an iteration of statements - introducing side effects - and thus discouraged in clojure
  • And a "loop/recure" that can be used to build everything you need in flow control (Stuart Halloway calls it the Swiss army knife).
So before I discuss the downside of the language and the book, let me bring up the two points that I loved most in clojure (even if it takes a lifetime to understand them 100%):

1. It has Metadata incorporated in the language right from the start! So you can tie pre- and post-conditions, tests, doc, arbitrary macros to any kind of data or functions. Whow! Do you remember how long it took Java to introduce Annotations? And to me they are still not 100% part of the language but an add on.

2. Clojure has powerful macros and multimethods. This means DSLs are incorporated. So if you loved the way Ruby can build DLSs (and the pragmatic programmers will bring up a nice book on this Ruby DSL topic!) you will get a step further in Clojure.

The book itself uses all hot Clojure features to create a build system called lancelet (every language since Rubys Rake seems to do this a little bit cooler then Ant does).

What I disliked in the book is that it's still difficult for beginners although it is very well written with beginners in mind. One example: I still havn't found the page where I can read a string from the console. And this is a key feature for beginners to test something. The interactive REPL is not enough here. What I mean is that the book has a thousand brilliant examples like fibonnaci. But fib is a two edged example. It just calculates. It creates no emotions in the reader. A better example is the snake game the book creates on a few pages later (here we get input from a keyListener...).

The language itself has two downsides for me:

1. If you are used to the huge Java Collection Lib you are astonished that Ruby boils down all data structure to just a super powerful Array and Hash (and the others are rarely used). That's cool. So you get the impression that Clojure get's on step further in stating that everything is a set (like Lisp stated that everything is a list). But when working with Clojure you are suddenly confronted with not only sets but vectors, lists, maps and trees. Now the book tells you that you always use the set abstraction to work with this. To me this doesn't really help if e.g. the vector notation differs significantly from a set and list definition. I still don't get used to this. but it must be surely my personal inability.

2. The most important drawback is the key feature at the same time: Clojure has an extreme steep learning curve! To become a true expert in Clojure, i.e. to think and dream in Clojure you need to stress every neuron in your brain. So it all boils down to the question: Is it really worth investing half a year in a hot language like Clojure to be able to produce code that is 3 times more accurate imperative Code?

What do you think?

Stefan Edlich


And finally have a look at this nice language comparison: Java.next
Make a list. For every topic give points from 0 to 3. What is the most elegant for you?


Anonymous said...

the blog post says "set" a number of times where you must have meant "seq"

Anonymous said...

The book tells you that you always use the seq abstraction to work with all collection types, not sets. A seq is not a set.