2024 年 Clojure 调查问卷 中分享您的想法!

欢迎!请查看 关于 页面以了解更多关于如何使用这个功能的信息。

+1
编译器
已关闭

当将 lazy-seq 传递到引用中时,我遇到了一个错误。这里有一个导致问题的示例

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

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

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

已关闭为一个重复项: 空 lazyseq 的引用在求值时产生错误

1 答案

0

是否存在某些场景与此相关?

许多Clojure方法会返回一个懒序列(lazy-seq),所以如果对一个空集合使用quote,可能导致这个问题。例如:“`(quote ~(map a b))”。

我上面给出的例子是直接使用lazy-seq来构造一个最小测试案例。
在没有使用eval的情况下,这种情况是否会引起问题?因为在Clojure的生产代码中,eval出现的非常少。
“(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应该处理这些情况。

问题是在'y'被赋予一个空向量时触发的。

我暂时通过将映射的惰性序列强制转换为向量来解决这个问题。
(defmacro m [x y] `(swap! global-data assoc ~(foo x) (quote ~(vec (map bar y)))))
谢谢,这很有帮助。
...