[Python-ideas] return value of yield expressions
Jacob Holm
jh at improva.dk
Tue Sep 13 20:35:27 CEST 2011
On 2011-09-13 20:07, Guido van Rossum wrote:
> On Tue, Sep 13, 2011 at 10:57 AM, Georg Brandl <g.brandl at gmx.net> wrote:
>> Am 13.09.2011 19:34, schrieb Guido van Rossum:
>>> On Tue, Sep 13, 2011 at 10:21 AM, H. Krishnan <hetchkay at gmail.com> wrote:
>>>
>>>> That (yield expr) can be used in expressions does not (I feel) affect this
>>>> (particularly if we go with Jacob's suggestion of this being a general
>>>> unpacking option), just in the same way that "a, b, *args, c = <tuple>" does
>>>> not affect using tuples in expressions. But after reading your comment in
>>>> another thread about those who don't know how python works should keep
>>>> quiet, I guess it is best if I end this here :-)
>>>
>>> I understand "a, b, *c = <something>". I do not understand three
>>> things in your example:
>>>
>>> *(....) = <something> # What is the meaning of the prefix *?
>>>
>>> *(.... = .....) = <something> # What does an = inside parentheses mean?
>>>
>>> *(.... = ......, **kwds) = <something> # What does **kwds mean in this context?
>>>
>>
>> Apparently that syntax would be exclusive for "= yield", which then "unpacks"
>> the arguments given to generator.send() as if the LHS was the argument list
>> of a function.
>
> That sounds like impossible to implement. If there should be
> special-case treatment it should use some other form of syntax (e.g.
> "yield <expr> as <var>"). But I really don't see why this is so
> important to change so much of the syntax of the language.
>
The '*(argument list) = <expression>' syntax was my attempt at fixing
some of the problems in the original proposal. I.e. to remove the
restriction that it only should work with "= yield", and distinguish the
"function argument unpacking" from the regular tuple unpacking.
My idea was to allow
*(argument list) = (args, kwds)
where the LHS follows all the rules of a function argument list (the
part of a function definition between the name and the colon), and
the RHS may be any expression that returns a 2-tuple consisting of a
sequence and a dictionary.
The intended semantics was to compute the arguments that a function with
the given argument list would see when called with (*args, **kwds), and
make the necessary assignments in the local scope. Any way I can think
of that works today violates DRY.
A simple example:
*(a, b, c=42, *args, **kwds) = ((1,), {'b':2, 'd':3})
assigns a=1, b=2, c=42, args=(), kwds={'d':3}
And my best hack so far to get the same effect today is:
args, kwds = ((1,), {'b':2, 'd':3})
a, b, c, args, kwds = \
(lambda a, b, c=42, *args, **kwds:a, b, c, args, kwds)(*args, **kwds)
I am not wed to the particular suggested syntax, but I would like to see
the functionality available *somehow* in a way where you don't have to
repeat the sequence of variable names. And I don't think that is
possible without *some* syntax change.
- Jacob
More information about the Python-ideas
mailing list