It's like the whitespace in Python debate that everyone gave up because the language got so popular that people stopped caring.
I'm not quite sure that this is the case enough to say "typically". In terms of undergraduate exposure to math, I think more people have taken Calculus (or Analysis) than Linear Algebra, and I think Calculus textbooks tend to index from 0 while Linear Algebra textbooks tend to index from 1.
Assuming that arrays start at 1 is a source of occasional bugs in public packages. The existence of OffsetArrays means that arrays can start at any index (so for people who get nauseated by 1-based arrays, you can change it).
Instead, write "for i in eachindex(arr)".
In fact, Julia’s array syntax means you can loop over and manipulate arrays without using indexes much of the time, so don’t even need to know how they’re based.
Most modern languages have a «foreach» operator or its functional equivalent as a collection item generator. «foreach elem in my_collection {}» also has a clearly defined semantics: «process everything». The code is cleaner, concise and a bit shorter and reduces the cognitive overload. And since many languages now support lambdas, the code can quickly and error free be converted into a staged data processing pipeline without the use of temporary variables that serve no purpose, e.g. «foreach elem in my_collection.filter (_ -> _.my_selection_criteria ("42"); ) { do_something (elem); }». Whether the collection is indexed from 0 or from 1 becomes irrelevant.
I thought the same thing about Python's indenting originally (and still do). But the ecosystem was enough to overcome it for me eventually.
A brave decision from the authors though, I imagine they would have got less flak matching the more popular 0-index languages.
Possibly, though those of us already in the space would have found it a (slightly) less pleasant language then.
I mean, computing mean - split range, get result per split and combine it back, and so on and so forth
I've always found 0-indexing mildly unpleasant too, even though C was the language I learnt programming with, and felt like I found home when I came across 1-indexed languages.
But I already know from real life that if there's maintanence in blocks 5 to 15, that's eleven blocks under maintanence. With half-open ranges, it once again introduces confusion and makes things unintuitive.
We can each find countless examples where each style comes out better, for eg `1:N` most often expresses the intent better than `range(N+1)`. I find people who prefer half-open ranges to be weird and incomprehensible, you probably find my preferences the same, I just don't like the categorical statement often made in this regard that one is inherently and universally superior to the other.
In Python, C/C++ and its descendant
[0...N)=[0...N/2)+[N/2...N)
Isn't that just n-1:-1:0 in Julia?
Was this sarcasm?
You cannot do easily [0...N) = [0...N/2) + [N/2...N)
But really, these discussions are funny to me - each side pretending their convention is how God intended indexing to be done. You see it's naturally composable because N/2 shows up twice, which is really the perfect amount of times to show up, and as you recall I just defined composable in that way (not to mention it matches the fact that N/2 occurs twice in [0, N)!)
In Python (C, C++ with whole STL) you could split in the middle, or at any M
[0...N)=[0...M)+[M...N)
You could split it k times at any boundaries, still
[0...N)=[0...M1)+...+[Mk...N)
Another important thing is that number of elements to process is exactly the difference between last and first index of the range
And in Julia, it’s
length(a:b)
which also works with non-unit step sizes like length(a:x:b)
The intent of these expressions seems clearer than the intent of `b-a` and `ceiling((b-a)/x)` with your proposed approach in a zero-indexed language.