Clojure可以通过宏生成函数吗?

时间:2014-05-08 12:49:45

标签: macros clojure

我正在尝试通过宏生成fn。但我遇到了一个奇怪的问题。 代码在这里。

(defmacro test2 [lmk]
   (fn [lmk2] (println lmk lmk2)))
((test2 12) 13) ;;----->Error
(defmacro test3 []
   (fn [lmk] (println lmk)))
((test3) 12) ;;----->OK
(defmacro test4 []
   `(fn [lmk] (println lmk)))
((test4) 12) ;;----->Error

我知道defn可以正常工作。我只想知道为什么我不能在这里使用defmacro。为什么test3运行良好,但test2失败。

1 个答案:

答案 0 :(得分:2)

在test2中,在编译之前,将调用test2宏(lmk尚未编译或评估) - 因为没有语法引用,这实际上将评估fn表单并返回一个函数对象(lmk已关闭)过度)。然后你将表单(fn-object 13)传递给编译器,我认为这是一个意想不到的路径(不确定究竟是什么)。有趣的是,这有效:

(def f (test2 12))
(f 13)

在test4中,语法引用将导致在命名空间中解析每个lmk符号,以便该错误的来源。你真的想要自动化:

(defmacro test4 [] 
  `(fn [lmk#] (println lmk#)))