Coroutines and Rust

I have a couple of comments.

In design requirements, the last 3 are dubious.

  • Having streams work with for-loops (or some await for variant which I propose im my RFC) would be nice, but shouldn't be a requirement. Using both iterators and streams with regular for looks could be problematic since it need to suspend, but only in the stream case. Since there would be references which can't cross a suspend point, requiring a suspend point for looping over iterator would be quite restrictive.
  • Iterators can already be used with for-loops. You probably meant that generators can be iterators here?
  • I don't think we should restrict ourself to designs with interact well with futures-rs. It was not designed with generators in mind, but rather convenient asynchronous programming given the current feature set of Rust. We will probably end up with a design which works well with it, but having it be a requirement seems wrong.

futures-rs combines return types and errors. This results in additional complexity when considering its traits when discussing generators. It is a good idea to deal with futures and streams which cannot results in errors. We can instead use Result to indicate that a future or stream can result in an error. This is what I did in my RFC.

I don't think the R yield Y sugar is a good idea, since you'd typically want to return iterators, futures or streams instead of plain generator types.

There are 2 reasons to have a Wait or Blocked variant on the result enum. You'd want yield x to work in streams without having to write yield State::Yield(x) there. This can be worked around with a yield! macro, with some loss of ergonomics. The other is to allow await for or for-loops to iterate over streams. The loops needs to yield Wait only when the streams it's waiting on does, so we need that concept in the language. This can again be worked around with a await_for! macros with greater loss of ergonomics.

Note that an await feature would not require the Wait variant as part of the language. In a poll model, await does the same thing as yield from. These are also the same in Python (ignoring some dynamic type checks).

You do mention generators which do not start out paused. These are useful where the generators are consuming input. They also work for futures-rs since it allows computations to start out immediately and well as starting out paused. I think this kind of generators will have to be separate kind of generators in the language, in addition to generators which start out paused. They do not work for iterators, and they aren't as nice for asynchronous programming since you have to pass around references to the event loop (like how you pass around Handle in tokio).

impl Iterator<Item=usize> + Move doesn't actually work since built in traits leak through. We'll probably need some syntax to indicate that a generator is immovable (or movable).