0-based indexes are commonplace in programming circles because of the C language, however 1-based indexes are the earlier standard set by Fortran.
EDIT: If Julia becomes popular outside data and numerics circles, it will have pulled off nothing short of a miracle in getting people to adopt 1-based indexes. This feud is older than vi vs. emacs. :-)
One-based indexing has a good, long history.
# Magic
julia> Base.to_indices(A, inds, I::Tuple{Complex, Vararg{Any}}) = (real(I[1]), imag(I[1]), to_indices(A, Base._maybetail(Base._maybetail(inds)), Base.tail(I))...)
julia> A
4×5 reshape(::UnitRange{Int64}, 4, 5) with eltype Int64:
1 5 9 13 17
2 6 10 14 18
3 7 11 15 19
4 8 12 16 20
julia> A[3 + 2im]
7
```When Octave was getting a lot of traffic from the first Coursera machine learning class, when it was just Andrew Ng doing a course and before the Coursera org existed, we were getting a lot of novice users who would do something like
some_matrix(i,j) = 5
and get cryptic errors about how matrices cannot be indexed by complex numbers. This is because by default, in Matlab and Octave `i` and `j` are functions that evaluate to the imaginary unit. You have to overwrite the function names with `i=2, j=3` or whatever beforehand, which novices often forget. This was happening often enough that I pushed some patches to warn, "did you forget to assign i or j?" if someone tried to index matrices with complex numbers.Point is, people in Matlab and Octave often unintentionally try to index by complex numbers.
It will for sure hurt adoption.
They're all 0-based (with maybe R as an exception, but R is a niche language. If that's what Julia aims to remain -- their loss).
The folks who designed these languages knew how not to alienate their future market.
Strongly disagree.
I can move from C to Python without a second thought and rewrite code from one to the other without even thinking.
Having to rewrite an algorithm working on multidimensional arrays that was written with 0-based conventions to 1-based conventions and have the resulting code remain readable is a freaking headache.
Compilers are pretty good about optimizing integer constants.
My reaction:
- the default is 1-based, which means the bulk of Julia code will adopt the convention and therefore the vast majority of coders in 2018 will have to do mental gymnastics to understand what the code does.
- when I read Julia code, I will never know which convention the code was written with unless I dig to find where that particular flag is set.
- passing 0-based arrays to a library routine that expects 1-based stuff, what happens then?
- for code that will be 0-based and uses library code that expects 1-based (assuming that's possible without paying copying overhead) will force the code to mentally switch between the two modes. Ugh.
In short: offering is a choice is maybe even worse than enforcing 1-based.For concern 2, it's as easy as finding the type. And without knowing the types you wouldn't know what the code did anyway.
For concern 3, a type error.
And for 4, because it's a type there is zero runtime overhead. A view of the array with the offset the code expects is constructed, often automatically based on the types involved. This view is often a zero cost abstraction at runtime because of how Julia specialization works. So at worst you pay some (extremely minor) compile-time/load-time costs.
1 based indexes were just fine.
Zero based is much more sane. If the array is regarded as being made up of larger groups of elements, say groups of 8, then ⌊index/8⌋ gives us the group and group x 8 gives us the base element of group. Not so if index is one-based.
Zero based multi-dimensional coordinates are easy to convert to a flat address. E.g. 3D case: just ABz + By + x.
Imagine distances were one based (so that either 1 m or 1 km means no displacement), and then trying to convert a given distance between m and km. Yikes!
Music intervals are one-based, to their great detriment. We end up with a "rule of nine" for interval inversion and that comes from the octave of the diatonic scale having seven notes!
One-based indexing is okay when the indices don't have a strong numeric meaning (beyond basic successor/predecessor relationships), or none at all (basically are symbolic and could be replaced by any set that can be enumerated by the natural numbers).
As soon as the index domain is involved in displacement calculations that feature multiplication and division, anything but zero based is disadvantaged.
In Algol based languages indexes are customizable, I don't remember ever writing array [0..9] of Integer instead of array [1..10] of Integer.
C, C++ and their descendants took over and I just had to adapt.
It's just a wanton complication, like insisting on Roman numerals instead of a radix enumeration.
Reminds me of the complaints my friends had about Linux when I first showed them a fantastic window manager.
"This will never get anywhere. It has no Start button."
If I were in a team that refused a language just because it is 1 based indexing, I would really worry about the abilities of the team.
When I do sigmas in math, they go: i=0,i<n and very rarely i=1, i<=n unless the problem really is made simpler by the weird 1-based indices.
guilty as charged :)
It's also not hard to get used to. No more OB1 errors.
That makes no sense. Neither 1-based indexing or 0-based indexing will save you from OB1 errors.
As a matter of fact, if you make more OB1 errors in a 0-based indexing language, it's probably because your brain is wired to think 1-based.
The problem: there are legions of programmers whose brain is wired to think 0-based and are guaranteed to suffer through a lot more OB1 errors if they try to adopt Julia.
0 based indexing is not because of C's influence. It's because that's how computers work. ASM is 0-based indexing. The first memory cell on a computer doesn't start at address 1.
If you are calculating an index the domain and range of the index function are very often 0-based. So you have to subtract and add one to convert from and to 1-based. It's just messy.