Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I tag a Clojure function so that I could recognize it with Java reflection

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.

like image 836
pron Avatar asked Apr 10 '13 11:04

pron


1 Answers

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 :)

like image 131
Ankur Avatar answered Nov 15 '22 08:11

Ankur