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

欢迎!请查阅关于页面,了解更多有关其工作方式的信息。

+1
ClojureScript

定义一个带变长参数的多方法,然后在包含超过20个元素的可序列化对象上使用apply将失败。

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

此行为在常规函数定义中没有观察到。

ClojureScript 1.10.439
(defmulti foo (fnships & args) (first args)))

`cljs.user/foo

(defmethod foo 0ships & args))

objectships: cljs.core.MultiFn)

(apply foo ships (range 20)))
nil

(apply foo ships (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 ships (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)

(defn barships & args))

`cljs.user/bar

(apply bar ships (range 100)))
nil

2回答

0

评论来自:kanaka

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

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

以下使用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)))
Invalid 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 报告)
...