2013-03-11 50 views
6

我最近一直在玩clojure,並達成了一個問題,我不知道如何處理。我有7個參數doseq,它擴大到一個巨大的塊,幾乎通過最大班級的大小。爲什麼doseq擴展到如此龐大的clojure代碼塊?Clojure doseq生成巨大的代碼?

實施例:

(def q '(doseq 
[p0 (nth (:params operator) 0 (quote (nil))) 
p1 (nth (:params operator) 1 (quote (nil))) 
p2 (nth (:params operator) 2 (quote (nil))) 
p3 (nth (:params operator) 3 (quote (nil))) 
p4 (nth (:params operator) 4 (quote (nil))) 
p5 (nth (:params operator) 5 (quote (nil))) 
p6 (nth (:params operator) 6 (quote (nil)))] 
(do-print board (:oname operator) p0 p1 p2 p3 p4 p5 p6))) 

然後:我的機器上

(macroexpand q) 

這給出的代碼大塊(97331個字節)。這是正常的還是我做錯了什麼?操作員是一個簡單的defrecord。下面就來展開的結果的鏈接,如果有人有興趣:http://pastebin.com/6gw1q078

編輯:

通過做相同,但有一個形式我得到的東西的幅度要小(3653個字節)的幾個命令:

(def q '(for 
[p0 (nth (:params operator) 0 (quote (nil))) 
p1 (nth (:params operator) 1 (quote (nil))) 
p2 (nth (:params operator) 2 (quote (nil))) 
p3 (nth (:params operator) 3 (quote (nil))) 
p4 (nth (:params operator) 4 (quote (nil))) 
p5 (nth (:params operator) 5 (quote (nil))) 
p6 (nth (:params operator) 6 (quote (nil)))] 
(do-print board (:oname operator) p0 p1 p2 p3 p4 p5 p6))) 

(macroexpand q) 

結果是在這裏:http://pastebin.com/9MAKK3VD

爲什麼兩者之間有如此巨大的差異? doseq表單看起來很無辜,當我得到一個錯誤說java class size已被超過時,我真的很驚訝。

回答

3

好,看着doseq較小的宏觀expasion揭示了原因:

(loop [seq_2365 (seq [1 2]) 
     chunk_2366 nil 
     count_2367 0 
     i_2368 0] 
    (if (< i_2368 count_2367) 
    (let [x (.nth chunk_2366 i_2368)] 
     (do x) 
     (recur seq_2365 chunk_2366 count_2367 (unchecked-inc i_2368))) 
    (when-let [seq_2365 (seq seq_2365)] 
     (if (chunked-seq? seq_2365) 
     (let [c__4197__auto__ (chunk-first seq_2365)] 
      (recur (chunk-rest seq_2365) c__4197__auto__ (int (count c__4197__auto__)) (int 0))) 
     (let [x (first seq_2365)] 
      (do x) 
      (recur (next seq_2365) nil 0 0)))))) 

理想情況下,我們只需要在最後let形式,但doseq被髮射額外的代碼以特定的方式,使得它處理chunked-seq採取第一個塊,然後爲塊中的每個項目執行doseq等的主體。

這個代碼是爲doseq中的單個seq生成的,但是當你有第二個seq時,就會生成類似的處理chunked-seq的代碼,因此它的大小會爆炸。

+1

感謝您的解釋,我認爲這是沿着這些線。它仍然感覺像一個很大的限制,我想知道這是預期的行爲... – 2013-03-11 18:44:19