20 ms·
Numbering should start at zero (1982)
- sim7c00 2y agolove this :D "The above has been triggered by a recent incident, when, in an emotional outburst, one of my mathematical colleagues at the University —not a computing scientist— accused a number of younger computing scientists of "pedantry" because —as they do by habit— they started numbering at zero. " :')
- roenxi 2y agoThe 1980s were not a particularly enlightened time for programming language design; and Dijkstra's opinions seem to carry extra weight mainly because his name has a certain shock and awe factor. It isn't usual for me to agree with the mathematical convention for notations, but the 1st element of a sequence being denoted with a "1" just seems obviously superior. I'm sure there is a culture that counts their first finger as 0 and I expect they're mocked mercilessly for it by all their neighbours. I've been programming for too long to appreciate it myself, but always assumed it traces back to memory offsets in an array rather than any principled stance because 0-counting sequences represents a crazy choice.
- sham1 2y agoZero-based counting works better with modular arithmetic. Like arr[(i++ % arr.length)] = foo; Is certainly nicer than the equivalent in one-based subscripting arr[(i++ % arr.length) + 1] = foo; (The above is actually wrong, which helps the idea) I'll concede that it's not all that significant as a difference, but at least IMO it's nicer. Also could argue that modular arithmetic and zero-based indexing makes more sense for negative indexing.
- Quekid5 2y agoYes, negative indexing as in e.g. Python (so basically "from the end") can be incredibly convenient and works seamlessly when indexes are 0-based.
- pansa2 2y agoNot quite seamlessly, unfortunately. `l[:n]` gives you the first `n` elements of the list `l`. Ideally `l[-n:]` would give you the last `n` elements - but that doesn't work when `n` is zero. I believe this is why C# introduced a special "index from end" operator, `^`, so you can refer to the end of the array as `^0`.
- UncleEntity 2y agoSo you're saying a negative index value should work like a count of elements to return and not an index? Then you couldn't do thing like l[-4:-2] to get a range of elements which seems slightly useful.
- pansa2 2y agoNo - negative indexing is fine as it is. You just need to be careful about the special case of negative zero.
- Ukv 2y ago> Yes, negative indexing as in e.g. Python (so basically "from the end") can be incredibly convenient and works seamlessly when indexes are 0-based. I'd claim 0-based indexing actually throws an annoying wrench in that. Consider for instance: for n in [3, 2, 1, 0]: start_window = arr[n: n+5] end_window = arr[-n-5: -n] The start_window indexing works fine, but end_window fails when n=0 because -0 is just 0, the start of the array, instead of the end. We're effectively missing one "fence-post". It'd work perfectly fine with MatLab-style (1-based, inclusive ranges) indexing.
- tmtvl 2y agoBut on the other hand, last := vector[vector-length(vector)]; is nicer than last := vector[vector-length(vector) - 1]; so in the end I'd say 'de gustibus non est disputandum' and people who prefer 0-based indexing can use most languages and I can dream of my own.
- naasking 2y agoThat's arguably one of the only downsides of zero-based, and can be handled easily with negative indexing. Basically all indexing arithmetic is easier with zero-based.
- tmtvl 2y agoUsing an array as a heap is also easier with 1-based indexing: base-element := some-vector[i]; left-child := some-vector[i * 2]; right-child := some-vector[i * 2 + 1]; where the root element is `some-vector[1]'.
- tetha 2y agoI've heard the statement "Let's just see if starting with 0 or 1 makes the equations and explanations prettier" quite a few times. For example, a sequence <x, f(x), f(f(x)), ...> is easier to look at if a_0 has f applied 0 times, a_1 has f applied 1 time, and so on.
- xandrius 2y agoWhat culture would that be? Because I was under the impression that counting "nothing" generally makes little sense in most of the practical world.
- branko_d 2y ago0-based indexing aligns better with how memory actually works, and is therefore more performant, all things being equal. Assuming `a` is the address of the beginning of the array, the 0-based indexing on the left is equivalent to the memory access on the right (I'm using C syntax here): a[0] == *(a + 0) a[1] == *(a + 1) a[2] == *(a + 2) ... a[i] == *(a + i) For 1-based indexing: a[1] == *(a + 1 - 1) a[2] == *(a + 2 - 1) a[3] == *(a + 3 - 1) ... a[i] == *(a + i - 1) This extra "-1" costs some performance (through it can be optimized-away in some cases).
- hn_throwaway_99 2y agoThe comment you are replying to essentially said exactly that: > but always assumed it traces back to memory offsets in an array rather than any principled stance because 0-counting sequences represents a crazy choice.
- goatlover 2y agoBut then again Fortran proceeded C, is known for being very performant, and is 1-based by default.
- Aardwolf 2y agoFor math too, 0-based indexing is superior. When taking sub-matrices (blocks), with 1-based indexing you have to deal with + 1 and - 1 terms for the element indices. E.g. the third size-4 block of a 16x16 matrix begins at (3-1)*4+1 in 1-based indexing, at 2*4 in 0-based indexing (where the 2 is naturally the 0-indexed block index). Also, the origin is at 0, not at 1. If you begin at 1, you've already moved some distance away from the origin at the start.
- shiandow 2y agoIn mathematics, if it matters what index your matrix starts on then you're likely doing something wrong. Besides, in the rare cases where it does matter you're free to pick whichever is convenient.
- deleted 2y ago[deleted]
- venusenvy47 2y agoJust speaking anecdotally, I had the impression that math people prefer 1-based indexing. I've heard that Matlab is 1-based because it was written by math majors, rather than CS majors.
- Aardwolf 2y agoYes but I think it might be just habit, and it's exactly in matlab that dealing with for loops over sub matrices is so annoying due to this
- BeetleB 2y agoIndeed. I was going to point out that mathematicians choose the index based on whatever is convenient for their problem. It could begin at -3, 2, or whatever. I've never heard a mathematician complain that another mathematician is using the "wrong" index. That's something only programmers seem to do.
- personalaccount 2y ago> The 1980s were not a particularly enlightened time for programming language design; and Dijkstra's opinions seem to carry extra weight mainly because his name has a certain shock and awe factor. Zero based indexing had nothing to do with Dijkstra's opinion but the practical realities of hardware, memory addressing and assembly programming. > I'm sure there is a culture that counts their first finger as 0 Not a one because zero as a concept was discovered many millenia after humans began counting.
- pwdisswordfishz 2y ago> Dijkstra's opinions seem to carry extra weight mainly because his name has a certain shock and awe factor So you claim this is just an appeal to authority and as a rebuttal you give appeal to emotion without being an authority at all? > the 1st element of a sequence being denoted with a "1" just seems obviously superior > I'm sure there is a culture that counts their first finger as 0 and I expect they're mocked mercilessly for it by all their neighbours > 0-counting sequences represents a crazy choice 5G chess move.
- barotalomey 2y ago1 or 0-based index... I recently picked up Lua for a toy project and I got to say that decades of training with 0-based indexes makes it hard for me to write correct lua code on the first try. I suppose 1-based index is more logical, but decades of programming languages choosing 0-based index is hard to ignore.
- ginko 2y ago>I suppose 1-based index is more logical I wouldn't say it's more logical. More intuitive perhaps.
- adrian_b 2y agoIt is not more intuitive. It just matches the convention used in the language that one has learned as a child, so one is already familiar with it. The association between ordinal numbers and cardinal numbers such that "first" corresponds to "one" has its origin in the custom of counting by uttering the string "one, two, three ..." while pointing in turn to each object of the sequence of objects that are counted. A more rigorous way of counting is to point with the hand not to an object, but to the space between 2 successive objects, when it becomes more clear that the number that is spoken is the number of objects located on one side of the hand. In this case, it becomes more obvious that the ordinal position of an object can be identified either by the number spoken when the counting hand was positioned at its right or by the number spoken when the counting hand was positioned at its left, i.e. either "0" or "1" may be chosen to correspond to "first". Both choices are valid and they are mostly equivalent, similarly to the choice between little-endian and big-endian number representation. Nevertheles, exactly like little-endian has a few advantages for some operations, so eventually it has mostly replaced big-endian representations, the choice of "0" for "first" has a few advantages and it is good that it has mostly replaced the "1 is first" convention. For people who use only high-level programming languages, the differences between "0 is first" and "1 is first" are less visible, exactly like the differences between little-endian and big-endian. In both cases the differences are much more apparent for compiler writers or hardware implementers. Besides "1 is first" vs. "0 is first" and little-endian vs. big-endian, there exists another similar choice, how to map the locations in a multi-dimensional array to memory addresses. There is the C array order and the Fortran array order (where elements of the same column are at successive addresses). Exactly like "1 is first" and big-endian numbers match the conventions used in writing the European languages, the C array order also matches the convention used in the traditional printed mathematical literature. However, exactly like in the other 2 cases, the opposite convention to the traditional written texts, i.e. the Fortran array order is the superior convention from the point-of-view of the implementation efficiency. Unfortunately, because much less people are familiar with the implementation of linear algebra than with the simpler operations with numbers and uni-dimensional arrays or strings, so they are not aware about the advantages and disadvantages of each choice, the Fortran array order is used only in a minority of programming languages. (An example of why the Fortran order is better is the matrix-vector product, which must never be implemented with scalar products as misleadingly defined in textbooks, but with AXPY operations, which are done with sequential memory accesses when the Fortran order is used, but which require strided memory accesses if the C order is used. There are workarounds when the C order is used, but with the Fortran order it is always simpler.)
- arnsholt 2y agoBoth are fine, IMO. In a context where array indexing is pointer plus offset, zero indexing makes a lot of sense, but in a higher level language either is fine. I worked in SmallTalk for a while, which is one indexed, and sometimes it made things easier and sometimes it was a bit inconvenient. It evens out in the end. Besides, in a high level language, manually futzing around with indexing is frequently a code smell; I feel you generally want to use higher level constructs in most cases.
- shrubble 2y agoExplains why he didn't like APL...
- personalityson 2y agoHe also hated Lisp
- kazinator 2y agoI don't know of evidence that he did. But Dijkstra left us a famous quote: "LISP has jokingly been described as “the most intelligent way to misuse a computer”. I think that description a great compliment because it transmits the full flavour of liberation: it has assisted a number of our most gifted fellow humans in thinking previously impossible thoughts." This is obviously a compliment; it even mentions that word. Even a less positive remark than this would still be resounding compliment from a computer scientist who said things such as that BASIC causes irreparable brain damage! So count this as a piece of evidence that he liked Lisp. Lisp emphasizes structured approaches, and from the start it has encouraged (though not required) techniques which avoid destructive manipulation. There is a lot in Lisp to appeal to someone with a mindset similar to Dijkstra.
- personalityson 2y ago"I must confess that I was very slow on appreciating LISP’s merits. My first introduction was via a paper that defined the semantics of LISP in terms of LISP, I did not see how that could make sense, I rejected the paper and LISP with it." https://www.cs.utexas.edu/~EWD/transcriptions/EWD12xx/EWD1284.html https://www.cs.utexas.edu/~EWD/transcriptions/EWD12xx/EWD128...
- kazinator 2y agoEven McCarthy initially rejected the idea that the Lisp-in-Lisp specification could simply be translated into working code so that an interpreter pops out; at first he thought Steve Russel was misunderstanding something.
- myfonj 2y agoI found it devastating that there are no distinct agreed-upon words denoting zero- and one-based addressing. Initially I thought that the word "index" clearly denotes zero-base, and for one-base there is "order", "position", "rank" or some other word, but after rather painful and humiliating research I stood corrected. ("Index" is really used in both meanings, and without prior knowledge of the context, there is really no way to tell what base it refers to.) So to be clear, we have to tediously specify "z e r o - b a s e d " or "o n e - b a s e d" every single time to avoid confusion. (Is there a chance for creating some new, terser consensus here?)
- aero142 2y agoI humbly submit '1ndex' and 'ind0x', or '1dx' and 'i0x'.
- pixl97 2y agoWhile most people ran screaming from programming assembly aero142 thought it was a rather swell idea.
- tdeck 2y agoFrankly it's no worse than "mebibyte".
- wasabi991011 2y agoPronounced "one-dex" and "in-dox"?
- Rygian 2y agoI think that "zero-based" and "one-based" expressions are the distinct agreed-upon "words" and they are terse enough. I can suggest "z8d" and "o7d" otherwise. (/jk)
- xandrius 2y agoI always thought: - Offset: 0-based - Index: 1-based
- deleted 2y ago[deleted]
- kibwen 2y agoI appreciate Dijkstra's arguments, but the fact remains that no non-technical user is ever going to jibe with a zero-indexed system, no matter the technical merits. Languages aimed at casual audiences (e.g. scripting languages like Lua) should maybe just provide two different ways of indexing into arrays: an `offset` method that's zero-indexed, and an `item` method that's one-indexed. Let users pick, in a way that's mildly less confusing than languages that let you override the behavior of the indexing operator (an operator which really doesn't particularly need to exist in a world where iterators are commonplace).
- School-Cotton 2y agoThere is no good reason to cater to non-technical users when designing programming languages. In what way is Lua “aimed at casual audiences”?
- pansa2 2y agoFrom Roberto Ierusalimschy himself [0]: "one of the design goals, was for Lua to be easy for nonprogrammers to use" [1] https://www.reddit.com/r/lua/comments/w8wgqb/complete_interview_with_roberto_ierusalimschy/ https://www.reddit.com/r/lua/comments/w8wgqb/complete_interv...
- kragen 2y agoA lot of Lua users are kids playing Luanti or Roblox or WoW who also spend a little time modding them—mostly editing textures or 3-D model meshes, but also scripting. Lua is a small and simple language which can be learned easily, prefers to produce incorrect answers instead of throwing exceptions when confronted with ambiguous situations (for example, permitting undeclared variables), has an interactive REPL, is memory-safe to avoid crashes, and uses dynamic typing (thus avoiding type declarations) and has garbage collection, as well as using 1-based indexing. All of these design features seem to be helpful to casual programmers and are common in languages and programming environments designed for them, such as BASIC, Smalltalk, sh, Python, Tcl, and Microsoft Excel. pansa2's comment https://news.ycombinator.com/item?id=43435736 https://news.ycombinator.com/item?id=43435736 also has a citation to Ierusalemschy, who said in https://old.reddit.com/r/lua/comments/w8wgqb/complete_interview_with_roberto_ierusalimschy/ https://old.reddit.com/r/lua/comments/w8wgqb/complete_interv...: > And at that time, the only other option would be Tcl, "tickle.” But we figured out that Tcl was not easy for nonprogrammers to use. And Lua, since the beginning, was designed for technical people, but not professional programmers only.In the beginning, the typical users of Lua, were civil engineers, geologists, people with some technical background, but not professional programmers. And "Tcl" was really, really difficult for a non-programmer. All those substitutions, all those notions, etc. So we decided to create a language because we actually needed it. (Tcl, of course, was designed for chip designers.)
- pansa2 2y ago"Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration." — Stan Kelly-Bootle
- kps 2y agoFirst person to get a postgraduate degree in CS. I still miss his satirical writing.
- TOGoS 2y agoHe was right. If the first fencepost is centered at x=0 and the second at x=1, and you want to give the rail in-between some identifier that corresponds to its position (as opposed to giviung it a UUID or calling it "Sam" or something), 0.5 makes perfect sense. In computer programming we often only need the position of the gap to the left, though, so calling it "the rail that starts at x=0" works. Calling it "the rail that ends at x=1" is alright, I guess, if that's what you really want, but leads to more minus ones when you have to sum collections of things.
- edbaskerville 2y agoI can't find a reference, but I have a vague memory that in original Mac OS X, 1-pixel-width lines drawn at integer locations would be blurred by antialiasing because they were "between" pixels, but lines drawn at e.g. x = 35.5 were sharp, single-pixel lines. Can anyone confirm/refute this?
- TOGoS 2y agoNot sure about old Mac OS, but I think HTML canvas works that way.
- boothby 2y agoPython supports a third way: start at -1. And if you think about it a little (but not too much) then there's some real appeal to it in C. If you allocate an array of length n and store its length and rewrite the pointer with (*a+=n)=n, then a[0] is the length, a[-1] is the first element (etc) and you free(a-a[0]) when you're done. As a nice side effect, certain tracing garbage collectors will never touch arrays stored in this manner. Upshot: if you take the above seriously (proposed by Kelly Boothby), the median proposed by Kelly-Bootle returns to the only sensible choice: zero.
- yazantapuz 2y agoI like my numbering to start like my tape measure: at zero.
- laurentlb 2y agoI like my numbering to start like my elevator panel: at zero.
- auggierose 2y agomine starts at -1
- tsm 2y agoAmerican elevators are 1-indexed!
- harrison_clarke 2y agoat the whitney art gallery (nyc), the ground floor is 1, but the basement is -1. there's no 0 in between it bothers me way more than it should. i have to tell myself that the point of art is often to evoke emotions, and the rage i feel is included in that
- 01HNNWZ0MV43FF 2y agoWhen my badge doesn't scan at work, that is great art
- Y_Y 2y agoIn the Boole Library in Ireland (which has entrances on different floors) they use an algebraic (affine) system. There is a floor designated "Q" and then other floors are labelled relatively, "Q+2", "Q-1", etc.
- School-Cotton 2y agoAt the University of Arizona (or at least in most of the buildings there), the lowest floor of the building is always 1, even if it’s a basement. So the ground floor is often 2. Maddening.
- golol 2y agoConsider n real numbers a_0, ..., a_{n-1}. That's not very elegant.
- nikolayasdf123 2y agoas a software engineer I see this all day long haha but good point, remembering academic linear algebra, seeing 0..n-1 in sigma/sums notations would be not convenient
- Y_Y 2y agoSure it is. This discrepancy appears in physics too. It's common to use 1,2,3 for spatial indices, but when you reach enlightenment and think in terms of spacetime you add a zero index and not a four.
- pwdisswordfishz 2y agoThat's only because you insist on explicitly mentioning the last element, which you can only do when the sequence is finite and non-empty (more generally, when it is indexed by a successor ordinal). So your choice of notation is not only inelegant, it cannot even express all possible sequences.
- 1970-01-01 2y agoNumbers are a joke. I count from A-Z and then Aa Ab Ac ... I have Ar apples for sale. Only $A.J each!
- School-Cotton 2y ago1-based numbering is nonsense. How many years old are you when you’re born? I notice almost all defenses of 1-based indexing are purely based on arbitrary cultural factors or historical conventions, e.g. “that’s how it’s done in math”, rather than logical arguments.
- Ukv 2y ago> How many years old are you when you’re born? You have lived zero full years and are in the first year of your life. In most (but not all) countries the former is considered "your age". That's consistent with both zero-based and one-based indexing. Both agree on cardinal numbers (an array [1, 2] has length 2), just not on ordinal numbers (whether the 1 in that array is the "first" or "zeroth" element). > I notice almost all defenses of 1-based indexing are purely based on arbitrary cultural factors or historical conventions, e.g. “that’s how it’s done in math”, rather than logical arguments. I think it's largely a matter of taste in either direction. But, I'd raise this challenge: arr = ['A', 'B', 'C', 'D', 'E', 'F'] slice = arr[3:1:-1] print(slice) If you're unfamiliar with Python (zero-based, half-open ranges exclusive of end), that's taking a slice from index 3 to index 1, backwards (step -1). How quickly can you intuit what it'll print? Personally I feel like I have to go through a few steps of reasoning to reach the right answer - even despite having almost exclusively used languages with 0-based indexing. If Python were instead to use MatLab-style indexing (one-based, inclusive ranges), I could immediately say ['C', 'B', 'A'].
- School-Cotton 2y agoI don’t know python but I figured out immediately that it should print ['C', 'B']. Does it? If not, Python is just wrong.
- pansa2 2y agoNo, it doesn't, it prints ['D', 'C']. I agree that it should be ['C', 'B'] - the way that Python handles negative `step` values is wrong.
- nivertech 2y agoNumbering should start at π (2025) (umars.edu) Seriously, it all depends on whether u're counting the items themselves (1-based) or the spaces btwn them (0-based). The former uses natural numbers, while the latter uses non-negative integers For instance, when dealing with memory words, do u address the word itself or its starting location (the first byte)? The same consideration applies to coordinate systems: r u positioning urself at the center of a pixel or at the pixel's origin? Almost 2 decades ago I designed an hierarchical IDs system (similar to OIDs[1]). First I made it 0-based for each index in the path. After a while I understood that I need to be able to represent invalid/dummy IDs also, so I used -1 for that. It was ugly - so I made it 1-based, & any 0 index would've made the entire ID - invalid --- 1. https://en.wikipedia.org/wiki/Object_identifier https://en.wikipedia.org/wiki/Object_identifier
- jacksnipe 2y agoZero is a natural number. It is in the axioms of Peano arithmetic, and any other definition is just teachers choosing a taxonomy that best fits their lesson.
- deleted 2y ago[deleted]
- jmkr 2y ago+1 for peano arithmetic club. I never realized it was controversial. I think I've always included 0 in the nat numbers since learning to count. But there are some programming books I've read, I want to say the Little Typer, or similar, that say "natural number" or "zero". Which makes actually confuses me.
- nivertech 2y agoIMO zero represents an absence of quantity and doesn't appear in Nature, so it cannot be classified as a Natural number Just like a negative numbers, it's a higher-level abstraction or a model, not a direct observation from the Nature Likewise, the digit "0" originating from the Hindu-Arabic numeral system[1] is merely a notation, not a number --- 1. https://en.wikipedia.org/wiki/Hindu%E2%80%93Arabic_numeral_system https://en.wikipedia.org/wiki/Hindu%E2%80%93Arabic_numeral_s...
- Aransentin 2y agoPerhaps ideally we'd change English to count the "first" entry in a sequence as the "zeroth" item, but the path dependency and the effort required to do that is rather large to say the least. At least we're not stuck with the Roman "inclusive counting" system that included one extra number in ranges* so that e.g. weeks have "8" days and Sunday is two days before Monday since Monday is itself included in the count. * https://en.wikipedia.org/wiki/Counting#Inclusive_counting https://en.wikipedia.org/wiki/Counting#Inclusive_counting
- davidgay 2y ago> At least we're not stuck with the Roman "inclusive counting" system that included one extra number in ranges* so that e.g. weeks have "8" days French (and likely other Latin languages?) are not quite so lucky. "En 8" means in a week, "une quinzaine" (from 15) means two weeks...
- MITSardine 2y agoHmm, "en 8" makes sense to me in that you're using it to reference the next Whateverday that is at least 8 days apart from now. If we're on a Tuesday, and I say we're meeting Wednesday in eight, that Wednesday is indeed 8 days away. Now I'm fascinated by this explanation, which covers the use of 15 as well. I'd always thought of it as an approximation for a half month, which is roughly 15 days, but also two weeks. To partially answer the other Latin languages, Portuguese also uses "quinze dias" (fifteen days) to mean two weeks. But I don't think there is an equivalent of the "en huit". We'd use "na quarta-feira seguinte" which is equivalent to "le mercredi suivant".
- 01HNNWZ0MV43FF 2y agoIt is definitely my engineer myopia, but octaves in music should be called dozens
- mdiesel 2y agoI think we should call them doubles
- silotis 2y agoPretty much any algorithm that involves mul/div/mod operations on array indexes will naturally use 0-based indexes (i.e. if using 1-based indexes they will have to be converted to/from 0-based to make the math work). To me this is a far more compelling argument for 0-based indexes than anything I've seen in favor of 1-based indexes.
- pwdisswordfishz 2y agoForget multiplication, even addition becomes simpler.
- nikolayasdf123 2y agosets is the most intuitive reason for me [0,1,2) + [2,3,4) = [0,1,2,3,4) meanwhile [0,1,2] + [2,3,4] = [0,1,2,2,3,4] — this double counting is just ugly
- phkahler 2y ago>> when starting with subscript 1, the subscript range 1 ≤ i < N+1; starting with 0, however, gives the nicer range 0 ≤ i < N. What about the range 0 < i ≤ N which starts with 1? Why only use ≤ on the lower end of the range? This zero-based vs one-based tends to come up in programming and mathematics, and both are used in both areas. Isn't it obvious that there is no universally correct way to index things?
- sfink 2y agoI believe the main argument (from the OP) is that you have to specify the range with two bounds, and that it is common to want a 0 (assuming a 0-based indexing world), and so in order to refer to a range that includes index 0 you'll need to use a number that is not in the set of valid indexes to define the bound. I would note that the argument is weakened when you look at the later bound, since you have the same problem there, it's just more subtle and less commonly encountered -- yet it routinely creates security bugs! It's because we don't work with integers, we work with fixed-size intervals within the set of integers (usually a power of two consecutive integers). So `for (i = 0; i < 256; i++)` is just weird when you're using 8-bit integers: your upper range is an inexpressible value, and could easily be compiled down to `for (i = 0; i < 0; i++)` with two's complement, eg if you did `uint8_t upper = 256; for (uint8_t i = 0; i < upper; i++)`. That case is simple, but it gets nastier when you are trying to properly check for overflow in advance and the actual upper value is computed. `if (n >= LIMIT) { return error; }` doesn't work if your LIMIT is based on the representable range. Nor does `if (n * elementSize >= LIMIT) { return error; }`. Even doing `limit = LIMIT / elementSize; if (n >= limit) { return error; }` requires doing the `LIMIT / elementSize` intermediate calculation in larger-width numbers. (In addition to the off-by-one if LIMIT is not evenly divisible by elementSize.) So when dealing with overflow checks, 0 ≤ i ≤ N may be better. Well, a little better. `for (i = 0; i <= LIMIT; i++)` could easily be an infinite loop if LIMIT is the largest in-domain value. You want `i = 0; while (true) do { ...stuff...; if (i == LIMIT) break; i++; }` and at that point, you've lost all simple correspondence with mathematical ranges. > Isn't it obvious that there is no universally correct way to index things? I don't know about "obvious", but I agree that there is no universally correct way to index things.
- calibas 2y agoI see people bringing up arrays, and an array index is represented by a number, you can do math on it, but it's not a regular number for counting a sequence of items. It's a unique reference to a location in the memory, and it's dangerous to treat an array index like it's just any old number. Behold, the really stupid things you can do in Javascript: let myArr = []; let index = 0; myArr[--index] = 5; console.log(myArr.length); // 0 console.log(myArr[index]); // 5
- IshKebab 2y agoAn index is a specific kind of number, but so is a count. Indexing should clearly start from 0. It leads to far more elegant code and lower risk of off-by-one mistakes.
- sunflowerfly 2y agoWe taught our toddler to count from zero. Their kindergarten teacher was not amused.
- krukah 2y agoWhenever I explain to someone when or why to use 0-indexing, I like to say: Start from 0 if you are counting boundaries (fenceposts, memory addresses) Start from 1 if you are counting spaces (pages in a book, ordinals) Floors are a case where both make intuitive sense, which is maybe how we ended up with European vs American floor numbering.
- IshKebab 2y agoThat's a very confused way of thinking about it IMO. I say: * Start from 0 if you are indexing. I.e. you are identifying an item or its position. * Start from 1 if you are counting. I.e. you are saying how many items there are. It doesn't matter what it is. I don't know why you think pages in a book are somehow different to memory addresses.
- krukah 2y agoYou know what I like this much better...rule of thumb updated.
- geenat 2y agoHard ask considering there's effectively 2 Americas: only the scientific one using scaleable units like mg/g/kg, cm/m/km- everyone else using randomized trash... ft, mile, yard, inch, pound....
- AndrewSwift 2y agoIn France, street-level is the 0th floor, and the one above is the first floor. You see zero in elevators all the time.
- wongarsu 2y agoSame in Germany, just that we usually call it ground floor instead of 0th floor. You could argue it's a bit of a translation error. The French and German words for floor are referring to ways to add platforms above ground. Either by referring to walls, wooden columns or floor joists. Over the course of language evolution those words have both broadened and specialized, referring to building levels in general. But the way they are counted still reflects that they originally refer to levels built above ground. The English "floor" on the other hand counts the number of levels that are ground-like, which naturally starts at the actual ground.
- mathieuh 2y agoIt’s the same in non-American Anglo countries as well. Zero-indexed with the zeroth floor being called “ground”.
- fecal_henge 2y agoIn my (physics faculty) building 0 is the lowest floor. 2 is ground level. I used to work in Civil Eng which started at either G or 0.
- AndrewSwift 2y agoA good observation that explains everything!
- frhack 2y agoStarting from zero saves memory. If I have a variable used as an index for an array of 256 elements, starting from 0 allows me to store it in a single byte. If I start from 1, I need two bytes, effectively doubling the memory usage—an unnecessary 100% increase. Now, multiply this inefficiency across every instance where programs encounter a similar situation.
- hulitu 2y ago> Starting from zero saves memory. Computer memory.
- bazoom42 2y agoIt is easy to miss that his argument boils down to that zero-based is “nicer” in a specific select case. The paper is written in the style of a mathematical proof but hinges on a completely subjective opinion.
- norir 2y agoAlways beware the word should. I agree with Dijkstra's logic in the context that he presents it, but there are other contexts where I don't think it applies. Personally, I find that in compiler writing, which is the only programming I do these days, the only things I use indexes for are line numbers and character offsets into strings. Calling the first character the zeroth character is ridiculous to me, so I just store a leading 0 byte in all strings and then can use one based indexing with no performance hit. Alternatively, since I am the compiler writer, I could just internally store the pointer to the string - 1 to avoid the < 1 byte per string average overhead (I also machine word align strings so often the leading zero doesn't affect the string size in memory). If you are often directly working with array indices, you are likely doing low level programming. It is worth asking if the task at hand requires that, or if you would be better off using higher level constructs and/or a higher level language. Low level details ideally should not leak into the application level.
- TZubiri 2y agoNot only is this preference not restricted to compiler programming, but it's not even restricted to programming. Try to count 4 seconds, if you start at 1 you messed up. Babies start at 0 years old. Etc.. I do agree it's a convention though. Months and years start at 1, but especially for years, only intervals are meaningful, so it doesn't really matter what zero is (even though christ is totally king)
- ufo 2y agoThis article is one my pet peeves. It always shows up in discussions as "proof" that 0 indexing is superior, but it hides under the carpet all the cases the where it is not. For instance, backwards iteration needs a "-1" and breaks with unsigned ints. for (i=N-1; i>=0; i--) I like the argument that 0-based is better for offsets and 1-based is better for indexes: https://hisham.hm/2021/01/18/again-on-0-based-vs-1-based-indexing/ https://hisham.hm/2021/01/18/again-on-0-based-vs-1-based-ind...
- 6yyyyyy 2y agofor (unsigned i = N - 1; i < N; --i)
- noneeeed 2y agoI've always appreciated Ada's approach to arrays. You can create array types and specify both the type of the values and of the index. If zero based makes sense for your use, use that, if something else makes sense use that. e.g. type Index is range 1 .. 5; type My_Int_Array is array (Index) of My_Int; It made life pretty nice when working in SPARK if you defined suitable range types for indexes. The proof steps were generally much easier and frequently automatically handled.
- nivertech 2y agoI think lower..higher index ranges for arrays were used in Algol-68, PL/1, and Pascal long before Ada At least in standard Pascal arrays with different index ranges were of different incompatible types, so it was hard to write reusable code, like sort or binary search. The solution was either parameterized types or proprietary language extensions
- deleted 2y ago[deleted]
- ninalanyon 2y agoPascal has it too.
- fweimer 2y agoOn the other hand, if you receive an unconstrained array argument (such as S : String, which is an array (Positive range <>) of Character underneath), you are expected to access its elements like this: S (S'First), S (S'First + 1), S (S'First + 2), …, S (S'Last) If you write S (1) etc. instead, the code is less general and will only work for subarrays that start at the first element of the underlying array. So effectively, indexing is zero-based for most code.
- tdeck 2y agoMany BASIC dialects had this too, which could make some code a bit easier to read e.g. DIM X(5 TO 10) AS INTEGER I recall in one program I made the array indices (-1 TO 0) so I could alternate indexing them with the NOT operator (in QuickBASIC there were only bitwise logical operators).
- jmount 2y agoI love the uncertain history of both 0 and 1: https://win-vector.com/2020/09/18/clearly-the-author-does-not-know-what-the-natural-numbers-are/ https://win-vector.com/2020/09/18/clearly-the-author-does-no...
- anigbrowl 2y ago'start counting on your zeroth finger' 'can I have none apples please' - statements dreamed up by the utterly deranged. They have played us for absolute fools.
- djmips 2y agoWhere I live and maybe where you live our ages are zero based although no one seems to like me calling their baby zero years old.
- BeetleB 2y agoI know I'll get downvoted to Hell for this, but I have a mental list of traits poor programmer's have, and one of them is "Excessively complains about 1 based indexing".
- pmarreck 2y agoIf it's about collections of things, use collection iterators (`each`, etc.) and avoid the problem entirely.
- neves 2y agoI'll upvote this Djisktra note every time it appears. :-) It settles the discussion of array numbering. F*ck off Visual Basic, MS Javascript, and all the languages that said you should start with 1.
- personalityson 2y agoMatlab, Fortran, Julia, R, SAS, SPSS, Mathematica, and the whole field of mathematics. F*ck off all mathematicians, what do they know about counting?
- pwdisswordfishz 2y agoYeah, they didn't even manage to get the circle constant right.
- ks2048 2y agoSwift uses 0-based indexes, but offers, IMHO, a nice choice for specifying ranges, Array(1...5) == [1,2,3,4,5] Array(1..<5) == [1,2,3,4]
- tim333 2y agoPerhaps we can extend this to everyday language? Taylor Swift had a number zero hit, ones company, two's a crowd, I won the race and came in at number zero and so on?
- effdee 2y agoLet's also add a link to the handwritten version for good taste: https://www.cs.utexas.edu/~EWD/ewd08xx/EWD831.PDF https://www.cs.utexas.edu/~EWD/ewd08xx/EWD831.PDF
- zkmon 2y agoThe question arises when people get confused between a cut and span. These two are opposite concepts, and they make up a continuum, and they define each other. So, it depends on what you understand as "numbering". If it is about counting objects, the word "first object" refers to existence of non-zero number of objects. This shows why the first one can't be called as zero, as zero is not equal to non-zero. If the numbering is about continuous scale such as tape measure, then the graduations can start with zero. But still the first meter refers to one meter, not zero meters. It looks silly when people have their book chapters numbering to begin with zero. They have no clue whether the chapter refers to a span or a cut. Sure, they can call the top surface of their book cover as zero, though. But still they can't number a page as zero. The use of zero index for memory location comes from possible magnetic states of array of bits. Each such state is a kind of a cut, not a span. It's like a graduation on the tape measure, or mile stone on the side of the road. So it can start with zero. So, if you are counting markers or separators, with zero magnitude, you can start at zero. And when you count spans or things of non-zero magnitude, you start at one. If you count apples, start at one. If you count spaces between apples start at zero.
- tsoukase 2y agoZero means nothing (not that it has no importance :-) but that it symbolises the void). So the symbol 0 could be also a single space or any other predetermined. So, it is not a number and should not be used like one (pun intended)