Lately I’ve been looking into the Clojure programming language, a Lisp that’s implemented on top of the JVM. One of the aspects of Clojure that I’m interested in is its ability to integrate into existing projects, especially Ruby projects. Since Clojure runs on the JVM and already integrates with Java it should be easy to integrate into a Ruby project run on JRuby. I discovered the JRuby Clojure Bridge gem, called jrclj, that does just that.

n

## Demonstration

n

I’ve created a test project that demonstrates using jrclj. It’s on github. Follow the directions in the README to try it out. It consists of a small Clojure project, powers_of_two, and a Ruby file that demonstrates calling the powers_of_two code.

n

## The Clojure Code

n

The main source code for powers_of_two is in one source file, core.clj

n

 1 2 3 4 5 6 7 8 9 10 11 `(ns powers_of_two.core)` `(defn powers_of_two` `([]` `(concat [``1` `2` `4``] (powers_of_two ``4N``)))` `([last_value]` `(let [next_value (* last_value ``2N``)]` `(lazy-seq (cons next_value (powers_of_two next_value))))))` `(defn powers_of_two_improved []` `(iterate (fn [v] (* v ``2N``)) ``1``))`

n

core.clj contains two functions that do the same thing, return a sequence of numbers containing the powers of two. ie. 2^0, 2^1, 2^2, 2^3,… or 1, 2, 4, 8, … The sequences are recursively infinite but use `lazy-seq` to avoid recursing forever. Lazy sequences in Clojure give you the power of defining a sequence of things (numbers, database records, dates, etc) recursively and infinitely. The first `powers_of_two` function does it manually using recursion and the lazy-seq function. The `powers_of_two_improved` function uses the `iterate` function, which lets you build a lazy sequence from a function and a starting value. The upper case `N` in the examples after numbers changes them to Clojure big integers. The powers of two sequence will quickly grow beyond what a normal integer can represent.

n

## The Ruby Code

n

The use_powers_of_two.rbillegalscript demonstrates calling Clojure from JRuby

n

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 `require ``'rubygems'` `require ``'java'` `# Require the clojure jars` `require ``'powers_of_two/lib/clojure-1.4.0.jar'` `require ``'powers_of_two/lib/clojure-contrib-1.2.0.jar'` `# Require the project jar that we want to use` `require ``'powers_of_two/powers_of_two-1.0.0-SNAPSHOT.jar'` `# Require the jrclj gem that lets us interact with clojure code` `require ``'jrclj'` `# Create a JRClj context. We can then import clojure namespaces which will make the functions available` `clj = JRClj.``new` `clj._import ``"powers_of_two.core"` `puts ``"2**500 == "` `+ clj.nth(clj.powers_of_two, ``500``).to_s`

n

The last line actually makes the call into Clojure. It calls the Clojure function `nth` which will take the 500th item from the sequence returned by the `powers_of_two` function. This prints out 2^500.

n

## Repl

n

You can try out a repl with jruby clojure integration using the jreplillegalscript included in the project. Run jrepl from a command line and then try the following bits of code

n

```./jrepl nYour .irbrc has loaded n>> clj.powers_of_two n=> #```
npowers_of_two just returns a lazy sequence

n

```>> clj.take( 10, clj.powers_of_two).map(&:to_i) n=> [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]```
nThis takes the first 10 items from the Clojure sequence. We then use Ruby’s map method to convert all of the results to integers. The Ruby map method works on lazy sequences from Clojure because one of it’s interfaces is standard Java interface `java.util.List`. JRuby allows `java.util.List`s to be treated like Ruby Arrays. This means the Clojure sequences themselves can be accessed like a Ruby array.

n

```>> clj.powers_of_two.map(&:to_i) nNativeException: java.lang.OutOfMemoryError: Java heap space```
nThe Clojure sequences are infinite. If you’re not careful you can run out of memory.

n

## Why?

n

So why would you want to integrate Clojure with Ruby? It would certainly be simpler to limit your projects to a single language. Clojure has benefits that are worth exploring. Clojure makes it very easy to write concurrent code that perform well. Functions that don’t manipulate state and minimize or have no side effects are easier to understand and test. Macros (http://clojure.org/macros) are like metaprogramming on steroids. There are also libraries built in Clojure that would be useful to integrate into a Ruby project. An example of this is Incanter, a platform for statistical computing and graphics. The fact that Clojure integrates so easily with JRuby makes it easy to experiment.

n

**Jason will be speaking on mixing Clojure with Ruby at the June12 B’more on Rails meeting.

n