# Add accessor with bounds check to Array

**URL:** <https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871>\
**Category:** Pitches\
**Tags:** collection\
**Created:** [October 10, 2018, 8:12pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871 "2018-10-10T20:12:08Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![maven](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/maven/32/688_2.png) [@maven](https://forums.swift.org/u/maven)\
**Post date:** [October 22, 2018, 11:49am UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/21 "2018-10-22T11:49:46Z")

</div>

> [@Tino](#):
>
> When a collection can be changed while you are working in it

Just to be clear, I wasn't talking about concurrent change (which leads to undefined behavior if not synchronized anyway -- as you say), but modification through nominally sequential program flow.

---

<div class="post-metadata">

**Author:** ![antonthehuman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/antonthehuman/32/3356_2.png) [@antonthehuman](https://forums.swift.org/u/antonthehuman)\
**Post date:** [October 22, 2018, 12:31pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/22 "2018-10-22T12:31:02Z")

</div>

+1 from me. And my personal top for syntax is the one in starter post, because it produces less ambiguity, and is convenient with some other languages I use, and is shorter also.

---

<div class="post-metadata">

**Author:** ![Dante-Broggi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dante-broggi/32/7955_2.png) [@Dante-Broggi](https://forums.swift.org/u/Dante-Broggi)\
**Post date:** [October 22, 2018, 8:57pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/23 "2018-10-22T20:57:44Z")

</div>

I do think this may be worthwhile as an addition. However, I would spell it:

```swift
extension RandomAccessCollection { // or Array specifically
    subscript (at index: Index) -> Element? {
        return self.indices.contains(index) ? self[index] : nil
    }
}

```

Additionally, for a use case where this would be valuable is if one is processing a multidimensional collection and have an algorithm that uses each inner element and all of its neighbors. In such a case the handling of the literal edge cases would obfuscate the algorithm without such an accessor:

```swift
func foo(arr: [[Int]]) {
    for outerIdx in arr.indices {
        let outer = arr[outerIdx]
        for innerIdx in outer.indices {
            let center = outer[innerIdx]
            // do the following without [at:]
            let left = outer[at: innerIdx - 1] ?? 0 // some default
            let right = outer[at: innerIdx + 1] ?? 0 // some default
            let up = arr[at: outerIdx - 1]?[at: innerIdx] ?? 0 // some default
            let doun = arr[at: outerIdx + 1]?[at: innerIdx] ?? 0 // some default
            
            /// ...
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![Jens](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jens/32/12903_2.png) [@Jens](https://forums.swift.org/u/Jens)\
**Post date:** [October 24, 2018, 5:18am UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/24 "2018-10-24T05:18:26Z")

</div>

I agree that `arr[at:]` is the best spelling so far.

> [@Chris\_Lattner3](#):
>
> the most frequently suggested spelling for this is: `yourArray[safe: idx]` , which seems great to me. I am very +1 for adding this.

Both `arr[checked:]` and `arr[safe:]` imply that the existing unlabeled subscript is _unchecked_ and _unsafe_, which is incorrect.

The existing unlabeled subscript is both _safe_ and _checked_. It is _safe_ (in the sense Swift uses the word) because it _checks_ whether the given index is within bounds and traps otherwise.

An unsafe or unchecked version of the subscript would not do any bounds check (for efficiency I guess) and have undefined behavior for out of bounds indices.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [October 24, 2018, 9:54am UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/25 "2018-10-24T09:54:42Z")

</div>

> [@Tino](#):
>
> init(serverStrings: [String]) {  
> self.value0 = serverStrings[checked: 0] ?? ""  
> self.value1 = serverStrings[checked: 1] ?? "n/a" //...  
> }

IMO, the "Swifty" way to write this would be:

```swift
init(serverStrings: [String]) { 
  var remainingStrings = serverStrings[...]
  self.value0 = remainingStrings.first ?? ""
  remainingStrings = serverStrings.dropFirst()
  self.value1 = remainingStrings.first ?? "n/a"
  // ...
}

```

It doesn't read as nicely, but that's generally how we do incremental parsing in Swift.

It might be nicer if there was a `popFirst()` method on `Slice<T>`, returning an Optional. Currently there is only `popLast()` which returns an Optional, and `remove{First/Last}()` which return non-Optionals and trap if the Collection is empty.

```swift
init(serverStrings: [String]) { 
  var remainingStrings = serverStrings[...]
  self.value0 = remainingStrings.popFirst() ?? ""
  self.value1 = remainingStrings.popFirst() ?? "n/a"
  // ...
}

```

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [October 24, 2018, 10:07am UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/26 "2018-10-24T10:07:43Z")

</div>

> [@Karl](#):
>
> It might be nicer if there was a `popFirst()` method on `Slice<T>` , returning an Optional.

Using an iterator of the slice might do the job... but servers often do stupid things ;-): What is when you only need the 3rd and 7th element?  
Maybe it's not the best example, but I think there are valid reasons to generalize the behavior of `first` and `last`.

---

<div class="post-metadata">

**Author:** ![andrekandore](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andrekandore/32/2292_2.png) [@andrekandore](https://forums.swift.org/u/andrekandore)\
**Post date:** [October 26, 2018, 7:30am UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/27 "2018-10-26T07:30:06Z")

</div>

I agree, with others, `[safe:]` has too many connotations and that `[at:]` seems better.

Just throwing my 2¢ in: what i usually use is `any(at:)` since its almost like asking "is there any item at" this index.

```
if array.any(at: 3) {
  // do something 
}

guard let anItem = items.any(at: 4) else {
    return
}

```

Its hard to express intent in a subscript... but if its gonna be in a subscript personally `[at:]` seems the best so far... jmo

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [October 26, 2018, 7:50am UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/28 "2018-10-26T07:50:51Z")

</div>

Imho we shouldn't forget that subscripts don't have to be read-only - and they can't throw (yet?).  
A setter could either throw, or append (or even insert, if the index is negativ).

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [October 26, 2018, 3:49pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/29 "2018-10-26T15:49:12Z")

</div>

Specifically on the name: `at` doesn't tell you how it's different from a normal subscript, which also gives you the element "at" an index. The only reason I can think of to use `at` is because C++ used it, but C++ uses it for the bounds-checked subscript (implemented as a reference-returning method) rather than the non-bounds-checked one (the default).

---

<div class="post-metadata">

**Author:** ![jarod](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jarod/32/364_2.png) [@jarod](https://forums.swift.org/u/jarod)\
**Post date:** [October 26, 2018, 8:06pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/30 "2018-10-26T20:06:42Z")

</div>

I very much agree with Jordan that `at` has no semantic difference from an unlabeled subscript. I think it's important to convey the behavioral difference of the API in the spelling.

Constraining the term "safe" to memory safety is unnecessary imo -- it's easy to say "memory safe" in a context that needs clarification. In the context of any given operation in Swift, I think "safe" can naturally generalize to mean "this won't mess up my program due to a programming error". It's a good term for this API in that sense, and would likely be useful in other areas as well.

With that said, here's my attempt at brainstorming for other spellings (including some suggested by others) that try to keep in mind all of the concerns that I've seen come up in the thread:

- Don't use "checked", since the unlabeled subscript is also checked.
- Don't use "safe", since that means memory safe.
- Convey the difference in functionality from the unlabeled subscript, which is that it returns nil instead of trapping on an out-of-bounds index.

I've also broken the spellings into groups based on what the subscript label is actually referencing, which I think is an important distinction to keep in mind.

Label references the index parameter:

- `values[potential: index]`
- `values[possible: index]`
- `values[maybeOutOfBounds: index]`
- `values[unvalidated: index]` (referencing that the index is unvalidated by the programmer rather than the API itself)

Label references the operation itself:

- `values[failable: index]`
- `values[untrapping: index]` or `values[nontrapping: index]`

Label references the return value:

- `values[optional: index]`
- `values[nilIfOutOfBounds: index]`

We could also use a method rather than a subscript (though I'd personally prefer to keep the subscript to maintain symmetry with the unlabeled subscript):

- `values.potentialElement(at: index)`
- `values.possibleElement(at: index)`
- `values.optionalElement(at: index)`

imo, these are all clunky or confusing in different ways.

I'm not aware of any official guidelines on subscript label naming, but the only one that I know of in the standard library (`dictionary[key, default: value]`) takes the approach of referencing the parameter rather than the operation or return value, which is also what makes the most sense to me. Admittedly, `safe` as a subscript can be thought of as referencing the operation, but I think it's equally valid to say that it references the safety of the index itself.

---

<div class="post-metadata">

**Author:** ![Jens](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jens/32/12903_2.png) [@Jens](https://forums.swift.org/u/Jens)\
**Post date:** [October 26, 2018, 8:55pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/31 "2018-10-26T20:55:49Z")

</div>

I agree that `values[at: index]` is not perfect because it doesn't say how/that it's different than `values[index]`.

But I think `values[safe: index]` is as bad as `values[checked: index]`. The term "safe" is used to describe the language (_Swift makes it easy to write software that is incredibly fast and safe by design._), hence Swift's regular array subscript has been designed to be _safe_ (by trapping if its out of bounds check fails), and it's also used consistently afaics in the language for things like `UnsafePointer`, `unsafeBitCast`, `unsafeDowncast`, `withUnsafeBytes`, etc, just like the term "(un)checked" is consistently used, in eg:

```swift
let a = Range(uncheckedBounds: (lower: 123, upper: -1))
print(a) // 123..<-1

```

It would be unfortunate to introduce additional meanings of the words "(un)safe" and "(un)checked" in the language when there currently afaik is only one.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [October 26, 2018, 8:56pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/32 "2018-10-26T20:56:37Z")

</div>

I’d actually like a more general solution:

A way to tell the compiler “Hey, I know some code in this expression / statement / block might trap—but that’s okay and I know how to handle it, so please don’t actually trap, just return `nil` instead, thanks.”

---

<div class="post-metadata">

**Author:** ![torquato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/torquato/32/1203_2.png) [@torquato](https://forums.swift.org/u/torquato)\
**Post date:** [October 26, 2018, 9:08pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/33 "2018-10-26T21:08:59Z")

</div>

Errr… Something like

```swift
unsafe {
    // whatever
} else { return nil }

```

?

---

<div class="post-metadata">

**Author:** ![bzamayo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bzamayo/32/764_2.png) [@bzamayo](https://forums.swift.org/u/bzamayo)\
**Post date:** [October 26, 2018, 9:21pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/34 "2018-10-26T21:21:05Z")

</div>

I recall previous discussion on this topic suggesting an `arr[ifExists: index]` spelling. I'm not sure if I support that or not, just raising it to give acknowledgement to previous Evolution contributions.

---

<div class="post-metadata">

**Author:** ![jarod](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jarod/32/364_2.png) [@jarod](https://forums.swift.org/u/jarod)\
**Post date:** [October 26, 2018, 9:25pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/35 "2018-10-26T21:25:10Z")

</div>

> [@Jens](#):
>
> But I think `values[safe: index]` is as bad as `values[checked: index]` . The term "safe" is used to describe the language ( _Swift makes it easy to write software that is incredibly fast and safe by design._ ), hence Swift's regular array subscript has been designed to be _safe_ (by trapping if its out of bounds check fails), and it's also used consistently afaics in the language for things like `UnsafePointer` , `unsafeBitCast` , `unsafeDowncast` , `withUnsafeBytes` , etc, just like the term "(un)checked" is consistently used, in eg:
> 
> ```swift
> let a = Range(uncheckedBounds: (lower: 123, upper: -1))
> print(a) // 123..<-1
> 
> ```
> 
> It would be unfortunate to introduce additional meanings of the words "(un)safe" and "(un)checked" in the language when there currently afaik is only one.

Safety can be thought of in tiers -- trapping is safer than reaching into out-of-bounds memory, but returning nil is even safer than trapping, requiring the programmer to consciously deal with the optionality at the call site instead of implicitly crashing. [Swift.org - About Swift](http://swift.org/about) explicitly references optionals as a safety feature, so I don't feel that it's a stretch to call this the safer version of the API.

---

<div class="post-metadata">

**Author:** ![Jens](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jens/32/12903_2.png) [@Jens](https://forums.swift.org/u/Jens)\
**Post date:** [October 26, 2018, 9:26pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/36 "2018-10-26T21:26:28Z")

</div>

- `values[safer: index]` (the new safer version)
- `values[index]` (the safe by design default version)
- `values[unsafe: index]` (the new unsafe but fast unchecked version)
- `values[unchecked: index]` (the better named new unchecked version)

---

<div class="post-metadata">

**Author:** ![andrekandore](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andrekandore/32/2292_2.png) [@andrekandore](https://forums.swift.org/u/andrekandore)\
**Post date:** [October 26, 2018, 9:47pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/37 "2018-10-26T21:47:32Z")

</div>

what about  
` values[maybeAt: index]`  
?

admittedly, that is not following the theme of ‘safetly levels’ but i think it’s more semantic to what it’s trying to do: access something that `may be at` index `index...

---

<div class="post-metadata">

**Author:** ![Torust](https://avatars.discourse-cdn.com/v4/letter/t/f17d59/32.png) [@Torust](https://forums.swift.org/u/Torust)\
**Post date:** [October 26, 2018, 10:06pm UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/38 "2018-10-26T22:06:20Z")

</div>

Another alternative:

`values[unconstrained: index]`

since for regular indexing to index is constrained to be within `values.indices`, whereas there is no such constraint here.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [October 27, 2018, 3:22am UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/39 "2018-10-27T03:22:18Z")

</div>

> [@Nevin](#):
>
> I’d actually like a more general solution:
> 
> A way to tell the compiler “Hey, I know some code in this expression / statement / block might trap—but that’s okay and I know how to handle it, so please don’t actually trap, just return `nil` instead, thanks.”

That's not really composable, and wanting it suggests a deeper misunderstanding of why Swift encourages precondition checks for this sort of thing, which is exactly why I'm antsy about adding this: I think it has valid uses, but I think those uses are going to be vastly outnumbered by people reaching for it out of some insistence that it's better or safer.

---

<div class="post-metadata">

**Author:** ![masters3d](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@masters3d](https://forums.swift.org/u/masters3d)\
**Post date:** [October 27, 2018, 5:22am UTC](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871/40 "2018-10-27T05:22:35Z")

</div>

I think `subscript(_:default:)` would address most of the use cases.  
[https://developer.apple.com/documentation/swift/dictionary/2894528-subscript](https://developer.apple.com/documentation/swift/dictionary/2894528-subscript)

[Previous page](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871.md?page=1)

[Next page](https://forums.swift.org/t/add-accessor-with-bounds-check-to-array/16871.md?page=3)
