[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