Setting up Clojure, Incanter, Emacs, Slime, Swank, and Paredit

Emacs is the favored development environment for the majority of Clojure developers, and there are good reasons for that, but personally, I don’t think it should be the first choice of developers new to Clojure, unless they have used it previously; it’s just too much to learn at once.

I recommend people use an editor they’re comfortable with, combined with a command-line REPL. There is no reason to tackle the complexities of configuring and using Emacs, Slime, and Swank until you’ve got your head around the basics of Clojure and functional programming. Once you’ve got the basics down though, it’s worth venturing into the arcane world of Emacs. You may decide it’s not for you, and luckily there are alternatives, from your favorite editor combined with a REPL to plugins for popular IDEs like Netbeans (Enclojure), IntelliJ (La Clojure), and Eclipse (Counter-Clockwise).

But you’ll never know if it’s for you unless you give it a try. So, I’ll be demonstrating how to build and install Incanter (which includes Clojure and Clojure-contrib), and then set up a development environment with Emacs, Slime, Swank, and Paredit.

Setting up Clojure and Incanter

Incanter is available on Clojars, so you can include it in your projects by adding it as a dependency in your project.clj file (see below). Alternatively, you can clone the full distribution from Github, which includes REPL and Swank start up scripts. Note: The repl scripts are necessary, since Leiningen’s repl task does not work correctly with Clojure 1.2.

The following examples will assume you cloned Incanter’s github repository (see below for instructions) and have the repl and swank scripts included with the distribution.

First, you’ll need Git and Leiningen to grab and build Incanter. First clone Incanter from its Github repository:

$ git clone git://github.com/liebke/incanter.git

This will create an incanter subdirectory

$ cd incanter

Use lein deps to downloads the necessary dependencies:

$ lein deps

Once this process is complete, you can start a Clojure REPL with all of Incanter’s dependencies pre-configured on the CLASSPATH by either using the repl scripts included in the script/ directory.

$ script/repl

or on Windows,

$ script/repl.bat

or you can start it directly with the java command:

$ java -cp 'lib/*' clojure.main

This will present you with the user=> prompt. As a simple example of using Incanter from the REPL, we’ll generate a line plot of the sine function over the range -4 to 4, first load the necessary Incanter libraries:

