将 Clojure 宏视为函数 [英] Treat Clojure macro as a function
问题描述
如何使 Clojure 宏充当函数,以便我可以将其作为参数传递?我希望必须以某种方式包装它.
How can I cause a Clojure macro to act as a function, so I can pass it as an argument for example? I would expect to have to wrap it somehow.
我不希望包装版本的行为与原始宏完全相同(按名称调用与按值调用的差异),但在这并不重要的少数情况下它会很有用.
I would not expect the wrapped version to behave exactly the same as the original macro (differences of call by name vs call by value), but it would be useful in a few cases where this wasn't important.
推荐答案
如果我没理解错的话,你可以把它包装在一个函数中.
If I'm understanding you correctly, you can just wrap it in a function.
将平方函数的这个(愚蠢的)实现视为宏:
Consider this (silly) implementation of a squaring function as a macro:
(defmacro square [x]
(list * x x))
如您所知,直接将其作为 arg 传递是行不通的:
Passing it directly as an arg won't work, as you know:
user=> (map square [1 2 3 4 5])
java.lang.Exception: Can't take value of a macro: #'user/square (NO_SOURCE_FILE:8)
但是将它包装在一个函数中可以解决问题:
But wrapping it in a function will do the trick:
user=> (map #(square %) [1 2 3 4 5])
(1 4 9 16 25)
或者(更邪恶一点),您可以制作另一个宏来进行更通用的包装:
Alternatively (and quite a bit more evil-ly), you could make another macro to do a more generic wrapping:
(defmacro make-fn [m]
`(fn [& args#]
(eval `(~'~m ~@args#))))
user=> (map (make-fn square) [1 2 3 4 5])
(1 4 9 16 25)
我会坚持使用正常的函数包装,并跳过最后一个 hack!:)
I'd stick with the normal function wrapping, and skip this last hack! :)
这篇关于将 Clojure 宏视为函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!