I have a question about java interop with overloaded methods. I want to call LinkedList.remove(int)
from clojure and I can’t seem to do it. I can only call LinkedList.remove(Object)
. I’ve read the Clojure docs on java interop and a few stackoverflow pages and haven’t found the solution yet.
$ clojure
Clojure 1.10.1
user=> (import (java.util LinkedList))
java.util.LinkedList
user=> (def ll (LinkedList.))
#'user/ll
user=> (.push ll "a")
nil
user=> (.push ll "b")
nil
user=> (.remove ll 0)
false
user=> (.remove ll (int 0))
false
user=> (.remove ll "b")
true
user=>
I haven't discovered a way to do it in a few other minor variations using let
,either. ^int
type hints give errors for several variations of expressions there.
yeah, I tried defining a function in order to type hint the function args, that didn't help either - I was surprised
I guess it's possible with some reflection hacking, but that seems a bit much
it should be possible with compile-time only reflection though(?)
I ran your code with
(set! *warn-on-reflection* true)
which said
call to method remove can't be resolved (target class is unknown)
this is solved with hinting the target class which is
ll
Thanks, that’s exactly what I was looking for!
for the LinkedList
interop before it is probably better to type hint ll
on the def?
If you do that you wouldn't need the cast to int
ie. (remove ll 0)
works.
Additionally, if you don't do it then you get the same warning on (.push ll "a")
ie. the Clojure compiler will fail to find the method (at compile time), because it doesn't know the type of ll
.
Reference: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L1538