9

C# 8 added the ranges syntax to C#:

var slice = myArray[0..2];

What I find not so intuitive is that the upper bound (2 in the previous example) is exclusive - not inclusive; i.e. myArray[0..2] returns a slice with 2 elements (0 and 1), not with 3 elements.

So my question is: Why did the C# language designers choose to make the upper bound exclusive?

Both the ranges documentation as well as the design champion issue simply state that the upper bound is exclusive - without giving any explanation as to why (at least none that I could find). There also was a discussion about this on GitHub but it also doesn't seem to contain any official explanation.

By searching StackOverflow I stumbled across the same question for Python. Python also treats the upper bound as exclusive. So I can imagine that the C# language designers were looking at other languages (that have ranges) and were trying to make C#'s behavior consistent with other languages. But I'm still wondering if there is any official documentation on this decision.

Sebastian Krysmanski
  • 8,114
  • 10
  • 49
  • 91
  • 1
    if there _were_ any official documentation anyone on SO could provide, it most likely _would_ have been officially documented somewhere to find. so i bet you'll only get guesses here, too. mine is: because it's interpreted as "starting at element (start), give me an array the _size_ of (end-start)" - so in this case, a two-element array. – Franz Gleichmann Sep 28 '20 at 05:48
  • 1
    Probably because it makes the most sense when using a range with a zero-based array - `0` is the start, and `array.Length` is the end. With `0`-based arrays, `maxIndex` is `Length - 1`. This follows that same idea. Note also that `Random.Next(min, max)` has similar constraints (`min` is inclusive, `max` is exclusive). – Rufus L Sep 28 '20 at 06:24
  • 1
    [EWD831](https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html) (Dijkstra, 1982) – Damien_The_Unbeliever Sep 28 '20 at 06:52
  • So you can easily represent an empty range, among other things. Mathematically, half-open intervals are much better for this kind of thing. – Matthew Watson Sep 28 '20 at 08:35

1 Answers1

15

There are a lot of design decisions that just won't have satisfying answers. However, this one at least has a paper-trail you can follow in the design notes (in one or more mentions) starting at the following link.

Note : This was just an arbitrary decision, the reason they chose exclusive is because they chose exclusive. It could easily not have been the case due to the pros and cons.

C# Language Design Notes for Jan 22, 2018

...

Conclusion

Let us go with .. means exclusive. Since we've chosen to focus on the indexing/slicing scenario, this seems the right thing to do:

  • It allows a.Length as an endpoint without adding/subtracting 1.
  • It lets the end of one range be the beginning of the next without overlap
  • It avoids ugly empty ranges of the form x..x-1

And as @vc74 mentions in the comments and also stated in the document supplied, other languages like Python follow this convention, however others don't.

halfer
  • 19,824
  • 17
  • 99
  • 186
TheGeneral
  • 79,002
  • 9
  • 103
  • 141