Fork me on GitHub
#clojure-dev
<
2023-09-04
>
borkdude14:09:42

Someone ran into an issue in babashka when calling Thread/sleep on a java.lang.Integer. bb uses reflection to find the right method (largely based on clojure.lang.Reflector) and it doesn't manage to find the method. A similar case can be constructed in Clojure itself:

user=> (def x (int 1))
#'user/x
user=> (type x)
java.lang.Integer
user=> (Thread/sleep x)
Execution error (IllegalArgumentException) at user/eval5 (REPL:1).
No matching method sleep found taking 1 args
I wonder if clojure.lang.Reflector itself could/should be updated to account for this, or maybe not? Any thoughts welcome.

borkdude15:09:19

This is on Java version 19 btw. Not sure if this issue happened before but from 19+ on Thread/sleep has multiple overloads

hiredman15:09:00

I think this might vaguely follow the java behavior (not sure though), that you can't pass an Integer(boxed object) to a method that takes a long(primitive), but you can pass an int to a method that takes a long

borkdude15:09:43

like this?

user=> (def x (int 1))
#'user/x
user=> (Thread/sleep ^int x)
nil
user=> (Thread/sleep ^java.lang.Integer x)
Execution error (IllegalArgumentException) at user/eval3 (REPL:1).
No matching method sleep found taking 1 args

hiredman15:09:11

But clojure does the conversion, or part of it for you in some cases, like whatever codepath it used before the sleep overload was added

hiredman15:09:12

We definitely had to wrap (long ...) around the arg in a lot of sleep calls when we started testing on 19+ javas

borkdude15:09:01

This is why I advocated for dedicated sleep function somewhere in the stdlib