
On Wed, Sep 7, 2016 at 3:27 PM, Nick Coghlan <ncoghlan@gmail.com> wrote: [...]
The new issue that's specific to comprehensions is that the statement form doesn't have the confounding factor of having an expression to the left of it. Thus, the prefix is unambiguous and can be read as modifying the entire statement rather than just the immediately following keyword:
async for row in db.execute(...): process(row)
It's also pragmatically necessary right now due to the sleight of hand that Yury used in the code generation pipeline to bring in "async def", "async with", and "async for" without a __future__ statement, but without making them full keywords either.
I don't think this issue strictly has anything to do with where that "async" is put in the syntax, as long as it's used within the definition of an async function: async def function(): # in here, is effectively "async" a keyword. Of course, in French, this would be: def function async(): # dedans, "async" est effectivement un mot clé I'm sure someone will be able to correct my French, though. [and Nick writes:]
[process(row) async for row in db.execute(...)]
When reading that, is "async" a postfix operator being used in a normal comprehension (wrong, but somewhat plausible)? Or is it part of a compound keyword with "for" that modifies the iteration behaviour of that part of the comprehension (the correct interpretation)?
[(process(row) async) for row in db.execute(...)] [process(row) (async for) row in db.execute(...)]
The postfix operator interpretation is just plain wrong, but even the correct interpretation as a compound keyword sits between two expressions *neither* of which is the one being modified (that would be "db.execute()")
By contrast, if the addition of full async comprehensions is deferred to 3.7 (when async becomes a true keyword), then the infix spelling can be permitted in both the statement and comprehension forms:
That's an interesting suggestion. What exactly is the relation between deferring this PEP and permitting the infix spelling? This would make it more obvious at a first glance, whether something is a with statement or for loop. The word "async" there is still not very easy to miss, especially with highlighted syntax. I didn't realize (or had forgotten) that PEP 492 is provisional.
for row in async db.execute(...): process(row)
[process(row) for row in async db.execute(...)]
with the prefix spelling of the statement form retained solely for backwards compatibility purposes (just as we retain "from __future__ import feature" flags even after the feature has become the default behaviour).
The beauty of the infix form is that it *doesn't matter* whether someone reads it as a compound keyword with "in" or as a prefix modifying the following expression:
[process(row) for row (in async) db.execute(...)] [process(row) for row in (async db.execute(...))]
In both cases, it clearly suggests something special about the way "db.execute()" is going to be handled, which is the correct interpretation.
And db.execute is an async iterarable after all, so "async" is a suitable adjective for db.execute(...). -- Koos [...]
Cheers, Nick.
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- + Koos Zevenhoven + http://twitter.com/k7hoven +