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

Haravikk swift-evolution at haravikk.me
Wed Jun 29 05:03:38 CDT 2016


> On 29 Jun 2016, at 00:10, Matthew Johnson via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
>> On Jun 28, 2016, at 3:33 PM, Brent Royal-Gordon <brent at architechies.com> wrote:
>> 
>>> This use case seems interesting enough to at least deserve some consideration before we decide to require iterators to have reference semantics.  IMO the fact that `next` is a mutating requirement provides a pretty strong indication of the destructive / consuming semantics of using an iterator.  Requiring reference semantics gives up flexibility and I’m not completely convinced it adds clarity (but still keeping an open mind about this).
>> 
>> My feeling is that, except for the trivial case of IndexingIterator and other iterators over collections, all iterators *should* need reference semantics. If your iterator can offer value semantics, then you should convert it into a Collection to gain the benefits of indices.
> 
> Assuming we are going to pin down the requirement that Collection be finite (in the sense that iterating over the whole collection is practical in a real program running on a real device that is available today) then it is trivial to come up with value semantic iterators that cannot conform to Collection.  For example, iterators over infinite mathematical sequences.
> 
>> If it can't offer value semantics, then you should write it as a class so those reference semantics are obvious.
> 
> I agree with this.
> 
>> This would get rid of the really ugly caveat that's always festered at the heart of Iterator:
>> 
>>>>> Obtain each separate iterator from separate calls to the sequence's makeIterator() method rather than by copying. Copying an iterator is safe, but advancing one copy of an iterator by calling its next() method may invalidate other copies of that iterator. for-in loops are safe in this regard.
>> 
>> The underlying cause of this requirement is that you can't know whether a given iterator is a value type or a reference type. Let's fix that.
> 
> I would like to see us eventually have a way to specify a generic constraint indicating value semantics regardless of what happens with iterators.  If we gain that capability you *can* know that you have a value semantic iterator when you use that constraint.  
> 
> I am not firmly opposed to making iterators require reference semantics but I don’t think the pros and cons have been thoroughly discussed on the list yet so I am pointing out what I think are interesting use cases for value semantic iterators.
> 
> Swift is a language that embraces value semantics.  Many common iterators *can* be implemented with value semantics.  Just because we can’t implement *all* iterators with value semantics doesn’t mean we should require them to have reference semantics.  It just means you can’t *assume* value semantics when working with iterators in generic code unless / until we have a way to specify a value semantics constraint.  That’s not necessarily a bad thing especially when it leaves the door open to interesting future possibilities.
> 
> -Matthew

I'm kind of undecided about this personally. I think one of the problems with Swift is that the only indication that you have a reference type is that you can declare it as a constant, yet still call mutating methods upon it, this isn't a very positive way of identifying it however. This may be more of a GUI/IDE issue though, in that something being a class isn't always that obvious at a glance.

I wonder, could we somehow force iterators stored in variables to be passed via inout? This would make it pretty clear that you're using the same iterator and not a copy in all cases, encouraging you to obtain another if you really do need to perform multiple passes.


More information about the swift-evolution mailing list