所以继续Clojure macro to create a synonym for a function之后,我发现def不能用于定义宏的同义词。下面是我尝试过Clojure不允许的例子。
;(def def-function defn)
;(def case cond)
;(def function fn)
是否可以在Clojure中为宏定义同义词/别名?它需要使用defmacro吗?
答案 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本身(不是它的值)。如果符号已在命名空间中并且未映射到实例变量
,则引发异常
宏不评估其形式:
宏是操纵表单的函数,允许语法抽象。如果调用的运算符是一个将全局变量命名为宏函数的符号,则调用该宏函数,并将传递给未评估的操作数形式 [italics mine]。然后在其位置评估宏的返回值。
总而言之,宏的观点是延迟评估,因此无法为def
提供绑定到符号的值。