(original) (raw)

On 22 November 2017 at 18:15, Paul Moore <p.f.moore@gmail.com> wrote:
On 22 November 2017 at 16:47, Ivan Levkivskyi <levkivskyi@gmail.com> wrote:
\> On 22 November 2017 at 17:43, Paul Moore <p.f.moore@gmail.com> wrote:
\>>
\>> On 22 November 2017 at 16:30, Ivan Levkivskyi <levkivskyi@gmail.com>
\>> wrote:
\>> > On 22 November 2017 at 17:24, Antoine Pitrou <solipsis@pitrou.net>
\>> > wrote:
\>> >> Given a comprehension (e.g. list comprehension) is expected to work
\>> >> nominally as \`constructor(generator expression)\`
\>> >
\>> > As Yury just explained, these two are not equivalent if there is an
\>> > \`await\`
\>> > in the comprehension/generator expression.
\>>
\>> As Antoine said, people \*expect\* them to work the same.
\>
\>
\> The difference is that a generator expression can be used independently, one
\> can assign it to a variable etc. not necessary to wrap it into a list()
\> Anyway, can you propose an equivalent "defining" code for both? Otherwise it
\> is not clear what you are defending.

\[...snip...\]

1\. List comprehensions expand into nested for/if statements in the
"obvious" way - with an empty list created to start and append used to
add items to it.
1a. Variables introduced in the comprehension don't "leak" (see below).
2\. Generator expressions expand into generators with the same "nested
loop" behaviour, and a yield of the generated value.
3\. List comprehensions are the same as list(the equivalent generator
expression).

Great, I agree with all three rules.
But there is a problem, it is hard to make these three rules consistent in some corner cases even \_without async\_.
For example, with the original problematic example, it is not clear to me how to apply the rule 2 so that it is consistent with 3:

def fun\_comp():
return \[(yield i) for i in range(3)\]

def fun\_gen():
return list((yield i) for i in range(3))

I think the solution may be to formulate the rules in terms of the iterator protocol (\_\_iter\_\_ and \_\_next\_\_).
I will try to think more about this.

--
Ivan