将Clojure宏视为一种功能

时间:2011-04-03 19:43:02

标签: macros clojure

如何让Clojure宏充当函数,所以我可以将它作为参数传递给你?我希望不得不以某种方式包装它。

我不希望包装版本的行为与原始宏完全相同(按名称调用与按值调用的差异),但在一些不重要的情况下它会很有用。

3 个答案:

答案 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#))))