Isn't this the idea behind generalizing `async` to `Generator`? You can set the `R` type parameter to whatever type you want to resume the computation with.
Correct! I played around with this in the past. It helps less than you'd think. As soon as you have a generic resume parameter, you can no longer drive the generator with a generic runtime.
If I am now writing my own runtime / eventloop to advance my state machine anyway, what exactly am I getting from doing that through an abstraction like the Generator trait?
On top of that, the resume and yield abstraction can get convoluted because a lot of times, you only want to do one or the other, meaning either case needs to support a no-op because a single `yield` always does both.
Lastly, with all input going through a single type, your state machine then needs to handle every possible input at every yield point. That is a lot of `match` statements and branching.
I am sure there are better ways to do this and having generators to express custom iterators would be amazing. But for generic state machines, I don't see much of a benefit.
It would be interesting to have polytyped coroutines, where each poll(r:R1) returns a sum type over some subset of poll()able objects that each take their own R2, R3, etc
At some point maybe the ergonomics get so bad that you are just better off writing the state machine manually.
The ergonomics of this could be made reasonably friendly if your completeness checker can narrow down the set of admissible matches a la "GADTs meet their match". A single R sum type, but the compiler only makes you handle the cases that can occur at each poll() site
I think at the end of this long road lies algebraic effects. You can write your computations with typed effects and, once you've handled every effect (or all but a finite subset, if you want to leave some to the runtime), you can drive your computation generically. Because the effects are typed, you get to narrow the types of the effect arguments at each yield, so you don't have to handle every possible effect at every yield (on either side of the channel).