[swift-evolution] [Pitch] Remove destructive consumption from Sequence

Jonathan Hull jhull at gbis.com
Tue Jun 28 14:06:44 CDT 2016


>>>> 1. Presumably these are all for-in-able.  What makes something
>>>> for-in-able?
>>> 
>>> I would think the potentially infinite should require for-in-until
>>> (even if you explicitly set until to false to create an infinite
>>> loop), but collection would allow for-in (with optional until).  That
>>> way you have to acknowledge the possibility of an infinite
>>> sequence/iterator.
>> 
>> Are you proposing a new language feature?  
> 
> That was my impression.  It’s an interesting idea.  It wouldn’t guarantee termination but would require developers to consider termination and therefore prevent accidents, which are the concerns I am raising.

Yes, exactly.

>> We could also do this with
>> 
>>   for i in allIntegers.until(isPrime)
> 
> Is `until` lazy or eager here?  I imagine you’re thinking it would be lazy because making it eager would introduce unnecessary allocation.  However, if it’s lazy it is an exception to the explicit laziness Swift has adopted.  
> 
> Wouldn’t it be better to require explicit laziness `allIntegers.lazy.until` if for..in is going to be require finite sequences and we’re going to use a library solution to support infinite sequences?  It’s more verbose but more consistent with how laziness is currently handled.  It also doesn’t privilege any specific operator (which isn’t necessary if we do this in the library).  

Everything with Iterators / Sequences should be lazy (because that is the only safe thing).  Collections would most likely still be eager.

In this case, ‘until' is creating a collection (most likely an array), so it would be eager.  For an iterator, it would immediately drain and buffer it.  For a sequence, I guess it is whatever is most efficient.

> If we went with a language solution I imagine it would look something like this:
> 
> for i in allIntegers until i.isPrime && i > 1000 where i.isEven {
>    // all even integers < the first prime > 1000
> }
> 
> IIRC the `until` clause has already been discussed as syntactic sugar for early termination.  Its utility wouldn’t be limited to looping over infinite sequences, however it would be *required* when you loop over an infinite sequence.  

Yeah, that is my thought as well.  I would also be ok with Dave’s suggestion as long as the path (compiler complain -> Suggest Fix) is the same, so you still consider and deal with the infinite case.

I do like the look of the language feature better, of course...

> This sugar wouldn’t have to be introduced in Swift 3.  We could make for..in require finite sequences in Swift 3 and add it later if there is sufficient demand.  In the meantime people could iterate infinite sequences manually and / or we could add library support via lazy operators that select a prefix (if we are willing to live with the fact that in practice termination may depend on arguments to the operator).

Ah, I just saw your point above.  allIntegers.until(isPrime) most likely needs to be eager, but that is the opposite of what we want for a for-in loop (it could have an early break), so the language feature might be quite a bit more efficient, and might actually be worthwhile (especially considering that people were already asking for it anyway).  I was indifferent to it, but I like it for this case…

Anyway, I am interested to see what they are cooking up for us (It may be much better than this)...

Thanks,
Jon

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160628/a0ae6a65/attachment.html>


More information about the swift-evolution mailing list