Offset Indexing and Slicing

I've come across this recently and I was surprised that the discussion veered in the direction of more complexity/duplicating the existing functional programming interfaces rather than ship sorely needed syntactical assistance for the .index(…offsetBy:…) family of methods.

Having had to do some heavy string manipulation, I've been absolutely surprised by the amount of friction I encountered, and I believe a simplification of that syntax is sorely needed, even if it takes the form of .first + 3....last - 1 — it isn't as powerful as .indices.filter(where:), but it is a quality of life improvement that does not preclude stronger solutions and would address a non-insignificant amount of cognitive load.

Is there some way forward for this?


The pitch went into review in and was returned for revision in SE-0265.

Maybe you can check out the discussion there, as well as the rationale for decision. If you think there's something new that can be added, maybe you can also start a new thread.


I also have similar problem, and ended up rolling my own subscript[offset: Range<Int>].

1 Like


In effect, it would be really nice to be able to mix an OffsetBound with an Index in some kind of range expression. But doing so may require re-thinking everything from Swift's subscript syntax to new hierarchies of range expressions. This sorta blew open the investigation area to a degree where I was unable to make progress at that time, and it could be a while before I can re-visit this.


I think it's inarguable that solving index-relative offsetting is a Really Hard™ problem. It's really hard to come to a decision about what "relative" should mean here, and it might be really hard to solve the Comparable conformance problem we're stuck with in RangeExpression.

In that case, might it not be sensible to ask whether it's at all likely that any future relative offset solution would require a source-breaking change to the current limited proposal, and would the answer to that not be a pretty big "no, not likely"?

In that case, might it not be sensible to ask for a re-review of the current proposal, with the above in mind? The longer this problem goes unsolved, the greater the accumulated pain to developers, and the better an incomplete solution starts to sound.


This is a good proposal and we definitely need something like this. What I like about Python's str[10:-3] approach is that is easy to read but as was pointed out, is not possible to be performant on strings. Adding the [.start+5....end-3] at the beginning of the word is more difficult to read, then adding the range operator leads needing grouping parenthesis to the make the plus clear that we are offsetting.

I propose this could be done with labeled parameters in subscripts we have today, and would still emphasize the offset nature of the indexes:

str[startIndex: +10, endIndex: -5]  // 10 from start, five from end
str[startIndex: +10, length: 3]     // 10 from start goes for 3
str[startIndex: +10]                // 10 from start goes to end
str[startIndex: -10]                // start ten from end of string. 
str[endIndex: -5]                   // beginning to 5 from end.    
str[endIndex: +5]                   // start to end index five from beginning
str[length: 3]                      // first three chars. 
str[]                               // go from start to end like python [:] and create a substring. 

The plus would be optional, and could be a convention, but I think it might make it clearer the intent. I think It is hard to express cleanly with the range operator. This gives a lot of the power of the Python slice while making offsets clear.The plus and minus work the same as python. Plus means from beginning offset, minus means from end index. This will be familiar to python and ruby programmers.