[swift-evolution] Optional safe subscripting for arrays

Maximilian Hünenberger m.huenenberger at me.com
Sat Jan 16 19:55:18 CST 2016


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.


In addition subscripts imply O(1) access/set so the expanding array setter should be implemented as method.

- Maximilian

> Am 17.01.2016 um 02:29 schrieb davesweeris at mac.com:
> 
> I’m definitely +1 on the getter. I have reservations on the setter. As described, this code:
> subscript(safe index: Index) -> Element? {
>     return self.indices ~= index ? self[index] : nil
> }
> subscript(clamp index: Index) -> Element? {
>     get { return self.indices ~= index ? self[index] : nil } // again, because subscripts can’t be setter-only
>     set {
>         if self.indices ~= index {
>             self[index] = newValue!
>         } else {
>             self.append(newValue!)
>         }
>     }
> }
> 
> Would lead to some counter-intuitive results.
> var foo = [0, 1, 2]
> print(foo[safe: 2]) // Optional(2)… Yep
> foo[clamp: 6] = 6
> print(foo[safe: 6]) // nil… Wait, what? I just set that to 6! Why is it nil now?
> 
> 
> Instead of just appending the new value, we could extend the array to the required capacity:
> subscript(safe index: Index) -> Element? {
>     get { return self.indices ~= index ? self[index] : nil }
>     set {
>         if self.indices ~= index {
>             self[index] = newValue!
>         } else {
>             while !(self.indices ~= index) {
>                 self.append(newValue!)
>             }
>         }
>     }
> }
> 
> The results could still be unexpected:
> var foo = [0, 1, 2]
> print(foo) 		// [0, 1, 2]… Yep
> foo[safe: 9] = 9
> print(foo[safe: 9]) 	// Optional(9)… Yep
> print(foo) 		// [0, 1, 2, 9, 9, 9, 9, 9, 9]… Wow, that’s bigger than I thought
> 
> but at least you’d be able to read from the index to which you just wrote.
> 
> - Dave Sweeris
> 
>> On Jan 16, 2016, at 14:08, Maximilian Hünenberger via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> I've also thought of this. But the concept of safe indexing can also be extended to CollectionType (or to the more abstract Indexable protocol) where it's index is Comparable.
>> 
>> For mutable Collections/MutableIndexable there could be two versions of a safe subscript set:
>> 
>> array[safe: 5] = 7 // does nothing if index out of bounds
>> 
>> array[clamp: 5] = 7
>> // if array is empty: does nothing
>> // if 5 >= array.endIndex : sets last element
>> // if index < 0 : sets first index
>> 
>> So definitely worth considering.
>> 
>> 
>> - Maximilian
>> 
>>> Am 16.01.2016 um 21:44 schrieb Rudolf Adamkovič via swift-evolution <swift-evolution at swift.org>:
>>> 
>>> Hi there!
>>> 
>>> From time to time, I find myself using safe subscripting, e.g.:
>>> 
>>> let array = [1, 2, 3]
>>> 
>>> array[safe: 0] // 1
>>> array[safe: 1] // 2
>>> array[safe: 2] // 3
>>> array[safe: 3] // nil
>>> 
>>> … with the following implementation:
>>> 
>>> subscript (safe index: Int) -> Element? {
>>>     return self.indices ~= index ? self[index] : nil
>>> }
>>> 
>>> I was wondering … wouldn’t it be handy to have this in the standard library?
>>> 
>>> Best regards,
>>> Rudolf Adamkovic
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> _______________________________________________
>> 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/20160117/7593cad3/attachment-0001.html>


More information about the swift-evolution mailing list