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

欢迎!有关如何工作的更多信息,请查看关于页面。

+1
编译器
已关闭

当将 lazy-seq 传递给 quote 时,我遇到了一个错误。以下是一个引发此问题的示例

`
user=> (eval `(quote ~(lazy-seq '(1 2 3))))
(1 2 3)

user=> (eval `(quote ~(lazy-seq '())))
语法错误(UnsupportedOperationException)编译 fn* 在 (REPL:1:1)。
未知集合类型

user=> (eval (quote ())) () ``

已关闭为重复问题: 当评估空 lazy-seq 时会导致错误

1 答案

0

这种情况是否有什么相关情况?

Clojure 的许多方法都会返回一个惰性序列,所以如果在一个空集合上使用 quote,可能会引发这个问题。例如:`'(quote ~(map a b))'

我直接使用 lazy-seq 编写了上面的示例,以制作一个最小测试用例。
我从未听说过有人遇到过这个问题,所以我更感兴趣的是在某个人(比如你自己)真正遇到过这种情况的时候。
有没有不涉及 eval 的情况下会导致问题的场景?因为在生产 Clojure 代码中,eval 几乎 never 出现。
`(defmacro m [] `'~(keep (constantly nil) (range 10)))` 也有相同的问题。

我发现 `Compiler$EmptyExpr` 除了空列表之外,并没有正确处理空序列。可能这里的 Compiler 代码 https://github.com/clojure/clojure/blob/6975553804b0f8da9e196e6fb97838ea4e153564/src/jvm/clojure/lang/Compiler.java#L2990-L2991 应该处理这些情况。

编辑了
我有一个使用quote将一些数据记录到数据结构中的宏。这类似于 "(defmacro m [x y] `(swap! global-data assoc ~(foo x) `(quote ~(map bar y))))"。
问题是在“y”传递一个空向量时触发的。

现在我已经通过仅仅将映射的懒序列转换为向量来解决这个问题。
"(defmacro m [x y] `(swap! global-data assoc ~(foo x) `(quote ~(vec (map bar y)))))"。
谢谢,这很有帮助。
...