Skip to content

Commit a2a1c31

Browse files
natecook1000airspeedswift
authored andcommitted
[Proposal] Make stdlib index types Hashable (#761)
* Add proposal for making stdlib index types Hashable * Kick off review * Remove `AnyIndex` from list
1 parent e1acf61 commit a2a1c31

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Make Standard Library Index Types Hashable
2+
3+
* Proposal: [SE-0188](0188-stdlib-index-types-hashable.md)
4+
* Author: [Nate Cook](https://github.com/natecook1000)
5+
* Review Manager: [Ben Cohen](https://github.com/airspeedswift)
6+
* Status: **Active Review (November 8...14, 2017)**
7+
* Implementation: [apple/swift#12777](https://github.com/apple/swift/pull/12777)
8+
9+
## Introduction
10+
11+
Key-path expressions can now include subscripts to reference individual positions in collections and other subscriptable types, but only when the subscript parameters are `Hashable`. To provide maximum utility, the standard library index types should all have `Hashable` conformance added.
12+
13+
Swift-evolution "thread:" [[draft] Make Standard Library Index Types Hashable](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171030/040908.html)
14+
15+
## Motivation
16+
17+
You can only use subscripts in key-path expressions when the subscript parameter type is `Hashable`. This means that you can use a subscript as part of a key-path expression with an array, which uses `Int` as its index type, but not with a string, which uses a custom index type.
18+
19+
```swift
20+
let numbers = [10, 20, 30, 40, 50]
21+
let firstValue = \[Int].[0]
22+
print(numbers[keyPath: firstValue]) // 10
23+
24+
let string = "Helloooo!"
25+
let firstChar = \String.[string.startIndex]
26+
// error: subscript index of type 'String.Index' in a key path must be Hashable
27+
```
28+
29+
## Proposed solution
30+
31+
This proposal would add `Hashable` conformance to all the index types in the standard library. With that done, `[Int]`, `String`, and all other standard libary collections would have the same behavior when using subscripts in key paths.
32+
33+
## Detailed design
34+
35+
For index types that wrap an internal offset or other value, adding `Hashable` conformance will be simple. For index types that wrap another index type, such as `ReversedIndex`, `Hashable` conformance must wait until the implementation of conditional conformance is complete.
36+
37+
This is the breakdown of the standard library's index types:
38+
39+
#### Simple Index Types
40+
41+
- `Int` (already `Hashable`)
42+
- `Dictionary.Index`
43+
- `Set.Index`
44+
- `String.Index`
45+
46+
#### Wrapping Index Types
47+
48+
- `ClosedRangeIndex`
49+
- `FlattenCollectionIndex`
50+
- `LazyDropWhileIndex`
51+
- `LazyFilterIndex`
52+
- `LazyPrefixWhileIndex`
53+
- `ReversedIndex`
54+
55+
`AnyIndex`, which type erases any index type at run-time, would not be hashable since it might wrap a non-hashable type.
56+
57+
## Source compatibility
58+
59+
This is an additive change in the behavior of standard library index types, so it should pose no source compatibility burden. Specifically, this proposal does *not* change the requirements for an index type in the `Collection` protocol, so collections and custom index types that have been written in prior versions of Swift will be unaffected.
60+
61+
## Effect on ABI stability & API resilience
62+
63+
Beyond an additional conformance for the types mentioned above, this proposal has no effect on ABI stability or API resilience.
64+
65+
## Alternatives considered
66+
67+
None.
68+

0 commit comments

Comments
 (0)