I was going to wait until I had more first-hand experience with Swift before blogging any opinions, but then I remembered this is the Internet. So here I am, late to the party, weighing in on Swift’s range operators, about which I have a definite opinion.
Swift’s original range operators, as defined in the first beta of Xcode 6, were:
x..y for a half-closed range (including x, excluding y)
x...y for a closed range (including both x and y)
There were lots of complaints about this choice, mostly in two categories as I recall:
... are too easy to confuse with each other, the same way
== are easy to confuse in C.
... are too easy to confuse with the same operators in Ruby, which are defined with the opposite meanings.
Note that these complaints aren’t about personal taste. They’re about making it too easy to write buggy code.
Here is a complaint that absolutely nobody made, so please don’t take it too seriously, but it did occur to me as a possible annoyance:
- Complaint #3: Some people want
... to be a system macro that automatically gets replaced with an ellipsis character.
A few people, including me, have proposed this alternative, which I am still convinced is best:
x..<y for half-closed
x..=y for closed
Here’s what I like about this option:
There is a parallel structure to the operators. “..” means this is a range, followed by a qualifier, either “<” or “=”, that indicates whether the last element of the range is less than or equal to y.
Neither operator is a substring of the other. You can’t make the mistake of typing one too few characters.
The meanings of the operators are clear from their appearance (addressing Complaint #1). You won’t have to pause each time to ask yourself “Which one was the closed one again?”
The operators don’t conflict with other languages (addressing Complaint #2). When I posted my suggestion, I didn’t think either operator had a precedent in any other language. It turns out
..< is used in Groovy, but it has the same meaning there as here.
In Xcode 6 beta 3, one of the range operators was changed. As of this writing, the operators are:
x..<y for half-closed
x...y for closed
This is fine with me, although I may change my mind if I ever start programming in Ruby. By only changing one of the two operators, the Swift designers leave them half-open, if you will, to Complaint #2.
I want to mention one more proposed alternative that seems nice in theory but that I don’t think should be adopted:
- [x..y) for half-closed
- [x..y] for closed
This notation is already familiar to people with a little math, and easily learnable by anyone else. It’s concise. It’s unambiguous. It allows for the possibility of variations like
But I think it could be open to Complaint #1. Depending on the font the programmer is using, and the resolution of their monitor, and how sleep-deprived they are, a parenthesis could maybe be mistaken for a square bracket. Or the difference might not be striking enough to register when they’re eyeballing the code, looking for why the program crashed.
Furthermore, I think mismatched brackets and parentheses could cause headaches in text editors other than Xcode. When we see an expression like that, we’re used to being able to double-click one of the delimiters to select the whole expression. I don’t know, maybe existing text editors could easily be updated to handle that, but it seems like a potential problem to me, and I do think this kind of consideration should influence language design. It’s worth looking for an option that both makes theoretical sense and plays well with the tools we use in practice.
 To the extent there is any such person other than Chris Lattner.