Clojure中匿名函数的Arity

时间:2017-08-11 09:24:30

标签: clojure

我对Clojure很新,并且问自己,如何定义/扣除匿名函数的arity。

请考虑以下穷人count功能:

(reduce #(+ 1 %1) 0 '(1 2 3 55))

使用clojure运行它我收到以下错误消息:

  

ArityException传递给:user / eval1157 / fn的错误数量(2):1158 clojure.lang.AFn.throwArity(AFn.java:429)

但是,它适用于JavaScript-Clojure并根据需要返回4(您可以执行命令here)。

通过将%1 - > %2换成

来更改命令
(reduce #(+ 1 %2) 0 '(1 2 3 55))

将在两个版本上编译(但不再作为count工作)。在这种情况下,似乎可以从%2推断出至少有两个论点。

那么哪个版本的Clojure是对的?我是否允许向通过#(...)定义的匿名函数提供任意数量的参数,或者只提供此函数内部提到的任意数量的参数?

它应该被视为JavaScript-Clojure中的错误吗?

编辑正如在评论和回答中所解释的那样,这就是JavaScript的工作方式。 Java-Clojure存在差异,其中记录了here,特别是:

  

调用fn

时,当前没有运行时强制执行arity

1 个答案:

答案 0 :(得分:6)

结果函数中的参数由编号最高的已使用参数确定。因此,通过使用%2两者都成为2 arity函数,但由于您只使用%1(或%),因此它在两个版本的Clojure中都成为一个arity函数。

在JavaScript中,您可以传递与您一样多的参数,甚至可以传递少于参数列表的参数。没有匹配参数的变量变为undefined,没有定义参数的参数在函数中根本没有绑定和可用。 ClojureScript必须在每个函数中添加参数检查,以获得与Clojure中相同的行为。如果这是指定的行为,那将是一个错误。许多已编译的语言都是这样做的。

您的示例的解决方案是不使用简短版本,而是使用fn

(reduce (fn [a _] (+ 1 a)) 0 '(1 2 3 55))