Tag Archives: lisp

Clojure’s Concurrency: Futures and Agents in Harmony

I’ve previously written on the wonders of Clojure’s agents, giving the programmer a wonderfully easy way of writing asynchronous code with very little effort.

Here’s a slightly more complex example for those wanting more context.

Combining Futures and Agents
We’ll use this (deliberately poor) inefficient find-primes in a (future) to allow for asynchronous processing in a seperate thread — which will also write to our agent — and continue with other tasks as necessary.

Futures are Clojure’s way of syphoning off some calculation in the background so you can retrieve it later on. It’s fork/join, but a hell of a lot simpler.

To define a future, all we have to do is assign it to some variable:
(def f (future (some-complex-long-running-function)))

and when we’re ready to get the value from the future, we just dereference it:
user=> @f

If the future is still processing when you dereference, it will block. This isn’t the same as agents which won’t block, but pass you the current value, unless you use (await).

Our inefficient (find-primes) function is a prime (HAH) candidate for asynchronous execution: knowing that it’s slow means we can let it run in the background while we favour other, more pressing tasks in our main thread.

(def f (future (find-primes 60000)))

So f‘s our reference to a new future that is happily running in the background. Calculating all primes up to 60,000 will take a while with the poor (find-primes) implementation (around 14 seconds). Let’s do the user a favour and present the results in a GUI. Here’s the full function:
(defn show-primes [i]
"Find all primes up to i inclusive and present them in a GUI"
(let [fr (JFrame. "Prime Numbers")
lbl (JLabel. (str "Here are all the prime numbers for " i ":"))
ta (JTextArea.)
sp (JScrollPane. ta)
pane (.getContentPane fr)]
(def f (future (find-primes i))) ; asynchronously find the primes while we set up the GUI
(.setPreferredSize lbl (Dimension. 410 20))
(.setPreferredSize sp (Dimension. 410 190))
(.setLineWrap ta true)
(.setSize fr 410 210)
(.add pane lbl BorderLayout/PAGE_START)
(.add pane sp BorderLayout/CENTER)
(.pack fr)
(.setVisible fr true)
(dotimes [n (count @f)] (.setText ta (str (.getText ta) (@f n) "\n")))))

As you can see at the future line, we let Clojure asynchronously execute the prime generation function while we set the GUI, then we add to the text area by derefencing the future — which will block if its work isn’t complete — and finally present the results.

It’s lovely: with one function we can fork calculation and get on with something else, retrieving the results at a later stage. Simple, easy.

Leiningen and standalone clojure programs

Hacking away at various clojure-related stuff lead me to start using Leiningen. “Lein” is a build tool similar to Maven (and interoperates in fact…) to help you concentrate on coding.

At some point in the day’s coding I wanted to run my code standalone instead of in a REPL. I needed a main entry point to the various algorithms I was writing that was outside of unit tests, so I decided to use the “lein run” command to do it for me.

In order to get a program running via lein using a main method, you have to provide the namespace of the class to run. If you want a JAR produced that’ll have the Main-Class declaration in your MANIFEST.MF you also need to add :aot and :main namespace.here to your project.clj AND add (:gen-class) in the (ns) call of your desired .clj holding a -main method. Phew!

To re-cap, then:

  • To run a .clj that has a -main method/function declared, add (:gen-class) to its (ns) call and then run lein run namespace.here
  • To produce a JAR with lein, do the above and add :aot and :main namespace.here to your project.clj then run lein compile && lein uberjar