On Mon, Jan 17, 2022 at 09:37:31PM +0000, forkit via Digitalmars-d-learn wrote: > On Monday, 17 January 2022 at 11:58:18 UTC, Paul Backus wrote: > > > > This kind of half-open interval, which includes the lower bound but > > excludes the upper bound, is used in programming because it lets you > > write > > > > foreach (i; 0 .. array.length) writef("%s ", array[i]); > > > > ...without going past the end of the array. > > Yes. But the intent here is clearly stated and cannot be misunderstood > -> array.length > > Whereas 1..5 is just an opportunity to shoot yourself in the foot.
The compiler cannot discern intent. Both `5` and `array.length` are expressions, as far as the compiler is concerned. So is `5 + (array.length - sin(x))/2*exp(array2.length)`, for that matter. The compiler does not understand what the programmer may have intended; it simply follows what the spec says. Of course, to a *human* the semantics of `1..5` can be totally confusing if you're not used to it. The bottom-line is, in D (and in other C-like languages) you just have to get used to 0-based indexing, because ultimately it actually makes more sense than the 1-based counting scheme we were taught in school. 1-based counting schemes are full of exceptions and off-by-1 errors; it's needlessly complex and hard for the mortal brain to keep track of all the places where you have to add or subtract 1. Whereas in 0-based index schemes, you *always* count from 0, and you always use `<` to check your bounds, and you can do arithmetic with indices just by adding and subtracting as usual, without off-by-1 errors. Basically, foreach (i; a .. b) is equivalent to: for (auto i = a; i < b; i++) Just think of that way and it will make sense. And never ever write 1..n unless you actually intend to skip the first element. Remember: 0-based counting, not 1-based counting. You always start from 0, and count up to (but not including) n. Which also means you should always write `<`, never write `<=`. So your upper bound is always the element *past* the last one. I.e., it's the index at which a new element would be added if you were appending to your list. I.e., the index at which a new element should be added is simply array.length (not array.length+1 or array.length-1 or any of that error-prone crap that nobody can remember). If you adhere to these simple rules, you'll never need to add or subtract 1 to your counters, loop indices, and lengths (because nobody can remember when to do that, so not having to do it significantly reduces the chances of bugs). T -- People say I'm arrogant, and I'm proud of it.