On Oct 8, 2016, at 5:00 PM, Nathaniel Smith <njs@pobox.com> wrote:

with -> applies a context manager to a with block
async with -> applies an async context manager to an async with block

for -> does a loop over an iterator
async for -> does an async loop over an async iterator

def + yield -> makes a generator
async def + yield -> makes an async generator

[... for ...] -> is a comprehension
[... async for ...] -> is an async comprehension

def -> creates a function
async def -> creates a coroutine

When I teach asyncio, I make the distinction between:
async def coro(): -> is a coroutine function
coro() -> creates a coroutine

This is something asyncio's documentation does itself, see: https://docs.python.org/3/library/asyncio-dev.html#detect-coroutine-objects-never-scheduled

I find that the parallel between "classes" and "objects" explains it well to people. Classes create objects. Coroutine functions create coroutines. With this nitpicking in mind, using "async functions" to describe "coroutine functions" makes perfect sense to me, especially if we keep calling the instantiated object a "coroutine".

Lukasz Langa | Facebook
Production Engineer | The Ministry of Silly Walks 
(+1) 650-681-7811