I’ve been meaning to get back to Lisp for a while. Clojure meanwhile has been evolving as one of the up and coming languages. Perfect time to have a play.

If a language has a REPL I’m not going to start writing in an editor without a good interaction with that. First stop, Stack Overflow for suggestions. Lots of votes for Emacs? Time to find out how good my muscle memory is from a few years ago then.

Emacs package management has improved a bit in the last couple of years with the Emacs Lisp Package Archive. So first step is download Emacs for OS X then get package.el from the ELPA site.

Copy package.el to ~/.emacs.d. In ~/.emacs.d/init.el add the following

(add-to-list 'load-path "~/.emacs.d/")
(load "package")
(add-to-list 'package-archives
             '("marmalade" . "http://marmalade-repo.org/packages/"))

The last line adds a good source of Clojure packages to the list. Now start Emacs and use M-x package-list-packages. You probably want


(There’s a slime-clj but that seemed to break stuff for me.) Mark those with i and hit x to install them. That’s the Emacs side done.

Technomancy’s Leiningen seems the recommended route to package and project management for Clojure. And so far it is so easy I haven’t bothered looking for anything else. Download it from Github and follow the installation instructions (i.e. put it in your path). Create your first project via

lein new clj-test

To get Emacs and your project talking, in theory you should be able to open clj-test/project.clj (or anything else beneath the project directory) in Emacs and use M-x clojure-jack-in. That didn’t work for me so I’m currently using the two stage approach of running lein swank from a terminal in the project directory and M-x slime-connect in Emacs.

Now go write code.

One of the nice things about Leiningen is that it sets up unit test stuff for you. So as you put code into src/clj-test/core.clj

(defn tree-reduce [f i tr]
  (if (and (seq? tr) (empty? tr))
    (let [value (f i tr)]
      (if (seq? tr)
        (let [branches (rest tr)]
          (reduce (fn [v subtree] (tree-reduce f v subtree)) value branches))

(defn count-nodes [tree]
  (tree-reduce (fn [c tr] (+ c 1)) 0 tree))

you can put tests into test/clj-test/test/core.clj

(deftest test-count-nodes-empty
  (is (zero? (count-nodes '()))))

(deftest test-count-nodes-root
  (is (= 1 (count-nodes '(x)))))

(deftest test-count-nodes-simple
  (is (= 3 (count-nodes '(add 1 2)))))

(deftest test-count-nodes-two-deep
  (is (= 7 (count-nodes '(add (sub 1 2) (mul 3 4))))))

And these are run simply with lein test

$ lein test
Testing clj-test.test.core
branch index 0 remaining 0
Ran 4 tests containing 4 assertions.
0 failures, 0 errors.

For the purposes of learning the language I’m really enjoying this easy unit test configuration (and wondering why no-one has written “Learn … through Test Driven Development” books).

There are still rough edges I would like to iron out of this, but as a learning environment it’s fairly quick and easy.