Sunday, June 27, 2010

Alternatives to Clojure

Other languages you might consider if Clojure isn't quite right for you:

Lisps:
  • Racket: Learning functional programming in a Lisp (Scheme descendent from the most active Scheme group)
  • Scheme: Some of these compile to C and Gambit has been used on the iPhone
  • Common Lisp: Mature and powerful
  • Arc: Paul Graham and Robert Morris's work towards a 100 year language
MLs:
  • OCaml: Practical, fast, mostly imperative, and strictly typed
  • F#: If you want to do functional programming on the CLR (.NET platform)
On the JVM:
  • Scala: Non-Lispy alternative on the JVM
  • A Common Lisp (ABCL) and a Scheme (Kawa) are available
Concurrent:
  • Erlang: Distributed as well as concurrent
Hard core:
  • Haskell: The purest functional language, lazy by default, increasingly influential
Popular:
  • JavaScript: Very functional under the covers, now appearing on the server-side as well as in web-browsers (node.js), and getting faster all the time thanks to V8
Or not:
  • With knowledge and discipline you can write in a functional style in other languages.  For example: Python (although the lambda is limited),  and increasingly in C# (especially with the addition of LINQ and lambda expressions)

Why Clojure?

Choosing to learn a new programming language is an investment in time and effort. This blog is to document my forthcoming adventures in learning the Clojure language.

Reflecting on the process will no doubt help me, and perhaps it will be of use and of interest to those who are considering are already embarking on similar adventures, with Clojure or other languages.

Why Clojure (for me)?
Rich Hickey, designer of Clojure, went looking for "A Lisp, for Functional Programming, symbiotic with an established Platform, designed for Concurrency". Here's an extended explication of his motivation.

Taking Rich's short version as a jumping off point, here's why I want pretty much those same things.

I want a Lisp for expressive power: I subscribe to the DRY programming maxim: Don't Repeat Yourself, also known as DIE (Duplication Is Evil).  Much (most?) lot of my refactoring is centered around identifying and eliminating duplication.  Now, while any given programming language will have idioms that can be used to eliminate some duplication, when it comes to the grammar and ceremonyof the language, in the absence of meta-programming features, you're stuck.  Instead of eliminating duplication, at some level, you end up endlessly repeating yourself!

Lisps, with their Keatsian code-data duality -- code is data, data is code -- have the most coherent and convenient approach to meta-programming, so I wants me a Lisp.  Lisps excel allow -- neigh encourage -- a DSL-construction approach to programming.  Although Ruby, Haskell and the ML family have some facilities in this area, and you can do a fair bit in any dynamic language with an eval statement, the Lisps have the cleanest approaches to meta-programming.

Functional Programming is fun, and powerful!  Read SICP (and do the exercises) to get into it!  Programs written in a functional style favor largely immutable data.  This jibes well with me given my mathematics background.  Things that don't change are much easier to reason about than things that do.  That's why, in the case of the very mutable object-oriented paradigm invariants are so helpful in figuring out what's going on (or going wrong).  Pure functions are easier to write tests for than almost everything else, since you don't have to set up or mock out the rest of a larger system.

An established Platform gives the batteries-included effect - access to existing libraries, and portability equal to the underlying platform.

Design for concurrency is a welcome bonus, if not a core criterion of mine.  Large scale multi-cores are coming, and the old techniques simply won't stand up. Time to learn...

* * *

Now, of the most prevalent Lisps: Common Lisp is big and imposing, and I find its Lisp-2-ness a bit kludgey, while Scheme is far cleaner, but despite spending some time in it, I find myself reverting to Python for day-to-day tasks; anyway I'll return to check out Racket periodically.  Arc is a ways off, so it will keep.

Clojure, by contrast, features a number of strong pragmatic balances in its design: For example, I particularly like that it is a Lisp-1, like Scheme, but offers a more CL-like approach to macros (although with somewhat better hygiene out-of-the-box).

On the platform front, hopefully Clojure in Clojure will get some traction soon, leading to availability on other platforms besides the JVM: Javascript (hello V8), CLR, and -- at a stretch -- Objective C would be nice too (but I won't hold my breath on that one!).