clojure.core :. operator,defmacro和setMacro

时间:2011-07-13 15:57:30

标签: clojure function

在查看defmacro定义后的clojure.core文件时,您会看到以下代码:

(. (var defmacro) (setMacro))

这意味着什么?

3 个答案:

答案 0 :(得分:6)

.的意思正如Joost和Jeremy的答案所解释的那样。如果您想知道这个特定方法调用所完成的细节:

这基本上将名为:macro的键值true插入到名称为clojure.core/defmacro的Var的元数据映射中。这样做的结果是,从这一点开始,如果编译器在解析为var defmacro的上下文中遇到符号#'clojure.core/defmacro#'foo(var foo)的简写) - 通常在任何地方,尽管你可以,例如使用let绑定的局部变量来影响此Var - 它将知道在宏名称的情况下它应该适当地对待它。

(也就是说,(1)如果符号#'clojure.core/defmacro出现在操作员位置,即紧接在开头的右边,则使用绑定到defmacro的函数扩展宏调用,或者抛出异常来抱怨在非操作员位置提到的宏名称。)

顺便提一下,Clojure编译器通常会在Vars上使用元数据映射,例如:决定各种对象的类型(参见:tag元数据)或是否内联函数调用(IIRC,:inline:inline-arities)。

答案 1 :(得分:2)

我会分解整行,因为我不知道你已经知道的是什么。

首先,documentation for var说:

  

符号必须解析为var,并返回Var对象本身(不是其值)。

如果我们将其输入REPL,我们得到:

user=> (var defmarco)
#'clojure.core/defmacro

现在,.特殊表单允许您call methods on instances of Java objects。在这种情况下,正在调用返回的Var对象上的setMacro method

我对代码的熟悉程度不足以真正理解setMacro正在做什么,但我认为它改变了var的状态,说它是一个宏,而不是一个函数或其他东西。

答案 2 :(得分:1)

(。foo(bar))是(.bar foo)的低级别等价物,所以这会在没有参数的defmacro var上调用方法setMacro。

我怀疑此调用将defmacro函数/ var标记为宏。一般来说,clojure.core中的很多东西使用低级技巧来引导语言,所以虽然有趣的是看到东西是如何构建的,但它并不是真正的惯用代码的好来源。