I need to somehow tag certain Clojure functions as "special" so that Java code could recognize them as such using reflection. I've tried to add an annotation to a function, but apparently that's not supported. I've tried to reify
an interface extending IFn
(so that the Java code could recognize the function object), but that's no good because Clojure doesn't directly use the reified method as the code implementing invoke
, but rather an indirect call to an Afunction
object that's actually implementing the method (I need to tag the actual invoke
method with the actual function code).
Any ideas?
EDIT: even tagging in a way that could be accessed with the ASM library (rather than regular reflection) would be fine, but I need to somehow tag the actual AFunction
object or the invoke
method. Also, I can't access the actual AFunction
object -- I need the tag to be visible on the class.
You can use clojure meta-data feature which allows meta data (a map) to be attached to any object that implements IMeta
interface (which turns out to be every object as IObj extends IMeta and every object extend IObj)
Now there are 2 options.
1) You can attach the meta data to a var (the var points to the actual IFn object)
(defn hello {:name "hello"} [] 10)
and on Java side you get hold of the var hello and use IMeta methods to get the meta data and detect if your specific meta data is there or not. The problem with this may be that your Java code access/handle IFn objects directly rather than their vars (ex: Anonymous functions), to solve this try the 2nd option.
2) Attach the meta data to the function object itself:
(def hello (with-meta (fn [] 10) {:name "hello"}))
You cannot use defn
as that attach meta data to the var. The above sample code attach the meta data to the function object itself. On Java side, typecase the function object to IMeta and do the check.
The above code can be made a bit more defn
likish with a help of a macro which is left as an exercise :)
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