2

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

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.