[swift-evolution] Strings in Swift 4

Dave Abrahams dabrahams at apple.com
Thu Feb 2 13:19:19 CST 2017


on Thu Feb 02 2017, Matthew Johnson <swift-evolution at swift.org> wrote:

>> On Feb 2, 2017, at 9:45 AM, Dave Abrahams <dabrahams at apple.com>
> wrote:
>> 
>> 
>> 
>> 
>
>> 
>> On Feb 2, 2017, at 7:11 AM, Matthew Johnson <matthew at anandabits.com <mailto:matthew at anandabits.com>> wrote:
>> 
>>>> 
>>>>> 
>>>>> Furthermore, we emphatically do *not* need to make the
>>>>> distinction you claim between “infinite” and “incomplete” ranges,
>>>>> which *is* needless hairsplitting.
>>>> 
>>>> Strongly disagree, unless you can describe the semantics of the type WITHOUT giving it different semantics depending on how it is used.
>>> 
>>> This is the point that convinced me.  I’m going to take a closer
>>> look at Brent’s `RangeExpression` design which I must admit I only
>>> skimmed in the earlier discussion.
>> 
>> We already have exactly this situation with CountableRange (which
>> will merge with Range when conditional conformances land).  When
>> used as a Collection, it means "every index value starting with the
>> lowerBound and ending just before the upperBound".  When used for
>> slicing, it means, roughly, "take every one of the collection's
>> indices that are in bounds.”
>
> I don’t see how the behavior of the following code means roughly “take
> every one of the collection’s indices that are in bounds”.  Can you
> elaborate?
>
> let range = 0..<20
> let array = [1, 2, 3]
> let slice = array[range] // trap on index out of bounds

“Roughly” means “I'm leaving out the part that it's a precondition that
any (explicit) bound must be a valid index in the collection.”  

>> These are not the same thing.  A collection's indices need not
>> include every expressible value of the Index type between startIndex
>> and endIndex.
>
> Sure, but it does appear as if the behavior of slicing assumes that
> the upper and lower bounds of the range provided are valid indices.

Properly stated, it's a precondition.  This is a design decision.  We could
have made slicing lenient, like Python's:

     >>> [1, 2][50]
     <Exception Backtrace>
     >>> [1, 2][5:10]
     []

We thought that in Swift it was more important to catch potential errors
than to silently accept

    [1, 2][5..<10]

we still have the option to loosen slicing so it works that way, but I
am not at all convinced it would be an improvement.

> Xiaodi had convinced me that a one-sided range must take a position on
> whether or not it has an infinite upper bound in order to make sense,
> but now you’ve changed my mind back.

Phew!  To be clear:

  A one-sided range is *partial*.  It *has no* upper bound.

>> The whole point of the name RangeExpression is to acknowledge this
>> truth: ranges in Swift bits of syntax whose meaning is given partly
>> by how they are used.
>
> This makes sense and is roughly the position I started with.  I should
> have read through the archives of this thread more before jumping into
> the middle of the discussion - I was missing some important context.
> I apologize for not doing so.

No apology needed.  I really appreciate how everyone on this list works
hard to discover the underlying truth in Swift's design.  Without that
kind of engagement, Swift would be far worse off.

Thanks, everybody

-- 
-Dave



More information about the swift-evolution mailing list