我对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
答案 0 :(得分:6)
结果函数中的参数由编号最高的已使用参数确定。因此,通过使用%2
两者都成为2 arity函数,但由于您只使用%1
(或%
),因此它在两个版本的Clojure中都成为一个arity函数。
在JavaScript中,您可以传递与您一样多的参数,甚至可以传递少于参数列表的参数。没有匹配参数的变量变为undefined
,没有定义参数的参数在函数中根本没有绑定和可用。 ClojureScript必须在每个函数中添加参数检查,以获得与Clojure中相同的行为。如果这是指定的行为,那将是一个错误。许多已编译的语言都是这样做的。
您的示例的解决方案是不使用简短版本,而是使用fn
:
(reduce (fn [a _] (+ 1 a)) 0 '(1 2 3 55))