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 email@example.com wrote:
On Tue, Nov 18, 2014 at 12:50 AM, Devin Jeanpierre firstname.lastname@example.org 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 Pythonemail@example.com https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/