> On Jul 2, 2016, at 11:40 AM, Jens Alfke via swift-users > <swift-users@swift.org> wrote: > > It’s hard to handle empty collections, otherwise. If endIndex were the last > valid subscript, then in an empty collection what would its value be? > Presumably it would have to point to one before the start, which is rather > weird because that’s never a valid index (in an int-indexed collection it > would be negative.) Even worse, endIndex is never reachable from startIndex, > so an iteration can’t simply continue until it reaches the endIndex. Instead > the Indexable type would have to implement a (cheap, constant-time) >= > operator to use as the test for an iteration.
To add to Jens's point, all of this adds up to simplify iterating over a collection with a `while` loop (remember, all loops are `while` loops eventually): // Without invalid endIndex: var index = c.startIndex var done = c.isEmpty while !done { ... if index == c.endIndex { done = true } else { index = c.index(after: index) } } // With invalid endIndex: var index = c.startIndex while index != c.endIndex { ... index = c.index(after: index) } There are even more reasons than this one. For instance, having `endIndex` be past the end means that `insert(_:at:)` can insert after the last element of the collection, in addition to before any other element. It gives other range-based APIs similar powers. It means that `distance(from: startIndex, to: endIndex)` is the count of the elements in the collection. It means you natively use `Range` instead of `ClosedRange`, which (perhaps counterintuitively) is easier to reason about. And so on. The manuscripts of famed computer scientist Edsger Dijkstra include a little note about ranges and zero-based indexes; its logic is intimately related to this: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html -- Brent Royal-Gordon Architechies _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users