[swift-evolution] [Pitch] Change the endIndex value for closed Ranges and Collections

Andrew Bennett cacoyi at gmail.com
Wed Mar 23 22:07:12 CDT 2016

Hi Pedro,

I'm going to refer to what you're proposing as *lastIndex* to distinguish
it from the current endIndex.

Worth considering is indexes for things like a linked list (or other
ForwardIndexType collections):

   - You can represent the endIndex in O(1) by using a nullable internally.
   - It's likely to be an O(n) operation resolve the *lastIndex* property*.*

The current system seems much cleaner to represent empty ranges:

   - How do you represent an empty range with *lastIndex*? Range(start: 0,
   end: -1) ?
   - Does this mean that UInt cannot be a ForwardIndexType, or cannot be
   used with Range, how do you show this in the protocol?

You should also consider migration in your proposal:

   - I don't think migration will be trivial, or even necessarily safely
   automated. I think the changes will be extensive.
   - Reusing the same name will likely make it confusing when people google
   Swift code, it will be unclear if code is in the old system or the new one.
   - If you do a formal proposal I recommend it proposes to deprecate the
   current system and introduce a new property with a different, clearer,
   name. I recommend *lastIndex*.

It's probably worthwhile for you to consider your proposed changes in the
context of this upcoming proposal, I think it's very likely to go ahead in
some form:


I'm in favour of having a new field:
    // for example
    var lastIndex: Index? {
        let count = self.count
        guard count > 0 else { return nil }
        return startIndex.advancedBy(count-1)

It's optional to represent an empty collection.

I'm not in favour of the proposal as it is stated. It's a fairly well
established convention for endIndex to be the index after the last element,
although perhaps it could be called something clearer. I think that
discussion is a good idea.

Andrew Bennett

On Thu, Mar 24, 2016 at 11:15 AM, Dave Abrahams via swift-evolution <
swift-evolution at swift.org> wrote:

> on Wed Mar 23 2016, Pedro Vieira <swift-evolution at swift.org> wrote:
> > Hi Swift developers,
> > I hereby present my first Swift proposal regarding the endIndex on
> > `Collections` and closed `Ranges`. I’ve searched the mailing list
> archives
> > for something similar to this but couldn’t find it, so I decided to come
> > forward.
> >
> > *The problem:*
> > I was recently working on a library and used a closed Range to define the
> > bounds of a board game and the tests that used its endIndex were all
> > failing. Started debugging it around and, to my complete surprise, found
> > out that the endIndex of the closed Ranges was always +1 from the value I
> > initially set. With this, I decided to dive into the Range source code
> and
> > discovered that all closed ranges are converted to half-open ones when
> > initialized:
> > a) 1..<10 stays 1..<10 (endIndex = 10)
> > b) 1...10 is converted to 1..<11 (endIndex = 11)
> >
> > To work around this behavior I had to subtract 1 every time I checked for
> > the endIndex, since I didn't want to use last! (force unwrapping) or
> > if-let, which ultimately polluted my code.
> Please see the work currently underway in
> https://github.com/apple/swift/blob/swift-3-indexing-model/stdlib/public/core/ClosedRange.swift
> ,
> which we intend to propose soon.  ClosedRange becomes a separate type
> that represents its upperBound without modification.
> --
> Dave
> _______________________________________________
> 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/20160324/703a4f33/attachment.html>

More information about the swift-evolution mailing list