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

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

+1
编译器
已关闭

当将懒序列传递到引号中时,我遇到了一个错误。以下是一个导致问题的示例

`
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))'

我直接使用惰性序列编写了上面的示例,以创建一个最小的测试用例。
我不知道有任何人遇到过这个问题,所以我对有人(比如你)实际遇到过这种情况很感兴趣。
是否有任何不涉及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 应该处理那些情况。

编辑
我有一个宏,用来通过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)))))"
by
谢谢,非常有帮助。
...