Sometimes, one wants to write a Clojure macro to assist in Java interoperability, where the object types are determined by the arguments to the macro. In this situation, the normal strategy of using a #^class type hint doesn’t work, since the class isn’t known at read time. Here’s a very contrived example, where the macro declare-first-char defines a function first-char, which calls the (.charAt % 0) method on its argument. The class for the type hint is passed as an argument to the macro.
user> (set! *warn-on-reflection* true)
true
user> (defmacro declare-first-char [cls]
(let [x (gensym)]
`(defn first-char [~(with-meta x {:tag cls})]
(.charAt ~x 0))))
#'user/declare-first-char
user> (declare-first-char String)
#'user/first-char ; No reflection warning!
user> (first-char "test")
\t |
The key here is the [~(with-meta x {:tag cls})] fragment, which replaces the normal [#^String x#] version that could be used if the type was known in advance.
Konrad Grzanek
Great advice. That’s exactly what I was searching for. Thanks !!!