为什么编译`*.clj`源也执行代码?

Mar*_*tus 3 clojure

我有以下非感性*.clj文件:

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

(println "foo")

(defn -main [& args]
   nil)
Run Code Online (Sandbox Code Playgroud)

使用以下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>
Run Code Online (Sandbox Code Playgroud)

我在输出上看到:

 [java] Compiling bar.zar.Foo to /home/[ommitted]/build
 [java] foo
Run Code Online (Sandbox Code Playgroud)

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

Art*_*ldt 7

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

把你不想要的东西放到init函数中,然后在main(或代码启动的地方)包含一个函数调用