+1 it seems like a generic type just for the sake of it. Many languages do without a specific type for distance and use Int and it is a better solution because it is simpler.
-- Howard. > On 9 Nov 2017, at 8:37 am, Ben Cohen via swift-evolution > <swift-evolution@swift.org> wrote: > > > Hi Swift Evolution, > > A pitch for review, aimed at simplifying generic Collection algorithms. > > Online copy here: > > https://github.com/airspeedswift/swift-evolution/blob/5d1ffda2e83f5b95a88d5ce3948c5fd0d59622f4/proposals/NNNN-eliminate-indexdistance.md > > # Eliminate `IndexDistance` from `Collection` > > * Proposal: [SE-NNNN](NNNN-eliminate-indexdistance.md) > * Authors: [Ben Cohen](https://github.com/airspeedswift) > * Review Manager: TBD > * Status: **Awaiting review** > * Implementation: > [apple/swift#12641](https://github.com/apple/swift/pull/12641) > > ## Introduction > > Eliminate the associated type `IndexDistance` from `Collection`, and modify > all uses to the concrete type `Int` instead. > > ## Motivation > > `Collection` allows for the distance between two indices to be any > `SignedInteger` type via the `IndexDistance` associated type. While in > practice the distance between indices is almost always > an `Int`, generic algorithms on `Collection` need to either constrain > `IndexDistance == Int`, or write their algorithm to be generic over any > `SignedInteger`. > > Swift 4.0 introduced the ability to constrain associated types with `where` > clauses > ([SE-142](https://github.com/apple/swift-evolution/blob/master/proposals/0142-associated-types-constraints.md)) > and will soon allow protocol constraints > to be recursive > ([SE-157](https://github.com/apple/swift-evolution/blob/master/proposals/0157-recursive-protocol-constraints.md)). > With these features, > writing generic algorithms against `Collection` is finally a realistic tool > for intermediate Swift programmers. You no longer need to know to > constrain `SubSequence.Element == Element` or `SubSequence: Collection`, > missing constraints that previously led to inexplicable error messages. > > At this point, the presence of `IndexDistance` is of of the biggest hurdles > that new users trying to write generic algorithms face. If you want to > write code that will compile against any distance type, you need to > constantly juggle with explicit type annotations (i.e. you need to write `let > i: > IndexDistance = 0` instead of just `let i = 0`), and perform `numericCast` to > convert from one distance type to another. > > But these `numericCasts` are hard to use correctly. Given two collections > with different index distances, it's very hard to reason about whether your > `numericCast` is casting from the smaller to larger type correctly. This > turns any problem of writing a generic collection algorithm into both a > collection _and_ > problem. And chances are you are going to need to interoperate with a method > that takes or provides a concrete `Int` anyway (like `Array.reserveCapacity` > inside > `Collection.map`). Much of the generic code in the standard library would > trap if ever presented with a collection with a distance greater than > `Int.max`. > Additionally, this generalization makes specialization less likely and > increases compile-time work. > > For these reasons, it's common to see algorithms constrained to > `IndexDistance == Int`. In fact, the inconvenience of having to deal with > generic index > distances probably encourages more algorithms to be constrained to `Index == > Int`, such as [this > code](https://github.com/airspeedswift/swift-package-manager/blob/472c647dcad3adf4344a06ef7ba91d2d4abddc94/Sources/Basic/OutputByteStream.swift#L119) > in > the Swift Package Manager. Converting this function to work with any index > type would be straightforward. Converting it to work with any index distance > as well would be much trickier. > > The general advice from [The Swift Programming > Language](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID309) > when writing Swift code is to encourage users to stick to using `Int` unless > they have a special reason not to: > > > Unless you need to work with a specific size of integer, always use `Int` > > for integer values in your code. [...] `Int` is preferred, even when the > > values to be stored are known to be nonnegative. A consistent use of Int > > for integer values aids > code interoperability, avoids the need to convert between different number > types, and matches integer type inference[.] > > There are two main use cases for keeping `IndexDistance` as an associated > type rather than concretizing it to be `Int`: tiny collections that might > benefit from tiny distances, and huge collections that need to address > greater than `Int.max` elements. For example, it may seem wasteful to force a > type that presents the bits in a `UInt` as a collection to need to use a > whole `Int` for its distance type. Or you may want to create a gigantic > collection, such as one backed by a memory mapped file, with a size great > than `Int.max`. The most likely scenario for this is on 32-bit processors > where a collection would be constrained to 2 billion elements. > > These use cases are very niche, and do not seem to justify the considerable > impedance to generic programming that `IndexDistance` causes. Therefore, > this proposal recommends removing the associated type and replacing all > references to it with `Int`. > > ## Proposed solution > > Scrap the `IndexDistance` associated type. Switch all references to it in the > standard library to the concrete `Int` type: > > ```swift > protocol Collection { > var count: Int { get } > func index(_ i: Index, offsetBy n: Int) -> Index > func index(_ i: Index, offsetBy n: Int, limitedBy limit: Index) -> > Index? > func distance(from start: Index, to end: Index) -> Int > } > // and in numerous extensions in the standard library > ``` > > The one instance where a concrete type uses an `IndexDistance` other than > `Int` in the standard library is `AnyCollection`, which uses `Int64`. This > would be changed to `Int`. > > ## Source compatibility > > This can be split into 2 parts: > > Algorithms that currently constrain `IndexDistance` to `Int` in their `where` > clause, and algorithms that use `IndexDistance` within the body of a > method, can be catered for by a deprecated typealias for `IndexDistance` > inside an extension on `Collection`. This is the common case. > > Collections that truly take advantage of the ability to define non-`Int` > distances would be source-broken, with no practical way of making this > compatible in a 4.0 mode. It's worth noting that there are no such types in > the Swift source compatibility suite. > > ## Effect on ABI stability > > This removes an associated type and changes function signatures, so must be > done before declaring ABI stability > > ## Alternatives considered > > None other than status quo. > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution