Clojure is the new hotness among people who think the JVM is an interesting platform for post-Java languages, and for people who think there’s still life in that ol’ Lisp beast, and for people who worry about concurrency and state in the context of the multicore future. Over the last few days I’ve been severely bipolar about Clojure, swinging from “way cool!” to “am I really that stupid?” Herewith some getting-started tips for newbies like me.

This is almost certainly not interesting to anyone except those who are already interested in Clojure, and to one other group: those who might want to package up a programming language in such a way that learning it will be straightforward.

Background · I understand the JVM and Java package structures reasonably well. I am by no means a Lisp hacker, my experience being limited to a few thousand lines of elisp, mostly to cook my own idiosyncratic XML editing mode that I’m using as I write this.

What To Read · Before I started, I read most of Mark Volmann’s Clojure — Functional Programming for the JVM, and bought the PDF of Stuart Halloway’s Programming Clojure from the Prags, although I’d only read the Concurrency section in any detail.

Neither is great, but both are OK, and with addition of another resource, will get you what you need. That other resource is the Clojure source code, which provides tons of examples of how-to-do-X; go grepping around in $CLOJURE/src/clj/... and you’ll strike gold.

REPL! · You just really can’t do any exploratory programming in a dynamic language without a REPL, as in Read-Evaluate-Print Loop. Unlike Ruby, Clojure doesn’t come with a precooked readline-equipped REPL, but you can get a primitive one going in a simple shell script.

Don’t do that though, get yourself some IDE help. Emacs and NetBeans are both plausible choices, because Emacs is already Lisp-centric and NetBeans knows about the acres of gleaming Java machinery that is holding this whole thing up.

IDE · I saw there was a NetBeans plug-in called Enclojure, so I went and got that from wherever Google took me. Don’t do that! Get whatever’s the latest from github.

Enclojure’s install documentation is a little baffling. I liked the idea of having a REPL right there in the IDE, so I followed the link and it expected me to understand what the difference between “managed local” and “remote unmanaged” and “standalone” REPLs were, and it wasn’t obvious what I’d need to download. I eventually convinced myself that I wanted a “Project REPL” and it turns out that you get that with the plug-in.

Here are the basic things you need to know before you can do anything with the Project REPL:

  • Right-click in your code buffer and select “Change REPL to file/ns”. Otherwise Nothing Will Work.

  • When you hop over to the REPL (command-T on the Mac flips back & forth), you have to do a “Load File” (control-L on the Mac) so that the REPL will know about your functions. Otherwise Nothing Will Work.

    I wasted literally the best part of a day trying various weird incantations so that I could define a function foo and say (foo) in the REPL. It’s worse, because the “Load File” option isn’t advertised when you right-click in the REPL.

Once you get past this stuff, Enclojure seems like a rather good (if young) IDE front-end for Clojure. And the REPL has all the command-line editing and history you could want. But it should be easier to get started.

Namespace Hell · I noticed when I made a Clojure project, taking all the defaults, some ceremonial arm-waving at the top of the file:

(ns org.tbray.paralines
  (:gen-class))

So I went to read up on this ns thing, and, well, it’s a maze of twisty little passages, all different. There’s ns and in-ns and use and require and import, except for ns takes :require and :use and :import clauses, which are said to be better.

Some of them are forms and some of them are macros, and eventually you come to the sickening realization that this is essentially your old friend CLASSPATH Hell, which evidently is not improved by the application of S-expressions.

The documentation in all the sources I could find shares the assumption that you understand what’s going on and leaps directly into the finer points. I have no fucking idea what’s going on, but I managed to spelunk through the Clojure sources and steal enough working samples to get my code to run.

On the other hand, I haven’t yet had the courage to try to distribute my code across more than one file.

Asking For Help · There’s a (very quiet) #enclojure IRC channel, and a rather high-quality Google group, where I was able to get some problems answered with archive searches.

And then there’s the #clojure channel, which is at that perfect point in history where it’s busy and you’re one of the few n00bs and when you ask ignorant questions, sometimes Rich Hickey answers them. Won’t last long, I bet.



