Search code examples
clojureclojure-java-interop

Can I partial a Java method invocation in Clojure?


I have a method on an object.

myObject.myMethod(1)

I can invoke this in Clojure

(.myMethod myObject 1)

I can also invoke it using information from the lexical environment

(let [x 1] (.myMethod myObject x))

Can I do this with a partial? E.g.

(let [myPartial (partial .myMethod myObject)]
      (myPartial 1))

This gives me a

java.lang.RuntimeException: Unable to resolve symbol: .myMethod in this context

I'm currently making this work with an anonymous function

(let [myThing #(.myMethod myObject %)]
      (myThing 1))

But if it would be nice to use a partial in this case. Is it possible?

I'm sure the answer will be to do with binding and dispatch but I don't yet have a feeling for where during the compiling and execution the dispatch happens.


Solution

  • You can have partial in your case, use (memfn).

    (memfn myMethod args)
    

    In the REPL:

    user=> (doc memfn)
    -------------------------
    clojure.core/memfn
    ([name & args])
    Macro
    Expands into code that creates a fn that expects to be passed an
    object and any args and calls the named instance method on the
    object passing the args. Use when you want to treat a Java method as
    a first-class fn. name may be type-hinted with the method receiver's
    type in order to avoid reflective calls.