Grails Clojure Plugin

  • Tags : clojure
  • Latest : 0.7
  • Last Updated: 23 March 2014
  • Grails version : 1.2 > *
  • Authors : Jeff Brown
4 votes
Dependency :
compile ":clojure:0.7"

Source

Summary

The Clojure plugin adds support for easily accessing Clojure code in a Grails application.

Description

Clojure Plugin

The clojure plugin provides easy access to execute clojure code from any Grails artifact (controllers, taglibs, services etc...)

A brief screencast is available at http://s3.amazonaws.com/jeffscreencasts/grails_clojure_demo.mov which demonstrates the basic usage of the plugin. A special "thanks" goes to Stu Halloway who let me borrow some fibonacci code from his Programming Clojure book for use in the video.

Installation

To install the clojure plug-in just run the following command from within an existing Grails project:

grails install-plugin clojure

Usage

The clojure plugin expects to find clojure source files under the src/clj/ directory. The directory is created for you when the plugin is installed. Clojure source files in a Grails project should have the .clj extension.

For example, src/clj/demo.clj might look like this:

(ns grails)

(def twenty 20)

(defn add_numbers [a b] (+ a b))

With that code in place, the add_numbers function may be executed as a method call on a dynamic property named clj from any Grails artifact. See below:

class MyMathService {

def addNumbers(x, y) { // invoke the function as a method on the // clj dynamic property… clj.add_numbers(x, y) }

def addTwenty(x) { // access a binding (twenty) in clojure via the dynamic // property and pass it as an argument to a clojure function clj.add_numbers(x, clj.twenty)

// or use it from groovy assert clj.twenty == 20 }

}

The Dynamic Property

The dynamic property will be named clj by default. The name of the property may be set explicitly in grails-app/conf/Config.groovy by assigning a value to the grails.clojure.dynamicPropertyName property.

grails.clojure.dynamicPropertyName = 'clojurePropertyName'

For most applications, the default name of clj should be fine.

Parameters And Return Values

Any object may be passed to a clojure function including primitives, objects, collections… anything. When you pass Java/Groovy objects into a clojure function and start manipulating it, you are giving up all guarantees that clojure can make in terms of concurrency and immutability. That is just part of the deal with clojure. Clojure can't keep you from mutating mutable Java objects because clojure allows you to call any method you like on a Java object.

More interesting than the ability to pass anything in to a clojure function, you can get anything back from a clojure function. For example, the following returns a persistent list...

(defn getit []
    (list "jeff" "zack" "jake"))

If you call that function from Java or Groovy, you will get back a clojure.lang.PersistentList. This is really interesting. Clojure has a great set of data structures. Some Java developers who don't want to write Clojure code may use the clojure libraries just for the data structures.

Clojure Namespaces

The plugin expects all clojure functions defined in your project to be in the grails namespace. You may define functions in other namespaces and the plugin supports a syntax for accessing those functions. The following clojure source code defines a function in the math namespace:

(ns math)

(defn add_numbers [a b] (+ a b))

Since that function is not in the grails namespace, a special syntax must be used to access it. The syntax involves specifying the namespace like this:

class MyMathService {

def addNumbers(x, y) { // invoke the function as a method on the // clj dynamic property and specify the namespace… clj['math'].add_numbers(x, y) }

}

Feedback

Your feedback is welcome on the Grails Dev mailing list. Please share what you would like to see provided by the plugin.

References

Stuart Halloway's Programming Clojure from The Pragmatic Bookshelf is a fantastic reference on the language.

A number of useful videos on clojure are available at http://clojure.blip.tv/.

Release Notes

Version 0.6

  • Upgrade to Clojure 1.2.0

Version 0.5

  • Require Grails 1.2 or later
  • Upgrade to Clojure 1.1.0
  • Prohibit invoking clojure macros from Groovy