On 27 November 2017 at 13:20, David Mertz <mertz@gnosis.cx> wrote:
Imagining that 'yield' vanished from the language tomorrow, and I wanted to write the same thing with async/await, I think the best I can come up with is... actually, I just don't know who to do it without any `yield`.  

I recently had to look into these things with quite some detail. When using `yield` for *iteration* specifically, you cannot use async/await to replace it. I find it easiest to think about all this in the context of the ABC table: 

https://docs.python.org/3/library/collections.abc.html#collections-abstract-base-classes

The `Generator` ABC also implement the `Iterator` protocol so this allows "normal" iteration to work, i.e. for-loop, while-loop, and comprehensions and so on. In contrast, the `Coroutine` ABC implements only send(), throw() and close().  This means that if you want to iterate a coroutine, *something* must drive send(), and Python's iteration syntax features don't do that.  async/await is only useful when an event loop drives coroutines using the Coroutine ABC protocol methods. Note that AsyncIterable and AsyncIterator doesn't help because objects implementing these protocols may only legally appear inside a coroutine, i.e. an `async def` coroutine function, which you still cannot drive via the Iterator protocol (e.g., from a for-loop).

The Coroutine ABC simply doesn't implement the Iterator protocol, so it seems it cannot be a replacement for generators. It is however true that `async/await` completely replaces `yield from` for *coroutines*, but both of those required a loop of some kind.

I'd be very grateful if anyone can point out if my understanding of the above is incorrect.  Private email is fine if you prefer not to post to the list.

rgds
Caleb