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 defaultclj
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.
The packages above can also be installed through Homebrew packages clojure, clojure-contrib and rlwrap.
+1 for homebrew. Doesn’t have duplication issues like MacPorts and keeps everything in a central folder for an easy uninstall.
wget is no longer a standard utility on Mac OS X. You can use ‘curl -O’ instead.
Good spotting, Steve. One can use curl, as you suggest, or install wget through MacPorts (
port install wget
) or Homebrew (brew install wget
).While I appreciate topics like this getting more coverage, I hope newbies don’t get the idea that it’s this complicated to get started with Clojure. These days it’s much easier to get started with a standalone repl using cljr or a project setup using Leiningen.
Hey Phil,
thanks for stopping by. While there are easier ways these days, I wanted to show how to do it from scratch (ergo the title), because, contrary to popular belief, it’s not that difficult. I updated the post with your suggestion, though.
hi there,
how about windows users ? step 1 and 2 seem to be similar assuming we have cygwin installed. How about other steps ?
BR,
~A
On Windows, you should really use cljr: http://github.com/liebke/cljr
Cygwin changes:
Assuming you have rlwrap in your path, you just need to fix the classpath so java doesn’t complain:
CLOJURE_CP=`cygpath -wp “$CLOJURE_CP”`
I also added multi-line ability to rlwrap:
exec rlwrap -m ‘\’ -r -c -b $breakchars ..etc..
so ctrl-^ opens an editor.
Don’t forget other rlwrap tricks like ctrl-r to search.
for some reason trying to perform step 5 completely kills my machine. can’t find out what’s broken as ps, top & activity monitor all hang
…rebooted and everything works fine.
Thanks for the guide.