当前位置:  开发笔记 > 人工智能 > 正文

为什么clojure函数有最多20个参数的限制

如何解决《为什么clojure函数有最多20个参数的限制》经验,为你挑选了2个好方法。

clojure函数可以采用的参数数量似乎有限制.

定义具有20个以上参数的函数时,我收到以下内容:

#

显然这可以避免,但我正在达到这个限制,将现有DSL的执行模型移植到clojure,并且我在我的DSL中有如下构造,通过宏扩展可以非常容易地映射到函数,除了这个限制:

(defAlias nn1 ((element ?e1) (element ?e2)) number
"@doc features of the elements are calculated for entry into
      the first neural network, the result is the score computed by the latter"
(nn1-recall (nn1-feature00 ?e1 ?e2) (nn1-feature01 ?e1 ?e2) ... (nn1-feature89 ?e1 ?e2)))

这是一个用于调用具有90个输入节点的神经网络的DSL语句.当然可以解决它,但想知道限制的来源.谢谢.



1> Michał Marcz..:

首先,限制仅适用于所需的位置参数 ; 你总是可以使用变量arity case(& more-args在函数的签名中)来处理你想要的任意数量的参数:

(defn foo [& args]
  (count args))

(foo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25)
;; returns 25

事实上,乍一看,& args很可能是您问题的正确解决方案.(例如,您将能够将一个函数映射到收集到序列中的输入节点上,loop/ recur通过所述序列等等. - 对于大量类似项目而言,比为每个项目分配单独的名称更有意义.

(请注意,我不会假装知道您正在转录到Clojure中的特定DSL的性质或您正在处理的问题,只是建议您可能感兴趣的点.如果您有一个非常时髦的情况,这似乎不适用,也许你可以提供更多细节,我们会看到这里是否有人可以提供一些有用的提示,以便在Clojure中处理它.)

为了完整起见,您可以将该& args位添加到一个函数中,该函数将前19个参数作为必需的位置参数:

(defn bar [a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 & as]
  (+ 19 (count as)))

(bar 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25)
;; returns 25

请注意,如果你指定20个位置args和&arg顶部,那么显然会出现奇怪现象.

至于基本原理,我认为这与JVM可以非常有效地调度到arity的方法这一事实有关,因此clojure.lang.Fn该类有invoke超过20的arities方法重载.我不完全确定它是否可以去高于此,但我认为这不是人们经常要求的......我的意思是,我当然发现任何API指定一个函数有20多个位置参数有点怀疑.


请注意:同时有20个位置args和rest args:有一个错误导致`nil`被返回而没有为这个arity评估函数的主体,Rich已经修复了几分钟.因此,1.2不会有这个问题.

2> raph.amiard..:

Michal Marczyk的答案告诉你如何绕过极限.如果您对此限制的原因感兴趣,您可能想要看一眼这个clojure来源:IFn

invoke是由Ifn接口实现的java重载方法,Rich重载它以支持最多20个参数.当你在clojure中调用一个函数时,底层实现会调用函数对象上的invoke,这个方法最多只支持20个args.

你可以超载它以支持更多,但我怀疑这样的事情的效用.如果你有一堆输入源,他们可能会被视为一个数组.

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有