Macros Clojure宏参数

Macros Clojure宏参数,macros,clojure,Macros,Clojure,大约一周前,我在这个帖子里问了一个问题: 我得到了一个很好的答案,然而,我脑海中出现了一个相当令人困惑的问题: 以下是部分答案: (defmacro anaphoric-let [alternating-symbols-and-values & body] `(let [~@alternating-symbols-and-values names# (quote ~(flatten (partition 1 2 alternating-symbols-and

大约一周前,我在这个帖子里问了一个问题: 我得到了一个很好的答案,然而,我脑海中出现了一个相当令人困惑的问题:

以下是部分答案:

(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。。。我个人的猜测是,由于我对如何组合所有这些奇怪的小符号缺乏充分的理解,我可能缺少了它们的某种组合…

~@expr在反引号表达式中表示计算expr并将其拼接到周围的表达式中

由于不想计算(dorun…)表达式,因此可以复制并粘贴它:

(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"))))))
由于您不再需要在身体中插入特定的符号,我将替换的局部变量改为gensym'd符号


现在,我不知道为什么要在这样的硬编码宏中引入用户指定的符号。我假设这只是为了实验。

~@expr在反引号中表示计算expr并将其拼接到周围的表达式中

由于不想计算(dorun…)表达式,因此可以复制并粘贴它:

(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"))))))
由于您不再需要在身体中插入特定的符号,我将替换的局部变量改为gensym'd符号


现在,我不知道为什么要在这样的硬编码宏中引入用户指定的符号。我假设这只是为了实验。

呵呵,我实际上尝试了一个简单的复制和粘贴,但由于这是我第一次处理#,似乎我的错误是没有在for语句中添加#。是的,我的目标不是实现伟大或什么,只是玩玩而已。你说这是一个我不知道的糟糕做法,我想我很难真正理解宏和函数之间的区别,我一直在尝试将东西翻译成Java的思路来尝试理解它,但我认为这样做不是很明智,因为这不是OOP…然而!!!我试过上面的代码,现在(回指let[a“cat”b2])不可能了?“它说传递的args(4)的数目错误”这很可能是因为(if…)表达式被破坏了。你缺少一个(在if之前),我像那样复制了它,缺少了错误。谢谢,这个已修复的错误。之后还有一个错误,抱怨“x”但是我把所有的x都换成了x,它现在似乎运行得很好。谢谢,我完全得去读一下“#”这个词了!呵呵,我实际上试过用一个简单的拷贝和粘贴,但因为这是我第一次处理#,所以我的错误似乎不是在for语句中添加#。是的,我并不是想达到伟大的目的你说这是一个我不知道的坏习惯,我想我真的很难理解宏和函数之间的区别,我一直试图把东西翻译成Java的思路来尝试理解它,但我认为这样做不是很明智,因为这不是OP…然而!!!我尝试了上面的代码,现在(回指let[a“cat”b 2])不可能了?“它说传递的args(4)数目错误”这可能是因为(if…)表达式被破坏了。您缺少了一个(在if之前,我这样复制了它,错过了错误。谢谢,这个修复错误。在那之后还有另一个错误,抱怨“x”,但我用x替换了所有的x,现在它似乎运行得很好。谢谢,我完全要去读一下“#”了!