[swift-evolution] [Draft]: Introducing a striding(by:) method on 3.0 ranges

Dave Abrahams dabrahams at apple.com
Mon Apr 11 13:36:26 CDT 2016

on Sun Apr 10 2016, Michel Fortin <michel.fortin-AT-michelf.ca> wrote:

> So if you take this into account, storing the comparator as part of
> the stride makes the cost more predictable: not only there is one
> branch less in `next()`, but you avoid evaluating the condition which
> has an unknown cost: the `stride < 0` part.
> And ideally you should make sure the optimizer can replace the
> indirect call with a direct call to the comparator. You do that by not
> making the comparator choice dependent on a runtime value, hence why I
> suggested having distinct "down" variants for the convenience
> functions: `stride(from:downTo:by:)` and
> `stride(from:downThrough:by:)` and `Range.strindingDown(by:)`.

A few points:

1. There's a balance to be struck between making sure the optimizer can
   do a good job under *absolutely all circumstances*, and keeping the
   API surface area small and simple.  That makes me somewhat reluctant
   to add “down” variants, if as I suspect the optimizer does well in
   the vast majority of cases without them.

2. Similarly, I view r.striding(by: x) as redundant with stride(from: x,
   to: y, by: z).  I'd rather not have them both.

3. The fact that we're migrating C-style for loops to
   uses of stride, as noted in https://github.com/apple/swift/pull/2125,
   has convinced me that, sadly, we may need an answer that doesn't
   involve ranges.  But maybe something like

     for x in loop(from: 0.1, while: { $0 < 10 }, next: { $0 + .2 })

   is sufficient for this purpose.


More information about the swift-evolution mailing list