On Fri, Jun 18, 2021 at
07:38:49AM -0700, Guido van Rossum wrote:
> Note the ambiguity around whether the user might have
meant
>
> [x,(y for y in a)]
>
> or
>
> [(x, y) for y in a]
We already have a rule to disambiguate generator
comprehensions: they
must always be parenthesized unless they are already
parenthised:
g = (y for y in a) # parens required
t = 999, (y for y in a) # parens required
func((y for y in a)) # inner parens optional
Yes, that's exactly what I was referring to.
> That’s a good enough reason for me to also disallow
*chunks.
That's an odd way to look at it. We must disallow an
unambiguous syntax
because a completely different syntax would have been
ambiguous if we
didn't already have a rule in place that disambiguates it.
Maybe, but the two are not unrelated. In other contexts,
when we accept "*chunk", and 'chunk' equals "1, 2", we also
accept "1, 2" in the original position, and it means the
same thing. This is useful as an explanation of the
semantics of the unary '*' operator[1]. For example
# Given:
chunk = 1, 2
# Equivalent:
f(*chunk)
f(1, 2)
# Equivalent:
[*chunk]
[1, 2]
So then if we were to allow this:
[*chunk for chunk in ...]
we ought to consider this equivalent:
[1, 2 for chunk in ...]
(Note there's nothing that says the expressions to the
left of 'for' need to involve the for-control variable
'chunk'. :-)
Now, this shouldn't be considered an airtight argument
against [*chunk for ...], but it does show that there's no
straightforward explanation of its meaning through
equivalence (like the OP seemed to think), and I think this
is what Serhiy was also getting at in his post.
__________
[1] Does the unary star operator have a name when used
like this in Python? In JavaScript the equivalent syntax
("...chunk", where the "..." are a literal ellipsis) is
called "spread". We could borrow this term.