Saturday, June 18, 2011

Calling R from Clojure

From what I've read and based on the time I've played around with it, Clojure looks like a very good language. There's no reason to praise it here. Just ask Google if you want to read some praise for Clojure.

For me, it is promising because it runs on the JVM and has complete access to existing Java code. That means it's both fast and will do most of what you want to do. (Scala fits into the same category. I will be checking out Scala in the future.)

In addition, it is a dialect of Lisp, which means I'm a huge fan of the syntax as wells as the approach to problem solving. I've enjoyed using Scheme in the past, but given the lack of libraries, Scheme is not suitable for the numerical programming I do. I'm aware of projects like Chicken Scheme and Gambit-C, and I know about Swig and their foreign function interfaces and all that, but I'm too busy to do everything my employer wants me to do. There's no way I'm going to spend months of my time extending the language, usually with crappy documentation if it even exists at all.

I said above that Java will do "most" of what you want to do because one of the few limitations of Java is that it is just not complete in terms of numerics. The situation is better than it was ten years ago, but I've still not worked much with Java, simply because I know it won't do everything I need it to do. Oh, and I hate the syntax with a passion. 8000 lines of GOTO-infested FORTRAN 77 is much more pleasant to me than 200 lines of Java.

The Clojure community offers a project called incanter that provides access to many of the available Java math libraries. There's also a project called rincanter that is supposed to bring R functionality to Clojure, building on the Java Rserve client. If it worked I would be happy to use it. Unfortunately rincanter does not work right now.

An Example

It's easy enough to get it working in Clojure. Here's what I did, along with a short example code.

First, I installed Eclipse. I then installed counterclockwise (no idea why they chose that name). I went through the tutorial instructions to set up a working project. All of my previous Clojure programs were REPL, so I just went through the experience of setting up the Eclipse environment, and can happily say that it is easy to do. I then downloaded Rserve.jar and Rengine.jar from rforge.

After starting my new project, I told Eclipse about Rserve.jar and Rengine.jar by right-clicking on "Referenced Libraries" --> "Build Path" --> "Configure Build Path..." --> "Add External JARs...".

Here's a sample program to demonstrate the calling syntax. You can convert the other parts of the Rserve Java examples into Clojure using the same ideas.

(import '(org.rosuda.REngine))
(import '(org.rosuda.REngine.Rserve RConnection))

(def c (new RConnection))
(def d (. c eval "rnorm(10)"))
(def e (. d asDoubles))
(println (first e))
(println (rest e))

This was done using Clojure 1.2 and Eclipse 3.5.2 on Linux Mint 11.