On 14 July 2013 12:04, Guido van Rossum <guido@python.org> wrote:
On Fri, Jul 12, 2013 at 5:25 PM, Joshua Landau
<joshua.landau.ws@gmail.com> wrote:
> A blessing from the Gods has resulted in
> http://www.python.org/dev/peps/pep-0448/! See what you think; it's not too
> changed from before but it's mighty pretty now.
>
> Still up for discussion are the specifics of function call syntax, the full
> details of which should already be in the PEP. If you come up with a better
> suggestion or want argue for one of the choices, go ahead.

I like it.

Finally read it myself - looks promising.
 
I note that we now end up with new ways for concatenating
sequences (e.g. [*a, *b]) and also for merging dicts (e.g. {**a,
**b}). I think it would be good to prepare an implementation in time
for inclusion in Python 3.4a1 to avoid the same issue with this we had
before -- I could imagine that there might be some implementation
problems and I don't want to accept an unimplementable PEP. Also it
would be good to know that code not using the new syntax won't run any
slower (especially for function calls this is very important).

I believe we should be able to confine those changes to the bytecode generation, which would mean existing code would be unaffected.
 

Regarding the decision about the allowable syntax for argument lists,
I prefer to keep the existing restriction (making *args after a
keyword argument basically an exception) since, as you point out,
placing regular positional arguments after regular keyword arguments
looks plain silly.

Agreed.

One interesting point I see is that the "*expr" syntax in comprehensions is getting close to a nested "yield from":

>>> list((yield from x) for x in ([1], [2, 3], [4, 5, 6]))
[1, None, 2, 3, None, 4, 5, 6, None]

The reason those "None" results show up is that this still emits the standard implied "yield value" for the comprehension, and the result of "(yield from x)" is None

So the translation for star unpacking in generator expressions would be along the lines of a straightforward replacement of the implied "yield" with an implied "yield from":

    # Expansion of existing generator expression
    g = (x for x in iterable)

    def _g(outermost_iterable):
        for x in outermost_iterable:
            yield x

    g = _g()

    # Flattening generator expression
    g = (*x for x in iterable)

    def _g(outermost_iterable):
        for x in outermost_iterable:
            yield from x

    g = _g(iterable)

The meaning for list and set comprehensions then follows from the generator expression semantics.

Dictionary comprehensions would remain a unique snowflake, as they would be the only form which permitted the doublestar unpacking (they're already unique, since they rely on the embedded "k:v" notation to distinguish themselves from set comprehensions and set displays in general). As with existing doublestar unpacking in function calls, the semantics of what is acceptable would be driven by http://docs.python.org/3/c-api/dict.html#PyDict_Update (Note that those docs are currently inaccurate, as they imply it also accepts an iterable of key, value 2-tuples like dict.update, which is not the case: http://bugs.python.org/issue18456)

Cheers,
Nick.

--
Nick Coghlan   |   ncoghlan@gmail.com   |   Brisbane, Australia