3 ms·
Is there any reason to not just switch to 1-based indexing if we could? Seems like 0-based indexing really exacerbates off-by-one errors without much benefit
by Fraterkes 8mo ago
Is there any reason to not just switch to 1-based indexing if we could? Seems like 0-based indexing really exacerbates off-by-one errors without much benefit
- tialaramex 8mo agoI would bet that in the opposite circumstance you'd say the same thing: "Is there any reason to not just switch to 0-based indexing if we could? Seems like 1-based indexing really exacerbates off-by-one errors without much benefit" The problem is that humans make off-by-one errors and not that we're using the wrong indexing system.
- Fraterkes 8mo agoNo indexing system is perfect, but one can be better than another. Being able to do array[array.length()] to get the last item is more concise and less error prone than having to add -1 every time. Programming languages are filled with tiny design choices that don’t completely prevent mistakes (that would be impossible) but do make them less likely.
- adrian_b 8mo agoHaving to use something like array[length] to get the last element demonstrates a defect of that programming language. There are better programming languages, where you do not need to do what you say. Some languages, like Ada, have special array attributes for accessing the first and the last elements. Other languages, like Icon, allow the use of both non-negative indices and of negative indices, where non-negative indices access the array from its first element towards its last element, while negative indices access the array from its last element towards its first element. I consider that your solution, i.e. using array[length] instead of array[length-1], is much worse. While it scores a point for simplifying this particular expression, it loses points by making other expressions more complex. There are a lot of better programming languages than the few that due to historical accidents happen to be popular today. It is sad that the designers of most of the languages that attempt today to replace C and C++ have not done due diligence by studying the history of programming languages before designing a new programming language. Had they done that, they could have avoided repeating the same mistakes of the languages with which they want to compete.
- GoblinSlayer 8mo agoIf your design works better in one scenario usually means it works worse in other scenarios, you just shuffled garbage around.
- tialaramex 8mo agoarray[array.length()] is nonsense if the array is empty. You should prefer a language, like Rust, in which [T]::last is Option<&T> -- that is, we can ask for a reference to the last item, but there might not be one and so we're encouraged to do something about that. IMNSHO The pit of success you're looking for is best dug with such features and not via fiddling with the index scheme.
- bruce343434 8mo agoYou say "seems like", can you argue/show/prove this?
- Fraterkes 8mo agoI think that many obo errors are caused by common situations where people can mistakenly mix up index and count. You could eliminate a (small) set of those situations with 1-based indexing: accessing items from the ends of arrays/lists.
- meindnoch 8mo agoAnd in turn you'd introduce off by one errors when people confuse the new 1-based indexes with offsets (which are inherently 0-based). So yeah, no. People smarter than you have thought about this before.
- SkiFire13 8mo agoI'm not sure what that has to do with the article, but anyway: https://www.cs.utexas.edu/~EWD/transcriptions/EWD08xx/EWD831.html https://www.cs.utexas.edu/~EWD/transcriptions/EWD08xx/EWD831... That said, I'm not sure how 1-based indexing will solve off-by-1 errors. They naturally come from the fencepost problem, i.e. the fact that sometimes we use indexes to indicate elements and sometimes to indicate boundaries between them. Mixing between them in our reasoning ultimately results in off-by-1 issues.
- Fraterkes 8mo agoThis is an article that (among other things) talks about off-by-one errors being caused by mixing up index and count (and having to remember to subtract 1 when converting between the two). That's what it has to with it.
- adrian_b 8mo agoIf you always use half-open intervals, you never have to subtract 1 from anything. With half-open intervals, the count of elements is the difference between the interval bounds, adjacent intervals share 1 bound and merging 2 adjacent intervals preserves the extreme bounds. Any programming problem is simplified when 0-based indexing together with half-open intervals are always used, without exceptions. The fact that most programmers have been taught when young to use 1-based ordinal numbers and closed intervals is a mental handicap, but normally it is easy to get rid of this, like also getting rid of the mental handicap of having learned to use decimal numbers, when there is no reason to ever use them instead of binary numbers.
- SkiFire13 8mo agoI must have missed that part, my bad
- cindyllm 8mo ago[dead]
- adrian_b 8mo agoThis is a matter of opinion. My opinion is that 1-based indexing really exacerbates off-by-one errors, besides requiring a more complex implementation in compilers, which is more bug-prone (with 1-based addressing, the compilers must create and use, in a manner transparent for the programmer, pointers that do not point to the intended object but towards an invalid location before the object, which must never be accessed through the pointer; this is why using 1-based addressing was easier in languages without pointers, like the original FORTRAN, but it would have been more difficult in languages that allow pointers, like C, the difficulty being in avoiding to expose the internal representation of pointers to the programmer). Off-by-one errors are caused by mixing conventions for expressing indices and ranges. If you always use a consistent convention, e.g. 0-based indexing together with half-open intervals, where the count of elements equals the difference between the interval bounds, there are no chances for ever making off-by-one errors.
- pansa2 8mo agoFundamentally, CPUs use 0-based addresses. That's unavoidable. We can't choose to switch to 1-based indexing - either we use 0-based everywhere, or a mixture of 0-based and 1-based. Given the prevalence of off-by-one errors, I think the most important thing is to be consistent.
- dgrunwald 8mo agoWhen accessing individual elements, 0-based and 1-based indexing are basically equally usable (up to personal preference). But this changes for other operations! For example, consider how to specify the index of where to insert in a string. With 0-based indexing, appending is str.insert(str.length(), ...). With 1-based indexing, appending is str.insert(str.length() + 1, ...). Similarly, when it comes to substr()-like operations, 0-based indexing with ranges specified by inclusive start and exclusive end works very nicely, without needing any +1/-1 adjustments. Languages with 1-based indexing tend to use inclusive-end for substr()-like operations instead, but that means empty substrings now are odd special cases. When writing something like a text editor where such operations happen frequently, it's the 1-based indexing that ends up with many more +1/-1 in the codebase than an editor written with 0-based indexing.
- GuB-42 8mo agoBecause it is not how computers work. It doesn't matter much for high level languages like LUA, you rarely manipulate raw bytes and pointers, but in system programming languages like Zig, it matters. To use the terminology from the article, with 0-based indexing, offset = index * node_size. If it was 1-based, you would have offset = (index - 1) * node_size + 1. And it became a convention even for high level languages, because no matter what you prefer, inconsistency is even worse. An interesting case is Perl, which, in classic Perl fashion, lets you choose by setting the $[ variable. Most people, even Perl programmers consider it a terrible feature and 0-based indexing is used by default.
- naasking 8mo ago> Is there any reason to not just switch to 1-based indexing if we could? Seems like 0-based indexing really exacerbates off-by-one errors without much benefit You'd just get a different set of off-by-one errors with 1-based indexing.
- layer8 8mo ago1-based indexing doesn’t work well as soon as you have a start offset within a sequence, from which you want to index. Then the first element is startIndex + 0, not startIndex + 1. 0-based indexing generalizes better in that way.