[swift-evolution] [Proposal] Change guarantee for GeneratorType.next() to always return nil past end

Dmitri Gribenko gribozavr at gmail.com
Tue Mar 8 18:41:23 CST 2016


On Tue, Mar 8, 2016 at 12:16 PM, Kevin Ballard <kevin at sb.org> wrote:
> On Tue, Mar 8, 2016, at 11:42 AM, Dmitri Gribenko wrote:
>> On Sun, Mar 6, 2016 at 5:58 PM, Kevin Ballard via swift-evolution
>> <swift-evolution at swift.org> wrote:
>> > That's a fair point. But I think the important sentence from my comparison to Rust is "And in practice, almost nobody ever has to actually use .fuse(), …".
>>
>> The concern is that people who do need to invoke .fuse(), won't,
>> because all generators they are likely to try in practice will 'just
>> work' and return a continuous stream of nils.
>>
>> I think what this really comes down to is the trade off between a
>> subtle correctness issue and a small performance win for a small
>> number of data types (which can be even non-existent as Patrick
>> Pijnappel shows).  Given the general direction of Swift, I'm inclined
>> to choose correctness here.
>
> Anyone who uses Generators directly has to understand their behavior and has to understand their requirements. The prohibition on not copying a Generator and invoking next() on both copies I think is actually more of a potential problem than handling post-nil behavior.

And that is another problem that we need to fix.  I don't think it is
acceptable to say that we won't fix one problem because there is
another anyway.

> If we define post-nil behavior as needing to return nil forever, I suspect it's actually more likely for implementors of new Generators to screw up and not enforce this requirement than it is for clients to even notice it.

I disagree.  Most people just use the default IndexingGenerator.

> As a side note, I just tested (using Xcode 7.3 beta 5) and AnyGenerator doesn't currently track this state itself. You can easily pass a closure to AnyGenerator() that causes it to return non-nil values after a previous call to next() has returned nil.

AnyGenerator is used to abstract away implementation details, but it
can't fix broken implementations.  Any time you conform to a protocol,
you are making a statement about semantics.  If the semantics are not
implemented correctly, then there are no guarantees about correctness
for things that build on top.

Dmitri

-- 
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr at gmail.com>*/


More information about the swift-evolution mailing list