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

Howard Lovatt howard.lovatt at gmail.com
Wed Apr 6 03:08:38 CDT 2016

```I think people are reading a ..< b as the mathematical notation [a, b)
which means {}, null, or empty, not error, if b < a and {a} if b = a.

If Range was changed to be an Array like collection indexed from 0 to count
and stride was how the indexed counted and was an Int > 0 then the
following would make sense in terms of interval mathematics as described
above (note how stride refers to how the index counts *not* how the values
count):

(0 ... -1) == []
(0 ..< 0) == []

(0 ... 0) == [0]
(0 ..< 2) == [0, 1]

(0 ... 2) == [0, 1, 2]

(0 ..< 4).strided(by: 2) == [0, 1, 2, 3].strided(by: 2) == [0, 2]

(0 ... 4).strided(by: 2) == [0, 1, 2, 3, 4].strided(by: 2) == [0, 2, 4]

(0 ..< 2).reversed == [0, 1].reversed == [1, 0]

(0 ..< 4).strided(by: 2).reversed == [0, 1, 2, 3].strided(by: 2).reversed
== [0, 2].reversed == [2, 0]

(-2 ..< 2).strided(by: 2).reversed == [-2, -1, 0, 1].strided(by:
2).reversed == [-2, 0].reversed == [0, -2]

(-2 ..< 2).reversed.strided(by: 2) == [-2, -1, 0, 1].reversed.strided(by:
2) == [1, 0, -1, -2].strided(by: 2) == [1, -1]

Then provide a very general init for Range to cope with difficult cases:

init(first: T, isFirstIncluded: Bool = true, last: T, isLastIncluded: Bool
= true, stride: Int = 1)

Range(first: 0, last: 0, stride: 0) // ERROR, stride must be > 0
Range(first: 0, last: 0) == [0]

Range(first: 0, isFirstIncluded: false, last: 0) == [] // {x | first < x <=
last }
Range(first: 0, last: 0, isLastIncluded: false) == [] // {x | first <= x <
last }

Range(first: -2, isFirstIncluded: false, last: 2, isLastIncluded: false) ==
[-1, 0, 1]
Range(first: -2, isFirstIncluded: false, last: 2, isLastIncluded: false,
stride: 2) == [-1, 1]

Note: only ForwardIndexType necessary.

-- Howard.

On 6 April 2016 at 09:22, Dave Abrahams via swift-evolution <
swift-evolution at swift.org> wrote:

>
> on Tue Apr 05 2016, Erica Sadun <swift-evolution at swift.org> wrote:
>
> >> On Apr 5, 2016, at 4:17 PM, Dave Abrahams via swift-evolution <
> swift-evolution at swift.org> wrote:
> >>
> >>
> >> on Tue Apr 05 2016, Erica Sadun <swift-evolution at swift.org> wrote:
> >>
> >
> >>>    On Apr 5, 2016, at 1:54 PM, Dave Abrahams
> >>>    <dabrahams at apple.com> wrote:
> >>>    IMO this:
> >>>
> >>>    (-9...0).reverse()
> >>>
> >>>    is better than
> >>>
> >>>    stride(from: 0, to: -10, by: -1)
> >>>
> >>>    What do you think?
> >>>
> >>> The latter better reflects an author's actual intent. The former
> depends on
> >>> implementation details, which can be hazy, especially, around the edge
> cases. It
> >>> is quicker to read, understand, and verify that the latter is what is
> >>> meant.
> >>
> >> Except that there seems to be some confusion over what "to:" means,
> right?
> >
> > obviously (0..<-10).by(-2) would be best.
>
> I don't think that's obvious at all, because 0 ≮ 10
>
> --
> Dave
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160406/97e5567d/attachment.html>
```