New range operator `..+`

I propose to add support for start ..+ length expression, which is equivalent to start ..< start + length (e.g. 100..+5 is the same as 100..<105).

This is especially useful for slicing when start expression is quite long.

Also, I do not think start ..+ length needs a special separate range type, i.e. it can be just of type Range with end set to start + length.

Do you find this feature useful?
  • Yes
  • Maybe
  • No
0 voters
2 Likes

Maybe just this?

for i in OpenRange(100, 110) {            // 100 ..< 110
    print(i)
}
for i in OpenRange(100, length: 10) {     // 100 ..< 110
    print(i)
}
for i in ClosedRange(100, 110) {          // 100 ... 110
    print(i)
}
for i in ClosedRange(100, length: 10) {   // 100 ... 110
    print(i)
}
Implementation
typealias OpenRange = Range

extension OpenRange {
    init(_ from: Bound, _ to: Bound) {
        self = from ..< to
    }
}

extension OpenRange where Bound: AdditiveArithmetic {
    init(_ from: Bound, length: Bound) {
        self = from ..< from + length
    }
}

extension ClosedRange {
    init(_ from: Bound, _ to: Bound) {
        self = from ... to
    }
}

extension ClosedRange where Bound: AdditiveArithmetic {
    init(_ from: Bound, length: Bound) {
        self = from ... from + length
    }
}
1 Like

I would've expected 0..+10 to index ten elements, but if defined like here it would not be

Also, it wouldn't work for non-numeric indices

I would rather have something like lhs..<collection(lhs, offsetBy: rhs)

infix operator ..+

func ..+<T: Numeric>(lhs: T, rhs: T) -> Range<T> {
    lhs..<(lhs+rhs)
}

let multiplesOfTwo = Array(0...100).lazy.filter { $0.isMultiple(of: 2) }

print(Array(multiplesOfTwo.prefix(10))) // [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
print(Array(multiplesOfTwo[0..<multiplesOfTwo.index(0, offsetBy: 10)])) // [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
print(Array(multiplesOfTwo[0..+10])) // [0, 2, 4, 6, 8]
1 Like

In my proposal 0..+10 is the same as 0 ..< (0+10), i.e. 0..<10, so it indexes exactly ten elements (from 0 through 9).

Swift indexes are weird. Check out my code sample - multiplesOfTwo[0..<10] is only five elements

1 Like