Hacking on the Clojure application

by

Being able to write, build and run a Clojure application, like I explained in a previous article, is not enough. You also want to hack on it, to iterative code on it, after all, you are using a Lisp.

What I mean by iterative coding is something not very few know or do, but it’s extremely common in Lisp. You have you REPL running all the time (that is, generally, the interpreter). You load the code into the REPL, run it, modify some part of the code and re-load it. You may not reload the whole file but only a function on it, and you may have background process running on the REPL, like a web server. It is very powerful.

After I made the application just like in How to create a Clojure application I’ve found out that I couldn’t just load the file into Slime because the Clojure REPL process didn’t have the right class-path.

I’ve found two solutions for this problem. Let’s start with the one I’m actually using. If I run this:

mvn dependency:copy-dependencies

on a Maven project I end up with all the dependency jars in the directory target/dependency. Having all files in one location makes it easier. I just write a project.el in the directory of my project containing something like:

(add-to-list 'swank-clojure-extra-classpaths (expand-file-name "target/dependency/*" (file-name-directory load-file-name)))

and I load that file (M-xload-file<return>project.el<return>) before I start to work on the project. It is like opening the project. After that, firing Slime just works. It seems it’s not possible to change the class-path of a running Java process, which means that when dependencies change, I’ll have to restart your REPL anyway. I suppose the JVM designers were not thinking on interactive programming environments when they designed it. Hopefully this would only be a problem at the start of a project.

The other solution is to run:

mvn dependency:build-classpath

which the way I configure it, it outputs the class-path to target/classpath, looking something like:

/home/pupeno/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar:/home/pupeno/.m2/repository/jvm/clojure/clojure-lang/1.0-SNAPSHOT/clojure-lang-1.0-SNAPSHOT.jar:/home/pupeno/.m2/repository/trail-taglib/trail-taglib/0.2/trail-taglib-0.2.jar

which then I can use to set the class-path of the Slime process. I was about to write a Emacs Lisp function to load that file and set the class-path, but my knowledge of Emacs Lisp is very limited and I want to code in Clojure, not Emacs Lisp, so I didn’t make this way work, although I believe it’s the cleaner.

I’ve also tried working with Enclojure in NetBeans. It should just work, but I’ve got an error installing the latest Enclojure in the latest NetBeans and I just reverted to good old Emacs.

If you haven’t noticed, this is another article mainly for myself.

You may also like:

If you want to work with me or hire me? Contact me

You can follow me or connect with me:

Or get new content delivered directly to your inbox.

Join 5,047 other subscribers

I wrote a book:

Stack of copies of How to Hire and Manage Remote Teams

How to Hire and Manage Remote Teams, where I distill all the techniques I’ve been using to build and manage distributed teams for the past 10 years.

I write about:

announcement blogging book book review book reviews books building Sano Business C# Clojure ClojureScript Common Lisp database Debian Esperanto Git ham radio history idea Java Kubuntu Lisp management Non-Fiction OpenID programming Python Radio Society of Great Britain Rails rant re-frame release Ruby Ruby on Rails Sano science science fiction security self-help Star Trek technology Ubuntu web Windows WordPress

I’ve been writing for a while:

Mastodon