我在某处读到 Clojure 已编译。它真的像 Java 或 Scala 那样编译,而不是像 Jython 或 JRuby 那样解释吗?
3 回答
Clojure总是被编译的。
Clojure 编译器生成 Java 字节码,然后通常由 JVM 将其 JIT 编译为本机代码。
令人困惑的是 Clojure 的动态和交互特性,这意味着您可以根据需要在运行时调用编译器。这都是 Lisp“代码就是数据”传统的一部分。
例如,以下将在运行时调用 Clojure 编译器来编译和执行表单(+ 1 2)
:
(eval '(+ 1 2))
=> 3
在运行时调用编译器的能力非常有用——例如,它使您能够使用 REPL 在正在运行的 Clojure 应用程序中间编译和运行新代码。但重要的是不要将这种“交互式”开发风格与“解释性”混淆——Clojure 开发是交互式的,但仍然始终是编译的。
两者兼而有之!(当涉及到生成字节码时)
Clojure在代码加载时动态编译成 JVM 字节码,具有解释语言的感觉和流程,并提前编译成 JVM 字节码,具有编译语言的流程。然后,这两者都由 Java Hotspot 编译器 JIT 编译成机器代码,该编译器负责 Clojure 依赖于速度的动态优化。只是为了让事情变得有趣,“加载/评估”的代码可以在运行时动态编译,而 AOT 编译的代码可以在运行时加载和评估源代码。
- 如果你想“解释”,那么你可以
(load "/my/file.clj")
从 repl. - 如果您想要提前编译,我建议您使用leiningen clojure 项目管理工具。
在这种情况下,当我提到编译与解释时,我应该清楚我正在谈论将源代码转换为 JVM 字节码。所有 JVM 语言都是由 JVM 在运行时编译的,因此这种区别并不是很有趣。
Clojure 是一种编译型 JVM 语言。这意味着面对新程序时,第一步是将其编译为 JVM 字节码。
如果您使用的是 OpenJDK 或其衍生版本,某些 JVM 字节码稍后可能会被 HotSpot 编译为机器码。
作为一种高级语言,Clojure 具有动态类型的一种形式,这就是“完全动态”短语所指的内容。