[swift-evolution] Proposal: Add Safe Subquence Access Via subscript For ColloctionType
Daniel Duan
daniel at duan.org
Mon Dec 14 14:52:53 CST 2015
In CollectionType, a `Range` is accepted as the argument in a version of `subscript`, which returns a subsequence.
[1,2,3,4][2...3] // [3, 4]
`subscript` raises a fatal error if the range is out of bound, which is really a side-effect from accessing an element with an out of bound index. This behavior forces users to check bounds beforehand. It has been serving us well.
I propose adding a new interface where user can recover from/defer out of bound error in this context. Here are two potential approaches.
Approach #1 is more conservative, we add a throwing version of `subscript`. It throws an error if the range is out of bound. We can give the range parameter a name for distinction, resulting usage would look like:
do {
let gimme = [1,2,3,4][safe: 2...4]
} catch {
recover()
}
As an alternative, we can replace the original `subscript` with this version, breaking backward compatibilty.
Apporoach #2 is a really sweet syntax sugar. We add a new subscript that accepts 2 arugments:
extension CollectionType where Self.Index: RandomAccessIndexType {
public subscript(start:Int?, end:Int?) -> Self.SubSequence { ... }
}
This version would make ANY combination of arugment safe by enabling a sematic similar to Python's slicing mechanism. Explanations come after these examples:
[0,1,2,3][1, -1] // [1, 2]
["H","e","l","l","o"][-1000, nil] // ["H","e","l","l","o"]
[1,2,3,4,5,6,7,8][1,5][2,3] // [4]
This should look familiar to Python users:
* the access is always clamped in-bound. Interpret out-of-bound number as the boundary. [1,2,3][0: 100] means [1,2,3][0: 2].
* nil indicate the boundary itself. [1,2,3][0: nil] means [1,2,3][0: 2]
* negative index counts from the end of the sequence. [1,2,3][-2, -1] means [1,2,3][(3-2), (3-1)]
Admittedly, this syntax suger seems a little out-of-place in Swift :P
Both approaches require just a little of work. As an example, here's one implementation of the 2nd: https://github.com/dduan/Lic/blob/master/Lic/Lic.swift (please ignore the extension for String, that'd be in a separate proposal, if any).
What do you think?
- Daniel Duan
More information about the swift-evolution
mailing list