Clojure可以通过宏生成函数吗? [英] Can Clojure generate function by macro?
问题描述
我想通过宏生成fn。但我遇到一个奇怪的问题。
代码在这里。
I'm trying to generator fn through macro.But I meet a strange issue. Code is Here.
(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 here.And为什么test3工作良好,但test2失败。
I know defn can work well.I just want to know why I can't use defmacro here.And why test3 works well,however test2 fails.
推荐答案
test2,在编译之前,test2宏将被调用(lmk尚未被编译或评估) - 因为没有语法quote,这将实际上评估fn形式并返回一个函数对象(使用lmk closed over)。所以,你的形式(fn-object 13)传递给编译器,我认为这是一个意想不到的路径(不确定是什么)。有趣的是,它的工作原理:
In test2, prior to compilation, the test2 macro will be invoked (lmk has not yet been compiled or evaluated) - because there is no syntax quote, this will actually evaluate the fn form and return a function object (with lmk closed over). So you then have the form (fn-object 13) passed to the compiler, which I think is going down an unexpected path (not sure exactly what that is). Interestingly this works:
(def f (test2 12))
(f 13)
在test4中,语法引用将导致每个lmk符号在命名空间中解析,因此是错误的来源。你真的想要那些自动生成:
In test4, the syntax quote will cause each lmk symbol to be resolved in the namespace so that's the source of that error. You really want autogensyming on those:
(defmacro test4 []
`(fn [lmk#] (println lmk#)))
这篇关于Clojure可以通过宏生成函数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!