String slicing ergonomics

I simply want to reopen the discussion about why this:

string[string.startIndex..<string.index(string.startIndex, offsetBy: 15)]

Cannot be simply this:

string[0..<15]

Or even better:

string[..<15]

After years of using Swift I continue to have to search how to slice a string each time. It's extremely cumbersome and user-hostile.

2 Likes

In another thread (on phone so hard to look up) there is a proposal to add subscript with an argument named o (for offset) to RandomAcessCollection which would allow what you want:

string[o: 1 ... 15]
1 Like

If it were possible, then people would write things like this:

func parseFooString(_ s: String) -> [Foo] {
  var i = 8
  var result: [Foo] = []
  
  while i < s.count {
    let slice = s[i-8 ..< i]
    let newFoo = Foo(slice)
    result.append(newFoo)
    i += 8
  }

  return result
}

And the performance would be quadratic.

We really shouldn't make "__ is a complete disaster" a meme here. True as it may be it sets terrible tone for a discussion. As for this particular topic, there's been a number of threads dedicated to the topic of collection indexing ergonomics, and I think it'd be more productive to continue one of those instead of start a new one, like maybe the one here.

6 Likes

Yes, completely true. Sorry!

1 Like

So instead they now write things like this:

let slice = s[string.index(string.startIndex, offsetBy: i-8)..<string.index(string.startIndex, offsetBy: i)]
1 Like

I think neither performance nor "this doesn't work for collections with custom index type" are convincing arguments for a complicated slicing API (without a simple one on top of it):
Average Joe doesn't really care about clever algorithms that work on any collection when all he needs is a plain old array, and we all know about premature optimization (and I'd consider a cumbersome API as extreme form of evil).

Imho we should at least have something like string[string.startIndex, length: 4] which removes the burden to tell the compiler that you want to do something with string four times. At least you save 50% redundancy, and the implementation is trivial (it might already be in the stdlib - subscripts are much harder to discover than methods ;-)

I'm not sure if we really need more, because

already exists as string.prefix(14), and I don't have examples where I need slices from arbitrary positions.

4 Likes