4 ms·
When I see "0..n" I wonder whether the range is inclusive or exclusive of n. When I see "0..<n" I know the range is exclusive of n.
by tomfitz 9y ago
When I see "0..n" I wonder whether the range is inclusive or exclusive of n.
When I see "0..<n" I know the range is exclusive of n.
- sillysaurus3 9y agoYes, but the corresponding design decision would be "0..=n". Swift's "0...n" is a bit less obvious. Also, exclusivity is almost always what you want, so "0..n" should just default to exclusivity and "0...n" could be inclusive.
- saghm 9y agoAs an alternative opinion, I personally hate when ranges are exclusive by default. In addition to it feeling somewhat unintuitive to me that I need to use range(0, 6) to include 5, it also makes downward ranges quite awkward, e.g. needing range(5, -1) to count from 5 to 0.
- dbaupp 9y agoExclusive by default is designed to fit with 0-based indexing (0..length(v), instead 0..(length(v)-1)). That said, this thinking is less relevant in languages with iterators/ranges and doubly so ones that offer a way to explicitly, but abstractly, iterate over the indices of a vector/array. On the point of downward ranges, you can often reverse the range explicitly, rather than swapping the endpoints, like reversed(range(0, 6)) or range(0, 6)[::-1] in Python (vs. range(5, -1, -1)). Of course, this isn't nearly as syntactically nice as range(5, 0)... but that comes with its own problems: automatically iterating backwards in ranges has been really annoying every time I've encountered it (mainly in R), requiring extra care and a pile of extra ifs and/or mins & maxs.
- saghm 9y agoI understand the benefits, I just personally don't prefer it. But this is just my subjective opinion.
- mixmastamyk 9y agoIt's due to the zero-based indexing, right? In something like lua, that starts at 1, inclusive makes more sense.
- Someone 9y agoOn the other hand, it's easier to determine the number of items in a range if it is exclusive; range(n, m) contains abs(m - n) items. Also, inclusive doesn't allow you to specify empty ranges. That may mean having to add if statements to your code, making it uglier. I would prefer using notations [m,n) and [m,n], even though that uses a notation used in mathematics for a set to specify a sequence. Of course, one would want (m,n) and (m,n], too, then, but that first one probably would make parsing your language difficult.
- enqk 9y agoRight-Exclusive ranges are superior to inclusive ranges because they can represent empty ranges, which removes one rare degenerate case and not overemphasizing it. Another benefit: creating a series of right-exclusive ranges from a sequence [a, b, c, f] is easy: [a, b) [b, c) [c, f)
- borland 9y agoThis is the exact opposite to ruby, which uses `0..n` as inclusive, and `0...n` as exclusive http://stackoverflow.com/questions/9690801/difference-between-double-dot-and-triple-dot-in-range-generation http://stackoverflow.com/questions/9690801/difference-betwee... I always remembered it as "the third dot makes it bigger so it pushes the range and the last item falls off". I can't remember where that came from, perhaps related to the poignant guide: http://poignant.guide/book/chapter-3.html#section2 http://poignant.guide/book/chapter-3.html#section2 I actually find in practice the swift ranges are the only ones I can reliably use without having to stop and look up the reference syntax every time. For some reason, for me, `0..<n` reads as "0 through less than n" which signals to my brain a clear signal of an exclusive range. Then I can work from there and if it doesn't have the < symbol it must be exclusive. I suspect `0..=n` would work similarly well, but I've not seen a real language to ever do that yet
- deleted 9y ago[deleted]
- yorwba 9y ago> I suspect `0..=n` would work similarly well, but I've not seen a real language to ever do that yet This could be extended to cover `0=..=n`, `0<..=n`, `0<..<n` and `0<..=n`. You can actually define that syntax in Haskell: Prelude> let a =..= b = [a..b] Prelude> let a <..= b = [(a+1)..b] Prelude> let a <..< b = [(a+1)..(b-1)] Prelude> let a =..< b = [a..(b-1)] Prelude> (1 =..= 4, 1 <..= 4, 1 <..< 4, 1 =..< 4) ([1,2,3,4],[2,3,4],[2,3],[1,2,3])