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

1回答

0

这是否有相关场景?

许多Clojure的方法会返回一个惰性序列(lazy-seq),因此如果对空集合使用quote,可能会导致这个问题。例如:`'(quote ~(map a b))'

我直接使用lazy-seq编写了上述示例,以制作一个最小测试用例。
本人并不了解任何出现过此类问题的人,因此我对像您这样的人实际遇到这种情况的时间更感兴趣。
是否有任何不涉及eval导致此问题的场景?因为eval在生产Clojure代码中非常罕见。
"(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)))))"
谢谢,非常有帮助
...