Reputation: 2220
In looking through the clojure.core file after the defmacro
definition you come to the following code:
(. (var defmacro) (setMacro))
What does this mean and do?
Upvotes: 4
Views: 468
Reputation: 84361
The meaning of .
is as explained by Joost's and Jeremy's answers. In case you're wondering about the details of what is accomplished by this particular method call:
This basically inserts a key called :macro
with the value true
into the metadata map of the Var whose name is clojure.core/defmacro
. The effect of this is that from this point on, if the compiler encounters the symbol defmacro
in a context where it resolves to the var #'clojure.core/defmacro
(#'foo
is shorthand for (var foo)
) -- which will normally be everywhere, though you could e.g. shadow this Var with a let
-bound local variable -- it will know that it should treat it as appropriate in the case of a name of a macro.
(Which is to say, either (1) expand the macro call using the function bound to #'clojure.core/defmacro
if the symbol defmacro
occurs in the operator position, i.e. immediately to the right of an opening paren, or else throw an exception to complain about a macro name being mentioned in non-operator position.)
Incidentally, the Clojure compiler routinely makes this sort of use of metadata maps on Vars, e.g. to decide on the types of various objects (cf. :tag
metadata) or whether to inline a function call (IIRC, :inline
and :inline-arities
).
Upvotes: 6
Reputation: 22435
I'll break down the entire line, as I don't know what you already know.
First, the documentation for var
says:
The symbol must resolve to a var, and the Var object itself (not its value) is returned.
If we type this into a REPL we get:
user=> (var defmarco)
#'clojure.core/defmacro
Now, the .
special form allows you to call methods on instances of Java objects. In this case, the setMacro
method on the returned Var
object is being called.
I am not familiar enough with the code to really understand what setMacro
is doing, but I gather it is altering the state of the var to say that it is a macro, and not a function or something else.
Upvotes: 2
Reputation: 17771
(. foo (bar)) is the low-level equivalent of (.bar foo), so this calls the method setMacro on the defmacro var with no arguments.
I suspect this call marks the defmacro function/var as being a macro. In general, lots of stuff in clojure.core uses low-level tricks to bootstrap the language so while it's interesting to see how stuff is build up, it's not really a good source for idiomatic code.
Upvotes: 1