4

How can I use java methods as a functions arguments in Clojure?

For example, I want to make a functions composition:

user> (Integer. (str \9))
9
user> ((comp Integer. str) \9)
CompilerException java.lang.ClassNotFoundException: Integer., compiling:(NO_SOURCE_PATH:1:2) 

That does not work.

memfn doesn't help also:

user> (map (comp (memfn  Integer.) str) "891")
IllegalArgumentException No matching method found: Integer. for class java.lang.String  clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53)

Any ideas?

Related questions (that, though, do not give the right answer to the question):

(Note: it seems to be that the answer suggested by dave, using of an anonymous function as a wrapper, is the best solution)

1 Answer 1

7

Unlike Clojure functions, Java methods weren't designed to be first class. When you use Java inter-op in Clojure, you're literally working with Java methods, so you don't get the added benefits that were implemented for Clojure functions. For more info, see the comments below.

As a workaround to use Java methods as arguments, you can wrap them in an anonymous function, like this, effectively making them Clojure functions:

((comp #(Integer. %) str) \9)
Sign up to request clarification or add additional context in comments.

6 Comments

Dave, thank you, that is better than nothing, but I hope there are some other ways also (+1)
Why aren't methods Clojure functions? Clojure functions are Java objects that comply with the IFn interface, which has a pile of invoke methods of all arities up to twenty, and a couple of ways of invoking on indefinitely long argument lists. All of these take Java Object arguments and also return a Java Object. You can find IFn at github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/…
They are not first class because as I see it the choices were either having functions that are not truly first class values (making the language weaker), or abstracting over all jvm method so they act like true functions (making the language excessively complex).
I'd be curious as well, to know why exactly you can't use Java methods as functions. I don't know much about Java, but my guess is that Java methods aren't first-class in Java, so Clojure added this functionality to its own functions, but when you use Java inter-op you're literally dealing with Java methods, so you don't get the added benefits that you get with Clojure functions.
Exactly. Clojure keeps its interop layer as small and simple as possible, and methods simply are not meant to be first class.
|

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.