Hacker News new | past | comments | ask | show | jobs | submit login

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.




Yes, 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.


This is the exact opposite to ruby, which uses `0..n` as inclusive, and `0...n` as exclusive

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

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


> 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])


As 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.


Exclusive 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.


I understand the benefits, I just personally don't prefer it. But this is just my subjective opinion.


Right-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)


On 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.


It's due to the zero-based indexing, right? In something like lua, that starts at 1, inclusive makes more sense.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: