2024年Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面以了解如何操作的更多信息。

+1
ClojureScript

定义带varargs的多方法,然后在包含20个以上元素的序列上使用apply失败。

错误取决于是否有准确21个参数或更多。

在正常函数定义中没有观察到这一行为。

ClojureScript 1.10.439
cljs.user=> (defmulti foo (fn (link: & args) (first args)))

'cljs.user/foo

cljs.user=> (defmethod foo 0 (link: & args))

object(link: cljs.core.MultiFn)

cljs.user=> (apply foo (range 20))
nil

cljs.user=> (apply foo (range 21))
错误:20不是ISeqable

 cljs$core$seq (.cljs_nashorn_repl/cljs/core.cljs:1223:13)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3739:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$spread (.cljs_nashorn_repl/cljs/core.cljs:3740:9)
 cljs$core$IFn$_invoke$arity$variadic (.cljs_nashorn_repl/cljs/core.cljs:3926:6)
 G__12749__22 (.cljs_nashorn_repl/cljs/core.cljs:10998:5)
 G__12749 (.cljs_nashorn_repl/cljs/core.cljs:10868:1)
 apply (.cljs_nashorn_repl/cljs/core.cljs:10868:1)
 cljs$core$IFn$_invoke$arity$6 (.cljs_nashorn_repl/cljs/core.cljs:3885:6)
 cljs$core$IFn$_invoke$arity$5 (.cljs_nashorn_repl/cljs/core.cljs:3879:6)
 cljs$core$IFn$_invoke$arity$4 (.cljs_nashorn_repl/cljs/core.cljs:3873:6)
 cljs$core$IFn$_invoke$arity$3 (.cljs_nashorn_repl/cljs/core.cljs:3867:6)
 cljs$core$IFn$_invoke$arity$2 (.cljs_nashorn_repl/cljs/core.cljs:3861:6)
 cljs$core$IFn$_invoke$arity$2 (.cljs_nashorn_repl/cljs/core.cljs:3896:6)
 cljs$core$apply (.cljs_nashorn_repl/cljs/core.cljs:3887:1)
 (<NO_SOURCE_FILE> <eval>:1:0)
 (<NO_SOURCE_FILE> <eval>:1:0)
 (<NO_SOURCE_FILE> <eval>:1:0)

cljs.user=> (apply foo (range 22))
错误:无效的arity:22

 G__12749 (.cljs_nashorn_repl/cljs/core.cljs:36125:0)
 apply (.cljs_nashorn_repl/cljs/core.cljs:10868:1)
 cljs$core$IFn$_invoke$arity$6 (.cljs_nashorn_repl/cljs/core.cljs:3885:6)
 cljs$core$IFn$_invoke$arity$5 (.cljs_nashorn_repl/cljs/core.cljs:3879:6)
 cljs$core$IFn$_invoke$arity$4 (.cljs_nashorn_repl/cljs/core.cljs:3873:6)
 cljs$core$IFn$_invoke$arity$3 (.cljs_nashorn_repl/cljs/core.cljs:3867:6)
 cljs$core$IFn$_invoke$arity$2 (.cljs_nashorn_repl/cljs/core.cljs:3861:6)
 cljs$core$IFn$_invoke$arity$2 (.cljs_nashorn_repl/cljs/core.cljs:3896:6)
 cljs$core$apply (.cljs_nashorn_repl/cljs/core.cljs:3887:1)
 (<NO_SOURCE_FILE> <eval>:1:0)
 (<NO_SOURCE_FILE> <eval>:1:0)
 (<NO_SOURCE_FILE> <eval>:1:0)

cljs.user=> (defn bar (link: & args))

'cljs.user/bar

cljs.user=> (apply bar (range 100))
nil

2 答案

0

评论者:kanaka

我认为这是一个相同的问题或与之密切相关的问题https://clojure.atlassian.net/browse/CLJS-2446

我在实际情况下遇到了我认为是相同的问题(使用ClojureScript开发的自我托管mal/make-a-lisp)。似乎元数据装饰的函数与多方法具有相同的限制。

以下展示了使用lumo的情况,但使用在浏览器中(AOT cljs运行)出现同样的问题

`
Lumo 1.10.1
ClojureScript 1.10.520
Node.js v11.13.0
...
cljs.user=> (apply + (range 20))
190
cljs.user=> (apply + (range 21))
210
cljs.user=> (apply + (range 22))
231

cljs.user=> (apply (with-meta + {}) (range 20))
190
cljs.user=> (apply (with-meta + {}) (range 21))
错误:20不是ISeqable

 Object.cljs.core.seq (NO_SOURCE_FILE <embedded>:503:388)
 Object.cljs.core.spread (NO_SOURCE_FILE <embedded>:834:335)
 Object.cljs.core.spread (NO_SOURCE_FILE <embedded>:834:500)
 Object.cljs.core.spread (NO_SOURCE_FILE <embedded>:834:500)
 Object.cljs.core.spread (NO_SOURCE_FILE <embedded>:834:500)
 Object.cljs.core.spread (NO_SOURCE_FILE <embedded>:834:500)
 Object.cljs.core.spread (NO_SOURCE_FILE <embedded>:834:500)
 Object.cljs.core.spread (NO_SOURCE_FILE <embedded>:834:500)
 Object.cljs.core.spread (NO_SOURCE_FILE <embedded>:834:500)
 Object.cljs.core.spread (NO_SOURCE_FILE <embedded>:834:500)

cljs.user=> (apply (with-meta + {}) (range 22))
错误:无效的arity:22

 (cljs.core.MetaFn.a)
 cljs.core.MetaFn.apply (NO_SOURCE_FILE <embedded>:603:289)
 Function.cljs.core.apply_to_simple.cljs$core$IFn$_invoke$arity$6 (NO_SOURCE_FILE <embedded>:874:323)
 Function.cljs.core.apply_to_simple.cljs$core$IFn$_invoke$arity$5 (NO_SOURCE_FILE <embedded>:867:205)
 Function.cljs.core.apply_to_simple.cljs$core$IFn$_invoke$arity$4 (NO_SOURCE_FILE <embedded>:866:199)
 Function.cljs.core.apply_to_simple.cljs$core$IFn$_invoke$arity$3 (NO_SOURCE_FILE <embedded>:865:193)
 Function.cljs.core.apply_to_simple.cljs$core$IFn$_invoke$arity$2 (NO_SOURCE_FILE <embedded>:864:188)
 Function.cljs.core.apply.cljs$core$IFn$_invoke$arity$2 (NO_SOURCE_FILE <embedded>:877:244)
 cljs.core.apply (NO_SOURCE_FILE <embedded>:875:84)
 (evalmachine.<anonymous>:1:17)

`

我来这里是要报告这个问题,很高兴找到了这个问题的解决方案。我在任何带有元数据的任何事情上和实际上任何实现了`IFn`的事情上都看到了相同的问题。

```
(let [args (repeat 21 0)]
  (apply (with-meta + {}) args))
```
0
参考: https://clojure.atlassian.net/browse/CLJS-3024(由alex+import报告)
...