On a somewhat related note there is another plausible point which is stack traces + exceptions. The nice thing about Future
is its decoupled from stacktraces, that is by design you are not meant to expect the stack to be consistent or (even be there at all). As is evident by anyone that has used Future
along with the standard ExecutionContext
(such as ForkJoinPool
) the stack traces are meaningless because the computation’s can jump between different at whim (thats the whole point of multiplexing computations onto real threads). You can see this even in the Future
api, i.e. you have methods like Future.failed
to designate a failed Future
with a Throwable
but its just passed around and propagated as a value. You can still recover from exceptions thrown in Future
but as stated before its expensive, critically you don’t have to throw
(i.e. you can just use Future.failed
).
This is one area where I am a bit skeptical loom, although I haven’t looked at loom in great detail but if VirtualThread
is meant to preserve stack traces and there is a lot of code out there that assumes stack traces are consistent and properly propagated, unless I am missing something this will have a performance penalty (versus not caring about the stack at all). This performance penalty is already visible right now, either in the case of Future
with custom ExecutionContext
's that preserve stack or other IO types that propagate the stack in the interpreter. I do believe that loom’s solution to this problem is not going to have the same overhead but as said previously I don’t see how it can be “cost free”.
Ultimately though this is one of the best benefits of doing value based error handling rather than throwing and catching exceptions, if you throw and expect to catch exceptions its expensive and Scala’s IO/Async takes forced programmers to not rely on the stack for basic error handling (which is a good thing). If my previous point about loom is correct (i.e. loom is forced to propagate stack in order to remain code compatible with existing code that relies on try/catch + preservation of stack to function). I also haven’t seen any ability for Loom to granularly handle stack propagation so you don’t deal with performance penalty if you don’t rely on exceptions.
For this reason alone (and others), despite what people claim Loom is not going to kill Scala’s Future
even in the hypothetical where everyone runs JVM 19+ (w/e version is released with Loom) and Scala.js/scala-native is ignored.