I'm conflicted here. I know this is a really common pain point, and I would like for the tools to meet those peoples' needs. At the same time, Swift's approach is correct, robust, and really underappreciated. I wish those users had a better awareness that this area has complex trade-offs, and understood the rationale behind Swift's take on it.
I don't want to be an out-of-touch Principle Skinner, but I'm still trying to teach others that these concepts are not as simple as they've been mislead to think from other languages.
Fundamentally, this boils down to a trade off of:
- Correctness
- Performance
- Familiarity/Ergnomics
Pick any 2.
Most other languages inherit C's notion of a String being a contiguous sequence of fixed-size code points (be they 8 bits, 16, w/e). This hits 2 and 3, but is completely and irreparably incorrect when it comes to handling foreign languages. Funny enough, it was ultimately Emoji (of all things, silly little pictograms!) that made devs care about unicode correctness.
I think that the majority of the drive behind String indexing comes from two main factors:
- Other languages where string indices are the only way to iterate a String, e.g. C. If you can just natively iterate a String (e.g.
for c in string { ... }
, this need for integer indices goes away completely.
- Programming problems like interview questions and Advent of Code, which perform rather rare/unusual transformations on simplistic string inputs, which don't have any of the complexities of real human text, which Swift's strings are optimized for.
My frustration is why we have to use the verbose index-advancing method to access the characters of a string.
This is the exact wrong takeaway, I'm afraid.
This is not merely a "you're holding it wrong" situation. If you're trying to do greeting[0]
but can't, the solution isn't to write some more boilerplated version of the same flawed idea (greeting[greeting.startIndex]
). It's entirely the wrong tool, regardless of how it's held/spelled.
In this example, it's to just use greeting.first
(which even handles empty strings safely).
To me, the most frustrating irony of this situation is that even in other languages, if you want to handle non-English text correctly, you need renounce their standard library (and the given indexing operator), and use third-party libraries that do it correctly. And to no surprise, those libraries employ the same techniques that Swift encourages to begin with.