Python 3.5 greatly expanded support for asynchronous programming with a new function definition syntax. Whereas async functions were previously just "generators with benefits":
def generate_numbers():
    """
    Generator function that lazily returns 1 - 100
    """
    for i in range 100:
        yield i
generate_async = asyncio.coroutine(generate_numbers)
generate_async.__doc__ = """
    Coroutine that lazily returns 1 - 100
    This can be used interchangeably as a generator or a coroutine
    """
they now have their own special declaration syntax and special behavior by which they are no longer usable as usual generator functions:
aysnc def generate_async_native():
    """
    A coroutine that returns 1 - 100
    This CANNOT be used as a generator, and can ONLY be executed by running it from an event loop
    """
    for i in range(100):
        await i
This is not a question about the functional or practical differences between these types -- that is discussed in this StackOverflow answer.
My question is: why would I ever want to use async def? It seems like it provides no additional benefit over @asyncio.coroutine, but imposes an additional cost in that it
- breaks backward-compatibility (Python 3.5 code with async defwon't even parse in older versions, although this is arguably a feature and not a bug) and
- seems to provide less flexibility in how the function can be called.
 
    