I think that’s an important question, but one not connected to async/sync or Loom.
If Scala decided to track exceptions via CanThrow
(which I would say is not decided, it is opt-in and experimental, and as of yet, lacks broad buy-in), then you would use the following Future
successor:
class Future[+E, +A](...) {
def virtualThread: VirtualThread = vt
def result: A throws E = ...
// etc.
}
object Future {
def apply[E, A](code: => A throws E): Future[E, A] = ...
}
The only explicit support Scala would need, if any (presumably you can “cheat” with casting), is a way to transfer a capability between (virtual) threads, which is needed anyway for all capabilities.
This allows you to have a “handle” on a running computation that you can use for purposes of:
- generating useful stack traces
- checking the progress of the computation
- interrupting the computation because the result is no longer needed
while still having a way to access the typed success value or exception from the completed computation.
Such a data type would have lots of other methods on it, too (e.g. Future#poll
), but would omit nearly all of the callback-based machinery of existing Future
, including all the monadic machinery (map
, flatMap
, etc.).
(And while we’re at it, Future
is not a great name, it’s more like RunningTask[E, A]
).