Grails Clojure
Dependency :
compile ":clojure:0.6"
Summary
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 thesrc/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))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 namedclj 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'
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"))Clojure Namespaces
The plugin expects all clojure functions defined in your project to be in thegrails 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))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