<p dir="ltr"><br>
</p>
<p dir="ltr"></p>
<p dir="ltr">On Sun, Apr 26, 2015, 17:49 Mark Shannon <<a href="mailto:mark@hotpy.org">mark@hotpy.org</a>> wrote:</p>
<blockquote><p dir="ltr"></p>
<p dir="ltr">On 26/04/15 21:40, Yury Selivanov wrote:<br>
> Hi Mark,<br>
><br>
> On 2015-04-26 4:21 PM, Mark Shannon wrote:<br>
>> Hi,<br>
>><br>
>> I was looking at PEP 492 and it seems to me that no new syntax is<br>
>> required.<br>
><br>
> Mark, all your points are explained in the PEP in a great detail:<br>
I did read the PEP. I do think that clarifying the distinction between<br>
coroutines and 'normal' generators is a good idea. Adding stuff to the<br>
standard library to help is fine. I just don't think that any new syntax<br>
is necessary.</p>
<p dir="ltr">><br>
>><br>
>> Looking at the code, it does four things; all of which, or a<br>
>> functional equivalent, could be done with no new syntax.<br>
><br>
> Yes, everything that the PEP proposes can be done without new syntax.<br>
> That's how people use asyncio right now, with only what we have in 3.4.<br>
><br>
> But it's hard.  Iterating through something asynchronously?  Write a<br>
> 'while True' loop.  Instead of 1 line you now have 5 or 6.  Want to<br>
> commit your database transaction?  Instead of 'async with' you will<br>
> write 'try..except..finally' block, with a very high probability to<br>
> introduce a bug, because you don't rollback or commit properly or<br>
> propagate exception.<br>
I don't see why you can't do transactions using a 'with' statement.<br>
><br>
>> 1. Make a normal function into a generator or coroutine. This can be<br>
>> done with a decorator.<br>
><br>
> <a href="https://www.python.org/dev/peps/pep-0492/#rationale-and-goals">https://www.python.org/dev/peps/pep-0492/#rationale-and-goals</a><br>
states that """<br>
it is not possible to natively define a coroutine which has no yield or<br>
yield from statement<br>
"""<br>
which is just not true.</p>
<p dir="ltr">> <a href="https://www.python.org/dev/peps/pep-0492/#debugging-features">https://www.python.org/dev/peps/pep-0492/#debugging-features</a><br>
Requires the addition of the CO_COROUTINE flag, not any new keywords.</p>
<p dir="ltr">> <a href="https://www.python.org/dev/peps/pep-0492/#importance-of-async-keyword">https://www.python.org/dev/peps/pep-0492/#importance-of-async-keyword</a><br>
Seems to be repeating the above.<br>
><br>
>> 2. Support a parallel set of special methods starting with 'a' or<br>
>> 'async'. Why not just use the current set of special methods?<br>
><br>
> Because you can't reuse them.<br>
><br>
> <a href="https://www.python.org/dev/peps/pep-0492/#why-not-reuse-existing-for-and-with-statements">https://www.python.org/dev/peps/pep-0492/#why-not-reuse-existing-for-and-with-statements</a><br>
Which seems back to front. The argument is that existing syntax<br>
constructs cannot be made to work with asynchronous objects. Why not<br>
make the asynchronous objects work with the existing syntax?</p>
<p dir="ltr">><br>
> <a href="https://www.python.org/dev/peps/pep-0492/#why-not-reuse-existing-magic-names">https://www.python.org/dev/peps/pep-0492/#why-not-reuse-existing-magic-names</a><br>
The argument here relies on the validity of the previous points.<br>
><br>
><br>
>> 3. "await". "await" is an operator that takes one argument and<br>
>> produces a single result, without altering flow control and can thus<br>
>> be replaced by an function.<br>
><br>
> It can't be replaced by a function. Only if you use greenlets or<br>
> Stackless Python.<br>
Why not? The implementation of await is here:<br>
<a href="https://github.com/python/cpython/compare/master...1st1:await#diff-23c87bfada1d01335a3019b9321502a0R642">https://github.com/python/cpython/compare/master...1st1:await#diff-23c87bfada1d01335a3019b9321502a0R642</a><br>
which clearly could be made into a function.<br>
><br>
>> 4. Asynchronous with statement. The PEP lists the equivalent as "with<br>
>> (yield from xxx)" which doesn't seem so bad.<br>
><br>
> There is no equivalent to 'async with'. "with (yield from xxx)" only<br>
> allows you to suspend execution<br>
> in __enter__ (and it's not actually in __enter__, but in a coroutine<br>
> that returns a context manager).<br>
><br>
> <a href="https://www.python.org/dev/peps/pep-0492/#asynchronous-context-managers-and-async-with">https://www.python.org/dev/peps/pep-0492/#asynchronous-context-managers-and-async-with</a><br>
> see "New Syntax" section to see what 'async with' is equivalent too.<br>
Which, by comparing with PEP 343, can be translated as:<br>
     with expr as e:<br>
         e = await(e)<br>
         ...<br>
><br>
>><br>
>> Please don't add unnecessary new syntax.<br>
><br>
><br>
> It is necessary.<br>
This isn't an argument, it's just contradiction ;)</p>
<p dir="ltr">  Perhaps you haven't spent a lot of time maintaining<br>
> huge code-bases developed with frameworks like asyncio, so I understand<br>
> why it does look unnecessary to you.<br>
This is a good reason for clarifying the distinction between 'normal'<br>
generators and coroutines. It is not, IMO, justification for burdening<br>
the language (and everyone porting Python 2 code) with extra syntax.</p>
</blockquote>
<p dir="ltr"></p>
<p dir="ltr">How is it a burden for people porting Python 2 code? Because they won't get to name anything 'async' just like anyone supporting older Python 3 versions? Otherwise I don't see how it is of any consequence to people maintaining 2/3 code as it will just be another thing they can't use until they drop Python 2 support.</p>