Clojure中的list?和宏

3
我正在尝试了解Clojure宏如何应用于列表。以下内容让我感到困惑:

我正在尝试了解Clojure宏如何应用于列表。以下内容让我感到困惑:

(defmacro islist [f] (list? f))
(islist (1 2)) ; true
(islist '(1 2)) ; false
(islist (quote (1 2))) ; true

这是正常现象吗?我注意到,我传递给宏的列表在宏内部使用list?进行求值时会返回false。也就是说,第二个示例特别令人困惑。

1
你确定不需要这个吗?(defmacro islist[f] `(list? ~f)) - BillRobertson42
1个回答

2

在宏 '(1 2) 中,类型为 clojure.lang.Cons(您可以通过将 list? 更改为 type 来检查此内容)。当操作数的类型为 clojure.lang.IPersistentList 时,list? 返回 true。

user=> (isa? clojure.lang.Cons clojure.lang.IPersistentList)
false

clojure.lang.Cons 出现的原因是,当将 '(1 2) 展开为 (quote (1 2)) 时,读取器会构造一个 cons 单元,而直接拼写 quote(quote (1 2)) 时则不会构造。

您可能想使用 seq? 而不是 list?


1
谢谢。你知道这是否是一个有意识的设计选择吗?当https://gist.github.com/karansag/2b907d0d9c570552d33f有效时,我很惊讶,所以我问了这个问题。 - karansag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接