2016-07-27 36 views
2

我已經成立了小項目:爲什麼Clojure在AOT編譯期間評估表單?

project.clj

(defproject testing-compilation "0.1.0-SNAPSHOT" 
    :dependencies [[org.clojure/clojure "1.8.0"]] 

    ;; this is important! 
    :aot :all) 

的src/core.clj

(ns testing-compilation.core) 

(def x (do 
     (println "Print during compilation?") 
     1)) 

後來,當我在項目目錄做lein compile我看到印刷品的輸出:

$ lein compile 
Compiling testing-compilation.core 
Print during compilation? 

我的問題是:爲什麼clojure在AOT編譯期間評估頂級表單?不應該在程序啓動時對它們進行評估嗎?

僅供參考,Common Lisp默認情況下不評估表格,provides ability to tune this behaviour。在Clojure中有類似的東西嗎?如果沒有,Clojure文檔是否明確聲明瞭這種行爲?

UPD:表單也在啓動時評估。

指定一個主命名空間和編寫打印Hello, world!主要功能後,我這樣做:

$ lein uberjar 
Compiling testing-compilation.core 
Print during compilation? 
Created testing-compilation-0.1.0-SNAPSHOT.jar 
Created testing-compilation-0.1.0-SNAPSHOT-standalone.jar 

$ java -jar target/testing-compilation-0.1.0-SNAPSHOT-standalone.jar 
Print during compilation? 
Hello world! 

回答

5

的AOT過程的第一部分是要找到包含主命名空間中的文件,並通過evaluating每次加載表達從上到下。

其中一些表達式將是require表達式,這些表達式將會加載其他名稱空間,這會遞歸地加載更多的名稱空間。

其他將爲defn的表達式將引發編譯器並生成類文件。產生一個類文件for each function

其他表達式可能會做一些計算,然後做一些產生類文件的事情,所以給它們一個運行的機會是很重要的。這裏有一個由例如:

user> (let [precomputed-value (reduce + (range 5))] 
     (defn funfunfun [x] 
      (+ x precomputed-value))) 
#'user/funfunfun 
user> (funfunfun 4) 
14 

有可能設計出不會在開始評估頂層的形式,或者你提到一個口齒不清,使其可選。在Clojure的情況下,決定在AOT和「非AOT」加載中保持單一評估策略,因此無論編譯方式如何,程序始終運行相同。這些是其他人做出的個人設計選擇,所以我不能在這裏談論他們的動機。

+0

謝謝你的回答!幾乎沒有後續:你提到了AOT編譯的第一部分:你能否指點我關於AOT編譯階段的文檔(找不到它)?我也相信這不是嚴格正確的,因爲我可以在不指定主名稱空間的情況下進行AOT編譯。關於例子:如果僅在程序啓動時評估表單,它也可以工作。 – OlegTheCat

+0

當您不指定主名稱空間時,是否指定:aot-all加載每個文件?否則它實際上不會編譯任何東西。我認爲這不是最好的用戶界面: - 我加在一起的兩個鏈接組成了官方文檔中最相關的部分。我將不得不花費一些時間尋找更簡潔的解釋 –

+0

啊,是的,':aot:all'出現了。 – OlegTheCat