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

欢迎!请参阅关于页面以获取更多关于如何使用本站的信息。

+1
ClojureScript

定义一个使用可变参数的多重方法,然后对一个具有20多个元素的序列使用apply将失败。

错误取决于是否有恰好21个参数或多于21个参数。

在正常函数定义中未观察到这种行为。

ClojureScript 1.10.439
(defmulti foo (fn ([args]) (first args)))

'foo

(defmethod foo 0 ([args]))

object(link: cljs.core.MultiFn)

(apply foo (range 20))
nil

(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)

(apply foo (range 22))
错误:无效的参数: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)

(defn bar ([args]))

'bar

(apply bar (range 100))
nil

2 回答

0

评论者:kanaka

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

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

以下使用lumo进行演示,但在浏览器(Chrome)中运行AOT cljs也存在同样的问题

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

(apply (with-meta + {}) (range 20))
190
(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)

(apply (with-meta + {}) (range 22))
无效的参数: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 提报)
...