ScheduledExecutorService.html#schedule has overloads that take a Runnable or a Callable<V>. Java seems to be able to disambiguate these without issue. I suppose it checks if your lambda has a return value (non-void) and then uses Callable, otherwise Runnable. With Scala I have to wrap my lambda in brackets and add : Runnable. Is there something more convenient I could do?
Supply an extension, perhaps?
extension (execService: ScheduledExecutorService)
def scheduleUnit(
command: Runnable,
delay: Long,
unit: TimeUnit
): ScheduledFuture[?] =
execService.schedule(command, delay, unit)
val execService: ScheduledExecutorService = ???
execService.scheduleUnit(() => (), 42L, TimeUnit.SECONDS)
IDK, but JLS 15.12.2.1 makes the distinction between what is “potentially applicable”.
- If the function type of T has a void return, then the lambda body is either a
statement expression (§14.8) or a void-compatible block (§15.27.2). - If the function type of T has a (non-void) return type, then the lambda body is
either an expression or a value-compatible block (§15.27.2).
That section §15.27.2 defines:
- A block lambda body is void-compatible if every return statement in the block has
the formreturn;. - A block lambda body is value-compatible if it cannot complete normally (§14.22)
and every return statement in the block has the formreturn Expression;.
The section §14.22 is a bunch of rote rules which I do not care to indulge. It says normal completion means reachable.