Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #107421 > unrolled thread

PEP proposal: sequence expansion support for yield statement: yield *

Started byKen Seehart <k.seehart@partner.samsung.com>
First post2016-04-20 19:34 +0000
Last post2016-04-22 01:26 +1000
Articles 4 — 4 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  PEP proposal: sequence expansion support for yield statement: yield * Ken Seehart <k.seehart@partner.samsung.com> - 2016-04-20 19:34 +0000
    Re: PEP proposal: sequence expansion support for yield statement: yield * Steven D'Aprano <steve@pearwood.info> - 2016-04-21 10:21 +1000
      Re: PEP proposal: sequence expansion support for yield statement: yield * justin walters <walters.justin01@gmail.com> - 2016-04-21 08:19 -0700
      Re: PEP proposal: sequence expansion support for yield statement: yield * Chris Angelico <rosuav@gmail.com> - 2016-04-22 01:26 +1000

#107421 — PEP proposal: sequence expansion support for yield statement: yield *

FromKen Seehart <k.seehart@partner.samsung.com>
Date2016-04-20 19:34 +0000
SubjectPEP proposal: sequence expansion support for yield statement: yield *
Message-ID<mailman.36.1461181657.12923.python-list@python.org>
Currently the common pattern for yielding the elements in a sequence is as follows:

  for x in sequence: yield x

I propose the following replacement (the result would be identical):

  yield *sequence

The semantics are somewhat different from argument expansion (from which the syntax is borrowed), but intuitive: yield all of the elements of a sequence (as opposed to yield the sequence as a single item). This doesn't appear to have any syntactical collisions, as it is currently a syntax error.

Motivation: More compact notation, and the compiler can produce more efficient bytecode than the former representation (the loop overhead is omitted). This pattern is very common in recursive generators, so a compact notation would be nice.

Also, there is precedent: the proposed notation is implemented in javascript with identical semantics (though in javascript, the conventional spacing is different: yield* sequence ).

Examples:
  yield *(1,2,3)
... instead of :
  yield 1; yield 2; yield 3
... or:
  for x in (1,2,3): yield x


  yield *chain(seq1, seq2)
... instead of :
  for x in chain(seq1, seq2) yield x

~ Ken Seehart

[toc] | [next] | [standalone]


#107428

FromSteven D'Aprano <steve@pearwood.info>
Date2016-04-21 10:21 +1000
Message-ID<57181d0e$0$1591$c3e8da3$5496439d@news.astraweb.com>
In reply to#107421
On Thu, 21 Apr 2016 05:34 am, Ken Seehart wrote:

> Currently the common pattern for yielding the elements in a sequence is as
> follows:
> 
>   for x in sequence: yield x
> 
> I propose the following replacement (the result would be identical):
> 
>   yield *sequence

Others have already pointed out that this already exists as "yield from
iter(sequence)", but I'd like to say that this syntax was not added merely
to shorten the "for x in sequence: yield x" idiom.

In its simplest case, "yield from expr" is equivalent to "for x in expr:
yield x", and it is completely reasonable to use it for such simple
purposes. But that's not why it was added to the language, and if that's
*all* it did, it probably wouldn't have been.

Rather, "yield from" was added to support the full set of generator
behaviour, including their send(), close() and throw() methods. That
makes "yield from expr" equivalent to this rather formidable chunk of code:



_i = iter(EXPR)
try:
    _y = next(_i)
except StopIteration as _e:
    _r = _e.value
else:
    while 1:
        try:
            _s = yield _y
        except GeneratorExit as _e:
            try:
                _m = _i.close
            except AttributeError:
                pass
            else:
                _m()
            raise _e
        except BaseException as _e:
            _x = sys.exc_info()
            try:
                _m = _i.throw
            except AttributeError:
                raise _e
            else:
                try:
                    _y = _m(*_x)
                except StopIteration as _e:
                    _r = _e.value
                    break
        else:
            try:
                if _s is None:
                    _y = next(_i)
                else:
                    _y = _i.send(_s)
            except StopIteration as _e:
                _r = _e.value
                break
RESULT = _r




See PEP 380 for more info:

https://www.python.org/dev/peps/pep-0380/


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#107456

Fromjustin walters <walters.justin01@gmail.com>
Date2016-04-21 08:19 -0700
Message-ID<mailman.17.1461251986.23626.python-list@python.org>
In reply to#107428
I agree with the others that the new syntax is not needed.

I would also like to point out that I believe any new added syntax or
functionality should avoid the use of '*' and '**' as both of these
characters are already used for many things such as optional arguments and
mathematical operators. Adding more uses for said characters only decreases
the readability of the code.

[toc] | [prev] | [next] | [standalone]


#107458

FromChris Angelico <rosuav@gmail.com>
Date2016-04-22 01:26 +1000
Message-ID<mailman.19.1461252410.23626.python-list@python.org>
In reply to#107428
On Fri, Apr 22, 2016 at 1:19 AM, justin walters
<walters.justin01@gmail.com> wrote:
> I agree with the others that the new syntax is not needed.
>
> I would also like to point out that I believe any new added syntax or
> functionality should avoid the use of '*' and '**' as both of these
> characters are already used for many things such as optional arguments and
> mathematical operators. Adding more uses for said characters only decreases
> the readability of the code.

The single asterisk is used for packing and unpacking, though. See PEP
448 [1] for some of the ways this can be used (in the context of "the
ways this can NOW be used in Python 3.5"). So the proposed "yield
*sequence" does make good sense; however, "yield from" has, as Steven
pointed out, *far* more detailed semantics, as it basically allows
generators to be refactored, with all their semantics (yield, send,
throw, return).

ChrisA

[1] https://www.python.org/dev/peps/pep-0448/

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web