Function 使用不同数量参数重载的函数

Function 使用不同数量参数重载的函数,function,clojure,arguments,Function,Clojure,Arguments,很多Clojure函数都接受不同数量的参数,我经常对文档以及它与我应该使用函数的方式的关系感到困惑 例如(doc partial)返回以下内容: ([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more]) 我的问题不是关于局部的,而是 为什么最多arg1 arg2 arg3&更多而不是arg1&更多或arg1 arg2&更多或arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8&更

很多Clojure函数都接受不同数量的参数,我经常对文档以及它与我应该使用函数的方式的关系感到困惑

例如
(doc partial)
返回以下内容:

([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more])
我的问题不是关于局部的,而是

为什么最多arg1 arg2 arg3&更多而不是arg1&更多或arg1 arg2&更多或arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8&更多


我对最后一个问题开玩笑,但这是一个非常真实的问题:什么决定了需要在&more之前放置多少“argX”?

以下答案是我的猜测:看看
部分的实现情况告诉我们:

(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 arg1]
   (fn [& args] (apply f arg1 args)))
  ([f arg1 arg2]
   (fn [& args] (apply f arg1 arg2 args)))
  ([f arg1 arg2 arg3]
   (fn [& args] (apply f arg1 arg2 arg3 args)))
  ([f arg1 arg2 arg3 & more]
   (fn [& args] (apply f arg1 arg2 arg3 (concat more args)))))
如您所见,对partial的每个调用都在做相同的事情,即返回一个函数,该函数接受一些参数,并使用输入参数和新参数对输入函数调用
apply
。所以这确实可以写成
arg1&more
。但是,等等,让我们看看apply的实现:

(defn apply
 "Applies fn f to the argument list formed by prepending intervening arguments to args."
 {:added "1.0"
  :static true}
 ([^clojure.lang.IFn f args]
    (. f (applyTo (seq args))))
 ([^clojure.lang.IFn f x args]
    (. f (applyTo (list* x args))))
 ([^clojure.lang.IFn f x y args]
    (. f (applyTo (list* x y args))))
 ([^clojure.lang.IFn f x y z args]
    (. f (applyTo (list* x y z args))))
 ([^clojure.lang.IFn f a b c d & args]
    (. f (applyTo (cons a (cons b (cons c (cons d (spread args)))))))))
Apply是一个核心函数,当给定不同数量的参数时,它的执行方式不同。这是出于性能原因而进行的优化。这就是公开分部函数(和其他类似函数)的不同arity的原因,因为不同arity的代码的内部执行不同


我假设clojure/core团队认为暴露arg1 arg2 arg3及以上部分的算术(即编写arg1 arg2 arg3 arg4及以上)不符合美学,因此他们决定停止使用3 Arg及以上。

任何您认为合理的方法。如果函数不是可变的,那么调用函数的速度会更快,所以它们提供了几个函数,如果不超过它们的限制,它们将被直接调用


我认为IFn对一个函数有20(?)个参数的限制,但我不知道编译器中是否有解决方法。

如果“重载”不是正确的术语,您可以编辑此问题的标题20不是
IFn
的限制。如果需要20个以上的参数,则有一个varargs方法。比尔:哦,我明白了+1到bth答案(他们的解释基本相同)。我将接受另一个,因为用户vedang的rep较少;)@Andrew对,我的意思是fixed的限制是20(?),然后是varargs,我想知道的是,如果你创建一个包含25个args的函数,编译器会自动为你调用varargs吗?