3

我有以下无意义的*.clj文件:

(ns bar.zar.Foo
  (:gen-class :main true))

(println "foo")

(defn -main [& args]
   nil)

使用以下 Ant 目标将其编译为*.class( ) 时:clojure.lang.Compile

<target name="compile-clojure" description="Compile Clojure sources." depends="resolve">
  <mkdir dir="${cljbuild.dir}"/>
  <java classname="clojure.lang.Compile"
        failonerror="true"
        fork="true">
    <classpath refid="compile.classpath"/>
    <sysproperty key="clojure.compile.path" value="${cljbuild.dir}"/>
    <arg value="${project.MainClass.name}"/>
  </java>
</target>

我在输出中看到:

 [java] Compiling bar.zar.Foo to /home/[ommitted]/build
 [java] foo

也就是说,(println "foo")表达式是在编译期间评估的。这是为什么?它与“Lisp 模糊了编译时/运行时的区别”有关吗?

4

1 回答 1

7

Clojure 中的编译单元是顶级 s 表达式,它在文件加载时被读取、扩展、评估并经常存储在命名空间中。整个文件没有单独的编译阶段。这样做可以让您编写定义其他函数、类型、DSL 等的函数,并且是宏系统的构建块。

将您不想运行的任何内容放入 init 函数中,然后从 main (或您的代码开始的任何地方)包含对该函数的调用

于 2013-10-15T00:05:19.417 回答