Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure defmacro loses metadata

Tags:

I am trying to create a little Clojure macro that defs a String with a type hint:

(defmacro def-string [name value]   `(def ^String ~name ~value))  (def-string db-host-option "db-host") 

When I macroexpand it, the type hint is lost:

(macroexpand '(def-string db-host-option "db-host")) ;=> (def db-host-option "db-host") 

Never mind the wisdom of type hinting this.

Why is the macro losing the metadata? How do I write this macro, or any that includes metadata?

like image 745
Ralph Avatar asked Oct 13 '11 12:10

Ralph


1 Answers

^ is a reader macro. defmacro never gets to see it. The hint is put on the list (unquote name). Compare for example (meta ^String 'x) with (meta ' ^String x) to see the effect.

You need to put the hint on the symbol.

(defmacro def-string   [name value]   `(def ~(vary-meta name assoc :tag `String) ~value)) 

And the usage:

user=> (def-string foo "bar") #'user/foo user=> (meta #'foo) {:ns #<Namespace user>, :name foo, :file "NO_SOURCE_PATH", :line 5, :tag java.lang.String} 
like image 130
kotarak Avatar answered Sep 19 '22 11:09

kotarak