Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News JRuby and Clojure - A Good Match?

JRuby and Clojure - A Good Match?

Leia em Português

This item in japanese

Clojure is a LISP-style language for the JVM. One focus of Clojure is concurrency, which it supports with its immutable its data structures (Clojure comes with persistent data structures). Another feature is Software Transactional Memory (STM), which allows to use transactions, instead of Locks or Mutexes, to update shared memory. While STM is a controversial technology that still needs to prove itself, having access to an implementation on the JVM offers an easy way to experiment with it.

Clojure is expected to have a 1.0 release in the near future, and a lot of Clojure libraries are already available. Some of them take inspiration from Ruby libraries, just to name a few:

  • Compojure is a Clojure web framework which, according to its README, was inspired by the Ruby web framework Sinatra.
  • Ring is a way to offer HTTP services, similar to Python's WSGI and Ruby's Rack.
  • clj-record is an ActiveRecord-like ORM mapper.
  • Lancet is a Clojure build tool, like Rake, by Stuart Halloway
  • clj-haml is a port of Ruby's HAML library.

Clojure libraries inspired by Ruby libraries are one way the two languages interact. Another way is JRuby -  the two languages share the same underlying runtime, the JVM.

Daniel Kwiecinski explores the idea of combining JRuby and Clojure in a blog entry and experiments with making Clojure data structures and features available in JRuby as Ruby objects.

Particularly interesting in this regard are Clojure's Persistent Data Structures, for instance its Persistent Vectors. Note: In this context, the word "persistent" doesn't refer to data being persisted to disk.  Persisted Data Structures are immutable; modifications, like insertions, are possible but they always yield a new "copy" of the full data structure. Clojure's implementation and the immutability constraint allow to avoid having to do a full deep copy; instead, only a relatively small delta has to be copied. Karl Krukow shows the implementation of Clojure's Persistent Vector, and explains how it achieves its performance behavior.

Another opportunity for JRuby developers is Clojure's STM support, which is offers a way for Ruby developers to experiment with this concept. Even if the Ruby code doesn't explcitly use any particular Clojure STM features, it's still possible to write the underlying application model in Clojure, and have JRuby for the fronted part, be it from Rails or other Ruby frameworks.

Another option is to use Clojure for performance bottlenecks. While JRuby's performance is steadily improving, there are still situations where it'd be nice to exchange (J)Ruby's polymorphmism and flexibility for performance.  In MRI, performance bottlenecks in a Ruby application can be fixed by writing a native extension. In JRuby, one solution is to write code in Java, be it Java source code or a way to generate JVM bytecode (either bytecode generation with a Ruby bytecode DSL or a language like Charles Nutters' Duby).
Choosing a lower level, system language, be it C (for MRI) or Java (for JRuby) has an obvious downside: dropping down to the level of Java and losing features such as Blocks, many types of metaprogramming, etc.
Clojure is a possible solution for this problem: the language has various levels of flexbility. For instance, normal Clojure functions have low call overhead as they're mostly reduced to static method calls. Clojure does offer different styles of runtime polymorphism, for instance in the form of multimethods.

Clojure is a LISP and comes with a powerful macro system. Macros allow compile time metaprogramming, which brings even more opportunities to offload code generation to the computer (instead of writing boilerplate or repetitive code in Java by hand). Clojure code is always compiled to JVM bytecode, Ahead Of Time (AOT) compilation is also supported. Azul's Cliff Click took a closer look at the performance of some JVM languages, including Clojure and JRuby and provides some information about Clojure's performance. All in all, Clojure offers a lot of opportunities to write fast code in an elegant style.

The other side of the medal is of course a matter of dependencies: using Clojure means another new dependency to a project. Whether it's a good idea to add another, still little known, language like Clojure to a project, is a question every team has to answer.
The STM solution to concurrency and shared data has been widely debated. Clojure creator Rich Hickey had a long discussion with Azul's Cliff Click on the topic of STM. Another source of information about STM is last September's ACMQueue issue on Concurrency.

What do you think: JRuby and Clojure - a good match?

Rate this Article