clojure-dev

borkdude 2023-09-04T14:58:42.968659Z

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.

borkdude 2023-09-04T15:02:19.196059Z

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

2023-09-04T15:14:00.879709Z

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

borkdude 2023-09-04T15:15:43.465419Z

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

2023-09-04T15:16:18.565129Z

Yeah

2023-09-04T15:17:11.319739Z

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

2023-09-04T15:19:12.061179Z

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

borkdude 2023-09-04T15:20:01.965289Z

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