Reputation: 14197
So, let's say I have this abstract class in Java named MyFunction, that has an abstract evaluate method.
To use this in clojure, I can do:
(def java-function
(proxy [MyJavaFunction] []
(evaluate [x]
(* x 2))))
And then call it with:
(.evaluate java-function 3)
returning
; => 6
What would be a nice way of turning the above into something more clojure:
(java-function 3)
that would also be returning
; => 6
Upvotes: 2
Views: 159
Reputation: 84341
You can accomplish that by implementing the clojure.lang.IFn
interface:
((proxy [clojure.lang.IFn] []
(invoke [x]
(str "A very a nice x indeed: " x)))
3)
;= "A very a nice x indeed: 3"
To have your proxy subclass MyFunction
and implement IFn
, mention them both in the first argument to proxy; NB. the class goes first:
(proxy [MyFunction clojure.lang.IFn] []
...)
Actually the above implementation is incomplete – you'll also want to implement the applyTo
method that takes a single seq argument apart from this
and is used by apply
. There are also separate invoke
methods for other fixed arities (up to 20). Follow this link to data.avl's sources (release 0.0.12) to see an applyTo
implementation delegating to the appropriate invoke
method while taking care to avoid going into an infinite loop / taking an inordinate amount of time if the seq that was passed in happens to be infinite / very long.
Upvotes: 5