Re: [swift-users] Confused/Surprised by IndexingIterator.forEach behavior

2016-12-28 Thread Guillaume Lessard via swift-users
forEach is defined by the Sequence protocol, and is not a mutating function. By 
definition, it must create a local iterator in order to perform its duty. As a 
consequence, the variable `stream` is the same immediately before and after the 
forEach call.

Cheers,
Guillaume Lessard

___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Confused/Surprised by IndexingIterator.forEach behavior

2016-12-28 Thread Ole Begemann via swift-users

On 28/12/2016 19:57, Travis Griggs via swift-users wrote:

The behavior of the following playground snippet surprised me:

var source = [10, 20, 30, 40]
var stream = source.makeIterator()
stream.next()  // 10
stream.next()  // 20
stream.forEach { (each) in
print("\(each)")
}  // prints 30, 40 to the console
stream.next()  // 30
stream.next()  // 40
stream.next()  // nil

I can move the forEach statement up and down the stack there, and it *appears* 
that while it respects the the current position of the stream/iterator as a 
start point, it does not actually consume the elements (as next does). That 
seems inconsistent to me I guess. I would have expected the forEach to either 
pass through to the source and just ignore the current position, or to consume 
the items. Whereas the current behavior is kind of a hybrid.

Guess I’m just looking for some enlightenment as to why it was designed to work 
this way. I figure there’s some valuable insight here that I’m missing.


The IndexingIterator returned by `source.makeIterator()` is itself a 
`Sequence` (you couldn't call `forEach` if it weren't).


When you call `forEach` (which is implemented using a `for ... in` 
loop), you effectively call `stream.makeIterator()`, thus making a new 
iterator. The state of the original `stream` iterator isn't affected by 
this.


You can see more clearly what happens when you deconstruct the call to 
`forEach`, first into a for-in loop and then into a while loop (which is 
equivalent to the for-in loop). All three variants give the same result 
even if called sequentially on the same sequence, because a new iterator 
is created for each loop:


// ...
stream.next()  // 10
stream.next()  // 20
stream.forEach { (each) in
print("forEach \(each)")
}  // prints 30, 40 to the console

// for-in loop has the same effect
for element in stream {
print("for in \(element)")
} // prints 30, 40 to the console

// while loop has the same effect
// Here you can see that a new iterator is created.
var iter = stream.makeIterator()
while let element = iter.next() {
print("while \(element)")
}

stream.next()  // 30
stream.next()  // 40
stream.next()  // nil

(The result would be different if the sequence were _destructively 
consumed_, i.e. it can only be iterated over once -- which is allowed by 
the Sequence protocol).


___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] Confused/Surprised by IndexingIterator.forEach behavior

2016-12-28 Thread Travis Griggs via swift-users
The behavior of the following playground snippet surprised me:

var source = [10, 20, 30, 40]
var stream = source.makeIterator()
stream.next()  // 10
stream.next()  // 20
stream.forEach { (each) in
print("\(each)")
}  // prints 30, 40 to the console
stream.next()  // 30
stream.next()  // 40
stream.next()  // nil

I can move the forEach statement up and down the stack there, and it *appears* 
that while it respects the the current position of the stream/iterator as a 
start point, it does not actually consume the elements (as next does). That 
seems inconsistent to me I guess. I would have expected the forEach to either 
pass through to the source and just ignore the current position, or to consume 
the items. Whereas the current behavior is kind of a hybrid. 

Guess I’m just looking for some enlightenment as to why it was designed to work 
this way. I figure there’s some valuable insight here that I’m missing.
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users