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?