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

欢迎!请参阅关于 页面以了解如何使用本站。

0
Clojure
重新标记

当评估非空队列时,编译器不尝试执行它(就像它会对 Seq 执行那样),而是将其视为 PersistentList,因此发送到 clojure.lang.Compiler/emitListAsObjectArray。这是一个错误,因为队列不是列表。

=> (eval (conj clojure.lang.PersistentQueue/EMPTY 1)) 语法错误(ClassCastException)在 (REPL:1:1) 编译 fn*。类 clojure.lang.PersistentQueue 不能转换为类 java.util.List (clojure.lang.PersistentQueue 在未命名的模块中;java.util.List 在模块 java.base 中)

堆栈跟踪是

`
语法错误编译 fn* 在 (1:1)。

at clojure.lang.Compiler.analyzeSeq(Compiler.java:7119)
at clojure.lang.Compiler.analyze(Compiler.java:6793)
at clojure.lang.Compiler.eval(Compiler.java:7178)
at clojure.lang.Compiler.eval(Compiler.java:7136)
at clojure.core$eval.invokeStatic(core.clj:3202)
at clojure.core$eval.invoke(core.clj:3198)
at user$eval242.invokeStatic(NO_SOURCE_FILE:1)
at user$eval242.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:7181)
at clojure.lang.Compiler.eval(Compiler.java:7136)
at clojure.core$eval.invokeStatic(core.clj:3202)
at clojure.core$eval.invoke(core.clj:3198)
at clojure.main$repl$read_eval_print__9110$fn__9113.invoke(main.clj:437)
at clojure.main$repl$read_eval_print__9110.invoke(main.clj:437)
at clojure.main$repl$fn__9119.invoke(main.clj:458)
at clojure.main$repl.invokeStatic(main.clj:458)
at clojure.main$repl_opt.invokeStatic(main.clj:522)
at clojure.main$main.invokeStatic(main.clj:667)
at clojure.main$main.doInvoke(main.clj:616)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.main.main(main.java:40)

原因是:java.lang.ClassCastException:类别 clojure.lang.PersistentQueue 不能转换为类别 java.util.List (clojure.lang.PersistentQueue 在 "app" 加载器的未命名模块中;
java.util.List 在 "bootstrap" 加载器的模块 java.base 中)

at clojure.lang.Compiler$ObjExpr.emitListAsObjectArray(Compiler.java:4701)
at clojure.lang.Compiler$ObjExpr.emitValue(Compiler.java:4874)
at clojure.lang.Compiler$ObjExpr.emitConstants(Compiler.java:4938)
at clojure.lang.Compiler$ObjExpr.compile(Compiler.java:4616)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:4110)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:7109)
... 23 more`

1 答案

0

https://clojure.atlassian.net/browse/CLJ-2628 形式登录,有一些选项。

感谢查看这个。我对ticket上的备选方案有一些评论

- 如果PersistentQueue实现了j.u.List,则它将继续打印列表,即使这不是它所返回的内容。所以如果一个宏尝试返回一个队列(即使在另一个seq内部),它将被转换为列表。所以不可能从宏中返回队列。现在就已经是这样了
=> (defmacro m [] clojure.lang.PersistentQueue/EMPTY)
=> (m)
()
user=> (type (m))
clojure.lang.PersistentList$EmptyList

- 如何实现特定的PQ输出?

现在,emitValue中的测试正在检查ISeq或IPersistentList。只有两种类型实现了IPersistentList:PersistentList和PersistentQueue。PersistentList已经是一个ISeq,所以检查IPersistentList是这里出现问题的具体原因。移除它将使其跌落到RT.printString(value),这是大多数没有文字表示的对象跌落的地方。

这引出了另一个问题(这个问题是我从别人那里转达的,但我自己也在思考):是否考虑为队列提供一个文字表示?
ClojureScript有:#queue [1 2 3]
对于嵌入到语言中的结构,可能会有自己的特殊读取宏,比如#[1 2 3]
这将提供一条路径,用于输出一个可以读回的结构
>  如果PersistentQueue实现了j.u.List,则它将继续打印列表

true,我还没有考虑所有的权衡,只是提出一些想法

> 如何实现特定的PQ输出?

这个方法有很多,可以添加另一个。但是,在没有更多评估的情况下,我不知道权衡是什么。


有一个关于队列的旧ticket,用于读取/打印支持

https://ask.clojure.org/index.php/3365/implement-reader-literal-support-persistentqueue-structure

我向自己提出的问题是:队列是否重要到足以在Clojure中添加语法?我没有好的答案 - 最终不是我的决定。 :) 但任何针对该问题的具体评论都可以放在那里。
...