77 ms·
Why do arrays start at 0?
- Gordonjcp 4y agoBecause memory starts at zero, because the lowest address you can select in memory has all its address lines set to zero. If you don't understand this, you should not be writing computer software.
- unnouinceput 4y agoWelcome to pagination and virtualization where physical address is different than what your program think is. Also welcome to hypervisors where entire operating systems think they own an entire physical line, only to have something like Spectre/Meltdown say otherwise.
- jschveibinz 4y agoI have always assumed that is just one less operation required to resolve the absolute memory address.
- nsajko 4y agoNo. 1. Optimizing compilers exist. 2. Addressing at fixed offsets is cheap (a single instruction): https://en.wikipedia.org/wiki/Addressing_mode https://en.wikipedia.org/wiki/Addressing_mode 0-based indexing is superior (as a default) because it simplifies a lot of common math, as discussed in TFA.
- mjevans 4y ago3. Less buggy for small systems since the Base Pointer address points directly to a record. 4. Macro expansion is often used to store indexes and other 'magic numbers' in Assembler, and this pattern originated either when Assembly was the primary programming language, or even earlier when humans directly punched out cards with machine instructions. Compilers in any remote sense of the luxury we have today did not exist or were not common.
- espadrine 4y agoThat is true for vectors, but not matrices, right? char at(char matrix[10][10], char i, char j) { return matrix[i][j]; } still has more computation on 1-indexed than on 0-indexed, I believe.
- contravariant 4y agoWell you've either got: memory_address + array_width*i + j or memory_address + array_width*(i-1) + (j-1) = (memory_address-array_width-1)+ array_width*i + j so you can just absorb the extra computation into the pointer.
- auggierose 4y agoTFA = Thanks For Asking?
- goatlover 4y ago> 0-based indexing is superior (as a default) because it simplifies a lot of common math, as discussed in TFA. If that was true, Fortran, Julia, R and Matlab would use 0 instead of 1-based.
- bee_rider 4y agoThe mental model of being an offset to a memory address is, I think, part of it. I'd be surprised if the use of zero vs one actually made any difference, from a number of operations point of view -- from the compiler's point of view, the first element in the array is the first element in the array, no matter what we call it. I mean in an extreme edge case maybe if you are computing an index, and it happens to be zero, then in your math maybe some identity related to zero could be exploited (go to element simple_integer*complicated_function(), where simple_number might be zero) but that seems a bit silly.
- Yujf 4y agoHow would it not make a difference? If you calculate an index at runtime, to get access to the element, in 0 based would be pointer + index. In 1 based it is however pointer + index - 1 clearly there is an extra subtraction there? In x86 you could probably hide it in the addressing but that does not mean it does not to be computed
- goatlover 4y agoIf you’re calculating indexes at runtime, you’re probably not worried about that level of optimization.
- bee_rider 4y agoOne option, at least, would be for malloc and friends to return pointer-1, rather than pointer. That said, I'm sure a compilers expert could come up with a much better option.
- rhacker 4y agoThis is primarily the actual answer. While most languages force you to see the array as an array, in C/C++ (in C++ I'm only referring to the memory allocated variable type, not an "array class") you can see it as a pointer and do your own math to address any part of it that you want. And the calculation for that memory address is idx * sizeof(the thing in your array). So the real answer here is that array semantics needed to match memory address semantics in the languages that provide that.
- copperx 4y agoThere's no reason why memory addresses had to start at 0.
- deleted 4y ago[deleted]
- User23 4y agoPascal's arrays start at 1, at least by default.
- wvenable 4y agoPretty much all variants of BASIC have arrays starting at 1.
- JKCalhoun 4y agoI think a language needs to decide if it is "high level" or if it is instead a convenience language on top of assembly. BASIC and Pascal I am sure would have been considered a high-level language in their day and naturally would have arrays be 1-based. C on the other hand....
- hwayne 4y agoPascal is a variant of ALGOL-60, made in part because Wirth thought ALGOL-68 was way too complicated. BASIC instead comes from the FORTRAN line.
- sacrosancty 4y agoExcept VB.NET which is only 0-based but you can just shut your eyes and imagine it's 1-based because you declare an array by specifying its upper bound which equals its number of elements in 1-based.
- unnouinceput 4y agoThis is false. Pascal arrays start at whatever you want. As for what is happening behind closed doors (aka linker), those start at zero, but with an offset kept separately (that's why C blew out of the water Pascal in terms of speed when looping through an array). And in Pascal you cannot create a dynamic array with anything other than 0-based. You are confusing arrays with strings. Those used to start at 1, but since Unicode took over (~2007) strings are implemented as zero-based too (even though you can still think of them as 1-based when writing code). Also in Delphi, when creating a cross-platform application, strings are treated as 0-based, with even multiple locations in documentation stressing this importance due to having enough differences between classic VCL and the new kid on the block (aka FireMonkey).
- codefreeordie 4y agoArrays start at 0 because they're really just pointers. "[x]" is just shorthand for "+ x * sizeof". The first element is the one stored at the pointer address (0 sizeofs ahead of the pointer, the next element is stored 1 sizeof ahead of the pointer, etc.
- nicoburns 4y agoThat's just convention though. There's no reason "[x]" couldn't have been defined to be "+ (x - 1) * sizeof". There would be no runtime cost to this, and the compile time penalty would be tiny even on ancient systems.
- nwlieb 4y agoIs `(x - 1)` not a runtime cost if `x` is a runtime variable?
- vikingerik 4y agoNot on many instruction architectures - addressing modes often support adding/subtracting a constant.
- giraffe_lady 4y agoThat answers something like "what are the technical benefits to zero-based arrays" but not "why are zero-based arrays such a strong convention in programming languages." For that you'd have to read the article I guess.
- JKCalhoun 4y agoOr it could be: "technical benefits to zero-based arrays" -> "why zero-based arrays are a strong convention" Article mentions that Hoye says as much but is dismissive of it. I am not sure why he would be so quick to dismiss.
- vidarh 4y agoIn C, "a[x]" is effectively syntactic sugar for just "*(a+x)" (conversion rules for "+" means you don't need the sizeof). It also means you can reverse it and write e.g. "5[somearray]" if you really want to make developers want to throw rocks at you.
- asveikau 4y agoThere is definitely a bunch of math that works out better in 0 based indices. I saw this a lot when I was working on filesystem focused stuff. I feel like I've also seen algorithms that work out better with 1 based indices, but not as many.
- shanewilhelm 4y agoI found it interesting that the author phrased their critique so definitely, i.e. "it's NOT this and NOT that", yet concluded the article by saying their whole argument was speculative. That said, I do agree with their premise that it's going to be pretty tough to get a definitive answer as to why 0-indexing won out. And their criticism of others being so ready to declare results is apt, if not a little ironic in this case :)
- briantakita 4y ago> yet concluded the article by saying their whole argument was speculative It's possible to have a speculative argument and also refute other arguments that claim certainty. Pointing out another answer as being wrong does not mean one needs to know the correct answer or claim to have a precise answer.
- JKCalhoun 4y ago> The usual arguments involving pointer arithmetic Yeah, I think this exactly why it is zero based. The index became a simple multiplier for sizeof(int).
- hougaard 4y agoAn assembler spillover into C.
- JKCalhoun 4y agoWas C ever much more than a veneer on top of assembler? Don't get me wrong, it's why I like C.
- adwn 4y ago> Was C ever much more than a veneer on top of assembler? Maybe in the very early days, but that necessarily had to end as soon as compilers started doing non-trivial optimizations. Today, C is very far from being "portable assembly".
- Guest42 4y agoI'd claim intuitively that having all bits 0 is a proper starting point and more efficient if there were any constraints on address, which was likely the case historically. I'm happy to hear any dissenting opinions if this is inaccurate.
- hougaard 4y agoIt really comes down to a choice between a machine-focused (0) or human-focused (1) approach. The 0 makes a lot of sense in a C pointer world where memcpy and other alike functions can be written very thight. The 1 makes a lot of sense in a human world, when we count, we start at 1, we talk about the "1st", counting on finger starts with 1, etc. I once were at a Lua (1 indexed language) conference where this was discussed, and Luis started explaining why Lua was 1-index with this sentence: "The 1st argument ...." :)
- kazinator 4y agoIs it machine-focused that we can convert a distance of 1.5 m to 150 cm just by multiplying by 100? Maybe distances should be human-focused, so that no displacement is equivalently expressed as 1 cm, 1 m, 1 km, ... Then converting a distance d from m to cm is (d - 1) x 100 + 1.
- hougaard 4y ago... but if you have something that's 150cm, that's not 151cm, that's 150cm?
- qsort 4y agoI don't think 1-based arrays are better notation, even completely ignoring that code has to run on a machine. 99% of the times, the correct approach is to use iterators. When you really need indices (and you almost never do), 0 is more practical, because it matches the "including start, not including end" convention.
- randomdata 4y ago> when we count, we start at 1, we talk about the "1st" Although often with an implicit zero. Under typical North American culture, your 1st birthday, for example, is more accurately the first anniversary of your birthday. Your birth is zero indexed.
- atwood22 4y agoNo, birthdays are 1 indexed. Your Nth birthday is the day you turn N years old. When you're 1 year old, you've been alive for 1 year, not 2 years.
- v-yadli 4y agoI'm fine with 0-based, 1-based or anything-based arrays (I recall it being convenient solving 8queen with pascal), but for Rage-Over-A-Lost-Penny sake, music note intervals are always beyond my understanding. Same pitched notes are called "interval 1" and there goes thirds, fifths, sevenths... All off-by-one in my base-offset-addressing mind... And then major vs. minor which creates all kinds of "aliased addresses"... I'd really love a BASE-12 floating number representation. Like 4.00 for the middle C; Chords can be then represented by a tuple of such numbers -- major = [+0.04, +0.07] (some sequencers already do something like that and I'm far better at reading that kind of sequencer data than a sheet)
- ur-whale 4y agoAnd then, there's the imperial system.
- gnulinux 4y agoYou do understand that besides thirds, fifths and sevenths, there really are seconds, fourths, sixths, ninths (same as second), elevenths (same as fourth) etc... as well, right? There even are intervals that are not named after a number e.g. the "tritone". The reason the 2nd and the 3rd note in a chord are called third and fifth is because usually chords are made with these intervals instead of dissonant intervals like seconds or fourths. It seems pretty clear you'd already know these things, so can you explain what's your issue with music note intervals?
- v-yadli 4y agoIt's that off-by-one nature of intervals that always bumps me. The difference between note a and b is (a-b+1). Calling an octave "an octave" feels to me like calling a numeric system with digits 0x0-0xf as "base 17"
- gnulinux 4y agoBy your logic, an octave/unison would be "seventh"/"zeroth"? (Note that "octave" literally means "eighth" in Latin.) I would think that could work too but the established terminology is not inconsistent. It's just 1-indexed. A lot of things are 1-indexed, in fact I think almost everything in spoken English is 1-indexed. A lot of mathematics, like number theory, is also 1-indexed. I think software engineers are a little too obsessed with 0-indexed things. I understand that things not being standard is annoying to us but pretending like this somehow makes music terminology broken is going too far. I don't see how 0x0-0xf could be called base 17. 0xf is 15. Did you mean base 15? I think if mathematics terminology developed differently it could be called base 15. The same way binary is 0 and 1 but we call it base 2 because there are 2 digits, but we could totally call it base 1 too, who cares, it's all convention.
- jaapsen01 4y agoEdsger Dijkstra wrote an interesting article titled 'why numbering should start at 0'. Perhaps not answering the question directly but an interesting read nonetheless. https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/E...
- gnufx 4y agoAs the article implies, Dijkstra was specifically wrong about FORTRAN, as defined at the time — the '77 standard, when it was still only conscionable to SHOUT 6 alphamerics. “… you probably know that arrogance in computer science is measured in nano-Dijkstras.” — Alan Kay
- tda 4y ago"This quote keeps on showing up out of context." — Alan Kay https://news.ycombinator.com/item?id=11799963 https://news.ycombinator.com/item?id=11799963
- gnufx 4y agoWell, I did hear it in context, and have also heard him talking about concocting aphorisms. Kay also said “He did like to pull chains …”
- pavon 4y agoI've never understood the first half of Dijkstra's argument. Unless we are programming a theoretical Turing machine, there will also be a maximum number that can be represented, so the argument about using inclusive bounds for the lower end also applies to the the upper end. So you can't represent all numbers with a single range style. You either end up excluding the smallest number, the largest number, or the empty set. Or you need special notation to handle one of those three cases. I suppose the 0,1,infinity principle argues that including the empty set and smallest number is more important that including the largest number, so that notation should be preferred by default. And when writing using A<=i<B it is clear enough, but once you remove those symbols and start using them in indexing or function call syntax, like [A:B] or range(A,B), the inconsistency of bounds really breaks my brain, and having to pass a number larger than the largest array index as an upper index range bound gives me nervous ticks. I'd rather use inclusive bounds everywhere and have special syntax for empty set.
- JustSomeNobody 4y agoI liked how in Pascal, one had a lot more flexibility here. Something like the following IIRC: Type IntArray = Array [-10...10] of Integer;
- unnouinceput 4y agowhat size is that array? (hint - is not 20)
- demindiro 4y agoI find 0-based indexing easier to work with when working with (dynamically sized) multi-dimensional arrays. For example, with 0-based indexing getting an element at (x, y, z) can be done with a[z * h * w + y * w + x] But with 1-based indexing you need to substract one first from each component except the last: a[(z - 1) * h * w + (y - 1) * w + x]
- hcrisp 4y agoDijkstra's answer (linked in the article) is best: "When dealing with a sequence of length N, the elements of which we wish to distinguish by subscript, the next vexing question is what subscript value to assign to its starting element. Adhering to convention a) yields, when starting with subscript 1, the subscript range 1 ≤ i < N+1; starting with 0, however, gives the nicer range 0 ≤ i < N. So let us let our ordinals start at zero: an element's ordinal (subscript) equals the number of elements preceding it in the sequence. And the moral of the story is that we had better regard —after all those centuries!— zero as a most natural number." https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/E...
- goatlover 4y agoI don't understand why 0 ≤ i ≤ N wouldn't have worked instead, since you already have a less than or equal operator at 0.
- weavejester 4y agoThat would give a sequence of N+1 elements, though. Confusing if you had a function like range(N), for example.
- goatlover 4y agoWhy, it would be an inclusive instead of exclusive range. N is the last element, so no reason for N+1.
- weavejester 4y agoIf we use inclusive ranges where 0 ≤ i ≤ N, then len(range(N)) == N+1. e.g. len(range(3)) == len([0, 1, 2, 3]) == 4
- goatlover 4y agoWait, why would range(3) start at 0 and not 1 in a 1-based language?
- beardyw 4y agoStarting at one led to the whole "2000 is not the millennium" thing, as there is no year zero.
- ziml77 4y agoEven more painful is that the 2001 began the 21st century, not the 20th.
- jfmc 4y agoThe general term of arithmetic and geometric sequences seem simpler when indexing from 0 rather than 1. I do not think that '1' is more human focused for anything than '0'.
- franciscop 4y agoI've discussed this a lot in real world in a different field: apartment floors. In Japan (where I live) they are 1-indexed, where the floor on the ground is number 1, while in Spain (where I am from) they are 0-indexed, where the floor on the ground is number 0. Both have inconsistencies, like in Spain you might have a "middle ground" (entresuelo) which is neither 0 nor 1, but sits between, and is normally commercial or non-livable, reserving the 1 to the first floor where people live. I like that system better though because it usually goes 1 => 0 => -1 (underground), while in Japan you go 2 => 1 => -1, so I feel like it's missing a floor. You could justify it though as 0 being the ground line, so +1 is "the first above the floor and -1 is "the first below the floor", but I still prefer having each floor to be a natural consecutive number.
- onlyrealcuzzo 4y agoIt seems like most newer buildings in the US and EU have "G" or "L" be the ground floor (0 / PB), and then the floor above is "1". In older buildings, the ground floor is usually "1" - which means the floor above has to be "2".
- user3939382 4y agoI (US) don’t remember seeing the second floor labeled 1. I often see G, 2, 3
- andy81 4y agoEnglish also has that "mezzanine" concept, for partial floors with a balcony over the main floor. You see it sometimes on elevators as an M.
- twanvl 4y agoOther advantages of zero based indexing, beyond being 'closer to the machine': It works better with the modulo operator: `array[i%length]` vs `array[(i+length-1)%length+1]`. Or you would have to define a modulo-like operator that maps ℕ to [1..n]. It works better if you have a multi-dimensional index, for example the pixels in an image. With 0 based indexing, pixel `(x,y)` is at `array[x+widthy]`. With 1 based indexing it is at `array[x+width(y-1)]`. You might argue that programming languages should support multi-dimensional arrays, but you still need operations like resizing, views, etc.
- msdrigg 4y agoThis is the reason I always think of when I hear the question
- bluetomcat 4y agoA disadvantage comes to mind. While the following loop works as expected: for (size_t i = 0; i < length; i++) ... The following causes an unsigned integer underflow and is an infinite loop: for (size_t i = length - 1; i >= 0; i--) ...
- ncmncm 4y agoIf you have foolishly turned off -W in your build system, that could happen. Otherwise, you get a nice warning pointing out your folly.
- 10000truths 4y agofor (size_t i = 0; i < length; i++) { size_t j = (length - 1) - i; ... } EDIT: change i to j
- yuliyp 4y agoThat's quite broken (you'd want a different variable inside the body, vs clobbering the iteration counter, else this would process the last item in your list, then exit).
- 4y ago
- snarfy 4y agoIndexes start at 1. Offsets start at 0. Arrays in programming use offsets. for(int i=0;i<10;i++) { array[i] = x; } The error here is calling it 'i' for index. It should be 'o' for offset.
- nomel 4y agoArrays in the programming languages you’re familiar with use offsets. Not all do [1]. 1. https://therenegadecoder.com/code/which-programming-languages-index-by-one/#programming-languages-with-one-based-indexing https://therenegadecoder.com/code/which-programming-language...
- onox 4y agoArrays in Ada start at the index based on the index type of the array. You can even use an enumeration type as the index: type Day is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday); type Hours is array (Day range <>) of Natural; V : Hours (Monday .. Friday); Which index type you should use depends on the problem that you're trying to model. You can find out the lower/higher end of a type/variable with the 'First and 'Last attributes. IIRC there's an RFC though to force the lower end of the index to a certain value like 1 or any other number/enum.
- copperx 4y agoI always wonder why such fundamental features were not adopted by all languages.
- dailykoder 4y agoWow, I never really looked at Ada code. Been using VHDL for the past 2 years a lot and when I looked at your code I was like: 'huh strange, this looks a lot like VHDL'. Turns out both were invented by the DoD. >Due to the Department of Defense requiring as much of the syntax as possible to be based on Ada, in order to avoid re-inventing concepts that had already been thoroughly tested in the development of Ada,[citation needed] VHDL borrows heavily from the Ada programming language in both concept and syntax. - https://en.wikipedia.org/wiki/VHDL https://en.wikipedia.org/wiki/VHDL Maybe I should pick up Ada soon. That could be a fun journey! (I really love writing VHDL)
- csours 4y agoThis reminds me of arguments about male -> female and man -> woman (and human etc). Without offending anyone's delicate sensibilities - you may note that there is a short version and long version of those words, suggesting that the longer version is derivative of the short version. However, when you examine the origin of the words, that is not the derivation. The derivation and path to English is quite complicated. You may feel a sense of righteous indignation or righteous repudiation on this topic. I would gently suggest deferring that feeling because I think the story is very interesting to follow. That is not the end of the story though. The reason those pairs of words stuck around is almost certainly because it makes a consistent mental picture. Bringing it back to the topic at hand - "Why we use 0" - because it works. There are many times when it has been evaluated, and at least to the people who design languages, it is more mentally appealing. https://www.etymologynerd.com/blog/man-vs-woman https://www.etymologynerd.com/blog/man-vs-woman https://medium.com/interesting-histories/interesting-histories-female-male-woman-man-fd8f436a554c https://medium.com/interesting-histories/interesting-histori...
- zwkrt 4y agoI really fail to understand what the etymology of sex and gender classifications has to do with array based indexing.
- csours 4y ago> "Bringing it back to the topic at hand - "Why we use 0" - because it works. There are many times when it has been evaluated, and at least to the people who design languages, it is more mentally appealing." The linked post is not just about a technical decision, it's about a social history. The conclusion of the linked post: > "Lessons Things can have more than one cause. Don’t trust easy explanations. Always look for information that refutes your theory, not just information that supports it. Hoye stopped as soon as he had a satisfying answer and didn’t keep researching. Don’t be a dick. It is tragically easy to trick me into doing free research."
- auggierose 4y agoFunny, just a few hours ago I asked myself the related question "Should indices start with 0 or 1?" (not for the first time). I pretty much switch my opinion as many times as I think about it. Here is a nice discussion on stackoverflow https://cseducators.stackexchange.com/questions/5023/why-do-we-count-starting-from-zero https://cseducators.stackexchange.com/questions/5023/why-do-... The first answer nicely retells the dijkstra argument: integer ranges should be described using half open intervals, and [n, m) is nicer than (n, m]. Furthermore, [0, n) is nicer than [1, n+1), and that's that. The second answer makes the observation that there is a difference between indexing and counting, and that even in daily life often the first element is indexed by 0. Still, I rather like indexing the first element of a sequence with 1.
- dang 4y agoThe article this one points to has had a few threads: The origin of zero-based array indexing - https://news.ycombinator.com/item?id=6879478 https://news.ycombinator.com/item?id=6879478 - Dec 2013 (107 comments) Zero-based arrays and the mythology of programming - https://news.ycombinator.com/item?id=6708409 https://news.ycombinator.com/item?id=6708409 - Nov 2013 (1 comment) Citation Needed - https://news.ycombinator.com/item?id=6595521 https://news.ycombinator.com/item?id=6595521 - Oct 2013 (2 comments) Threads about the EWD mentioned by jaapsen01: Why numbering should start at zero (1982) - https://news.ycombinator.com/item?id=22162705 https://news.ycombinator.com/item?id=22162705 - Jan 2020 (220 comments) Dijkstra's argument on why numbering should start at zero [pdf] - https://news.ycombinator.com/item?id=17850441 https://news.ycombinator.com/item?id=17850441 - Aug 2018 (1 comment) Why numbering should start at zero (1982) - https://news.ycombinator.com/item?id=17765034 https://news.ycombinator.com/item?id=17765034 - Aug 2018 (63 comments) Why numbering should start at zero (1982) - https://news.ycombinator.com/item?id=13186225 https://news.ycombinator.com/item?id=13186225 - Dec 2016 (216 comments) Why numbering should start at zero (1982) - https://news.ycombinator.com/item?id=9761355 https://news.ycombinator.com/item?id=9761355 - June 2015 (47 comments) Dijkstra: Why numbering should start at zero - https://news.ycombinator.com/item?id=777580 https://news.ycombinator.com/item?id=777580 - Aug 2009 (71 comments) Also these. Others? I'm a little surprised there aren't more. Why do we count starting from zero? - https://news.ycombinator.com/item?id=17923391 https://news.ycombinator.com/item?id=17923391 - Sept 2018 (1 comment) Why C Arrays Start at Zero: I Don't Know - https://news.ycombinator.com/item?id=11228267 https://news.ycombinator.com/item?id=11228267 - March 2016 (3 comments) Why C Arrays Start at Zero: I Don't Know - https://news.ycombinator.com/item?id=11114704 https://news.ycombinator.com/item?id=11114704 - Feb 2016 (2 comments)
- cannam 4y agoPerhaps also worth adding that the linked article (the one titled "Citation Needed") itself originally had hundreds of comments beneath it, many quite argumentative, which seem to be now missing - I guess lost in a site update. It was a very contentious article. I'm sympathetic to its author's approach - we talk about indexing and it's a strangely fascinating topic but the history of it hasn't been all that well dug out. We do indeed tend to respond to articles like this by going "well obviously [x]-based is good because" - you can see that at work in this discussion here - but those are not necessarily the true historical reasons. But I think the author made a leap too far, the article was a bit too brittle, and it landed in a slightly too argumentative spot.
- AndrewOMartin 4y ago"Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration." -- Stan Kelly-Bootle
- pavon 4y agoThis comes up when giving fractional coordinates into a grid. Is (1,1) the upper-left corner of the upper-left grid box, the center, or the lower-right (or the center of the next grid box)? Alternately, is the upper-left corner of the upper-left grid box (-0.5, -0.5), (0.0, 0.0), (0.5, 0.5), or (1.0, 1.0). I've seen all four conventions used in different places, depending on whether the grid boxes themselves are numbered starting at 0 or 1, and when extended to fractional if it makes more sense to have the corner or the center of the grid box take the value of the box itself.
- bartwe 4y agoWhich is how we got the dx9 half pixel offset in fragment shaders. luckily not replicated in newer revisions.
- glitchc 4y agoArray indices denote offsets from the base address. The first element is at the base address of the array, hence the offset is zero. It avoids a conditional when resolving the address, introducing it would slow down all forms of memory access across the language domain.
- goatlover 4y agoYet somehow Fortran manages to be highly performant.
- daneelsan 4y agoIn Mathematica/Wolfram Languege, the part 0 of an expression is reserved for the head of the expression: f[x, y, z][[0]] == f. Or g[f][x, y][[0, 1]] == f.
- patatino 4y agoMy 4 year old starts at 0 when asked to count, so proud! Never said a thing about starting at 0.
- jcelerier 4y agoLook at your 4 year old's ruler. What's the first number on it?
- thetwentyone 4y agoThey point at 3 apples and goes "0,1,2" naturally?
- spullara 4y ago0 is offset based. 1 is index based.
- thetwentyone 4y agoThis is my take and when working directly with computer memory/addresses, 0-based is most convenient. For working with data/stuff at a higher level, 1-based is more natural and convenient.
- kshacker 4y agoI can understand the rationale for 0 and 1. I can even understand the rationale for a arbitrary range (from -5 to +10) in current era where languages have iterated for many generations. However I did not understand why they would have a range in the early days of programming. On one hand it would have been hard to make a language and its compilers and then you add arbitrary ranges?
- aaaaaaaaaaab 4y agoEarly programmers were mostly mathematicians and physicists, so the notation borrowed a lot from their fields, where it's common to index sequences with arbitrary numbers. And it's not particularly complicated to implement either.
- lowbloodsugar 4y agoThe argument that "BCPL doesn't have pointers, so it's not about pointers" fails immediately because every language has pointers, but some of them don't expose them to the developer.
- deleted 4y ago[deleted]
- Taywee 4y agoI've spent so long working with both 0-indexed and 1-indexed (I work with Lua a LOT at work) that it makes almost no difference to me, and I can switch between the two with usually no hiccups. Either one is something you get used to with practice. I do prefer 0-based, but 1-based isn't as big of a deal as many people treat it in the vast majority of situations, and almost every situation where you'd be using something like Lua in the first place.
- tunesmith 4y agoI always assumed it came back to math, and that t0 or time-zero is useful for the beginning state before anything happens.
- goatlover 4y agoWhat if there was no t0 for the universe, as Hawking and a few other physicists have argued? There was just the first plank second and no meaningful before.
- tejtm 4y agoFor me it comes down to; are you enumerating intervals or items to offset into.
- walnutclosefarm 4y agoThere were a number of systems oriented languages that, while algol-like in syntax, used zero-based array indexing, predating C. BCPL was intended to be a generic systems oriented language, but Burroughs had ESPOL for their mainframe architecture, and HP wrote their operating systems and compilers in SPL, which was specific to their stack-oriented HP3000 architecture. All these used zero-based indexing, because for low-level, memory conscious manipulations, it's much more natural than one-based. But nothing is universal, and IBM's systems oriented languages (BPL, PL/S, and PLS/II) were more an evolution of IBM assembler and then Wirth and PASCAL, and used one-based array indexing. Personally, I've always found zero-based more intuitive and satisfying, absent arbitrary indexing (in which case I'd chose zero-based for most purposes where there wasn't a compelling solution based reason to use a different index base). But then spent years writing SPL ... I
- unixbane 4y agoOn a cursory look, I'd say one based is more intuitive, for the sole fact that the a[len(a)] is the last element. Actually I remember there was a small time when I started programming in assembly it took me a while to get used to reasoning about the end of the array.
- walnutclosefarm 4y agomuch of intuition is made, not innate, at least for things as abstract and arbitrary as languages and notation. If you come at this question from a point of view where an array is a block of memory words indexed by a pointer - which is pretty much how system programmers back in the day when I did such things, 50 years ago - then zero based seems natural and obvious. The pointer to the array is the array, and the first element in the array is the pointer plus zero, the second, the pointer plus one, and so on. Once you start thinking that way. For multi-dimensions, the arithmetic just falls out as well. But I don't think the fact that many of us developed that intuition, makes it inherently better. It just makes it more intuitive for those of us who developed that inuition. I've written oodles of codes with both paradigms. Either works. Zero is just more natural, to me.
- ncmncm 4y agoThe crucial fact is that if your language supports 0-indexing, you can do that if you like. OR, you can pretend it has 1-indexing, and do that instead. If your language doesn't support zero-indexing, then you are stuck with 1-indexing, and that's that. So, zero-indexing is the natural thing to put in a language, as it accommodates everybody.
- kgwxd 4y agoIf everyone just called it offset instead of index there'd be no confusion.
- drfuchs 4y agoEasy: I have an array with 256 elements. And I want to store the indexes of various elements of the array off in another data structure. So many of them, in fact, that it’s important that the index values each fit into a byte. So, I want the index values to be 0..255, and not 1..256, since 256 doesn’t fit into a byte.
- _gabe_ 4y agoYou can still fit that information into one byte and convert it at compile time or runtime :) In a minecraft clone I made, each chunk consists of 16 subchunks so that I only need 12 bits to represent the block position in the shader. Technically, the block position ranges from INT32_MIN -> INT32_MAX, but since each subchunk only consists of 16x16x16 blocks I can get away with storing the position in 12 bits and then passing in the subchunk's world position once as a uniform.
- zaroth 4y agoSimple: Because you add zero to the memory address of an array to access the first element. The array indexer was syntactic sugar for pointer arithmetic.
- avisser 4y agoLooking at my own coding experience, I certainly favor 0 over 1. When I examine why, I can't help but see my aversion to & distaste of Visual Basic as a driver. VB is the only 1-indexed language I have used. VB is bad. Therefore 1-indexed languages must be bad.
- rmason 4y agoActually in not all languages do arrays start at 0. In ColdFusion for example arrays start at 1. I've never been able to receive a reason as to why CF's original author, J.J. Allaire, did it that way.
- amilios 4y agoalso Lua and R.
- ur-whale 4y agoAnd Julia, an otherwise nice language.
- Grazester 4y agoCame here to say this about CF. I work in Coldfusion but coming from a background of other languages I would always reference 0 as the start of an array. This was the source of countless errors for me until I got use to it.
- Grazester 4y agoCame here to say this about CF. I work in Coldfusion but coming from a background of other languages I would always reference 0 as the start of an array. This was the source of countless errors for me until I got use to it. My manager thinks it was done to make the language easier to understand for people just getting into programming.
- tomkaos 4y agoWorst than 0 and 1 is to have the choice. In Visual Basic 6 you have the option between the base 0 or 1 for each module. It make debugging a nightmare and you can create bug just by copy/pasting code from one program to other with a different base index.
- GuB-42 4y agoYou also have the choice in Perl, because of course, it is Perl. The old way of doing it was setting the $[ variable to 1. You can actually set it to any value, in case you prefer to start your arrays at 42. It is now deprecated but you now have Array::Base that offers similar functionality. Use it if you absolutely hate the person who will read your code, as if having someone read Perl code wasn't hateful enough.
- hoosieree 4y agoOne of the least-loved APL features is the fact that you can change the index origin at runtime.
- bregma 4y agoIf you ask people which floor of building they're on, it's going to depend on which country they're in. In North America, at least, the first floor you walk into (in a sane city: I understand there are some which do not qualify in this respect due to hills or historic disaster recovery) is the first floor. On other continents, you enter the ground floor and need to take stairs or an elevating device to get to the first floor. "Natural" zero-based counting at its best.
- perlgeek 4y agoA big international corporation (Siemens) had, at one point, standardized their buildings world wide to have room numbers starting with 2 on the ground floor, 3 on the floor above etc., leaving space for two basements. All room numbers were 5 digits, and skipped numbers if there were multiple windows in one room, based on the theory that such a room might later be sub-divided, and wanting to avoid renumbering of rooms down the hallway. (I encountered this around 2003, so might have well changed since then; didn't find any references only with a quick search).
- mywittyname 4y agoI worked for them relatively recently and didn't encounter this; or at least never noticed. Then again, our office building was an open office plan where desks next to the windows and rooms (conference or office) were all in the center of each floor.
- ajuc 4y agoThe ground floor is 0. The floor above 0 is 1. The floor below 0 is -1. Anything else is crazy TBH, the whole point of integer numbers is to count things that start at a defined point and go opposite ways. Why shift it and then reinvent weird pseudo-negative numbers like S1? But then again people measure distance in feet and write dates as month day year :)
- jccalhoun 4y agoIt would be nice if this was the case. In grad school I taught in a building that was on a hill and had once been separate buildings so different entrances were on different floor and the transition between the former separate buildings was 4 stairs. So there was a floor with rooms numbered 1xx and 0xx. There was also a floor below the 0xx floor. They just numbered it 00xx. And you could enter the building on any of those floors depending on what door you picked. The class I taught was in 0005. Room 005 was someone's office. So on the first day of every semester we would have students waiting outside the door of 005 instead of 0005...
- kybernetyk 4y agoBecause an array is just syntactic sugar for pointer arithmetic ... at least in C :)
- make3 4y agoI always assumed that it was because arrays and pointers would've been interchangeable in the start, and that adding a zero index times the object size gives you the first element
- ur-whale 4y agoUnfortunate that the Julia folks weren't exposed to this when they designed the language.
- Jtsummers 4y agohttps://juliaarrays.github.io/OffsetArrays.jl/stable/ https://juliaarrays.github.io/OffsetArrays.jl/stable/ 0-based or any arbitrary offset of your choice so that your data model can more closely map to what you need it to. And use eachindex instead of making assumptions and you can work with arrays using 1-based, 0-based, or arbitrary-based indexing.
- ur-whale 4y agoFor this particular problem, having a choice even worse than 1-based indexing. Code become a giant PITA to read because you have to switch back and forth.
- chmod775 4y agoAnother reason can be performance/memory. When you index starting at 1, you either have to add/subtract 1 internally, which sometimes but not always can be optimized away by a smart JIT/compiler, or you have to "waste" the first element in memory, trading memory for performance. Lua always subtracts 1, while LuaJIT instead went with the latter approach.
- ur-whale 4y agoSo that modulo works the way god intended inside a ring buffer.
- calibas 4y agoThe index of an array is an integer, and integer values start at zero, so it seems like an obvious choice as to where the starting point should be. It's only outside of computer science that it seems to be counter-intuitive.
- ottoflux 4y agomy thought is just "why not"? 0 is a number, and just because the west ignored it for quite some time (read: "Zero: The Biography of a Dangerous Idea") we have these odd built-in aversions to it but in the end it makes plenty of sense. 0th element is 0, so why don't we just do a better job of educating kids to start counting with 0 and thinking about 0. in the end - as a CS person, i think it's good - but i also don't mind if you disagree with me. :)
- mirekrusin 4y agoAlmost as interesting as hearing arguments for/against tabs/spaces.
- asimpletune 4y agoIn English, the day of your birth, when you're 0, is also your birthday. So, technically speaking, when you're turning 29, you're having your 30th birthday, even though no-one says it like that. I always assumed 0-based indexing was something like that, similar to the example given about the ground floor being the 0th floor in some countries and the first floor in others. Another example is if I'm getting directions from someone, and they say, "Walk 3 blocks that way", in my mind I conceptualize that I'm presently on the 0th block and I don't yet count it. I don't think every day people disagree with these examples so much (well, maybe the birthday one, but that's because we use the same word for the literal day as well as anniversary), and they're all fairly intuitive. I never realized that 0-based indexing required such a deep background to be justified.
- kbenson 4y ago> In English, the day of your birth, when you're 0, is also your birthday. That depends on whether you think of "birthday" as synonymous with "the actual day of my birth" or "a celebration of the day of my birth". I think most of us actual consider it the latter, which is why the first one is after you've been born for a year. If you look up the definition of "birthday" (one word, no spaces) you'll see that there is often some acknowledgement of this in the differing definitions offered. > "Walk 3 blocks that way", in my mind I conceptualize that I'm presently on the 0th block and I don't yet count it. You have to decide whether the person is saying something is on the third block from your position, or you need to walk about three blocks of distance. You probably do this automatically based on how close you are to the edge of the current block. If I'm 30 feet from the edge of a black, I'm probably not going to include the current block in that distance. I imagine you probably won't as well. > they're all fairly intuitive. I never realized that 0-based indexing required such a deep background to be justified. I think they're only intuitive because we're all context sensitive. The issue is when people don't have the same context, or the context no longer strictly makes sense when the terminology is used in contexts that make less sense. As an offset, and in programming languages where it's easy to see it's an offset (C), it makes perfect sense. In languages where that's all hidden from you, and you're really just referencing the nth item in a list, the 0th item doesn't make a lot of sense. People in these different contexts will likely have different ideas of what "intuitive" means with regards to this.
- Stratoscope 4y agoA related question: why is a rectangle containing a single pixel defined as (x,y):(x+1,y+1) instead of (x,y):(x,y)? Here's a discussion from some years ago that starts with some of Guido's thoughts on array indexing and moves on to the QuickDraw coordinate plane and points and rectangles, including how grid lines and points are infinitely thin/small, but pixels occupy the space between the grid lines. https://news.ycombinator.com/item?id=6602497 https://news.ycombinator.com/item?id=6602497
- pklausler 4y agoBecause sometimes we number things, and sometimes we count things.
- xg15 4y agoI don't quite understand the argument "0-based being easier for pointer arithmetic is nonsense because the language doesn't have pointers". Whether or not the language presents the concept of "pointer" to the user is independent of whether or not it uses pointers internally. And if it exposes arrays as a concept, it has to implement them somehow. The simplest possible implementation of arrays is having a start address and putting all elements next to each other in RAM. To get the address of a particular item, this layout naturally leads to the formula "base address + index * element size", with "index" being 0-based. If you want to expose other indexing schemes in your language, you'll have to add more logic to convert the user-visible index back to 0-based before you can obtain the address. All of this is completely independent of the fact whether your language exposes pointers to the user or not. Even the yacht story sort of hints at this: > To keep people from having their jobs cut short by yacht-racing, Richards designed the language to compile as fast as possible. One optimization was setting arrays to start at 0. If all indexing schemes were equal, why would this change even be an optimisation in the first place?
- Uptrenda 4y agoThis is far easier and clearer than the entire article. Good stuff.
- bluetomcat 4y agoThe "language" that has a 0-based indexing scheme is assembly. An HLL with 1-based counting that compiles to assembly will introduce additional computational overhead for the translation of the index. If 1-based indexing was used in assembly, then "mov 1(%ebx),%eax" would be the equivalent of "mov (%ebx),%eax".
- jiveturkey 4y ago> additional computational overhead at compile time, not runtime.
- saalweachter 4y agoFor constant addressing; for arr[i] = 2, you'll still need to subtract 1 from i with 1-based addressing when converting to machine instructions.
- soheil 4y agoThe concept of nothing doesn’t really belong in the number line. It’s like inventing a new “number” to represent blue and then using it instead of pi.
- soheil 4y agoQbasic uses 1 and that’s what I always loved about it. Coincidentally it was the same language I learned programming with at age 12.
- deleted 4y ago[deleted]
- caxco93 4y agoI always thought it was because it’s easier multiplying the index by the size of the array item to get the correct offset
- labrador 4y agoBecause zero is a concept that can mean "at the beginning" The symbol changed over time as positional notation (for which zero was crucial), made its way to the Babylonian empire and from there to India, via the Greeks (in whose own culture zero made a late and only occasional appearance; the Romans had no trace of it at all) Another meaning is "nothing" but we're talking about position, not nothingness The mathematical zero and the philosophical notion of nothingness are related but are not the same. Nothingness plays a central role very early on in Indian thought (there called sunya), and we find speculation in virtually all cosmogonical myths about what must have preceded the world's creation. So in the Bible's book of Genesis (1:2): "And the earth was without form, and void." https://www.scientificamerican.com/article/what-is-the-origin-of-zer https://www.scientificamerican.com/article/what-is-the-origi...
- deleted 4y ago[deleted]
- Symmetry 4y agoFor me, far more significant than anything else here is having to convert array indices into human readable text describing objects. And the objects are named by mechanical engineers who don't use 0 based indexing. So my code is full of print("Finger {}'s motor has overheated".format(i+1))
- jefftk 4y agoMy favorite example of this confusion is JS and (original) Java dates: > new Date() Wed Aug 24 2022 ... > new Date().getFullYear() 2022 > new Date().getMonth() 7 > new Date().getDate() 24 So 2022-08-24 comes out as (2022, 7, 24). One-based indexing for the year and day, zero-based indexing for the month.
- iainmerrick 4y agoThat comes from C’s standard library (and presumably from somewhere else before that). Classic bad design, took a very long time for people to figure out it was unhelpful and dangerous.
- jefftk 4y agohttps://linux.die.net/man/3/localtime https://linux.die.net/man/3/localtime: tm_mday: The day of the month, in the range 1 to 31. tm_mon: The number of months since January, in the range 0 to 11. I wonder where C got it? It goes back to at least 1973's V4: https://github.com/dspinellis/unix-history-repo/commit/92779735baa444db17a716db25ccb5dba7d1bf65 https://github.com/dspinellis/unix-history-repo/commit/92779...
- Jtsummers 4y agohttps://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/source/s4/ctime.c https://minnie.tuhs.org/cgi-bin/utree.pl?file=V6/usr/source/... Convenience. Look at how the days in the months are stored and accessed. Using 1-based months would introduce an extra calculation (-1) on all searches or an unused value in the 0-index. Also look at how printing is handled for weekday and month names. They, again, take advantage of 0-based indexing. Day and year are already represented as numbers, so it's natural to keep them as the "correct" (conventional) number as used by most people. Since the months aren't being stored as strings but as an index, this saves them from having useless data (entries in 0) or doing an extra calculation.
- jefftk 4y ago
- WaitWaitWha 4y agoI started programming in assembly, then Fortran, Algol, COBOL, etc. 0 based index makes sense to me. The memory location is offset 0 bytes from where the first data byte is stored (without getting into endianism).
- degrees57 4y agoFor me, it was 1 based index that makes sense to me. I started programming in FORTRAN, then COBOL, then (Lord help me) RPG II. All had 1 based arrays. I got paid to program in RPG II eight hours a day, five days a week, for two and a half years. A common bit of code was to create an array of month names. Then take an input date, say 20220825, and split that into $Year (first four characters) and $MonthNumber (next two) and $Day (next two). $MonthIndex = strip the leading zero (if present) from $MonthNumber Then, this code worked: $MonthName = @Month[$MonthIndex] When I ran into my first language with 0 based arrays, and @Month[1] returned February, I was pretty much convinced you all had gone insane. December is an out of bounds condition now? Really? Much later, a friend explained the stuff about multiplying the index by the array element length, and easily getting the memory location of the item in that array. It does make sense; but, I've always hated the code I've had to write that says $MonthName = @Month[$MonthNumber - 1]
- diego_sandoval 4y agoBecause otherwise you would be wasting a perfectly good number for no reason, which means you need to use more bits to do the same thing. To write 4 numbers (including zero) you only need two bits 0: 00 1: 01 2: 10 3: 11 To write 4 numbers if you avoid using the number zero, you need three bits 1: 001 2: 010 3: 011 4: 100 If you extrapolate that a little bit, you'll realize that you'll need two bytes (1 Byte + 1 bit from another byte) to store the indices of an array with 2^8 elements, which is just dumb. Some of you might be thinking: you don't need to store it the same way it's written, you can just substract 1 from whatever the user typed and convert it behind the scenes. Yes, you could subtract 1, but then you would be making the whole system more complex, opaque, and unelegant, while hiding information from the programmer for no good reason.
- divbzero 4y agoThe same applies to counting in other bases too. For instance, in 1-indexed counting grids for kids, the last column always feels out of place. 0-indexed decimal grid: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 1-indexed decimal grid: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
- waynecochran 4y agoIt's an offset from the beginning. Simple as that.
- dark-star 4y agoSimple answer: because everything in computers starts at 0. Address 0 is the first byte of memory, etc. You can now ask, "why does everything start with 0"? I guess because it gives you nice round (base-2) numbers. With 4 bits you can have 16 different "numbers", either 0 to 15 or 1 to 16. However, representing the number "16" in binary requires 5 bits, so you need an additional bit for the same number of elements. So representing 4 bits as 0 to 15 makes more sense
- anigbrowl 4y agoI may think that counting 0 as a natural number makes a lot of math more elegant, but clearly I’m just too dumb to rise to the level of wrong. fruits = ['apple'] \\ Hello I have fruits x = len(fruits) \\ Only one kind tho lol fruits[x] \\ OK here is what I have SUBSCRIPT OUT OF RANGE I have always hated zero indexing for this reason (other than thinking in assembler where it is beautiful). It is of course useful in many contexts, albeit with tradeoffs; more importantly everyone is used to it and it's predictable. But I was absolutely thrilled to discover Julia defaults to indexing from 1 like a normal person. Essentially what we have here is a mismatch between the tool (computer that does everything in binary) and the task (mathematical abstraction of quantities). Now it's completely understandable that people work within the limitations of the tool when there is no other choice, but that's the same sort of path dependency that creates technical debt. If zero indexing were so great, mathematicians would have made it the default centuries if not millennia ago; but mathematicians don't want to do off-by-1 adjustments on all sorts of common operations because it makes things unnecessarily complicated. To be honest, I think this has become a moat to keep people out of programming even though it's a shallow one. It could be interesting to test this, say by taking two classes of schoolchildren and teaching one Julia and the other Python (or...). By not having to take on the idea of zero-indexing at the same time as the concept of an array, the Julia group can get into collections using their intuitive understanding of the natural numbers. I expect that picking up language elements quickly will have a compounding effect and that at the end of the evaluation period the Julia group will be able to make significantly more complex programs than a control group. Edit: in your heart you know I'm right
- goatlover 4y agoAlso, considering that Python uses -1 for indexing the last element, instead of -0, which means the last element is not an offset when using negative indices.
- Rayhem 4y ago> If zero indexing were so great, mathematicians would have made it the default centuries if not millennia ago They did. For any context where the index contributes to the math[1] (i.e. is not simply a label convention like "the x (first) component") the index always start at zero. Polynomials, Fourier series, geometric series, Bessel functions (both their order and their series expansions), etc. [1]: Except, of course, when a divergent 1/0 term shows up.
- korse 4y agobase^0 = 1 base^1 = base base^2 = base * base et cetera. I've always considered the index and the power to which a base has been raised to be equivalent in many circumstances. Thus starting at 0 makes sense.
- thomasahle 4y agoDiscussion form 2013: https://news.ycombinator.com/item?id=6601515 https://news.ycombinator.com/item?id=6601515
- Koshkin 4y agoThe first element having the index zero may be natural or unnatural depending on the context. In mathematics, we count the rows in a matrix starting from 1, but we count the monomials in a polynomial starting (or ending) with 0. Generally, there is less need to use zero as the starting index: the Common Era does not have "the year zero" (there, -1 is followed by +1), etc.
- juped 4y agoZero-based indexing is always wrong; an ordered collection of things does not have a zeroth thing. Sometimes you have a data structure called an "array", which means "a bunch of things that are the same size next to each other in memory". You can store the address of the whole array as the address of its first element, and offset into it by an offset; clearly, the offset of the first element is zero, but it's not the "zeroth" element. And finally, sometimes you have cargo cult behavior by people who think that the way offsets into arrays work is because "numbering starts at zero in computers!" or some similarly wrong rationalization. This is when you get stupid things like (nth 0 list) in a lisp.
- dalmo3 4y agoAn ordered collection of events in time usually starts at t(0).
- ryanisnan 4y agoI hate to break it to you but natural spoken language is not a fixed concept, words can have many meanings and interpretations, and those meanings and interpretations can mean different things to different people at different times. Because you predominantly think of indexing as the first definition as shown here[1], does not mean everyone else does. Be careful when using absolutes, especially when talking about languages. [1] - https://www.merriam-webster.com/dictionary/index https://www.merriam-webster.com/dictionary/index
- Schroedingersat 4y agoAn ordered collection of things starts no things from the beginning. A journey starts 0 metres from the origin. If you count the number of _ you are along your journey and start with 1, then at the second metre you are at the 101st centimetre. When someone says how many dragons have you slain? Just as you leave and haven't heard of any dragons yet, you don't say "I'm slaying my first dragon now" Every construction of the natural numbers I have seen starts with 0. The first hour of the day has passed when the clock strikes one. The hour preceding that is the same day. English calls it 12 because it was invented before we had a firm grasp of zero and english is inconsistent. 24 hour clocks call it 00. 1 based indexing can be correct, but 1 based ordered discrete sets map incredibly poorly to any ordered set with a different number of elements (such as the reals). Additionally dealing with ranges is less easy to make consistent. 0 based indexing is always correct.
- dhosek 4y agoWhen he talked about BASIC having 1-based arrays, I had to check my memory against online AppleSoft BASIC documentation and indeed, AppleSoft, at least did have 0-based arrays.¹ I also had to check on Pascal which I haven’t written anything significant in for some 20 years and it turns out that by default, Pascal arrays are 1-based, but most of the code that I worked with (which tended to have its roots in Knuth-written Pascal) explicitly specified the range of indices. ⸻ 1. As did all the other contemporaneous BASICs that I encountered. For added fun, when creating an array with DIM, you gave the highest index and not the number of elements so, e.g., DIM A(20) created a 21-element array. The 1980 Apple ][ manual I found which discusses both Integer BASIC and AppleSoft doesn’t admit that 0 is a valid index for an array, but elsewhere I saw it indicated as such which leads me to suspect that Integer BASIC has 1-based arrays.
- wizofaus 4y agoModern Basic (VBA etc.) still supports 1 based arrays, and there's even Option Base (0|1). This is a global directive for all arrays declared in the same file. And individual arrays can be declared with any starting index you like.
- bitwize 4y agoMost of the BASICs I remember had 0-based indexing by default. But you could change this with the statement OPTION BASE 1 at the top of your program. This was true of even TI-99/4A BASIC, which was closer to Dartmouth BASIC and not written by Microsoft.
- Grustaf 4y agoSimple: because we start with index 0 in mathematics.
- yen223 4y agoI have encountered a lot of linear algebra textbooks that use 1-indexing to describe matrices and matrix operations.
- phaedryx 4y agoIf it starts at zero we should call it an "offset" That would fix so many of these discussions.
- rcoveson 4y agoMaybe, but then they'd just become discussions about whether `y` in the `x[y]` syntax "should" be an offset or an index. Which one gets the language priority? ...Of course, the answer is offset, because offsets are beautiful, composable, elegant things that harmonize with bitmasks, modulo, array slices, and everything else, while (one-based) indexes are nothing but "offset plus one", no more useful than "offset plus two".
- thwarted 4y agoIf your arrays start at 0, you have offsets. If your arrays start at 1, you have indexes. "0-indexed" shouldn't be a thing. I like the screenshot quote that refers to this as either "1-origin" or "0-origin".
- unixbane 4y agoSo what's the actual reason you'd want to have zero based arrays and such in your language (In 2020, not 1970)? In a language from scratch that doesn't care about being like previous ones, and doesn't care about micro optimization. I've been annoyed recently by this obnoxious neckbeard behavior when they make things zero based for no reason (other than to conform to their supposedly existent philosophy), like Ratpoison and Screen selecting windows by a zero based index, which means you have to move your hand to the far right of the keyboard to select the first window with the 0 key, the far left to select the second window, with the 1 key, and one to the right to select the third window, with the 2 key. I so happen to have been trying to work out a tangible explanation on paper of which system is better on trips a few weeks ago, and could not come up with one (and none are given in the article nor the top comments in this thread). On a side note, the moment you say, "zeroeth", you can no longer be sure anyone knows what you're talking about because at any moment you may count in English or this pretentious UN*Xtard dialect of English. Seems like another pedagogical stumbling block held on to boomers and boomer-wannabes who just want to have their little counter counter counter culture or whatever.
- oh_my_goodness 4y ago"math [...] sums seem to always be 0-indexed," What? Is this some kind of trolling challenge? If you don't care about math, just say so. Most people don't. But making up a nonexistent convention is just silly.
- deleted 4y ago[deleted]
- Schroedingersat 4y agoThe correct starting ordinal is 0. A list with a 0th element has cardinality 1. This is a concept that exists in many places in english, where the naturality of starting with the zeroth element trumps inertia but english is wildly inconsistent so it has both. Constructing the naturals without including 0 and starting with it is incredibly awkward. Addition doesn't even have an identity. Look at a clock, is 1 at the top, or is it the next one after the top. Look at a ruler. Does it start at 1? Do you want to have to shuffle everything around when you go from whole numbers to halves? Do you start at 0.5 or 0? Depends if it is "halves" or the real number 0.5 This is a recipe for pain and off by ones any time you're dealing with time steps (which is why it's so stupid that matlab and fortran are 1 indexed by default, if anything there's a better argument for C to be 1 indexed than scientific languages). Now index and compose a bunch of ranges. A half open range of two elements is incredibly stupid 1 <= i < 3. So closed ranges go with 1 indexing. Composing and splitting them is incredibly awkward [a,c] is split into [a,b], [b+1, c] ... that's kind of okay, but not unique as you could use [a,b-1], [b,c]. Now do [d,e], [e,f] compose at a glance? Half open ranges go with zero indexing and they just work.
- dboreham 4y agoUnusually for me, I read TFA first. Immediately thought "this is all wrong", then realized 400 commenters had posted the same thing already. I have Martin Richards book on my shelf, and for a while shared an office with his coworker. I'm also one of the few folks here who has coded in BCPL. Ok, so that said, this article is obvious nonsense. Zero indexing comes from the CPU itself. It's how you generate an indirect address by adding the offset. Many CPUs have this in hardware. They don't support non-zero offsets. The reason some languages have zero-based indexes is that their developers had the mind set of doing the same thing you do when writing machine code. They probably also wanted to directly interface between their language and libraries written in assembler (and the kernel was typically written in assembler too). Also they wanted to be efficient. Any offset other than zero is not efficient because you can't use the hardware addressing modes. So then why do some languages _not_ have zero based indices? The obvious answer it that Mathematics by convention always used 1 as the base (or some arbitrary value). Many languages were conceived by mathematicians or people with a strong mathematical background.
- notpushkin 4y agoThe Lessons section is brilliant.
- OJFord 4y agoWhy do tape measures start at 0?
- 323 4y agoObligatory, there are a lot of memes on this subject: https://www.google.com/search?q=arrays+start+at+zero+meme&tbm=isch https://www.google.com/search?q=arrays+start+at+zero+meme&tb...
- charlieyu1 4y agoA problem with 0-based arrays is that 0 is the only index with a Falsely Boolean value.
- zzo38computer 4y agoI think that zero indexed is generally better, including that it involves adding the index number to the base address, and other properties that can be helpful. However, it can also be useful for many purposes to allow arbitrary ranges, so a programming language probably should allow that; if the index of the first element is not zero, then the base address will not be the address of the first element (if the first element index is positive, then the base address may actually point into a different array, or a different variable). Then, if you have the base address and add the index, you will have the proper address of that element, whether or not the first index number is zero. Zero is not always the most useful starting index; sometimes other numbers (which may be positive or negative) are useful. But, I think in general, zero is better.
- kentonv 4y agoThe 1900's were the twentieth century. Except the year 1900 specifically was still the nineteenth century; the twentieth century started in 1901 and ended at the end of 2000, much to the chagrin of all the chumps who celebrated the millennium a year early. You know what would make all this confusion go away? Zero-based indexing.
- cpurdy 4y agoGood article. Especially the DBAD comment.
- jy14898 4y agodata Position = Start | Next Position
- Koshkin 4y agoBut the first year of this century was 2001…
- mjcohen 4y agoLanguages like fortran and Ada allow arrays to start at any index. This allows you to do what matches your problem.
- quickthrower2 4y agoI write code that interfaces between C# and R and you have to be careful to remember to do the indexing change. Fun!
- dathinab 4y agoIgnoring the past; 0 indexing is: - closer to hardware - makes index == element wise offset from the first element - there are both algorithm which are (very slightly) easier to implement with 0 and 1 indexing, AFIK more of the "bread and butter" algorithm are easier with 0 then 1 (e.g. indexing of C-style arrays used all the time, heaps etc.) - 0 is not special => less bounds checks in typed languages (if you have an unsigned int index you only have to check the upper bounds, with 1-index you also have to check for 0) - 0 is not special => with signed integer you can have negative indices (from the end) in which case all signed integers are valid (but potential out of bounds), with 1 indexing you have a "gap" in the middle which for some (rare) use cases can be very painful to handle So independent of what the history was. It's just much more pragmatic to use 0-indexing in many common use-cases. Especially given that 1-indexing produces more special cases for very common use-cases makes it sub-optimal for both usability and performance.
- notshuttingdown 4y agoBSD bash arrays are 1 indexed for some reason
- mlindner 4y agoBecause back when computers were young, all bit representations were needed to represent something and having 000 not be used as a valid value wastes a huge percentage of available space.
- petilon 4y agoThe best source for the development of C language is Bell Labs https://www.bell-labs.com/usr/dmr/www/chist.html https://www.bell-labs.com/usr/dmr/www/chist.html Excerpt: By a general rule, in B the expression *(V+i) adds V and i, and refers to the i-th location after V. Both BCPL and B each add special notation to sweeten such array accesses; in B an equivalent expression is V[i] C was designed to be as close to the machine as possible. Prior to C the only programming language for systems programming was assembly. If the compiler-generated code subtracted 1 from the index every time you indexed an array that would have been seen as not as efficient as assembly.
- civilized 4y agoIn defense of starting at 1: if you're counting things, starting at 1 ensures that the last number you said is equal to the number of things you've counted so far. Toddlers love this invariant.
- magpi3 4y agoAfter programming in C for a while, I really began to have the feeling that arrays were physical things that took up space in RAM. When I think like this, starting an index at 0 is very intuitive, as 0 implies the origin point of the physical construct. If you think of arrays just as a kind of abstract list, then beginning at 1 makes much more sense. No one who looks at a to-do list at home talks about the 0th thing on their list to do. But the spacial nature of arrays makes starting at 1 confusing. After I take 1 step, I am no longer at my starting point. And cycling through arrays in code for me has a very similar feeling to taking actual physical steps through a data structure.
- xmprt 4y agoThat reminds me of this article about the history of hjkl in VIM: https://www.hillelwayne.com/post/always-more-history/ https://www.hillelwayne.com/post/always-more-history/ Lo and behold, it's written by the same author.
- fomine3 4y agoWhy do months start at 0? is my real claim.
- dirkg 4y agoNatural numbers start at 0, so it makes sense. 1 is just as arbitrary as 2 or 79823 etc. Math wouldn't work without 0. Thats good enough for me.
- notsapiensatall 4y agoNobody mentioned Lua? Really? Lua's arrays are 1-indexed, and it is a terrific interpreted language! Array[0] is nil, makes sense. v5.1 has a solid JIT, and it's got a great 2D game engine called Löve2D.
- hans_castorp 4y agoPascal and SQL also use 1-based arrays
- kwertyoowiyop 4y agoSeeing 544 comments about this story has restored my faith in HN. :-)
- nullc 4y agoMaybe my thinking is just warped by the language, but I think 0 indexing is the right thing most-- but not all-- of the time. Looking at my code I have relatively few places where I need to -1 to convert a natural 1 index into a zero index. It would be easy for languages to offer two array access syntaxes, one for 0 and one for 1 like array[i] for 0 index and array{i} for 1 index access, then the accessing code could use the right tool for the job. Unlike defining the indexing type as a property of an array you shouldn't have problems with accidentally using the wrong one at time of use. ... but to really know if it's a good idea you'd have to test it, and sadly very few concepts in programming are subjected to any kind of rigorous scientific study.
- smeagull 4y agoBecause indexing happens with integers. Back then space was a concern, so you'd use unsigned integers, and those start with zero. Internally they'll all be using offsets, and its easier to not do a conversion, than to do a conversion.
- parentheses 4y agohttps://blog.nelhage.com/2015/08/indices-point-between-elements/ https://blog.nelhage.com/2015/08/indices-point-between-eleme...
- osigurdson 4y agoWow, we are still talking about this, are we? Honestly, linear algebra texts should just give in and adopt zero based indexing for matrices at this point.
- fvold 4y ago"It's an offset from the beginning. The first element is 0 slots from the beginning." is what I was taught. (Of course, it's more complicated than that, with pointer math etc etc, but that works as a general gist) In the past, I've written roughly half a million lines of Lua. Arrays don't always start at 0. I've regularly shaken my fist at Lua and cursed it's wicked ways, but it's really damn useful in a lot of contexts.
- IshKebab 4y ago0-based indexing is clearly the best option because it results in more elegant code and it matches what computers actually do. In fact, it's so fundamentally more elegant that I've come to the conclusion that the real issue is that it's actually the mathematicians and language itself that got indexing wrong. Instead of "first" being associated with 1, it should be associated with 0. We should give athletes 0th place, and talk about the 0th man on the moon etc. That's where the cognitive dissonance for the 1-based-indexing people is coming from. They can't deal with the fact that their "normal" way of indexing is wrong. It's a bit like how pi should really be tau (2*pi), or the electron should really be positive. We got it wrong, but we're stuck with it because it's too much of a hassle to change it. Fortunately computing got it right! But now there's a mismatch with everyday life where people are used to the wrong thing.
- de6u99er 4y agoReminds me of a simple implementation of a Prisoners and Boxes riddle that showed up in my YouTube feed where I had to add a comment so others (and eventually future older me) will understand what I did. >// if one prisoner fails all are dead (1st try -> tries = 0) https://gist.github.com/amalic/c107b5289d946b758418778a95fdce64#file-prisonersandboxes-java-L32 https://gist.github.com/amalic/c107b5289d946b758418778a95fdc... That being said, it seems to be a junior software engineer issue where the brain isn't wired yet for "0-based" indexing. I don't hear such complaints from more experienced developers who have simply learned to appreciate it because like in my example above it is more intuitive to me. I have added "and eventually future older me" above because I don't do much coding these days, and my career trajectory looks like it's going to be even less in the future.
- cortic 4y agoIts an absolute pain in my arse, i honestly don't know what problems i would have with an array system that started at 1, but since the length method sometimes starts at 0 and sometimes 1, (I'm thinking Perl vs JS) I'm always forgetting whether to put = or <= into for loops and when to add one for the read out or subtract 1 when looking at the array again. I mean in what universe should [2]+[3]=7?
- andsoitis 4y agoAn Array in Ada is interesting. https://learn.adacore.com/courses/intro-to-ada/chapters/arrays.html https://learn.adacore.com/courses/intro-to-ada/chapters/arra... Like other languages, it is a collection of contiguous elements that can be selected by indexing. Unlike other languages: - any discrete type can be used for indexing, not just integers - bounds can be any value (doesn’t have to start at 0 or 1. First index could be 13) - one consequence of the aforementioned is that arrays are types that map to the problem domain, rather than being tied to the computing domain - and more…
- Jemm 4y agoBecause ordinal counting has been a tenant of computer science since inception.
- effnorwood 4y ago