Iterate, Generate, Destroy

SequenceType makes no requirement on conforming types regarding whether they will be destructively “consumed” by iteration. To ensure non-destructive iteration, constrain your sequence to CollectionType.

So a sequence may be destroyed while iterating?

Not really in value semantic world.

If you check the definition of SequenceType protocol you will see no mutating API. It means no conforming structs can mutate themselves while using the protocol API, including iterating API.

However, unless iteration is implemented using recursion there must be some iteration tracking state that is changing while iterating. So something is mutating. But what?

In order to answer this question, let’s first review the iterating API of SequenceType.

Actually there is no iterating API in SequenceType.

SequenceType is iterated via its Generator which is accessed via its generate method. Generator conforms to GeneratorType protocol:

public protocol GeneratorType {
    typealias Element
    public mutating func next() -> Self.Element?
}

Voila! The mutating API next is exactly the iterating API. That’s no coincidence at all.

So what may be destroyed while iterating is not SequenceType per se but its Generator.

What about those sequences that return self as generator in generate method? Then the destructive generator is also destroying the sequence while iterating because they are the same thing?

Yes, that’s true. But in value semantic world it is not an issue. The destroyed sequence/generator is a not the original sequence but a mutable copy of it. It is more clear in code:

// The `for`…`in` loop should be implemented semantically like this. 
var generator = sequence.generate() // Copy. 
while let element = generator.next() {
    // Process element.
}