Macros Clojure反向膨胀

Macros Clojure反向膨胀,macros,clojure,backticks,Macros,Clojure,Backticks,根据学习结果,Clojure backticks扩展如下 `(x1 x2 x3 ... xn) 被解释为意味着 (clojure.core/seq (clojure.core/concat |x1| |x2| |x3| ... |xn|)) 为什么用seq包装concat?它有什么区别?严格地说,它扩展到: (macroexpand '`(x1 x2 x3)) (clojure.core/seq (clojure.core/concat (clojure.core/list (quote u

根据学习结果,Clojure backticks扩展如下

`(x1 x2 x3 ... xn)
被解释为意味着

(clojure.core/seq (clojure.core/concat |x1| |x2| |x3| ... |xn|))

为什么用seq包装concat?它有什么区别?

严格地说,它扩展到:

(macroexpand '`(x1 x2 x3))
(clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/x1)) (clojure.core/list    (quote user/x2)) (clojure.core/list (quote user/x3))))

(macroexpand `(x1 x2 x3))
(user/x1 user/x2 user/x3)

为什么要调用seq?因为序列是Clojure哲学的基石。我建议你阅读。否则,我会在这里复制它。

不管它是如何产生的

  • concat
    返回一个序列,然后
  • seq
    返回与序列参数内容相同的序列
。。。所以
seq
实际上是
concat
上的一个身份操作。。。除一种情况外:

s
为空序列时,
(seq s)
nil

我怀疑这个扩展是正确的,因为

`()
。。。评估为

()
nil
。。。带类型

clojure.lang.PersistentList$EmptyList
鉴于

(seq (concat))
。。。评估为

()
nil

这表明对
seq
的包装调用不存在

在这里进行宏观扩张的呼吁完全是徒劳的<代码>'`(x1x2x3)的计算结果是相同的。@amalloy是的。我只是在这里发布了更多的解释。若你们建议的话,我可以删除它。这甚至不能回答一点问题。这不是真的。保留空列表:-对seq的调用已存在。“就我所知,我的回答是正确的,你已经证实了这一点。我的观点是,拟议的扩张是错误的。正如您所说,空列表将被保留。我同意:这在我的答案中,作为一个明确的例子。如果问题或问题中的扩张占上风,它们就不会出现。我不知道这是如何在编译器中发生的。查看您引用的代码,结果是
RT.cons(LIST,null)
。这可能会返回
null
,但我们知道它不会返回。看看第837行上方的所有其他情况——以及第837行的else——它们都以seq开头包装了一个列表。这就是它在读者中发生的方式。@Leon Grapenthin然而,出于所述原因,提议的扩展是无效的。答案到底错在哪里?拟议的扩张是正确的``()`被读取为
()
,因为它有一个例外。在所有其他情况下,
seq
被包装。