getkyo / kyo

Toolkit for Scala Development
https://getkyo.io
Apache License 2.0
481 stars 38 forks source link

prelude: Coroutine effect #505

Open fwbrasil opened 5 days ago

fwbrasil commented 5 days ago

I've been trying to find an effect that can leverage the fact that the new kernel makes effect handling aware of the return type of the computation. My first try was a Shift effect that encodes delimited continuations (shift/reset) since it requires the type of the computation being handled to be the same as the shift being handled. Although the effect is remarkably safer and cleaner with the new core design, I think it's too low-level to introduce in the codebase.

This PR introduces a purely functional Coroutine implementation. It provides cooperative multitasking within a single thread, allowing for deterministic and more controlled concurrency. The effect uses suspensions to provide two operations:

  1. Coroutine.pause: Yields the execution, moving the current computation to the end of the queue.
  2. Coroutine.spawn: Submits a sub-task to the queue and immediately resumes execution.

The return type of the effect handling is used to maintain the final result of the computation via a Maybe, even when other sub-tasks are still being processed. An important limitation of this initial version is that spawn returns Unit, so it's not possible to directly use the result of a spawned computation. But, as the tests demonstrate, it's possible to use other effects to propagate values in and out of spawned computations. The use of Queue is also not optimized yet.

This new effect is not meant as a replacement for Fiber but it can be useful to provide computation scheduling behavior without IO. Something I worry about is users getting confused with Kyo providing both Coroutine and Fiber, maybe we could use a more opaque name for this new effect like Coop to avoid that?