[swift-evolution] [Review] SE-0065 A New Model for Collections and Indices

Dave Abrahams dabrahams at apple.com
Tue Apr 12 16:42:01 CDT 2016

on Mon Apr 11 2016, Brent Royal-Gordon <brent-AT-architechies.com> wrote:

>>> If these types are for implementation sharing, should they be
>>> underscored to discourage their use? Or is the position they occupy in
>>> the type hierarchy important because Range and ClosedRange will
>>> eventually occupy them?
>> Underscoring hides names from users completely, and IMO that would not
>> be appropriate here.  If we underscored them, it would be mysterious
>> where an implementation of various methods came from.
> If the concrete types show these members, does it matter that they
> actually came from a protocol?

I don't know; would the concrete types show these members?

>>> On the other hand, it's not like the SubSequence subscript now takes a
>>> RangeProtocol. Should it?
>> No; subscript can't be generic (language limitation).
> Right, and RangeProtocol isn't existential. Ouch.
>>>> func successor(of i: Index) -> Index
>>> Two things:
>>> 1. I would really like a version of this which returns Optional and is
>>> guaranteed to go `nil` once it hits `endIndex`. 
>> The primary question to answer when exploring this idea is, IMO, “what
>> does that do to the code in algorithms?”  I can't imagine writing binary
>> search, partition, or rotate if I had to check for nil every time I
>> moved an index.
> If you're confident you're remaining in bounds, you should
> force-unwrap it.

s/check for nil/force unwrap/

>>> There can be a non-optional version too, or it might even be a feature
>>> of the `index` family of methods instead of `successor` itself, but I
>>> think it would be valuable to let the collection worry about the
>>> bounds check.
>> Why would that be valuable?
>>> It seems silly to check the index before calling `successor(of:)` when
>>> `successor(of:)` is going to immediately perform the same check again
>>> as a precondition.
>> Preconditions are not necessarily checked.  We don't promise to trap
>> every precondition violation.  We promise memory and type safety in the
>> absence of data races, and some precondition failures will trap in order
>> to ensure that.  Others will trap, where we think it is affordable, just
>> to provide a better programmer experience.
> I understand that, but many—perhaps most—clients of APIs like
> `successor(of:)` will need to perform a bounds check. 

Why do you say so?

> I think we would be better off if the check were implicit in the
> call. That would force all clients, or at least all clients which used
> the bounds-checking variants (which would be encouraged), to
> explicitly handle out-of-bounds conditions, in much the same way that
> `index(of:)` forces its clients to explicitly handle the possibility
> that a matching element might not exist, rather than returning
> `endIndex` (which would be easier).

I think we agree that the proposed index method that takes a limit
should return optional.  Dmitri's going to explain more in his response.

>>> 	collection.index(5, from: i)
>> I don't think this one reads clearly enough.
> "The index 5 from i" reads fine to me, but I guess that's a matter of opinion.
>>> 	collection.traveling(5, from: i)
>>> 	collection.striding(5, from: i)
>>> 	collection.advancing(i, by: 5)
>> None of the “ing” names work, IMO because that suffix suggests you're
>> returning a modified version of the receiver.
> Huh, that clarifies something. How about the non-`ing` variants?
> 	collection.travel(5, from: i)
> 	collection.stride(5, from: i)
> 	collection.advance(i, by: 5)

Active verb phrases are reserved for methods with side-effects according
to the API guidelines.

> I'd say `stride` might be an attractive nuisance in this form
> (although if Strideable's public face becomes `Self.striding(by:)`,
> only to Swift 2 users) but the others look fine to me.

I'm going to leave the rest of this for Dmitri, at least for the time

More information about the swift-evolution mailing list