Searching for Signal

the n01se blog

clojure is the best lisp yet

I've dabbled in a few lisp dialects, but I generally become frustrated with some deficiency or other. I had been holding out some hope for Paul Graham's arc, but when I tried it out, I wasn't exactly blown away.

Common Lisp has a rather bloated library of functions, many with disgustingly long names. Arc has indeed successfully addressed this problem, and so has clojure: the longest function name I could find in Clojure's succinct and powerful library was the outlier "clear-agent-errors".

Lisp is old enough that many dialects have trouble with modern character encodings. Arc doesn't support anything but ASCII (so far anyway), and although elisp does it seems to regard UTF-8 with suspicion. Clojure supports UTF-8 out of the box, even inlined in your source code.

Many lisps have a shocking shortage of useful library modules for common tasks, especially related to networking or particular file formats, when compared to Perl, Python, etc., and creating bindings for existing C or other native libraries can be pretty tricky. Clojure allows you to directly use any part of any existing Java library, no special bindings needed.

With a large variety of libraries comes name collisions. Arc apparently hasn't addressed this problem yet, while clojure has all the namespace support you'll need.

JavaScript and other modern languages have demonstrated to me the power of hashes and the utility of being able to easily initialize them with literals in my code, yet few lisps make this convenient. Clojure has rich support for sorted maps, hash maps, and struct maps (which allow you to efficiently store a large number of hashs with common keys), including succinct syntax for creating new ones.

Besides cleaning up some of lisp's historic weaknesses, clojure provides several innovative new features. For example, the idea of data structure interfaces allows you to write code that can work the same on a variety of concrete types. The (conj ...) function adds an item to a collection, whether that collection is a list, a vector, or a hash.

I also found it interesting that Clojure's built in data structures are all immutable. The API makes working with these convenient, and should allow you to avoid common hassles when dealing with concurrency.

There are many other little details that clojure seems to have tweaked for the better compared to older lisps. The syntax for defining macros is a little tidier, (cond... ) is a bit more succinct, and it even has support for literal regular expressions.

I don't know that many lisps, and none of them very deeply. But for what it's worth, clojure is my favorite.