大约一周前,我在这个帖子中问了一个问题:在 Clojure 中循环遍历“let”列表? 我得到了一个很好的答案,然而,一个相当令人困惑的问题出现在我的脑海中:
以下是部分答案:
(defmacro anaphoric-let [alternating-symbols-and-values & body]
`(let [~@alternating-symbols-and-values
names# (quote ~(flatten (partition 1 2 alternating-symbols-and-values)))
values# ~(vec (flatten (partition 1 2 alternating-symbols-and-values)))
~'locals (zipmap names# values#)]
~@body))
Input:
(anaphoric-let [a 1 b 2 c 3 d 4 e "cat"]
(dorun (for [x (vals locals)]
(if (number? x) (println "roar")))))
本例中的 (dorun) 语句是宏参数中的主体,对吗?所以我的印象是它只会“复制粘贴”身体。所以而不是:
~@body
它看起来像下面,然后它会取消引用复制的文本和所有内容:
~@(dorun (for [x (vals locals)]
(if (number? x) (println "roar"))))
在试图解释所有正在发生的事情时,我尝试了我刚刚解释的确切内容。我没有尝试使用 ~@body,而是尝试在其中放置一些“真实代码”。
然后它看起来像这样:
(defmacro anaphoric-let [alternating-symbols-and-values & body]
`(let [~@alternating-symbols-and-values
names# (quote ~(flatten (partition 1 2 alternating-symbols-and-values)))
values# ~(vec (flatten (partition 1 2 alternating-symbols-and-values)))
~'locals (zipmap names# values#)]
~@(dorun (for [x (vals locals)]
if (number? x) (println "roar"))))))
这不起作用并抱怨它是“无法解析符号:在这种情况下的本地人”我是一个新手,我已经尝试过实验和分析,但我并没有变得更聪明。每次我想我都明白了,总会有一个小小的“但是……”出现并粉碎一切!
我觉得我对示例的其余部分确实有一个不错的理解,除了邪恶的 ~@body ... 我个人的猜测是,由于我对如何组合所有这些古怪的小符号缺乏全面的了解,所以我可能错过了它们的某种组合......