我知道你可以很容易地混合 groovy&java、clojure&java、whateverJvmLang&java。
这是否也意味着我也可以让 clojure 和 groovy 代码交互?如果我使用 Grails 或 jRoR,我也可以在那个环境中使用 clojure 吗?
只要所讨论的语言实际上产生 Java 类(即:Java 平台已知的类,不一定用 Java 语言编写),那么是的:它们可以轻松地相互交互。
至少对于 Groovy,我知道编写可以从“普通”Java 代码中使用的类是完全可能的。
Clojure 可以gen-class
像任何其他代码一样通过 Java 编译为 .class 文件并从 Java 中使用;看这里。
还有一个关于如何从 JRuby 调用 Clojure 代码的示例。
如前所述,Clojure 可以轻松地与 Java 交互。尽管您看到的许多示例都展示了如何从 REPL 执行此操作,但一旦您将 Clojure 或任何其他 JVM 语言编译为类或 jar 文件,就可以像任何其他类一样从 Java 调用它。
就我而言,困难(不大)是弄清楚如何gen-class
正确使用。在http://kenai.com/projects/binomialstats中有一小部分用 Clojure 编写的统计函数,说明了如何执行此操作。这个 Clojure 库被一个 Java 项目使用——signtest。(抱歉,由于我是新手,StackOverflow 不会让我发布多个链接。)
现在真正好的是如果某些 IDE 可以在同一个项目中处理不同的语言。例如,上面提到的两个项目作为两个单独的 NetBeans 项目进行维护。确保这两个部分始终同步可能需要一些额外的工作。
如前所述,您可以通过预编译从 Groovy 访问 Clojure 类。
您也可以通过 Java 6 的脚本 API 访问最流行的脚本语言,尽管 Scala 和 Clojure 似乎并未得到官方支持。以下是来自 Groovy 的示例:
http://groovy.codehaus.org/JSR-223+access+to+other+JVM+languages
您还可以从 Groovy 访问 Clojure 的类,例如(对于 Groovy 1.7 快照):
@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
}
或者通过创建一个新进程进行交互(同样适用于 Groovy 1.7 快照):
@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)
}
}
还有一个用于 Grails 的 Clojure 插件,可以轻松访问从任何 Grails 工件(控制器、标记库、服务等)执行 clojure 代码:
http://grails.org/plugin/clojure
另一个有助于在 JVM 上混合语言的环境是WebSphere sMash(又名零项目)。这包括: