How to setup Clojure from scratch

My previous post about Clojure generated quite a bit of interest, so I thought I’d follow it up with something a bit more concrete. I primarily wrote this article for a friend who asked me for guidance on how to set it all up; and while this isn’t he only way to setup Clojure, I hope it will help other people who are also getting started with this great language.

As some people pointed out, setting up your Clojure environment can be slightly challenging. For example, when you install Ruby or Python, you can expect a Read-Eval-Print Loop (REPL) such as IRB or IDLE to be ready for you to use right out of the box, whereas the current version of Clojure (version 1.1) does not include an interactive top-level.

This post explains how to setup a Clojure environment step-by-step, including a working clj script (the common name for Clojure’s REPL). For this post I used the clj script contained within the Getting Started guide on Wikibooks as a base, but I built on top of it , so as to customize and improve it. In writing this post, I’ve made the assumption that you’re using a *nix environment. My instructions will be Mac OS X specific, even though it should be a breeze to adapt them for Linux, if required.

Step 1: Download and Build Clojure

The first step is to download and build the latest version of Clojure. (Please note, I used bit.ly below for code formatting reasons.)

$ cd /tmp
$ wget https://bit.ly/clojure
$ unzip clojure-1.1.0.zip
$ cd clojure-1.1.0
$ ant

This will generate several jars for us, including clojure.jar, which we’re interested in. Aside from clojure.core, we are also interested in clojure.contrib, a collection of useful libraries and functions that are often used in Clojure programs. To download and build clojure.contrib, follow these instructions:

$ cd /tmp
$ wget https://bit.ly/clojure-contrib
$ unzip clojure-contrib-1.1.0.zip
$ cd clojure-contrib-1.1.0
$ ant

This should generate a clojure-contrib.jar file. We can now proceed to copy both the clojure.jar and clojure-contrib.jar files to a convenient location. (You can copy the files with a single line, but for formatting reasons I split the operation into two copy operations).

$ mkdir -p ~/Library/Clojure/lib
$ cd ~/Library/Clojure/lib
$ cp /tmp/clojure-1.1.0/clojure.jar .
$ cp /tmp/clojure-contrib-1.1.0/clojure-contrib.jar .

Note that on Linux, you’d choose a different location (e.g., /opt/clojure/lib).

Step 2: Install rlwrap

Before we can proceed with creating a fancy clj script, we need rlwrap, which will make our interactive prompt much more friendly. On Mac OS X, if you are using MacPorts, you can simply run the following:

$ sudo port install rlwrap

Step 3: Create a clj script

Now we can finally finally create a clj script and save it as ~/Library/Clojure/clj:

#!/bin/sh
breakchars="(){}[],^%$#@\"\";:''|\"
CLOJURE_DIR=$HOME/Library/Clojure/lib
CLOJURE_JAR=$CLOJURE_DIR/clojure.jar
CONTRIB_JAR=$CLOJURE_DIR/clojure-contrib.jar
CLOJURE_CP=$CLOJURE_JAR:$CONTRIB_JAR:$PWD

if [ -f .clojure ]; then
	CLOJURE_CP=$CLOJURE_CP:`cat .clojure`
fi

if [ $# -eq 0 ]; then
	exec rlwrap --remember -c -b $breakchars \
                -f $HOME/.clj_completions \
                java -cp $CLOJURE_CP clojure.main -i $HOME/.clojure.clj --repl
else
     exec java -cp $CLOJURE_CP clojure.main -i $HOME/.clojure.clj $1 -- $@
fi

Make it executable and symlink it to a convenient place on your path (e.g., ~/bin):

$ chmod a+x ~/Library/Clojure/clj
$ ln -s ~/Library/Clojure/clj ~/bin/.

At this point we almost have a working script. Before declaring it fully functional, let’s take a look at three files this script references:

  • .clojure: This file is optional and is located in the same folder as the scripts you want to execute. It can be used to include further jars in your classpath.
  • ~/.clj_completions: Includes a list of Clojure functions for tab completion (courtesy of rlwrap).
  • ~/.clojure.clj: Your Clojure startup file. It’s the first Clojure file that’s run when we start the REPL or execute a script. We’ll use this to add a couple of nice functions to the default clj REPL, but you can add anything you’d like to load at startup.

Step 4: Create a startup file

By default, clj will not have an exit function. You can either CTRL+D or enter a call to System/exit. This is not a big deal, but I like the idea of exiting with a simple (exit) call (as one does with Ruby and Python). Fortunately, we can add this function to the startup file. Furthermore, for learning purposes, few things beat having the source function which reveals the source code of built-in Clojure functions. This too can be added to ~/.clojure.clj:

(use 'clojure.contrib.repl-utils)
(defn exit [] (System/exit 0))

(exit) will now exit the REPL and source will reveal the source code as shown below:

user=> (source peek)
(defn peek
  "For a list or queue, same as first, for a vector, same as, but much
  more efficient than, last. If the collection is empty, returns nil."
  [coll] (. clojure.lang.RT (peek coll)))
nil

Step 5: Create a ~/.clj_completions file

As explained in the Clojure Wikibook referenced above, you can create the .clj_completions file by running the following from the REPL or as a script (e.g., clj myscript.clj):

(def completions
    (reduce concat (map (fn [p] (keys (ns-publics (find-ns p))))
                        '(clojure.core clojure.set clojure.xml clojure.zip))))

(with-open [f (java.io.BufferedWriter. (java.io.FileWriter. (str (System/getenv "HOME") "/.clj_completions")))]
    (.write f (apply str (interleave completions (repeat "\n")))))

This will populate the file .clj_completions with a list of 500+ symbols. You can now run clj and try tab completion by inserting a few characters and then pressing tab. For example:

mbp:~ acangiano$ clj
Clojure 1.1.0
user=> (re<tab>
re-find                ref-min-history        repeatedly
re-groups              ref-set                replace
re-matcher             refer                  replicate
re-matches             refer-clojure          require
re-pattern             release-pending-sends  reset!
re-seq                 rem                    reset-meta!
read                   remove                 resolve
read-line              remove-method          rest
read-string            remove-ns              resultset-seq
reduce                 remove-watch           reverse
ref                    rename                 reversible?
ref-history-count      rename-keys            
ref-max-history        repeat 

There you have it, a complete setup of Clojure from source to clj. You can find information about setting up your favorite editor/IDE on the Assembla Wiki.

Note: As pointed out by Phil and other commenters elsewhere, the easiest way to get started these days is probably to install cljr, a standalone REPL and package manager. My post outlines how to do it from scratch (as you can deduct from the title), just like we used to before these tools were released. You may however consider the pre-packaged solution instead.

Get more stuff like this

Subscribe to my mailing list to receive similar updates about programming.

Thank you for subscribing. Please check your email to confirm your subscription.

Something went wrong.

11 Comments

  1. David Backeus July 13, 2010
    • David J. July 13, 2010
  2. Steve Miner July 13, 2010
    • Antonio Cangiano July 13, 2010
  3. Phil July 13, 2010
    • Antonio Cangiano July 13, 2010
  4. anjan bacchu July 13, 2010
    • Antonio Cangiano July 13, 2010
    • MC July 13, 2010
  5. ScottM July 14, 2010
    • ScottM July 14, 2010

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: