I don't want to contemplate a new __next__ protocol. The existing protocol was carefully designed and tuned to have minimal memory overhead (even to the point where the exception instance returned may be reused). Wapping each result would just result in an extra allocation + deallocation per iteration, unless you can play games with reference counts or do something else to complicate the semantics). Introducing __nextx__ would require thousands of libraries implementing this to incur churn as they feel the pressure to switch to the new protocol, and the compatibility issue would be felt everywhere.

The problem we're trying to fix is unique to generators (thereby also implicating generator expressions).

On Mon, Nov 17, 2014 at 6:04 AM, Chris Angelico <rosuav@gmail.com> wrote:
On Tue, Nov 18, 2014 at 12:50 AM, Devin Jeanpierre
<jeanpierreda@gmail.com> wrote:
> As another alternative, how about a new iterator protocol that is
> defined without this ambiguity? Code at the bottom of my post to help
> explain:  define a new method __nextx__ which doesn't use
> StopIteration for any signalling, instead, it returns None if there
> are no values to return, and returns a special value Some(v) if it
> wants to return a value v.  Both next(it) and nextx(it) are made to
> work for any iterator that is defined using either protocol, but for
> loops and Python builtins all use nextx internally. Generators define
> __next__ unless you from __future__ import iterators, in which case
> they define __nextx__ instead.

I had actually contemplated adding a "what if __next__ returned a
sentinel instead of raising an exception" possibility to the PEP, if
only for completeness. Since someone else has suggested it too now, it
may be worth doing.

Rather than a wrapper around every returned value, what I'd be
inclined toward is a special sentinel that otherwise cannot be
returned. This could be a dedicated, arbitrary object, or something
globally unique, or something locally unique. One option that comes to
mind is to have the generator return _itself_ to signal that it's
returned.

I don't think this option will be better than the current front
runners, but would you like me to add it for completeness? The biggest
downside is that it might give a false positive; you can't, for
instance, have an iterator "all_objects()" which returns, like the
name says, every object currently known to Python. (I don't know that
CPython is capable of implementing that, but there's no reason another
Python couldn't, and it might be useful.) I expect that's why the
exception system was used instead; can anyone confirm that?

ChrisA
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/



--
--Guido van Rossum (python.org/~guido)