Clojure Programming/Getting Started
From Wikibooks, the open-content textbooks collection
This page walks you though several tasks for installing Clojure. You'll goes through the following steps.
- Install clojure either by downloading a prebuilt jar, or from the source
- Install several standard enhancements to clojure, such as making the REPL easier to use and creating a script to load the classpath for you
- Configure clojure for use with either emacs or vim
Once these steps are done, you'll be ready to get coding.
Contents |
[edit] Installation
Clojure is based on Java, so make sure that you have a current (1.5 or later) JVM installed.
[edit] Installing a JAR
The easiest way to start with clojure is to download the zip file available here [1]. Numbered releases append the version number to the jar file, e.g. clojure-1.0.0.jar.
However, Clojure is under active development, and you may want to download and build from source.
[edit] Installation from Source
You need Git to download the latest source code. To compile you need the Java Development Kit (javac) and either Maven (mvn) or Ant (ant). The examples below use mvn to run the build, but ant may be used in its place.
You can download the latest code using:
git clone git://github.com/richhickey/clojure.git
Then to compile:
cd clojure ant
[edit] Installation using MacPorts
Users running Mac OS X can install Clojure automatically using MacPorts. If MacPorts is not already installed, first go to http://www.macports.org and follow the directions there to install it.
Once MacPorts is installed, Clojure can be installed by issuing the command
sudo port install clojure +rlwrap
The "+rlwrap" part of the command can be left off (or changed to "+readline), but it is recommended, since it will include JLine and rlwrap for better history support in the REPL. Once Clojure has been installed with MacPorts, you can enter the REPL with the command
clj
or run a script with
clj myscript.clj
If Clojure is installed this way, the steps below related to creating a "clj" script and enhancing the REPL with JLine or rlwrap do not need to be performed.
[edit] Running Clojure
To start a clojure REPL:
java -cp clojure.jar clojure.main
or
java -cp clojure-1.0.0.jar clojure.main
Press Ctrl+C to get out of it.
For more usage options:
java -cp clojure.jar clojure.main --help
[edit] Enhancing the Environment
In this section we explain how to install some standard enhancements to clojure. You can either use rlwrap or JLine with the Clojure REPL to get functionality, like being able to press the up arrow to retrieve the previous command.
[edit] Enhancing Clojure REPL with JLine
Download JLine and copy the jar into the clojure directory. Then you can run:
java -cp jline-VERSION.jar:clojure.jar jline.ConsoleRunner clojure.lang.Repl
If you are on Ubuntu, you can install the JLine library like so:
sudo apt-get install libjline-java libjline-java-doc
Run 'dpkg -L libjline-java' to check the name of the library. On Ubuntu 8.0.4 you'll see something like this:
$ dpkg -L libjline-java /. /usr/share/java /usr/share/java/jline-VERSION.jar
Then run:
java -cp /usr/share/java/jline-VERSION.jar:clojure.jar jline.ConsoleRunner clojure.lang.Repl
If you want to run a script from the command line:
echo "(println \"Hello, World\")" > hello-world.clj java -cp clojure.jar clojure.lang.Script hello-world.clj
The clojure.lang.Repl startup method also supports script arguments. This differs from clojure.lang.Script startup in that scripts are loaded in the user namespace and Clojure enters the REPL instead of exiting after the scripts are loaded.
[edit] Create clj Script
A clj script is a convenient script to launch you clojure applications. Each of the recipes below depends on the jline library being installed.
[edit] Linux
For Linux users, here's a bash script[2] that will make using Clojure from the command line a little less verbose:
#!/bin/bash
CLOJURE_DIR=/path/to/clojure
CLOJURE_JAR=$CLOJURE_DIR/clojure.jar
if [ -z "$1" ]; then
java -cp $CLOJURE_DIR/jline-VERSION.jar:$CLOJURE_JAR \
jline.ConsoleRunner clojure.lang.Repl
else
java -cp $CLOJURE_JAR clojure.lang.Script $1 -- $*
fi
Put this in a file named "clj" and make it executable.
If your .clj script(s) will take command line arguments (*command-line-args*), there is a slight modification to the script:
#!/bin/bash
CLOJURE_DIR=/path/to/clojure
CLOJURE_JAR=$CLOJURE_DIR/clojure.jar
if [ -z "$1" ]; then
java -cp $CLOJURE_DIR/jline-VERSION.jar:$CLOJURE_JAR \
jline.ConsoleRunner clojure.lang.Repl
else
scriptname=$1
java -cp $CLOJURE_JAR clojure.lang.Script $scriptname -- $*
fi
[edit] Windows
For Windows users, here's the equivalent BATCH file:
@echo off
set CLOJURE_DIR=path\to\clojure
set CLOJURE_JAR=%CLOJURE_DIR%\clojure.jar
IF (%1)==() (
java -cp %CLOJURE_DIR%\jline-VERSION.jar;%CLOJURE_JAR% jline.ConsoleRunner clojure.main
) ELSE (
java -cp %CLOJURE_JAR% clojure.main %1 -- %*
)
Put this in a file named clj.bat.
After adding the location of the script to your path, you can either run a script:
clj hello-world.clj
or invoke the REPL:
clj
[edit] Enhancing Clojure REPL with rlwrap
To enhance the clojure REPL under Unix variants, one very useful utility is rlwrap.
It adds the following features to the Clojure interactive shell.
- Tab Completion
- Parenthesis matching
- History across Clojure sessions
- Vi or Emacs binding based on your readline .inputrc settings
As a first step build and install rlwrap. It might also be available as a part of you package repository for your GNU/Linux distribution. Ensure that rlwrap version 0.30 or above is in your path (previous versions have issues with multiline prompts).
[cljuser:~]% rlwrap -v rlwrap 0.30 [cljuser:~]%
Save the following bash script as clj and add it to your path after making it executable:
#!/bin/bash
BREAK_CHARS="(){}[],^%$#@\"\";:''|\\"
CLOJURE_DIR=/home/cljuser/install/clojure
CLOJURE_JAR=$CLOJURE_DIR/clojure.jar
if [ $# -eq 0 ]; then
rlwrap --remember -c -b $BREAK_CHARS -f $HOME/.clj_completions \
java -cp $CLOJURE_JAR clojure.lang.Repl
else
java -cp $CLOJURE_JAR clojure.lang.Script $1 -- $@
fi
Note that this script uses rlwrap and not JLine. The file ~/.clj_completions is the file rlwrap will use for providing tab completions.
Also, note that the file clojure.jar in the script should refer to whatever is the name of the jar built by either ant or maven. Ant builds clojure.jar. Similarly update cljuser in the script to be the username.
The following Clojure program can be used to generate this file:
(def completions (keys (ns-publics (find-ns 'clojure.core)))) (with-open [f (java.io.BufferedWriter. (java.io.FileWriter. (str (System/getenv "HOME") "/.clj_completions")))] (.write f (apply str (interleave completions (repeat "\n")))))
To generate completions for all the standard clojure namespaces (not just 'closure), substitute the first line of that code with the following definition.
(def completions (reduce concat (map (fn [p] (keys (ns-publics (find-ns p)))) '(clojure.core clojure.set clojure.xml clojure.zip))))
At this point you are good to go. Here are the settings from ~/.inputrc:
set editing-mode vi tab: complete set completion-ignore-case on set blink-matching-paren on
For the Vi key bindings, the user can use % for jumping to matching parenthesis in the interactive shell. For Emacs bindings the key is ????.
Invoke the REPL as clj
[cljuser:~]% clj Clojure user=> (de --> tab Desktop/ defmethod defstruct deref dec defmulti delay derive definline defn delay? descendants defmacro defn- destructure user=> (def --> tab definline defmacro defmethod defmulti defn defn- defstruct user=> (take- --> tab take-nth take-while user=> (take-
This REPL also remembers the symbols created by you:
[cljuser:~]% clj Clojure user=> (def foo 10) #'user/foo user=> (def foobar 20) #'user/foobar user=> (def foo-next 30) #'user/foo-next user=> (fo --> tab foo foo-next foobar for force user=> (fo
Happy REPLing!
[edit] User settings
clojure.lang.Repl will run all the files listed before it goes to the prompt. So I have my clj script updated to accept a .cljrc.clj file that has my settings.
(set! *print-length* 50) (set! *print-level* 10)
[edit] Installing clojure.contrib
Clojure contrib is a common library for clojure. Several projects depend on it, so it should be one of the first things you install. It is currently only available in source form, so check it out as follows:
git clone git://github.com/richhickey/clojure-contrib.git
Use ant to build, not maven (just type ant in the trunk subdirectory). Add clojure-contrib.jar from that trunk directory to the classpath in your startup script:
java -cp $CLOJURE_JAR:$CONTRIB_JAR clojure.lang.Repl
Or skip building the clojure-contrib.jar and add clojure-contrib/src to your classpath instead.
[edit] Editors/IDEs
[edit] Emacs / inferior-lisp
Emacs can take care of installing Clojure and the necessary Emacs integration libraries for you. First install clojure-mode.el, either from ELPA (the Emacs package manager) or manually. With this installed you'll get syntax highlighting and indentation when you open .clj files.
Then when it's done press M-x clojure-install, and it will download, compile, and configure Clojure, Clojure Contrib, SLIME, and the Swank-Clojure adapter. The installation process requires a JDK 1.5+, git, and ant. It will give you instructions about what config to copy to your .emacs file so Clojure will work for future sessions.
Now M-x slime launches Clojure in a subprocess with buffers you can use to interact with it. It may be easiest to run it in a separate buffer in the same frame (via C-x 2, switch between windows using C-x o)
M-C-x will send whatever expression the point is in to the lisp buffer, with the key defines above, C-x C-e will send the previous expression to the lisp buffer and C-c C-k will send the entire working buffer to the lisp buffer, useful when you've made a bunch of changes and don't want to reload them individually. M-p cycles through the repl entry history.
Note to GNU Emacs users on Windows: If the absolute file name of the directory containing clojure.jar has spaces, an easy workaround is to set the inferior-lisp-program variable to the name of a batch file that starts the REPL. Just ensure that the batch file doesn't launch the REPL using the jline.ConsoleRunner.
[edit] Emacs tab completion
This trick was found somewhere on the internet. add after clojure configuration is done
(defun indent-or-expand (arg) "Either indent according to mode, or expand the word preceding point." (interactive "*P") (if (and (or (bobp) (= ?w (char-syntax (char-before)))) (or (eobp) (not (= ?w (char-syntax (char-after)))))) (dabbrev-expand arg) (indent-according-to-mode))) (defun my-tab-fix () (local-set-key [tab] 'indent-or-expand)) ;; add hooks for modes you want to use the tab completion for: (add-hook 'c-mode-hook 'my-tab-fix) (add-hook 'sh-mode-hook 'my-tab-fix) (add-hook 'emacs-lisp-mode-hook 'my-tab-fix) (add-hook 'clojure-mode-hook 'my-tab-fix)
[edit] Emacs / Slime / Clojure on Ubuntu - Tutorial
A detailed tutorial for installing clojure, emacs and slime on Ubuntu is available here: UbuntuSetup
[edit] Vim
The state of the art in using Vim to edit Clojure code is the VimClojure plugin (recently merged with the Gorilla plugin, and depends on having a Ruby-enabled Vim (A Windows build of vim including Ruby support can be found here)).
With VimClojure set up, you have:
- syntax highlighting (including rainbow parens) and indenting
- a REPL buffer inside Vim (with command history, highlighting and indenting)
- the ability to evaluate code from your program
- documentation lookup, omni-completion, and more
Gorilla is in active development (particularly to remove the Ruby dependency), but is very stable and useful.
Both VimClojure and Gorilla were created by, and are maintained by, Meikel Brandmeyer.
Some notes on these plugins:
- Two (out of date) screencasts can be viewed: VimClojure and Gorilla.
- A more UpToDate-Screencast can be found at: Installing VimClojure
- Installation instructions are included at the plugin pages. Note that Gorilla comes with a file gorilla.jar that needs to be in your classpath when you run Gorilla.
- The way to use Gorilla is this: run it (so that a REPL server is in operation), then open a Clojure file in Vim. \sr will start a REPL buffer; \et will evaluate the expression under the cursor; see :help gorilla.txt for more.
[edit] Completions
If you are using the VimClojure plugin from the previous section, Ctrl-N completions should work for you out of the box and you don't really need to bother with this section.
However, if you are using the bleeding edge Clojure from the sources, there may be some additions / changes to the API. If this is the case, you would need to generate an updated list of completions for Clojure. This can be created using the Clojure script from section Clojure_Programming#Enhancing_Clojure_REPL_with_rlwrap. Once generated this completions file may be linked into your VimClojure plugin or you could update your .vimrc. Note that the completions generator script is already available as a part of the VimClojure plugin.
Once you have the file ~/.clj_completions add the following line to your ~/.vimrc.
au Bufenter,Bufnewfile *.clj setl complete+=k~/.clj_completions
With this setting you should be able to use Ctrl+N in insert mode to see possible completions. For example, takeCtrl+N will show take-while, take-nth and take in a drop-down list.
[edit] Other ways to communicate with a REPL from Vim
If you are unwilling or unable to run Gorilla, there are two other ways you can access a Clojure REPL from Vim.
Chimp is the precursor to Gorilla. It uses screen to send text to a running REPL. It is far less convenient that Gorilla, but better than nothing.
This article describes exactly the same basic idea as Chimp, but is a more lightweight plugin.
As these two approaches rely on Screen, they are essentially available on Unix-like (including Cygwin) systems only.
[edit] Clojure in a box
An all in one win32 emacs + clojure installer, the quickest way to get started:
[edit] Eclipse
There are a couple Eclipse plug-ins for Clojure development, the most prominent one being Counterclockwise.