SE-0241: Explicit Encoded Offsets for String Indices

  • What is your evaluation of the proposal?

-1

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes.

  • Does this proposal fit well with the feel and direction of Swift?

Undecided.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I used lots of languages, none of them had an explicit solution for indexing into strings.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I took some time to try to understand the problem but I have to admit that I'm not sure if I succeeded. I do understand that having a single Int as index does not work for the four different views that string supports. On the other hand, I do not see how String.Index actually solves that problem.

One of the problems I see is that String.Index does not seem to have any knownledge about the string. Thus there is no defined error behaviour for

let i = String.Index(offset: 1, within: "one")
let x = i.offset(within: "other".utf8)

I do understand that Swift has different views on strings that use different index values for the same position in the string. As shown in the previous point, the proposed solution seems to have problems here. Isn't this the main reason for not using Int as index type? I boiled down this comment to: “Users will mix up the index into different *Views or into the Collection of Characters that String is.”
With a dedicated index type that supports convertion (by retaining the string it comes from) this would indeed not be a problem.
On the other hand, the argument in the comment is not too strong in my opinion as subscript with Int is unquestioned for arrays (where array.sorted() is a “view” on array) .

TL;DR

I think String.Index is too complicated to use when the benefit is unclear.

I would be fine if String.Index was the return type for all offset calculation methods but the views should (also) accept Int as input.

This thread shows that users do not understand why you have to write

let x = "abc"
let c = x[x.index(x.startIndex, offsetBy: 2)]

instead of let c = "abc"[2].