On 2021-10-16 20:31, Erik Demaine wrote:
On Sun, 17 Oct 2021, Steven D'Aprano wrote:

On Sat, Oct 16, 2021 at 11:42:49AM -0400, Erik Demaine wrote:

I guess the question is whether to define `(*it for it in its)` to mean
tuple or generator comprehension or nothing at all.

I don't see why that is even a question. We don't have tuple
comprehensions and `(expr for x in items)` is always a generator, never
a tuple. There's no ambiguity there. Why would allowing unpacking turn
it into a tuple?

Agreed.  I got confused by the symmetry.

The only tricky corner case is that generator comprehensions can forgo
the surrounding brackets in the case of a function call:

   func( (expr for x in items) )
   func( expr for x in items )  # we can leave out the brackets

But with the unpacking operator, it is unclear whether the unpacking
star applies to the entire generator or the inner expression:

   func(*expr for x in items)

That could be read as either:

   it = (expr for x in items)
   func(*it)

or this:

   it = (*expr for x in items)
   func(it)

Of course we can disambiguate it with precedence rules, [...]

I'd be inclined to go that way, as the latter seems like the only reasonable
(to me) parse for that syntax.  Indeed, that's how the current parser
interprets this:

```
      func(*expr for x in items)
           ^
SyntaxError: iterable unpacking cannot be used in comprehension
```

To get the former meaning, which is possible today, you already need
parentheses, as in

   func(*(expr for x in items))


But it would be quite surprising for this minor issue to lead to the
major inconsistency of prohibiting unpacking inside generator comps when
it is allowed in list, dict and set comps.

Good point.  Now I'm much more inclined to define the generator expression
`(*expr for x in items)`.  Thanks for your input!

As we can already have:

    func(*a, *b)

it's clear that * has a high precedence, so having:

    func(*expr for x in items)

be equivalent to:

    func((*expr for x in items))

does makes sense. It would be passing a generator.

On the other hand, wouldn't that make:

    [*s for s in ["abc", "def", "ghi"]]

be equivalent to:

    [(*s for s in ["abc", "def", "ghi"])]

? It would be making a list that contains a generator.

If:

    [*s for s in ["abc", "def", "ghi"]]

should unpack, then shouldn't:

    func(*expr for x in items)

also unpack?

On Sat, 16 Oct 2021, Serhiy Storchaka wrote:

It was considered and rejected in PEP 448. What was changed since? What
new facts or arguments have emerged?

I need to read the original discussion more (e.g.
https://mail.python.org/pipermail/python-dev/2015-February/138564.html), but
you can see the summary of why it was removed here:
https://www.python.org/dev/peps/pep-0448/#variations

In particular, there was "limited support" before (and the generator ambiguity
issue discussed above).  I expect now that we've gotten to enjoy PEP 448 for 5
years, it's more "obvious" that this functionality is missing and useful.  So
far that seems true (all responses have been at least +0), but if anyone
disagree, please say so.

Erik


_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/BWRSUO7AL4KFNWDHDR5SIWBGSFGGTUXH/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to