Contributions

Comment feed for ongoing:Comments feed

From: James Reeves (Nov 03 2009, at 14:28)

There are a number of namespace-related functions in Clojure, but only four that are important:

'ns' creates a new namespace, e.g.

(ns my-library)

'require' loads a namespace from the classpath:

(ns my-library

(:require clojure.contrib.duck-streams))

(clojure.contrib.duck-streams/read-lines "blah.txt")

'use' also loads a namespace, but allows the loaded functions to be accessed without a preceding namespace:

(ns my-library

(:use clojure.contrib.duck-streams))

(read-lines "blah.txt")

'import' is like 'use', but only for Java classes:

(ns my-library

(:import java.io.File))

(def f (File "blah.txt"))

[link]

From: Geoffrey Grosenbach (Nov 03 2009, at 15:46)

For those who like to learn visually, Clojure contributor Phil Hagelberg and I have put together a (commercial) screencast on Clojure that has sold quite well. With technical editing by Rich Hickey, too:

http://peepcode.com/products/functional-programming-with-clojure

[link]

From: Patrick Logan (Nov 03 2009, at 16:01)

The namespace stuff is a bit complex - and it uses classpath, but it's not exactly the same as the java package system.

The good news is that n00bs don't have to really know much about it at all, other than how to "import" java and "use" clojure.

I don't know anything about the non-emacs IDEs. I would recommend n00bs stay away from those altogether, even emacs if you don't already use it.

Just stick to Stuart's book, chapter-by-chapter. He's got scripts and everything setup for you. You remain in the REPL.

Just toss in JLine to get better editing...

java -cp jline-0.9.91.jar:clojure.jar jline.ConsoleRunner clojure.lang.Repl

Stuart's book seemed pretty good to me (although I've been Lisping for a long time so it is hard to tell what will click with n00bs.) I would recommend you go front to back with it, and then branch out. Getting into the headier parts of Clojure too soon would almost certainly turn you off from the actual simplicity of it all.

[link]

From: Andy Kish (Nov 03 2009, at 23:48)

Overall clojure is pretty great, but it's clear that most of the development of the language has been pushed forward by those who are balls deep in the implementation.

There's lots of niggles I have at the "user interface" level of the language. One of them is the "import" vs "require" vs "use" thing. The keywords don't provide useful information to distinguish what they do, so I had to go look up the difference every time I used them at first. One keyword for importing stuff would be a good place to start.

Another example of needing to remember annoying details: "send" vs "send-off" for agents. I'm sure there's a big difference at an implementation level, but fuck if I know if a more complex update function I send an agent will block at some place far removed from my code. The implementation should figure it out and I should only have to "send"!

[link]

From: Mark Volkmann (Nov 04 2009, at 05:59)

Thank you for your kind words "Neither is great." ;-)

[link]

From: Mac (Nov 04 2009, at 09:28)

On the IDE front, I want to mention two more.

vimclojure: http://kotka.de/projects/clojure/vimclojure.html I use it with MacVIM, it's wonderful.

and La Clojure plugin for IntelliJ. It works with the open source community edition. I use this when I'm doing clojure work with java/grails/griffon. There is a plugin for both grails and griffon that let you write clojure code with it.

[link]

From: Patrick Logan (Nov 04 2009, at 16:59)

"fuck if I know if a more complex update function I send an agent will block"

I think you boil it down to one rule and you should be fine by-and-large:

* Most of the time the update is purely functional. Use send.

* Otherwise use send-off.

Probably either side of that rule will run into trouble in weird cases. But there you go.

[link]

author · Dad · software · colophon · rights
picture of the day
November 03, 2009
· Technology (85 fragments)
· · Coding (98 more)
· · Concurrency (70 more)
· · Java (123 more)

By

I am an employee of Amazon.com, but the opinions expressed here are my own, and no other party necessarily agrees with them.

A full disclosure of my professional interests is on the author page.