如何让Clojure宏充当函数,所以我可以将它作为参数传递给你?我希望不得不以某种方式包装它。
我不希望包装版本的行为与原始宏完全相同(按名称调用与按值调用的差异),但在一些不重要的情况下它会很有用。
答案 0 :(得分:20)
如果我正确理解你,你可以将它包装在一个函数中。
将平方函数的这种(愚蠢的)实现视为宏:
(defmacro square [x]
(list * x x))
直接将其作为arg传递将无效,如您所知:
user=> (map square [1 2 3 4 5])
java.lang.Exception: Can't take value of a macro: #'user/square (NO_SOURCE_FILE:8)
但是将它包装在一个函数中可以解决问题:
user=> (map #(square %) [1 2 3 4 5])
(1 4 9 16 25)
或者(并且更加邪恶),你可以制作另一个宏来进行更通用的包装:
(defmacro make-fn [m]
`(fn [& args#]
(eval `(~'~m ~@args#))))
user=> (map (make-fn square) [1 2 3 4 5])
(1 4 9 16 25)
我坚持使用正常的功能包装,并跳过最后一次黑客攻击! :)
答案 1 :(得分:5)
你不应该使用一个危险的,已弃用的宏。 :-P
http://clojure.github.com/clojure-contrib/apply-macro-api.html
答案 2 :(得分:4)
对于疯狂的宏 make-fn ,下面那个怎么样? 它也应该有效,希望更容易理解。
(defmacro make-fn [m]
`(fn [& args#]
(eval
(cons '~m args#))))