【问题标题】:clojure template variadic macroclojure 模板可变参数宏
【发布时间】:2017-03-03 11:51:31
【问题描述】:

我尝试了以下代码(学习宏):

(require '[clojure.template :as temp])

(defn fna [x] (println "a" x) x)
(defn fnb [x] (println "b" x) x)

(temp/apply-template '[& fns]
                     '(fn [payload] (-> payload fns))
                     '[fna fnb])
;; returns (fn [payload] (-> payload fnb))

正如我所料,我对输出感到惊讶:

(fn [payload] (-> payload fna fnb))

为什么会产生这种输出,以及实现上述目标的方法是什么?我在文档中特别说:

argv 是一个参数列表,就像在 defn 中一样。

注意:可以这样写,但我想了解如何使用模板:

(defmacro wrap-fn-> [& fns]
  `(fn [~'x#]
     (-> ~'x
         ~@fns)))

【问题讨论】:

  • 我想说,如果您正在学习使用template,因为您希望它有用,请不要打扰。它没有在 clojure.test 之外的现实生活中使用,而且它是一个相当有限的工具;知道如何自己编写宏将为您提供更好的服务。

标签: clojure macros


【解决方案1】:

这里的例子

不要像[& fns] 那样显示“rest args”的使用。我认为那是你出错的地方。试试这个:

(println
  (temp/apply-template
    '[x y]
    '(fn [payload] (-> payload x y))
    '[fna fnb]))

=> (fn [payload] (-> payload fna fnb))

顺便说一句,我以前从未见过 clojure.template 使用过 - 它看起来像是一个非常专业的工具。

【讨论】:

  • 是的,它会像那样工作,但是对于固定数量的fns,我试图让它采用可变数量的参数。请注意,这是出于学习目的(在查看 clojure.test 源之前从未见过它)。在实践中,我会使用defmacro 获取可变数量的参数,并将其传递给apply-template。这纯粹是好奇(到目前为止)。此外,我不明白为什么需要fnb 而不是fna
  • 它“接受”fnb,因为[& fns] 是一个包含两个符号&fns 的参数列表。您的模板定义忽略了名为& 并传递了fna 的第一个参数,而只使用了名为fns 并传递了fnb 的第二个参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多