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 !!!