It just occured to me after posting that there should be no way for Sequence to provide default implementations for non-mutating functions with only the mutating next function.
It seems the default implementations make a copy of self, making such a sequence multi-pass.
You may be misunderstanding me. In the following code, it seems map is copying self:
code
struct NumberSequence: IteratorProtocol, Sequence {
var nextItem = 0
mutating func next() -> Int? {
if nextItem == 10 {return nil}
defer {nextItem += 1}
return nextItem
}
}
let s = NumberSequence()
let a = s.map{$0}
let b = s.map{$0} //b == a when NumberSequence is a struct
That aside, I agree that any single-pass sequence must have reference-sematics, to render this copying ineffective.
edit: …and all my reasoning on this topic so far was based on Iterators being single-pass when conformed to Sequence. So I'm back to square one, not understanding why Iterator and Sequence are separate protocols.
It occurs to me that perhaps this is a lack-of-moveonly issue. If Sequence.makeIterator() on a move-only type consumed self, then the type system would prevent you from treating a single-pass sequence as multi-pass, because any attempt to access the sequence's elements would destroy it.
Have we given any thought to how Sequence should look in a world with moveonly types? Have we thought about forward compatibility with such a future design?