I've just (15th February 2011) had to set this up again for someone on an Ubuntu 10.10 box.

And to my speechless amazement (16th February 2011), it worked absolutely the same way on Radek Ostrowski (a complete stranger) 's mac at dev8d, thus condemning him to years of suffering at the hands of Aquamacs.

This method is still my favourite, still the one I actually use in practice, and still the easiest, and it's been stable for about a year now.

Since I've just confirmed that it still works, I've moved it back to the top.

Install maven:

$sudo apt-get install maven2

Then create a pom.xml file to tell maven which repositories to use. There's an example below to copy and paste.

Once you've got maven installed, and made a pom.xml file, then:

$mvn clojure:repl

Will start a REPL with clojure 1.2 and clojure-contrib 1.2 on the classpath. The REPL should use jLine to give it editing and history on all platforms.

If you like to use EMACS instead, then

$mvn clojure:swank

Will start a swank server, which you can connect to with M-x slime-connect.

That's it from the clojure side.

To set up emacs, and equip it to talk to the clojure swank server:

$sudo apt-get install emacs

Then install the emacs lisp package archive (see http://tromey.com/elpa/) by evaluating this code:

(cut and paste it into the scratch buffer, put the cursor in the middle, and use M-C-x):

Now use M-x package-list-packages to bring up the list of packages, and use i and then x to mark and then install slime, slime-repl, and clojure-mode.

Then connect emacs to the already running clojure image with M-x slime-connect

That should be it. You should now be at a running clojure 1.2 repl inside emacs.

Here's an example of a pom.xml file that pulls in clojure and clojure-contrib 1.2 . Just cut and paste it.

As well as the essentials, I've also added: the clojars.org repository, where many useful clojure packages live; the maven versions plugin, which helps with keeping everything cutting edge; and jline so that command line repls work better (mvn clojure:repl)

I like to have my startup repls conditioned a little, so if you have a startup script that you always want to run, add this snippet

<configuration>

<replScript>startup.clj</replScript>

</configuration>

to the clojure-maven-plugin section so that when maven starts a repl, the code in startup.clj is loaded as the first action. This is a good place to set print-length and print-level, so that they will be set before the swank server starts, which means that you won't hang emacs by evaluating an infinite sequence.

I also like to require everything on the classpath, so that I can use things like find-doc to find out about everything.

pom.xml files look terrifying, but they're really not. It's just that xml is such a godawful verbose way to write things out.

It contains: the addresses of three repositories which hold vital code; the names and versions of four vital jar files that you need; and the names and versions of two helpful maven plugins.

;; Numerical Integration: Better Approximations
;; Remember our example function:
(defnsquare[x] (* x x))
;; We're trying to find ways to calculate the 'area under its graph between 0
;; and 2', or the 'integral over the interval [0,2]'
;; A better estimate of this area under the graph is to imagine a trapezium
;; which has its base corners at (0,0) and (2,0), and the top corners at
;; (0,(square 0)) (2, (square 2)), and calculate the area of that.
;; More generally, if the interval we're interested is [a,b], and the function's
;; values there are fa and fb, then the area of the trapezium will just be:
(defntrapezium [a fa b fb]
(* 1/2 (- b a) (+ fa fb)))
;; Another way to think about that is that it's the length of the interval
;; multiplied by the average of the values of the function at the ends.
;; So another approximation to the integral of f over [a,b] is:
(defntrapezium-rule [f a b]
(trapezium a (f a) b (f b)))
(trapezium-rule square 0 2) ; 4
;; We can make another approximation by using the trapezium rule on the two
;; subintervals [0,1] and [1,2] and adding the results
(+ (trapezium-rule square 0 1)
(trapezium-rule square 1 2)) ; 3
;; And an even better one by splitting those subintervals in half
(+ (trapezium-rule square 0 1/2)
(trapezium-rule square 1/2 1)
(trapezium-rule square 1 3/2)
(trapezium-rule square 3/2 2)) ; 11/4
;; And so on...
(defniterated-rule [rule f a b N]
(if (= N 0)
(rule f a b)
(let [midpoint (+ a (/ (- b a) 2))]
(+ (iterated-rule rule f a midpoint (dec N))
(iterated-rule rule f midpoint b (dec N))))))
;; This converges fairly nicely:
(map (partial iterated-rule trapezium-rule square 0 2) (range 10))
;; (4 3 11/4 43/16 171/64 683/256 2731/1024 10923/4096 43691/16384 174763/65536)
(map (partial - 8/3)
(map (partial iterated-rule trapezium-rule square 0 2) (range 10)))
;; (-4/3 -1/3 -1/12 -1/48 -1/192 -1/768 -1/3072 -1/12288 -1/49152 -1/196608)
;; We now only need a thousand samples of the function to get the answer
;; accurate to one part in 100000.
;; But an even nicer approximation is Simpson's rule, which involves fitting a
;; parabola to the two end points and the midpoint, and calculating the area
;; under that.
;; That's equivalent to taking a weighted sum of the values of f at the
;; beginning, midpoint, and end of the interval, with weights 1:4:1
(defnsimpson-rule [f a b]
(let [midpoint (+ a (/ (- b a) 2))]
(* 1/6 (- b a) (+ (f a) (* 4 (f midpoint)) (f b)))))
;; For the square function, which is itself a parabola, this rule actually
;; calculates the area exactly!
(simpson-rule square 0 2) ; 8/3
;; That about wraps it up for numerical approximations to the integrals of
;; quadratics, but they are easy to calculate exactly anyway.