[swift-evolution] [Draft]: Introducing a striding(by:) method on 3.0 ranges
michel.fortin at michelf.ca
Sun Apr 10 07:35:43 CDT 2016
Le 10 avr. 2016 à 6:17, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org> a écrit :
> Remember, conditional branches are relatively slow, and we want to avoid them where we can. If this is, for instance, the test of a loop, the extra branch is not a good thing.
Perhaps it's a bit extreme, but my idea for stride is that it should only have one branch in the loop condition and absolutely no other branch. The primitive stride could be defined like this:
stride(from: 0, compare: <, to: 10, by: 2)
and on top you could add some convenience functions for the <, >, <=, and >= cases:
stride(from: 0, to: 10, by: 2) // stride(from: 0, compare: <, to: 10, by: 2)
stride(from: 10, downTo: 0, by: -2) // stride(from: 10, compare: >, to: 0, by -2)
stride(from: 0, through: 10, by: 2) // stride(from: 10, compare: <=, to: 10, by 2)
stride(from: 10, downThrough: 0, by: -2) // stride(from: 10, compare: >=, to: 0, by -2)
None of these should try to prevent you from making an infinite sequence, so no trap for `by: 0` or one that moves the value in the wrong direction. And certainly no extra loop branch based on the sign of the stride (that's the most important part).
Based on that, you could add some convenience for ranges:
(0 ..< 10).striding(by: 2) // shortcut for: stride(from: 0, to: 10, by 2)
(0 ..< 10).stridingDown(by: -2) // shortcut for: stride(from: 10, to: 0, by -2)
I guess in this case it'd be fine to add a precondition to check that `by` is not in the reverse direction so we can preserve the semantics of iterating over a collection. But because of this precondition and the other one in Range, I would actually prefer the non-range forms if I was using a `stride` in a nested loop.
More information about the swift-evolution