2016-11-27 135 views
1

我是clojure的初學者,目前正試圖在基本級別上理解它。在Clojure中部分源代碼澄清

我一直在嘗試使用partial,以及它如何創建閉包,並深入瞭解我認爲我應該通過執行(source partial)來窺視源代碼。

在那裏,我得到

(defn partial 
    "Takes a function f and fewer than the normal arguments to f, and 
    returns a fn that takes a variable number of additional args. When 
    called, the returned function calls f with args + additional args." 
    {:added "1.0" 
    :static true} 
    ([f] f) 
    ([f arg1] 
    (fn 
    ([] (f arg1)) 
    ([x] (f arg1 x)) 
    ([x y] (f arg1 x y)) 
    ([x y z] (f arg1 x y z)) 
    ([x y z & args] (apply f arg1 x y z args)))) 
    ([f arg1 arg2] 
    (fn 
    ([] (f arg1 arg2)) 
    ([x] (f arg1 arg2 x)) 
    ([x y] (f arg1 arg2 x y)) 
    ([x y z] (f arg1 arg2 x y z)) 
    ([x y z & args] (apply f arg1 arg2 x y z args)))) 
    ([f arg1 arg2 arg3] 
    (fn 
    ([] (f arg1 arg2 arg3)) 
    ([x] (f arg1 arg2 arg3 x)) 
    ([x y] (f arg1 arg2 arg3 x y)) 
    ([x y z] (f arg1 arg2 arg3 x y z)) 
    ([x y z & args] (apply f arg1 arg2 arg3 x y z args)))) 
    ([f arg1 arg2 arg3 & more] 
    (fn [& args] (apply f arg1 arg2 arg3 (concat more args))))) 

我覺得整個的定義是多餘的,因爲我只會把它寫在「可變參數」方式,即在最後2行。

這是一個可讀性功能還是我缺少一些基本的東西?

回答

4

這不是一個可讀性功能,而是一個性能問題。 Stuart Sierra在Clojure Don’ts: Optional Arguments with Varargs中解釋過它:

變量函數調用必須分配一個序列來存放參數,然後通過apply。 Timothy Baldridge做了一個快速的performance comparison,表明調用具有多個固定區域的函數可能比變量區(可變參數)函數調用快得多。

在該基準中,可變參數版本1個參數是圍繞大小比多元數版本1個ARG慢的順序,並用3 ARGS的差上升到〜2個數量級。

這並不是說可變參數不應該被使用:稀疏地調用帶可變參數的fn可能不會影響性能,但是當從緊密循環中調用它時它可能會打到你很難。

1

我覺得整個的定義是多餘的,因爲我只會寫一個「可變參數」時尚 ,

你說得很對。除了可變參數定義都是多餘的。正如@nberger指出的那樣,其他人在那裏提高性能。你會發現很多這樣的clojure核心:如map,maxcomp