标准库功能的重载实现

时间:2019-07-23 14:58:51

标签: clojure

我目前正在学习Clojure,并且正在研究partial的实现。它具体实现了很多情况(其他功能也实现了),但是apply也适用于空列表,那么为什么partial的实现这么大?为什么不这样:

(defn partial [f & args]
  (fn [& inner_args] 
    (apply f (concat args inner_args))))

2 个答案:

答案 0 :(得分:2)

这样做是为了提高性能:

  • Ticket
      

    此修补程序仅在需要时使用apply来提高部分性能。代码结构遵循并发代码。

  • Patch

答案 1 :(得分:1)

AFAIK这些是出于性能原因,在最常见的用例中,0-,1-,2-,3-artity是函数调用,否则它的使用(位)开销更大。

完整性源(clj 1.10.1):

user=> (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)))))