定义Clojure宏的同义词

时间:2009-08-23 00:15:34

标签: clojure macros

所以继续Clojure macro to create a synonym for a function之后,我发现def不能用于定义宏的同义词。下面是我尝试过Clojure不允许的例子。

;(def def-function defn)
;(def case cond)
;(def function fn)

是否可以在Clojure中为宏定义同义词/别名?它需要使用defmacro吗?

3 个答案:

答案 0 :(得分:29)

可能会发出声音(线路)嘈杂但

(def #^{:macro true} case #'cond)

作品!

答案 1 :(得分:8)

您可以使用宏:

user=> (defmacro def-function [& args] `(defn ~@args))
#'user/def-function
user=> (def-function g [] 2)
#'user/g
user=> (g)
2

或者您可以使用clojure.contrib.def/defalias

user=> (use 'clojure.contrib.def)
nil
user=> (defalias def-function defn)
#'user/def-function
user=> (def-function g [] 2)
#'user/g
user=> (g)
2

答案 2 :(得分:3)

要做到这一点,从本质上讲,你必须完全重写宏,而不是替换另一个名称(你当然会使用defmacro来完成)。这是唯一可行的方法,因为宏不返回值,而只是写出随后要评估的代码。

Def要求将名称绑定到值而不是代码块。

  

(def符号init?)

     

使用符号名称和当前命名空间值( ns )的命名空间创建并实习或定位全局var。如果提供了init,则对其进行求值,并将var的根绑定设置为结果值。如果未提供init,则var的根绑定不受影响。 def 始终适用于根绑定,即使var在调用def的位置是线程绑定的。 def 产生var本身(不是它的值)。如果符号已在命名空间中并且未映射到实例变量

,则引发异常

来自Clojure: Special Forms

宏不评估其形式:

  

宏是操纵表单的函数,允许语法抽象。如果调用的运算符是一个将全局变量命名为宏函数的符号,则调用该宏函数,并将传递给未评估的操作数形式 [italics mine]。然后在其位置评估宏的返回值。

来自Clojure: Evaluation

总而言之,宏的观点是延迟评估,因此无法为def提供绑定到符号的值。