[swift-evolution] Optional safe subscripting for arrays

davesweeris at mac.com davesweeris at mac.com
Sat Jan 16 21:06:52 CST 2016


So, this?
subscript(safe index: Index) -> Element? {
    get { return self.indices ~= index ? self[index] : nil }
    set {
        if self.indices ~= index {
            self[index] = newValue!
        }
    }
}

The problem with that is again semantics. You’re (sorta) saying “here, let me safely store this for you”, and then it doesn’t get stored because “safe” applies to the indexing as opposed to the assignment. What about “failable”?
subscript(failable index: Index) -> Element? {
    get { return self.indices ~= index ? self[index] : nil }
    set {
        if self.indices ~= index && newValue != nil {
            self[index] = newValue!
        }
    }
}

var foo = [1] // normal
var bar = foo[failable: 2] //nil, but it’s clearly failable, so no surprise 
foo[failable: 2] = 3 //nothing happens, but again it’s clearly failable, so we know the assignment might not’ve stuck



> On Jan 16, 2016, at 17:55, Maximilian Hünenberger <m.huenenberger at me.com> wrote:
> 
> It is true that the setter could cause some confusion in the first place but I think of these particular setters as optional chaining:
> 
> person.residence?.address = "1 Infinite Loop"
> 
> Where the `address` is not set when `residence` is nil. So it’s like the array is nil/not defined if you access it out of bounds.

I really like that! I think the optional chaining syntax would make the semantics crystal clear
// note the ? after subscript
subscript?(index: Index) -> Element? {…}

var foo = [1] // normal
var bar = foo?[2] // returns an Int?, just like with [Int]?
foo?[2] = 3 // performs assignment if possible, just like with [Int]?

I don’t know what it would take to get the “?” to apply to `[]` instead of `foo`. I have no (well, little) doubt that it’s possible, but I don’t know how hard it’d be or if it’d break anything. Off the top of my head, even though the results are just like if foo were `[Int]?`, the compiled code would not be the same. If we’re only talking about “safely” (or whatever the adverb is) indexing normal arrays, it’s not an issue because there’s nothing for the “?” to unwrap, so the programmer must be referring to the “safe” variant. With [Int]? though, are we unwrapping it? I guess we’d have to since `Optional<T>` isn’t subscriptable, so… Maybe this?
var optionalfoo:[Int]? = [1]
var bar = optionalfoo??[2] // “??”, so the optional is unwrapped *and* we use the “safe" subscript. bar = nil
var crashBar = optionalfoo?[2] // “?”, so the optional is unwrapped, but we use the normal subscript and crash

I’m not at all certain what the implications of this would be for the rest of the language, though. Hmm…


- Dave Sweeris

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160116/89919565/attachment.html>


More information about the swift-evolution mailing list