Programming in Clojure

We are going to extend a Java system, which must be able to start Pig, Hive and Hadoop jobs. As a programmer with 19 years experience with C++, I have no interest to learn Java. I like Go, but I found no way to invoke Java API from Go. So I am going to retreat to Clojure, a Lisp dialect, which I am expecting as powerful as Lisp, the most expressive language ever.

This article is my learning note of Clojure, aiming at learn it as fast as possible to start development in production.

The Compiler

Clojure is a Java package. We can checkout the source code from Github and build it using Maven:

git clone https://github.com/clojure/clojure.git
cd clojure
mvn -T 6 install

This will give you target/clojure-1.7.0-master-SNAPSHOT.jar. When we run clojure.main in this pacakge, we got a REPL:

java -cp target/clojure-1.7.0-master-SNAPSHOT.jar clojure.main

The Hello World Program

Write a hello world program, say /tmp/app.hello.clj:

(ns helloworld (:gen-class))
(defn -main [& args] (println "Hello world!"))

We can build this program from within the REPL:

cd /tmp
java -cp ~/Projects/clojure/target/clojure-1.7.0-master-SNAPSHOT.jar clojure.main
=> (compile 'app.hello)

If compile prompts error messages like

CompilerException java.io.IOException: No such file or directory, compiling:(app/hello.clj:1:1)

you need to create a directory name classes in the current directory:

mkdir /tmp/classes

and compile the program again. This should give you /tmp/classes/app/hello.class. You can run this program:

java -cp ~/Projects/clojure/target/clojure-1.7.0-master-SNAPSHOT.jar:/tmp/classes app.hello

which should print

Hello world!

The Build System

Above build procedure is unbearablly complex. Usually people build Clojure projects using Leiningen. To install Leiningen on Mac OS X:

brew update && brew doctor && brew install leiningen

Then you can create a project using Leiningen

cd /tmp
lein new app hello

This creates a directory hello containing a template program. You can build it using

cd hello
lein uberjar

This creates /tmp/hello/target/hello-0.1.0-SNAPSHOT-standalone.jar. You can run it as:

java -cp /tmp/hello/target/uberjar/hello-0.1.0-SNAPSHOT-standalone.jar hello.core

Or, a simple form is

cd /tmp/hello
lein run

The Editor

Most Clojure programmer use Emacs. You can use Homebrew to install Emacs 24 on Mac OS X:

brew install --cocoa --srgb emacs

Then we can use package package to install Clojure related plugins. In Emacs, type C-x list-packages, you will see a list of packages. Type i to mark for installation, u for unmark, d for uninstall, and x for execute (start install and uninstall). You need to install clojure-mode and cider.