Exploring Clojure (Lisp on the JVM) - Part 2 - Setup
Thursday, October 23, 2008
Yesterday, I talked a little bit about Rich Hickey's new Lisp implementation Clojure. In this post, I'll talk about getting setup to use Clojure. If you already use a CL implementation with SLIME and Emacs, then getting setup with Clojure is pretty straight-forward. There is a quick start and a detailed installation tutorial; however, since I am already setup with SLIME/Emacs (for use with Common Lisp) and intend to use SLIME/Emacs with Clojure, I didn't need to follow all of the steps. I did the following:
- Downloaded the SVN version of Clojure:
svn co https://clojure.svn.sourceforge.net/svnroot/clojure clojureThere is a zip file as well; however, Rich is making changes/fixes on a regular basis, so I prefer to use the development copy of the code.
- Used Ant or Maven to build the Clojure code.
- Downloaded the GIT versions of clojure-mode (for editing Clojure
code in Emacs) and swank-clojure (for interacting with Clojure from
git clone git://github.com/jochu/clojure-mode.git git clone git://github.com/jochu/swank-clojure.git
- Created a bash script (named "clojure") to launch Clojure:
#!/bin/sh -e java -server \ -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888 \ -cp /Users/bc/lisp/clojure/clojure/target/clojure-lang-1.0-SNAPSHOT.jar:/Users/bc/.clojure/*:/Users/bc/lisp/clojure/clojure/target/* \ clojure.lang.ReplThe only things to note here are that:
- I start Java with "-server" so that I have a larger default heap
- I specify that I want to enable debugging with communications occuring on port 8888 (this is so that I can attach the JSwat debugger for debugging Clojure/Java code)
- I set the classpath to the required locations
- Since this bash script is going to be used as the executable called by SLIME (in my setup in the next step), I also start the Clojure REPL.
- Added the following lines to my .emacs file:
(add-to-list 'load-path (concat home-dir "lisp/clojure/clojure-mode")) (add-to-list 'load-path (concat home-dir "lisp/clojure/swank-clojure")) (setq swank-clojure-binary "clojure") (require 'clojure-auto) (require 'swank-clojure-autoload)These are just the additional lines that I've added (on top of my standard SLIME and Emacs setup code). Note that I set "swank-clojure-binary" to the name of the bash file that I created in the previous step.
M-- M-x slimeAnd, specify "clojure" at the prompt. The following screenshot shows some typical SLIME windows when using Clojure: In the upper-left window, is some Clojure code (the code is a Clojure version of Norvig's spelling corrector). In the bottom-left window is Inspector output (from the *ns* variable in the REPL window). In the right-hand window is the REPL with some interactions (using definitions from the Clojure code in the upper-left window).
If you're developing Clojure code that interoperates with Java code, it can be useful to have a debugger that lets you set breakpoints in both the Clojure code and the Java code. With my above setup, I can easily attach the Java JSwat debugger to localhost/8888 for debugging. The screenshot below shows the same code in the JSwat debugger after I attached to my Clojure REPL running in Emacs. The screenshot shows the execution stopped at a breakpoint in the Clojure code with the "Variables" debug window showing the values of variables:
Traditional Lisp debugging practices can still be used; however, using the JSwat debugger to debug a combination of Clojure and Java code can be useful!
Update-2008-11-18: With the latest Clojure AOT changes, the setup instructions I listed in this post will need a little tweaking. If you're getting started with Clojure and want a simple Emacs setup to begin with, you might want to look at my later post "A Basic Emacs Setup for Clojure"
Update-2008-12-05: I posted an update of my setup here: My Clojure Emacs Setup
Update-2009-05-28: There have been changes made to Clojure since this post was written and much of the material in this post is now out-of-date.