What is
Clojure, I hear you ask? Well, as you know, in the last decade or so, Sun's Java thing has taken the world by storm. Few can deny that it is acceptably fast for most purposes, nor that it will run just about anywhere with sufficient prodding and coaxing, nor even that it has plenty of handy libraries for every occasion, and a GUI library which, while revolting, is a great deal less revolting than most other very cross-platform GUI things; I'm looking at
you,
TK.
The problem is that Java the Language, as opposed to Java the Virtual Machine or Java the Rather Strong Sort Of Coffee, Now Out Of Favour And Replaced By Varieties From Famine
Hotspots, is really, really, amazingly bloody awful. Shockingly bad. It's like C++ with a memory manager stuffed in and most of the useful stuff sneaked out the back door. Things aren't all bad; the Java
implementers are slowly adding scary things like generics, and who knows, there may be closures and multiple
inheritance and unsigned integers before the decade is out! Okay, well maybe the century. Anyway, the point is that as it stands Java is unusable, except by masochistic website developers who somehow think that it being a pseudo-industry-standard forgives all, and that writing endless reams of crap again and again and again builds character, anyway.
How, then, do we get the admitted convenience of the
JVM without having to wrap things in endless other things just to make them vaguely usable? Fortunately, more Java-tolerant people than I have looked into the issue, and have produced other languages
targeting the
JVM. Lots of them. They are legion.
Some are
re-implementations of nice-
ish languages, like Python, Ruby, and Common Lisp. These, sadly, tend to have one thing in common; they don't work properly. Then there are endless Schemes, as is required for any
VM whatsoever, a variety of scary BASIC derivatives, frankly sick and twisted things like COBOL for the
JVM, nasty things designed by XML fetishists... and then there are the oddities.
Clojure is one such, as is
Scala. These are effectively new languages, albeit heavily influenced by older
tongues, for the
JVM.
Clojure, which, I think, was the original point of this ramble, is a
Lispish,
brackety creature; it also has funny concurrency stuff, of which more anon. It's really quite nice, though it has its quirks.
A big problem with these funny little new languages is generally that there is no acceptable way to work with them without going mad. There's no
IDE, no tools, no debugger... Fortunately, this turns out
not to be the case with
Clojure. There is a port of the SLIME
backend (SLIME is a nice Emacs interaction mode for Common Lisp). The one tiny little problem is that nowhere on the great wide Internet, as far as I can see, is there any guide to getting this stuff set up.
Here we go, then.
First, you'll want the
SVN version of
Clojure. The packaged version Will Not Do for these purposes, it seems. Actually, aha, fooled you, you'll want Apache Ant
first; it is a scary tool for building Java projects. Yes, of
course it has plenty of XML; did you even need to ask? Get it and install it, then in your checkout, type 'ant jar'. This will cause a JAR file (a ZIP of compiled Java code) to appear before you in short order.
You'll then want to get all
three things from
here. One is a script to run
Clojure conveniently, one is a standard Emacs mode, and the third is the SWANK
backend. Set up the script, and put the other two somewhere.
Right. You will now want a .
emacs file something like this:
(setq slime-lisp-implementations
'((clojure ("/Users/robertsynnott/bin/clojure") :init clojure-init)))
(add-to-list 'load-path "/Users/robertsynnott/clojure/clojure-mode/")
(require 'clojure-mode)
(add-to-list 'load-path "/Users/robertsynnott/clojure/swank-clojure/")
(require 'swank-clojure)
(add-to-list 'load-path "/Users/robertsynnott/lisp/slime/")
(require 'slime)
(set-language-environment "UTF-8")
(setq slime-net-coding-system 'utf-8-unix)
(slime-setup)
Obviously, you should substitute paths on your
own system; mine has quite enough to be doing.
You may now restart Emacs, and type
M-x slime. All going well, you should be presented with a
Clojure REPL. You may now open a file to put stuff in; the mandated extension is '.
clj', displeasing in that, to me at least, it suggests both Common Lisp and Java;
Clojure is neither. Possibly I am being over-paranoid. Depending on the phase of the moon, you may or may not have to do
M-x clojure-mode to get things to behave, at that point.
You now have
Clojure running! Try typing '4'; you will note that you get '4' in return. This pleasing result can be replicated for even very large numbers.
What's
Clojure like? Lisp-
ish... mostly. There are
extra types of bracket, you see. [] are for arrays and various other things; {} are for dictionaries/hash tables. A function looks like this:
(defn bla ([x] x)
([x y] (+ x y)))
You will note that there's a weird pattern matching thing going on here; (
bla 4) will return 4 while (
bla 4 5) will return 9. lets are similar:
(let [[a b c] [1 2 3 4]]
b)
That gives you 2; it's a little like a combination between a Common Lisp let and
destructuring-bind. I actually quite like this; it looks like the sort of thing CL
should have.
There are also
multimethods! They're not as
cabable as those in
CLOS, to be sure, but a fair bit better than Java's
OO system. They operate on dictionaries as objects, for some reason.
Then there are the weird concurrency things. One is a Software Transactional Memory system, meaning that it behaves a bit like a database, it seems; the other is something similar to
Erlang's message passing. I like these; so much nicer than mucking around with proper threads.
There are also quite nice semantics for talking to scary
ol' Java, when it becomes necessary.
I've barely scratched the surface, of course, but the
online guide is well worth a look, if you're interested.
Would I actually use it?
Hmm, well, now, I'm not sure. There's certainly an appeal; if I was doing something which might ordinarily call for Java,
Clojure might be a nice substitute. Your
mileage may vary, of course, but I'd say it's definitely worth looking into.