[Python-ideas] async/await in Python

Steven D'Aprano steve at pearwood.info
Sat Apr 18 19:11:45 CEST 2015


Nicely written and very complete! I only have a couple of little 
niggles, which some might consider bike-shedding. See below.


On Fri, Apr 17, 2015 at 02:58:58PM -0400, Yury Selivanov wrote:

[...]
> From this point in this document we use the word *coroutine* to refer to
> functions declared using the new syntax.  *generator-based coroutine* is 
> used where necessary to refer to coroutines that are based on 
> generator syntax.

It concerns me that we will have two kinds of coroutines.

At the moment, we have two kinds of generator functions: those that are 
used as generators, and those that are used as coroutines, depending on 
whether they contain "yield expr" or "x = (yield expr)". That 
distinction won't go away, but now we will have even more ambiguity of 
language: there will be generators which are functions:

    def gen(): yield 1

generators which are not functions but the result of calling a generator 
function:

    g = gen()

coroutines which are generators:

    def gen():
        x = (yield 1)
        y = (yield x+1)

    cr = gen()

and coroutines which are not generators:

    async def g():
        await spam()

Except that they will be implemented internally as generators. There 
will be generators that use yield and generators which give a syntax 
error with yield. My head hurts :-)

I think it will be hard to unambiguously talk about these things without 
confusion, especially for people with limited asyncronous experience.

I don't have an answer to this, but I know that even the generator 
versus generator-function ambiguity (both get called "generator") 
sometimes leads to confusion. (E.g. below you talk about passing a 
generator to types.async_def but it isn't clear to me whether you mean 
the generator or the generator function.) There's been at least one 
thread on python-list in the last few months about that. Is it possible 
to use another name to distinguish generator-based coroutines from 
async-based coroutines?

It's a pity we can't steal the name "goroutine" from Go. I've always 
liked that name :-) but as I understand it, goroutines completely 
unrelated to coroutines. Hmmm... maybe we could use pyroutines? *wink*

If the name must stay as-is, it would help to have an unambigous and 
clear summary of the various generator-or-coroutine uses and how they 
differ.


> types.async_def()
> -----------------
> 
> A new function ``async_def(gen)`` is added to the ``types`` module. It
> applies ``CO_ASYNC`` flag to the passed generator's code object, so that it
> returns a *coroutine object* when called.
> 
> This feature enables an easy upgrade path for existing libraries.

When you say "the passed generator", do you mean the generator function or the generator object? 
E.g. given:

def gen():
    yield 1

which do I use? async_def(gen()) or async_def(gen)? 


-- 
Steve


More information about the Python-ideas mailing list