Clojure是编译型还是解释型语言?

42

我在某处读到,Clojure是一种编译语言。它确实像Java或Scala一样被编译,而不是像Jython或JRuby解释。


1
@Marcin 我看过了,但还是有点困惑。你能否提供一个回答并附上你的踩票原因? - OscarRyz
1
Clojure是一种编译语言 - 它直接编译为JVM字节码,但仍然完全动态。清楚吗? - Marcin
实际上,那段文字是我第一次来到这里的原因。 - OscarRyz
6
我看不出你为什么感到困惑。Clojure是一种严格的编译语言,就像Java和Scala一样。与Java的区别在于它可以在运行时编译代码并加载它,而不是依赖于明确的编译阶段。 - Joost Diepenmaat
3
我不确定还能更清楚了。 - Rayne
这可能与以下内容有关:https://dev59.com/v2kw5IYBdhLWcg3w_Pbn - David Asher
3个回答

59

Clojure总是被编译的。

Clojure编译器生成Java字节码,通常由JVM JIT编译成本地代码。

让人困惑的是Clojure的动态和交互性质,这意味着你可以在运行时调用编译器。这是Lisp“代码即数据”的传统的一部分。

例如,以下代码会在运行时调用Clojure编译器来编译并执行表达式(+ 1 2)

(eval '(+ 1 2))
=> 3

在运行时调用编译器的能力非常有用 - 例如,它使您能够通过使用REPL在运行中的Clojure应用程序中编译和运行新代码。但是重要的是不要混淆这种“交互式”开发风格与“解释式”开发 - Clojure开发是交互式的,但仍然始终是编译的。


19

关于生成字节码,Clojure可以实现即时编译(在代码加载时)成JVM字节码,具有解释语言的感觉和流程,也可以提前编译成JVM字节码(AOT编译) ,具有编译语言的流程。这两者都由Java Hotspot编译器进行JIT编译为机器码,它负责Clojure所依赖的动态优化,以提高速度。有趣的是,“已加载/评估”的代码可以在运行时即时编译,而AOT编译的代码可以在运行时加载和评估源代码。

  • 如果你想要“解释”,那么可以从repl中(load "/my/file.clj")
  • 如果你想要提前编译,请使用leiningen clojure项目管理工具。

在这种情况下,当我提到编译与解释时,我应该明确指出我正在谈论将源代码转换为JVM字节码。所有JVM语言都是在运行时由JVM编译,因此这种区别实际上并不太有趣。


1
都错了!这只是解释性语言的流程,从来没有什么被解释的东西。 - nickik
3
我们正在纠结于纯定义和清晰简洁回答之间的争议。在最后一段中,我谈论的是创建JVM字节码的过程。 - Arthur Ulfeldt

5

Clojure是一种编译成JVM字节码的语言。这意味着当面对一个新程序时,它首先会将其编译成JVM字节码。

如果您使用的是OpenJDK或其衍生版本,则HotSpot可能会将某些JVM字节码编译成机器码。

作为一种高级语言,Clojure具有动态类型的形式,这就是“完全动态”短语所指的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接