I'm trying to generate some Clojure code with type hints, however the type hints seem to disappear whenever I build some code (they also don't function when the code is compiled)
e.g.
`(let [^BufferedImage b (create-buffered-image)]
(.getRGB b 0 0))
=> (clojure.core/let [user/b (user/create-buffered-image)] (.getRGB user/b 0 0))
I'm not precisely sure why the type hint is disappearing, but I assume it is something to do with how metatdata is handled by the reader.
What's the right way to create correct type hints in generated code?
There are two answers to this question. To answer your specific question: in the actual code you just posted, nothing is wrong: it's working just fine. (set! *print-meta* true)
and try again, and you'll see the metadata annotation. It just doesn't normally print.
But, in general this is not the right way to do things from a macro, and you will have trouble before long. Remember, you don't want metadata on the forms the macro evaluates, you want metadata on the forms the macro emits. So, a more accurate solution is to use with-meta
on the symbols or forms that you want to attach metadata to - or, if they're user-supplied forms, you should usually use vary-meta
so that you don't discard the metadata they added explicitly. For example,
(defmacro with-image [name & body]
(let [tagged-name (vary-meta name assoc :tag `BufferedImage)
`(let [~tagged-name (create-buffered-image)
~@body)))
(with-image i (.getRGB i 0 0))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With