【问题标题】:Clojure macro parametersClojure 宏参数
【发布时间】:2013-01-18 12:15:23
【问题描述】:

大约一周前,我在这个帖子中问了一个问题:Looping through a "let"-list in Clojure? 我得到了一个很好的答案,然而,一个相当令人困惑的问题出现在我的脑海中:

以下是部分答案:

(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 ...我个人的猜测是,因为我对如何组合所有这些小古怪的东西缺乏充分的理解符号,我可能错过了它们的某种组合......

【问题讨论】:

    标签: macros clojure


    【解决方案1】:

    ~@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...
    • 但是!!!我尝试了上面的代码,现在 (anaphoric-let [a "cat" b 2]) 是不可能的吗? “它表示通过的 args(4) 数量错误”
    • 这~可能~因为 (if ...) 表达式被破坏了。你错过了一个 ( 在 if 之前我就这样复制了它,错过了错误。
    • 谢谢,这个已修复的错误。之后还有另一个错误,抱怨“x”,但我用 x# 替换了所有 x,现在它似乎运行良好。谢谢,我完全得去读一下“#”,不过看起来!
    猜你喜欢
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-09
    • 1970-01-01
    • 2011-07-12
    相关资源
    最近更新 更多