On Wed, Apr 22, 2015 at 10:44 PM, PJ Eby <p...@telecommunity.com> wrote: > On Tue, Apr 21, 2015 at 1:26 PM, Yury Selivanov <yselivanov...@gmail.com> > wrote: >> It is an error to pass a regular context manager without ``__aenter__`` >> and ``__aexit__`` methods to ``async with``. It is a ``SyntaxError`` >> to use ``async with`` outside of a coroutine. > > I find this a little weird. Why not just have `with` and `for` inside > a coroutine dynamically check the iterator or context manager, and > either behave sync or async accordingly? Why must there be a > *syntactic* difference?
IIRC Guido always like to have different syntax for calling regular functions and coroutines. That's why we need explicit syntax for asynchronous context managers and iterators. > > Not only would this simplify the syntax, it would also allow dropping > the need for `async` to be a true keyword, since functions could be > defined via "def async foo():" rather than "async def foo():" > > ...which, incidentally, highlights one of the things that's been > bothering me about all this "async foo" stuff: "async def" looks like > it *defines the function* asynchronously (as with "async with" and > "async for"), rather than defining an asynchronous function. ISTM it > should be "def async bar():" or even "def bar() async:". > > Also, even that seems suspect to me: if `await` looks for an __await__ > method and simply returns the same object (synchronously) if the > object doesn't have an await method, then your code sample that > supposedly will fail if a function ceases to be a coroutine *will not > actually fail*. > > In my experience working with coroutine systems, making a system > polymorphic (do something appropriate with what's given) and > idempotent (don't do anything if what's wanted is already done) makes > it more robust. In particular, it eliminates the issue of mixing > coroutines and non-coroutines. > > To sum up: I can see the use case for a new `await` distinguished from > `yield`, but I don't see the need to create new syntax for everything; > ISTM that adding the new asynchronous protocols and using them on > demand is sufficient. Marking a function asynchronous so it can use > asynchronous iteration and context management seems reasonably useful, > but I don't think it's terribly important for the type of function > result. Indeed, ISTM that the built-in `object` class could just > implement `__await__` as a no-op returning self, and then *all* > results are trivially asynchronous results and can be awaited > idempotently, so that awaiting something that has already been waited > for is a no-op. (Prior art: the Javascript Promise.resolve() method, > which takes either a promise or a plain value and returns a promise, > so that you can write code which is always-async in the presence of > values that may already be known.) > > Finally, if the async for and with operations have to be distinguished > by syntax at the point of use (vs. just always being used in > coroutines), then ISTM that they should be `with async foo:` and `for > async x in bar:`, since the asynchronousness is just an aspect of how > the main keyword is executed. > > tl;dr: I like the overall ideas but hate the syntax and type > segregation involved: declaring a function async at the top is OK to > enable async with/for semantics and await expressions, but the rest > seems unnecessary and bad for writing robust code. (e.g. note that > requiring different syntax means a function must either duplicate code > or restrict its input types more, and type changes in remote parts of > the program will propagate syntax changes throughout.) > _______________________________________________ > Python-Dev mailing list > Python-Dev@python.org > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > https://mail.python.org/mailman/options/python-dev/andrew.svetlov%40gmail.com -- Thanks, Andrew Svetlov _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com