[swift-evolution] Strings in Swift 4

Xiaodi Wu xiaodi.wu at gmail.com
Tue Jan 31 17:35:19 CST 2017


On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris <davesweeris at mac.com> wrote:

>
> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution <swift-
> evolution at swift.org> wrote:
>
>>
>> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> I think that is perfectly reasonable, but then it seems weird to be able
>> to iterate over it (with no upper bound) independently of a collection). It
>> would surprise me if
>> ```
>> for x in arr[arr.startIndex…] { print(x) }
>> ```
>> yielded different results than
>> ```
>> for i in arr.startIndex… { print(arr[i]) } // CRASH
>> ```
>> which it does under this model.
>>
>>
>> (I *think* this how it works... semantically, anyway) Since the upper
>> bound isn't specified, it's inferred from the context.
>>
>> In the first case, the context is as an index into an array, so the upper
>> bound is inferred to be the last valid index.
>>
>> In the second case, there is no context, so it goes to Int.max. Then,
>> *after* the "wrong" context has been established, you try to index an
>> array with numbers from the too-large range.
>>
>> Semantically speaking, they're pretty different operations. Why is it
>> surprising that they have different results?
>>
>
> I must say, I was originally rather fond of `0...` as a spelling, but IMO,
> Jaden and others have pointed out a real semantic issue.
>
> A range is, to put it simply, the "stuff" between two end points. A "range
> with no upper bound" _has to be_ one that continues forever. The upper
> bound _must_ be infinity.
>
>
> Depends… Swift doesn’t allow partial initializations, and neither the
> `.endIndex` nor the `.upperBound` properties of a `Range` are optional.
> From a strictly syntactic PoV, a "Range without an upperBound” can’t exist
> without getting into undefined behavior territory.
>
> Plus, mathematically speaking, an infinite range would be written "[x,
> ∞)", with an open upper bracket. If you write “[x, ∞]”, with a *closed*
> upper bracket, that’s kind of a meaningless statement. I would argue that
> if we’re going to represent that “infinite” range, the closest Swift
> spelling would be “x..<“. That leaves the mathematically undefined notation
> of “[x, ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x”
> (which by similar reasoning can’t mean "(∞, x]”) return one of these:
>
> enum IncompleteRange<T> {
>     case upperValue(T)
>     case lowerValue(T)
> }
>
> which we could then pass to the subscript function of a collection to
> create the actual Range like this:
>
> extension Collection {
>     subscript(_ ir: IncompleteRange<Index>) -> SubSequence {
>         switch ir {
>         case .lowerValue(let lower): return self[lower ..< self.endIndex]
>         case .upperValue(let upper): return self[self.startIndex ..<
> upper]
>         }
>     }
> }
>
>
I understand that you can do this from a technical perspective. But I'm
arguing it's devoid of semantics. That is, it's a spelling to dress up a
number.

What is such an `IncompleteRange<T>` other than a value of type T? It's not
an upper bound or lower bound of anything until it's used to index a
collection. Why have a new type (IncompleteRange<T>), a new set of
operators (prefix and postfix range operators), and these muddied semantics
for something that can be written `subscript(upTo upperBound: Index) ->
SubSequence { ... }`? _That_ has unmistakable semantics and requires no new
syntax.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170131/4211f812/attachment-0001.html>


More information about the swift-evolution mailing list