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

欢迎!请参阅关于页面以获取更多关于如何使用本站的信息。

+1
编译器
已关闭

我在将lazy-seq传递到quote时遇到了一个bug。以下是一个引起问题的示例

`
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的许多方法会返回懒序列,如果在空集合上使用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应该处理这些情况。

编辑了
我有一个宏,它会将一些数据通过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)))))"
谢谢,这很有帮助
...