2

Can someone explain the new syntax outlined in PEP 0492: Coroutines with async and await syntax? What will be the main differences between something like

def do_nothing():
    return

and

async def do_nothing():
    return
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
caleb.levy
  • 53
  • 2
  • 5
  • 2
    I think the abstract and rationale of that PEP are quite understandable. What about them do you not understand? Do you understand *coroutines/asynchronous programming* in general, or would we need to start there? – deceze May 27 '15 at 06:39
  • Have you used the Python 3.4 `asyncio` module? It's a _lot_ easier to understand `async`/`await` by looking at existing 3.4 code and the corresponding 3.5 code. (There are some messages on the python-ideas and python-dev threads cited in the PEP that include links to such comparisons; I wish one of them had gotten into the PEP itself, but…) – abarnert May 27 '15 at 06:43
  • Maybe that would help. I haven't ever used asynchronous programming per se, though I have some idea what it is. Maybe just a minimal working example in pure python of what this syntax replaces is what I am hoping for. – caleb.levy May 27 '15 at 06:45
  • The only difference between those two functions (since they have no `yield`, `yield from`, `await`, or non-bare `return` statements) is that the first one is a coroutine. So, when you call it, instead of getting `None`, you get a coroutine object which, when `await`ed, gives you `None`. Which will mean absolutely nothing to you if you don't first understand the basic concepts of coroutines and how they're used in async I/O. You need to read an `asyncio` tutorial first, or wait until someone writes a new tutorial for 3.5. – abarnert May 27 '15 at 06:48
  • If you have at least a little bit background with C# or even JavaScript, you can look at those languages’ `async`/`await` functionality to see some examples in the wild. – poke May 27 '15 at 06:54

1 Answers1

8

In a nutshell, because this is a broad topic:

@asyncio.coroutine
def foo():
    bar = yield from some_async_func()
    print(bar)

asyncio.get_event_loop().run_until_complete(foo())

This defines a coroutine using the asyncio module. foo is a coroutine, and it makes a call to a coroutine some_async_func (because it makes a call to an asynchronous function it itself must be asynchronous too). This whole contraption needs to be run in an event loop, asynchronously.

The call to foo() produces a generator object, which the event loop runs until it doesn't generate anything anymore. yield from suspends the function and yields to the other coroutine, which is basically executed the same way (generator, until done, etc. etc.). When that generator is done the value is returned and assigned to bar and the function is unfrozen.

That's asynchronous programming in a nutshell.

PEP 0492 wants to improve the support for this kind of programming in some specific ways:

  • It is proposed to make coroutines a proper standalone concept in Python [..]
  • It is easy to confuse coroutines with regular generators, since they share the same syntax [..]
  • Whether or not a function is a coroutine is determined by a presence of yield or yield from statements in its body , which can lead to unobvious errors [..]
  • Support for asynchronous calls is limited to expressions where yield is allowed syntactically, limiting the usefulness of syntactic features [..]

These points are saying that coroutines are a rather unique thing, but are not very distinguishable from other things in the language because they mostly hijack the already existing generator syntax. The PEP wants to improve this by making coroutines and asynchronous programming its own standalone thing which is easier to work with.

  • This proposal introduces new syntax and semantics to enhance coroutine support in Python.
  • The following new syntax is used to declare a native coroutine [..]

Just promoting a coroutine to a native type should be an obvious improvement. It allows you to type-detect coroutines like any other type. It also unifies the implementation. Currently there's a "native" asyncio module for coroutines, but there are also 3rd party libraries like Twisted which have their own syntax and decorators for coroutines.

  • This PEP assumes that the asynchronous tasks are scheduled and coordinated by an Event Loop [..] While the PEP is not tied to any specific Event Loop implementation [..]

This is saying you will be able to write coroutines using one defined syntax, yet execute them using any compatible event loop implementation you want.

The rest of the proposals you can read in the PEP itself.

deceze
  • 510,633
  • 85
  • 743
  • 889