views:

1046

answers:

6

I understand that you can easily mix groovy&java, clojure&java, whateverJvmLang&java.

Does this also mean I can have clojure and groovy code interact as well? If I use Grails or jRoR, can I also make use of clojure in that environment?

+10  A: 

As long as the languages in question actually produce Java classes (that is: classes that are known to the Java platform, not necessarily written in the Java language), then yes: they can easily interact with each other.

At least for Groovy I know that it's entirely possible to write classes that can be used from "normal" Java code.

Joachim Sauer
It's also possible to use Clojure generated classes in Java code and vice versa: so the whole Clojure <-> Java <-> Groovy path should work
mikera
+10  A: 

Clojure can be compiled to .class files via gen-class and used from Java like any other code; see here.

Brian Carper
+1  A: 

There is also an example on how you can call Clojure code from JRuby.

Lauri Oherd
A: 

As already mentioned, you can access Clojure classes from Groovy via pre-compilation.

You can access most popular scripting languages via Java 6's scripting API as well, though Scala and Clojure don't seem to be officially supported. Here are examples from Groovy:

http://groovy.codehaus.org/JSR-223+access+to+other+JVM+languages

You can also get access to Clojure's classes from Groovy, e.g. (for Groovy 1.7 snapshot):

@Grab(group='org.clojure', module='clojure', version='1.0.0')
import clojure.lang.*

def ss = StringSeq.create('The quick brown fox')
def done = false
while (!done) {
  println ss.first()
  ss = ss.next()
  done = !ss
}

Or interact via creating a new Process (again for Groovy 1.7 snapshot):

@Grab(group='org.clojure', module='clojure', version='1.0.0')
import clojure.lang.Script

def src = new File('temp.clj')
src.text = '''
(defn factorial [n]
   (if (< n 2)
       1
       (* n (factorial (- n 1)))))
(println (factorial 4))
'''
def path = System.getProperty('user.home') + '/.groovy/grapes/org.clojure/clojure/jars/clojure-1.0.0.jar'
new AntBuilder().with {
    java(classname:Script.name, classpath:path) {
        arg(value:src.path)
    }
}

There is also a Clojure plugin for Grails which provides easy access to execute clojure code from any Grails artifact (controllers, taglibs, services etc...):

http : / / grails.org/plugin/clojure

Paul King
+1  A: 

As has been mentioned, Clojure can interact easily with Java. Although many of the examples you see show how to do it from the REPL, once you compile Clojure, or any other JVM language, to a class or jar file, it can be called from Java just like any other class.

In my case, the difficulty (not much of one) was figuring out how to use gen-class correctly. There is a small set of statistical functions written in Clojure at http://kenai.com/projects/binomialstats that illustrates how to do it. That Clojure library is used by a Java project -- signtest. (Sorry, since I'm new, StackOverflow won't let me post multiple links.)

What would really be nice now is if some of the IDEs could deal with different languages in the same project. The two projects mentioned above are maintained as two individual NetBeans projects for example. Assuring that the two parts are always synchronized can be a bit of extra work.

A: 

Another environment which facilitates mixing languages on the JVM is WebSphere sMash (aka Project Zero). It includes:

rewbs