user=> (use '(incanter core charts))

and then use the function-plot function:

user=> (view (function-plot sin -4 4))

Now that we know Incanter and Clojure are installed correctly, let’s set up an Emacs development environment.

Setting up and using Emacs, Swank, Slime, and Paredit

I’m a long time vi/vim user and I typically use MacVim, but I have recently gone back to Emacs (the editor I used when I first learned Lisp) in order to take advantage of Slime, Swank, and Paredit. Doing most of my development on a Macbook, I like Aquamacs, which blends standard OS X and Emacs behaviors. Another nice option on the Mac is Carbon Emacs.

The procedure I’m going to use to setup the Emacs development environment is based on the instructions provided by Phil Hagelberg (a.k.a Technomancy) in this blog post and in the README for his fork of swank-clojure.

The best way to install the necessary packages (clojure-mode, slime, slime-repl, swank-clojure) is by using the Emacs Lisp Package Archive, or ELPA.

To access ELPA, use the following command:

M-x package-list-packages

The meta-key on the Mac for most flavors of Emacs is the command key, but with Aquamacs it’s the alt/option key.

If the ‘package-list-packages’ command cannot be found, you’ll need to paste the following snippet of elisp in your *scratch* buffer and then evaluate it, (go here for more detailed instructions).

 (let ((buffer (url-retrieve-synchronously
	       "http://tromey.com/elpa/package-install.el")))
  (save-excursion
    (set-buffer buffer)
    (goto-char (point-min))
    (re-search-forward "^$" nil 'move)
    (eval-region (point) (point-max))
    (kill-buffer (current-buffer))))

In Aquamacs, you’ll evaluate it by placing your cursor right after the last parentheses and entering:

C-x C-e

On most other version of Emacs, including Carbon Emacs, you’ll enter

C-j

Once this has been done, you should be able access ELPA with:

M-x package-list-packages

You’ll see a list of packages, either scroll down to find or search for, using C-s, the following packages:

  • clojure-mode
  • slime
  • slime-repl
  • swank-clojure
  • paredit

When you’re cursor is on the appropriate package, hit the i key to select it. Once all the packages are selected, hit x to begin their installation. When it’s complete, you might see some warnings, but don’t worry about them.

Slime is an Emacs-mode for editing Lisp/Clojure code and Swank is a back-end service that Slime connects to, letting you evaluate Clojure code from within Emacs. Paredit provides some additional Clojure/Lisp editing functionality, although, like Emacs, it requires some getting used to (see mudphone’s introduction to Paredit presentation and the Paredit cheat sheet).

Now it’s time to start up a Swank server that will let us run Clojure code from Emacs. We can use Leiningen to start one up that is pre-configured with all of Incanter’s dependencies with the script/swank script, or by running the following Leiningen command Incanter directory:

$ lein swank

This will generate some messages, ending with

Connection opened on local port  4005
#<ServerSocket ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=4005]>

Now we need to connect to the server from Emacs with the following command:

M-x slime-connect

It will prompt you for the IP address and port of the server, just use the defaults it offers. It may then show the following prompt:

Versions differ: nil (slime) vs. 2009-09-14 (swank). Continue? (y or n)

Just say ‘yes’. You will then get a message confirming you’re connected, and a window will open with a Clojure REPL and a ‘user>’ prompt. A cool feature of slime-connect is that you can connect to a swank server on a remote system, just provide the system’s IP address or host name, instead of the default 127.0.0.1, when prompted.

Now open or create a Clojure file, using ‘C-x C-f’ (or using ‘command-o’ or ‘command-n’ in Aquamacs). If you’re creating a new file, give it a *.clj suffix and Emacs will start clojure-mode automatically.

Now start up Paredit,

M-x paredit-mode

You’re now ready to edit Clojure code. Start by loading a few Incanter libraries with the following line:

(use '(incanter core stats charts))

You’ll notice that closing parens are automatically created when you create an opening paren, this is due to Paredit. You can evaluate this block of code by placing your cursor right after the last paren, and entering ‘C-x C-e’. You should see the return value, nil, in the Emacs message pane.

Now let’s generate a plot of the PDF of the Normal distribution, over the range -3 to 3, by entering and evaluating the following line:

(view (function-plot pdf-normal -3 3))

That’s it, you’re all set up. Have fun!

See also:

30 responses to “Setting up Clojure, Incanter, Emacs, Slime, Swank, and Paredit

  1. As far as Emacs for OSX goes, there’s a native Cocoa build as of Emacs 23 that’s worth mentioning alongside Carbon and Aqua. You can grab just the Cocoa app at: http://www.emacsformacosx.com/

    Also, with the swank-clojure package, you just need to issue ‘M-x slime’ and it will drop you into a REPL without needing to fire one up with Maven beforehand. It will even install Clojure for you! (See docs: http://github.com/technomancy/swank-clojure )

    Great writeup!

    • Thanks for pointing out some additional options and configurations, and for providing a link to Technomancy’s fork of swank-clojure (I was just about to add that to the post).

      David

  2. Thanks for the detailed introduction- it is greatly appreciated. I’ve been happy with vim-clojure so far but it is hard not to get jealous of paredit and the overall slick integration emacs provides.. I think I may be joining the dark side with you soon… However, I think I’ll have to keep my movement keys via viper mode. :)

    • It is nice to have viper-mode around, I still think vi’s movement keys are the best. However, I’ve been trying life without viper-mode, and depending entirely on Paredit; it takes some getting used to, but it is pretty cool.

  3. Is there a good way to set this up with leinengen instead of using maven?

    • I had intended to use Leiningen for Incanter’s build process, but I ran into enough difficulties that I gave up and went with Maven (with the help of several people more familiar with Maven than me). And It looks like Maven 3 will soon have the ability to create Clojure-based config files, and the syntax looks a lot like Leiningen’s.

      You can certainly create Incanter projects with Leiningen (see my earlier posts), and then use ‘lein swank’ to start the swank server.

  4. So I got to the part about “mvn clojure:repl” and it didn’t work, gave a build error (plugin ‘org.apache.maven.plugins:maven-clojure-plugin’ does not exist or no valid version could be found).

    What do you think? Hope you could help…

    bin/clj works though. Build using “mvn install” worked perfectly, no errors.

    I’m hoping to use “mvn clojure:swank” (which currently gives a similar error as above) so I could connect to it via emacs (and maybe then I could stop using octave/matlab!).

    The entire part about using emacs elpa to install clojure-mode etc. was great. Beats pulling all the different parts using git! Thanks!!

    • That’s my fault, I recently pushed a new, more modular, version of Incanter to github, and I need to update the blog post to reflect some changes. See this post in the Google group for more information.

      To start swank now, just use the bin/swank script. All it does is run ‘mvn clojure:swank’ from the modules/incanter-app directory. You can run ‘mvn clojure:repl’ from that directory as well.

      I’m going to update the blog post to reflect these changes. Thanks for pointing them out.

      David

  5. Just to be clear: to run mvn clojure:repl after the install step:

    (1) cd modules/incanter-app/
    (2) mvn clojure:repl

    • You are correct, and I just updated my previous comment to reflect the recent name change of the incanter-bundle directory to incanter-app. Hopefully, this will be the last name change.

  6. I had some issues after a successful installation in Windows 7, using mvn install and even though I can start the REPL using
    mvn clojure:repl
    I get an error when I try to start swank with
    mvn clojure:swank

    The exception I get is this

    Exception in thread “main” clojure.lang.LispReader$ReaderException: java.lang.NumberFormatException: Invalid number: 2009-09-14

    I could not identify the source of the problem but I will look into it a little better tonight.

    Thank you. I have not tried Incanter yet but I am sure it will be very useful.

    • That’s very interesting. If you figure out the issue, please let me know. I’m very interested in feedback from Windows users.

      You might also try creating a simple project using Leiningen, and see if ‘lein swank’ works on Win7 (see: this post)

      Thanks,
      David

      • Just a simple note (I have not managed to correct it yet), but 2009-09-14 is probably the swank version (and it is somehow passed as a numeric argument?). Is this a jochu/swank-clojure?

      • OK. I have not managed to pinpoint the problem, nor have I run Incanter with Lein. I am going to document a workaround that got me working with Incanter in Emacs in Windows 7 soon. With Lein finally, albeit not sure maven was the problem as this is a workaround.

    • It’s swank-clojure version 1.1.0-SNAPSHOT on Clojars, so it’s either jochu’s or technomancy’s, I’m not sure which.

    • Christos,

      I didn’t realize that the message you were getting was: ‘Versions differ: nil (slime) vs. 2009-09-14 (swank). Continue? (y or n)’.

      I get that too when I use Maven to start Swank, and I don’t get it when I use Leiningen. But just select ‘y’ to continue, it doesn’t cause any problems that I’ve noticed.

      I mentioned this error in the in the post above because I knew it would cause confusion.

      Good luck,
      David

      • David, this was not the problem. I got the errors when building clojure:swank. I (almost) give a detailed account of the steps (failures and not) that I did take to resolve this issue in my blog, but the synopsis of my workaround so that everything is available in this site is:

        1. install swank-clojure using ELPA (technomancy’s instructions)

        2.open powershell as administrator

        3.set-executionpolicy remotesigned

        4.follow liebke’s instructions on lein installation (it includes a link with a powershell implementation of lein by Roland Sadowski). I got an error on uberjar creation (something from zip – did not look into it).

        5.follow liebke’s instructions on lein swank. I got an error again when evaluating lein swank, but it was clojure error, so I tried the following.

        6.start emacs -> M-x swank-clojure-project
        when prompted for directory choose the incanter-swank (or however you named it) directory from step 5.

        (I can’t add the links but most are to incanter-blog or can be found in it already)

    • Christos, thanks for provided the details necessary to get swank running on Windows.

      -David

  7. I am running XP and already have project clojure (emacs, swank, clojure) installed. How do I connect to incanter? thx!!

  8. I am having trouble with this installation on XP with an existing ‘Project Clojure’ install. These are the steps I have taken:

    1. Download and install maven. (note: on the maven website they instruct you on setting up and assigning some user variables. this is a mistake. all of the variables must be configured as system variables in order for things to work proprerly!)

    2. Install JDK. My current setup is a ‘Project Clojure’ installation, which only uses a JRE. So, you need to install the JDK and then make some additional changes to your environment variables as described on the maven website.

    3. In a windows command window I enter:

    mvn install

    This command downloads a bunch of stuff, but then reports a problem: clojure failed BUILD ERROR. it suggests using mvn -e

    so I run it again:

    mvn -e install

    I see a couple of errors. The first one is:

    ERROR in (is-within-date-range) (chrono_test.clj:117)
    expected: (= false (is-within? in [e nil]))
    actual: java.lang.IllegalArgumentException: No interval converter found for type: org.joda.time.DateTime

    • How long ago did you download Incanter? I ask because the error you saw:

      ERROR in (is-within-date-range) (chrono_test.clj:117)
      expected: (= false (is-within? in [e nil]))
      actual: java.lang.IllegalArgumentException: No interval converter found for type: org.joda.time.DateTime

      should have been eliminated a while back. Try a git pull from the Incanter directory, and see if that helps.

      If it doesn’t, try downloading the pre-built version of Incanter from http://incanter.org, or better yet, if you are using Leiningen for your existing project, you don’t have to manually download and install Incanter at all. Just follow the directions at http://repo.incanter.org to include Incanter as a dependency in your project.

      David

  9. This was the latest pre-built version of incanter i downloaded yesterday. I do not know what Leiningen is, but I went to their website, which said:

    On Windows you can download lein.bat, instead, though support on that platform is still experimental.

    • That’s very strange, I don’t know why the incanter.chrono test error is there then. I just downloaded and mvn installed the latest version on the Incanter website without error.

      I assume you’ve tried bin\clj.bat and it started a repl and you have been able to at least play with the Incanter libraries?

      Is your goal to start a swank server for use with Emacs? If so, I’d suggest telling Maven to skip the tests during install, with the following command:

      mvn install -Dmaven.test.skip

      then cd to the modules/incanter-app directory and start a swank server with the following command:

      mvn clojure:swank

      David

  10. I, do not have git. I am on Windows XP.

  11. Ok, I installed as you suggested. When I try to run swank server, I get the following:

    C:\Program Files\incanter\modules\incanter-app>mvn clojure:swank
    [INFO] Scanning for projects…
    [INFO] ————————————————————————
    [INFO] Building Incanter App Jar
    [INFO] task-segment: [clojure:swank]
    [INFO] ————————————————————————
    [INFO] Preparing clojure:swank
    [INFO] [resources:resources {execution: default-resources}]
    [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources,
    i.e. build is platform dependent!
    [INFO] skip non existing resourceDirectory C:\Program Files\incanter\modules\inc
    anter-app\src\main\resources
    [INFO] snapshot org.incanter:incanter-core:1.2.0-SNAPSHOT: checking for updates
    from build.clojure.org
    [INFO] snapshot org.incanter:incanter-core:1.2.0-SNAPSHOT: checking for updates
    from clojars.org
    [INFO] snapshot org.incanter:incanter-io:1.2.0-SNAPSHOT: checking for updates fr
    om build.clojure.org
    [INFO] snapshot org.incanter:incanter-io:1.2.0-SNAPSHOT: checking for updates fr
    om clojars.org
    [INFO] snapshot org.incanter:incanter-chrono:1.2.0-SNAPSHOT: checking for update
    s from build.clojure.org
    [INFO] snapshot org.incanter:incanter-chrono:1.2.0-SNAPSHOT: checking for update
    s from clojars.org
    [INFO] snapshot org.incanter:incanter-processing:1.2.0-SNAPSHOT: checking for up
    dates from build.clojure.org
    [INFO] snapshot org.incanter:incanter-processing:1.2.0-SNAPSHOT: checking for up
    dates from clojars.org
    [INFO] snapshot org.incanter:incanter-charts:1.2.0-SNAPSHOT: checking for update
    s from build.clojure.org
    [INFO] snapshot org.incanter:incanter-charts:1.2.0-SNAPSHOT: checking for update
    s from clojars.org
    [INFO] snapshot org.incanter:incanter-mongodb:1.2.0-SNAPSHOT: checking for updat
    es from build.clojure.org
    [INFO] snapshot org.incanter:incanter-mongodb:1.2.0-SNAPSHOT: checking for updat
    es from clojars.org
    [INFO] snapshot org.incanter:incanter-pdf:1.2.0-SNAPSHOT: checking for updates f
    rom build.clojure.org
    [INFO] snapshot org.incanter:incanter-pdf:1.2.0-SNAPSHOT: checking for updates f
    rom clojars.org
    [INFO] [compiler:compile {execution: default-compile}]
    [INFO] No sources to compile
    [INFO] [clojure:swank {execution: default-cli}]
    WARNING: reader macro ^ is deprecated; use meta instead
    WARNING: reader macro ^ is deprecated; use meta instead
    WARNING: reader macro ^ is deprecated; use meta instead
    WARNING: reader macro ^ is deprecated; use meta instead
    WARNING: reader macro ^ is deprecated; use meta instead
    WARNING: reader macro ^ is deprecated; use meta instead
    WARNING: reader macro ^ is deprecated; use meta instead
    WARNING: reader macro ^ is deprecated; use meta instead
    WARNING: reader macro ^ is deprecated; use meta instead
    Exception in thread “main” clojure.lang.LispReader$ReaderException: java.lang.Nu
    mberFormatException: Invalid number: 2009-09-14
    at clojure.lang.LispReader.read(LispReader.java:180)
    at clojure.core$read__4316.invoke(core.clj:2525)
    at clojure.core$read__4316.invoke(core.clj:2523)
    at clojure.main$eval_opt__6210.invoke(main.clj:225)
    at clojure.main$initialize__6215.invoke(main.clj:246)
    at clojure.main$null_opt__6238.invoke(main.clj:271)
    at clojure.main$main__6253.doInvoke(main.clj:346)
    at clojure.lang.RestFn.invoke(RestFn.java:458)
    at clojure.lang.Var.invoke(Var.java:377)
    at clojure.lang.AFn.applyToHelper(AFn.java:176)
    at clojure.lang.Var.applyTo(Var.java:482)
    at clojure.main.main(main.java:37)
    Caused by: java.lang.NumberFormatException: Invalid number: 2009-09-14
    at clojure.lang.LispReader.readNumber(LispReader.java:218)
    at clojure.lang.LispReader.read(LispReader.java:136)
    at clojure.lang.LispReader.readDelimitedList(LispReader.java:1057)
    at clojure.lang.LispReader$ListReader.invoke(LispReader.java:897)
    at clojure.lang.LispReader.readDelimitedList(LispReader.java:1048)
    at clojure.lang.LispReader$ListReader.invoke(LispReader.java:897)
    at clojure.lang.LispReader.read(LispReader.java:145)
    … 11 more
    [INFO] ————————————————————————
    [ERROR] BUILD ERROR
    [INFO] ————————————————————————
    [INFO] Clojure failed.
    [INFO] ————————————————————————
    [INFO] For more information, run Maven with the -e switch
    [INFO] ————————————————————————
    [INFO] Total time: 1 minute 7 seconds
    [INFO] Finished at: Sun Mar 28 14:34:07 EDT 2010
    [INFO] Final Memory: 12M/29M
    [INFO] ————————————————————————

  12. “mvn install” leads to a BUILD ERROR

    “””Cannot execute mojo: resources. git It requires a project with an existing pom.xml, but the build is not using one.”””

    I’m reporting this to the incanter google group

    • Incanter no longer uses Maven for builds (not since version 1.0). You’ll need to install Leiningen and use the script/install script to build and install each module.

Leave a comment