clojure的快乐,宏

时间:2013-12-24 11:48:00

标签: macros clojure symbols

我一直在经历clojure练习的喜悦,并且遇到了这个例子

(defn build-contract [c]
    (let [args (first c)]
      (list
       (into '[f] args) ;; here is where i am confused
       (apply merge
              (for [con (rest c)]
                (cond (= (first con) :require)
                      (assoc {} :pre (vec (rest con)))
                      (= (first con) :ensure)
                      (assoc {} :post (vec (rest con)))
                      :else (throw (Exception. (str "Unkown tag " (first con)))))))
       (list* 'f args)))) ;; and here

  (defn collect-bodies [forms]
    (for [form (partition 3 forms)]
      (build-contract form)))

  (defmacro contract [cg & forms]
    (list* `fn cg (collect-bodies forms)))

我似乎无法理解你为什么要在那个向量中使用一个名为f的符号。符号是对事物的引用,那么将引用什么?为什么我们需要引用它?

2 个答案:

答案 0 :(得分:5)

宏构建一个函数文字表达式(fn形式)。

(into '[f] args) ;; here is where i am confused

这是参数向量。 f出现在正式论证的角色中。

(list* 'f args)))) ;; and here

这是功能应用程序。 f是一个函数参数,此处它已应用于args

构建时,生成的定义将如下所示。

(fn name [f arg1 arg2] ... (f arg1 arg2))

答案 1 :(得分:2)

符号是对事物的引用,特定宏正在构建函数,而符号f是指由该函数接收的函数参数f。 (宏正在构建一个函数,它接收一个名为f的参数的函数

在宏内部,当您需要引用命名参数时,那就是您的f

在这个特殊情况下:

(into '[f] args)

与:

相同
(into ['f] [a1 a2 a3])

正在构建函数参数,如

(fn cg [f a1 a2 a3] ...

最后一次调用只是函数调用

 (f a1 a2 a3)