[Python-Dev] Tricky way of of creating a generator via a comprehension expression (original) (raw)

Ivan Levkivskyi levkivskyi at gmail.com
Sat Nov 25 09:55:28 EST 2017


On 25 November 2017 at 04:30, Guido van Rossum <guido at python.org> wrote:

On Fri, Nov 24, 2017 at 4:22 PM, Guido van Rossum <guido at python.org> wrote:

The more I hear about this topic, the more I think that await, yield and yield from should all be banned from occurring in all comprehensions and generator expressions. That's not much different from disallowing return or break.

From the responses it seems that I tried to simplify things too far. Let's say that await in comprehensions is fine, as long as that comprehension is contained in an async def. While we could save yield [from] in comprehensions, I still see it as mostly a source of confusion, and the fact that the presence of yield [from] implicitly makes the surrounding def a generator makes things worse. It just requires too many mental contortions to figure out what it does.

There were some arguments that await is like a function call, while yield is like return. TBH, I don't really like these arguments since to me they are to vague. Continuing this logic one can say that return is just a fancy function call (calling continuation with the result). To me there is one clear distinction: return and break are statements, while yield, yield from, and await are expressions.

Continuing the topic of the ban, what exactly should be banned? For example will this still be valid?

def pack_two():
    return [(yield), (yield)]  # Just a list display

I don't see how this is controversial. It is clear that pack_two is a generator. If this is going to be prohibited, then one may be surprised by lack of referential transparency, since this will be valid:

def pack_two():
    first = (yield)
    second = (yield)
    return [first, second]

If the first example will be allowed, then one will be surprised why it can't be rewritten as

def pack_two():
    return [(yield) for _ in range(2)]

I have found several other examples where it is not clear whether they should be prohibited with yield or not.

I still propose to rule out all of the above from generator expressions,

because those can escape from the surrounding scope.

Here I agree. Also note that the above problem does not apply to generator expressions since (x, x) and (x for _ in range(2)) are two very different expressions.

-- Ivan -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20171125/034060fc/attachment.html>



More information about the Python-Dev mailing list