> I can’t imagine any scenario in which getting the step's sign wrong wouldn’t 
> just be a typo.

Well, it could be an error if you derive the stride by subtracting two numbers, 
and the second number is unexpectedly larger than the first. Of course, that 
makes it a *bug*, not a typo.

> Why not just assign it the correct sign during the init function?
> (0 ... 6).striding(by: 2) // [0, 2, 4, 6], end > start, so stride = by
> (6 ... 0).striding(by: 2) // [6, 4, 2, 0], start > end, so stride = -by

One reason not to do it this way is that, if we extend `striding(by:)` to other 
collections, they will not be as easy to walk backwards through as this. You 
will have to do something like `collection.reversed().striding(by:)` which will 
be a hassle.

And the same may apply to Range, for that matter, because…

> (OTOH, I don’t understand why 6…0 is currently a crash, rather than the, 
> IMHO, obviously intended sequence of “6,5,4,3,2,1,0”, so maybe I’m not the 
> best person to ask)

Well, suppose you say `6...0`. There are three ways that could be represented:

1.      Range(start: 0, end: 6)
2.      Range(start: 6, end: 0)
3.      Range(start: 0, end: 6, reversed: true)

Option 1 throws away the fact that the range was ever reversed, so it doesn't 
actually help with this case.

Option 2 complicates testing. Where before you might have written this:

        let inBounds = start <= x < end

Now you must write:

        let inBounds: Bool
        if start < end {
                inBounds = start <= x && x < end
        }
        else {
                inBounds = start >= x && x > end
        }

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.

Option 3 avoids this issue, but it requires more space. It also requires 
branches in other places which care about order.

And both 2 and 3 complicate slicing. If you say `array[6...0] = newValues`, the 
operation should probably be performed such that `array[6] == newValues[0]`. 
That seems difficult to implement—and all too easy to forget to handle. And I 
can imagine that it might prevent certain optimizations if the compiler 
couldn't prove they were forward ranges.

-- 
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to