Clojure

def discards ^:macro when used outside the top-level

Details

Description

If I evaluate

(def ^:macro my-defn1 #'defn)

a macro named 'my-defn1' is defined, which I can use just like 'defn'.

However, if I evaluate instead

(if true
  (def ^:macro my-defn2 #'defn))

the var for 'my-defn2' doesn't have the :macro metadata set and I can't use it as a macro, even though the 'def' form is equal to the previous case.

Here is a complete example:

(def ^:macro my-defn1 #'defn)

(if true
  (def ^:macro my-defn2 #'defn))

(println (meta #'my-defn1))    ; => contains :macro

(println (meta #'my-defn2))    ; => doesn't contain :macro!

(my-defn1 hello1 []
          (println "hello 1"))

(hello1)                       ; => prints "hello 1"

(my-defn2 hello2 []            ; => CompilerException: Unable to resolve 
  (println "hello 2"))         ;    symbol: hello2 in this context

Activity

Hide
Nicola Mometto added a comment -
Show
Nicola Mometto added a comment - Duplicate of http://dev.clojure.org/jira/browse/CLJ-1021
Hide
Gary Fredericks added a comment -

I hopped around the code for a while and all I could find is that the bindRoot method in Var.java intentionally clears :macro from the metadata.

Show
Gary Fredericks added a comment - I hopped around the code for a while and all I could find is that the bindRoot method in Var.java intentionally clears :macro from the metadata.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: