[swift-evolution] Feature proposal: Range operator with step

Brent Royal-Gordon brent at architechies.com
Wed Apr 6 18:55:18 CDT 2016

> I (am familiar with and) agree with Dijkstra's logic, but not with your
> conclusion about it.  The fact that one representation is more natural
> for most common computing tasks doesn't mean it's not worth supporting
> the other representations.

I'm not saying that Dijkstra proves that we don't need any other range operators. Rather, I'm saying that he demonstrates why supporting `..<` but not `<..` is not arbitrary or capricious. Dijkstra's argument *permits* us to privilege `..<` as uniquely important, but doesn't *force* us to do so.

To another person just now, you said:

> He was talking about ranges of integer indices, though, and even
> more-specifically about how to address arrays.  Range<Bound> is a more
> general concept that applies to much more than indices.  Once you
> involve floating point (and rationals, and patterns for matching,
> e.g. UnicodeScalar("a")..."z"), the conclusions no longer apply.

I actually think he was talking a little more broadly than that—essentially, he was discussing ordered, discrete types. In principle, the same argument applies to UnicodeScalars, but not to floating-point numbers (unless you use treat floats as a discrete type using `nextafter` as the `successor()` operation, which is coherent but not very useful in practice). Having said that, I *do* think that `...` is in practice quite useful for many types. I'm less certain that `<..` or `<.<` are.

* * *

By the way, another reason to have `stride` as a free function is that I think some types need a "strider", an instance which performs the striding.

That was the conclusion I came to when I started experimenting with striding over NSDates a week or two ago. The best design I could come up with looked like this:

	calendar.using(.Day).stride(from: startDate, to: endDate, by: 1)

The `start` and `end` parameters could be grouped together into a single parameter to match `stride(over:by:)`, but you can't put the calendar or the unit into the stride—without them, there is no coherent way to calculate the distance between two dates.

So if some types need a strider, and will need to have the method structured as `strider.stride(something:by:)`, it seems like the free function version for types which *don't* need a strider ought to be `stride(something:by:)`. The `something.striding(by:)` design can't be easily adapted to this situation.

Brent Royal-Gordon

More information about the swift-evolution mailing list