Rustem
Rustem

Reputation: 2932

deftype in defmacro with metadata

Let's suppose I have deftype looking next way:

(deftype ^{A: a} Name [])

I want define macro generating deftype:

(defmacro dotype [name]
  `(deftype ^{A :a} ~name []))

However, I'm losing information about metadata.

(macroexpand-1 '(dotype T))
;> (clojure.core/deftype T [])

I tried to use tricks with vary-meta to avoid using ^{} in macro. Unfortunately, deftype doesn't support IObj interface (doesn't support metadata), and all my tries didn't work.

Please suggest the way to implement this macro. thanks!

Upvotes: 1

Views: 126

Answers (1)

Scott
Scott

Reputation: 17257

This works for me:

(deftype A [])

(defmacro dotype [name]
  `(deftype ~(with-meta name {:tag A}) []))

(binding [*print-meta* true]
  (prn (macroexpand-1 '(dotype T))))

; user=> (clojure.core/deftype ^user.A T [])

Note: the metadata doesn't print by default, so you have to enable that by binding *print-meta* as shown above, or else set it in the REPL with (set! *print-meta* true), but setting that permanently in the REPL will print a massive amount of uninteresting info to the screen, so best to avoid (!).

Upvotes: 2

Related Questions