[Rant] Indexing into ArraySlice

Here is a bit more of the design I have in mind:

private extension RandomAccessCollection {
    //This function is the core of the design I am proposing:
    func _index(_ offset: Int) -> Self.Index {
        // Rule: Positive offsets are always relative to `startIndex`,
        // while negative offsets are always relative to `endIndex`.
        let base = offset >= 0 ? startIndex : endIndex
        return index(base, offsetBy: offset)
    }
}

// We need our own range, because standard library ranges are not compatible with this design:
public struct OffsetRange {
    public let start: Int
    public let end: Int
}

// Only (partial) closed ranges make sense in this design:
public prefix  func ... (rhs: Int) -> OffsetRange           { return OffsetRange(start: 0, end: rhs) }
public postfix func ... (lhs: Int) -> OffsetRange           { return OffsetRange(start: lhs, end: -1) }
public         func ... (lhs: Int, rhs: Int) -> OffsetRange { return OffsetRange(start: lhs, end: rhs) }

public extension RandomAccessCollection {
    subscript (o offset: Int) -> Element {
        get { return self[_index(offset)] }
    }
    subscript(o range: OffsetRange) -> Self.SubSequence {
        get { return self[_index(range.start) ... _index(range.end)] }
    }
}

public extension RandomAccessCollection where Self: MutableCollection {
    subscript (o offset: Int) -> Element {
        get { return self[_index(offset)] }
        set { self[_index(offset)] = newValue }
    }
    subscript(o range: OffsetRange) -> Self.SubSequence {
        get { return self[_index(range.start) ... _index(range.end)] }
        set { self[_index(range.start) ... _index(range.end)] = newValue }
    }
}

let a = ["a","b","c","d","e","f","g"]
let b = a[2...]
print("b=\(b)")

// Forward offset:
for i in 0..<b.count { print(b[o: i], terminator: " ") }
print()

// Backward offset (from endIndex):
for i in -b.count..<0 { print(b[o: i], terminator: " ") }
print()

// Offset range:
print("b[o: 1...(-2)]=\(b[o: 1...(-2)])") // Note that -1 gives us the last element.
print("b[o: 1...3]=\(b[o: 1...3])")
print("b[o: -4...(-2)]=\(b[o: -4...(-2)])") // We can define `...-` to eliminate `()`.
print("b[o: -4...3]=\(b[o: -4...3])")
// Offset partial ranges:
print("b[o: 2...]=\(b[o: 2...])")
print("b[o: ...(-3)]=\(b[o: ...(-3)])")