[HN Gopher] Why do arrays start at 0?
       ___________________________________________________________________
        
       Why do arrays start at 0?
        
       Author : snikolaev
       Score  : 248 points
       Date   : 2022-08-24 16:25 UTC (6 hours ago)
        
 (HTM) web link (buttondown.email)
 (TXT) w3m dump (buttondown.email)
        
       | lowbloodsugar wrote:
       | The 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.
        
       | walnutclosefarm wrote:
       | There 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 wrote:
         | On 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.
        
       | [deleted]
        
       | v-yadli wrote:
       | I'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)
        
         | gnulinux wrote:
         | You 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 wrote:
           | It'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"
        
         | ur-whale wrote:
         | And then, there's the imperial system.
        
       | Taywee wrote:
       | I'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.
        
       | kybernetyk wrote:
       | Because an array is just syntactic sugar for pointer arithmetic
       | ... at least in C :)
        
       | ncmncm wrote:
       | The 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.
        
       | soheil wrote:
       | Qbasic uses 1 and that's what I always loved about it.
       | Coincidentally it was the same language I learned programming
       | with at age 12.
        
       | daneelsan wrote:
       | In 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.
        
       | [deleted]
        
       | [deleted]
        
       | charlieyu1 wrote:
       | A problem with 0-based arrays is that 0 is the only index with a
       | Falsely Boolean value.
        
       | onox wrote:
       | Arrays 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 wrote:
         | I always wonder why such fundamental features were not adopted
         | by all languages.
        
       | shanewilhelm wrote:
       | I 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 wrote:
         | > 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.
        
       | asveikau wrote:
       | There 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.
        
       | thwarted wrote:
       | If 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".
        
       | mmaunder wrote:
       | Because if you iterate backwards through an array your
       | terminating condition can be when your iterator evaluates to
       | false in loosely typed languages. /jk
        
       | dang wrote:
       | The article this one points to has had a few threads:
       | 
       |  _The origin of zero-based array indexing_ -
       | 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 - Nov 2013 (1
       | comment)
       | 
       |  _Citation Needed_ - 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 - Jan 2020 (220
       | comments)
       | 
       |  _Dijkstra 's argument on why numbering should start at zero
       | [pdf]_ - 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 - Aug 2018 (63
       | comments)
       | 
       |  _Why numbering should start at zero (1982)_ -
       | 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 - June 2015 (47
       | comments)
       | 
       |  _Dijkstra: Why numbering should start at zero_ -
       | 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 - Sept 2018 (1
       | comment)
       | 
       |  _Why C Arrays Start at Zero: I Don 't Know_ -
       | 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 - Feb 2016 (2
       | comments)
        
         | cannam wrote:
         | Perhaps 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.
        
       | Symmetry wrote:
       | For 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))
        
       | zzo38computer wrote:
       | I 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.
        
       | jaapsen01 wrote:
       | Edsger 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/E...
        
         | oboes wrote:
         | Interestingly, that Dijkstra article was originally
         | published/circulated in handwritten form. It helps showcase the
         | author's handwriting skills.
         | 
         | https://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
        
           | Koshkin wrote:
           | The handwriting skills were common back in the day... By the
           | way, are you sure that it was Dijkstra himself who hand
           | _printed_ these texts (rather than have, say, his secretary
           | do that)? Because this is not exactly the (beautiful)
           | handwriting as it was taught back then.
        
             | Jtsummers wrote:
             | He handwrote them, and occasionally typed them (especially
             | early on, I gave up trying to find the transition point).
             | It was something he was known for. If you read the EWD's
             | over the years you'll see the same (or _very_ similar)
             | handwriting throughout, which would not be the case if he
             | had a secretary writing them for him (who wouldn 't have
             | been the same person as he moved between countries).
             | 
             | https://en.wikipedia.org/wiki/Edsger_W._Dijkstra#EWD_manusc
             | r...
             | 
             | https://www.cs.utexas.edu/~EWD/ - Pick random ones from
             | different decades and you'll see very similar handwriting.
             | 
             | (Didn't read these, picked two at random):
             | 
             | 2001 - https://www.cs.utexas.edu/~EWD/ewd13xx/EWD1307.PDF
             | 
             | 1984 - https://www.cs.utexas.edu/~EWD/ewd09xx/EWD901.PDF
        
         | pavon wrote:
         | I'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.
        
           | zeroonetwothree wrote:
           | Sure but it's much more common for a range to include 0 than
           | INT_MAX
        
         | [deleted]
        
         | gnufx wrote:
         | As 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 wrote:
           | "This quote keeps on showing up out of context." -- Alan Kay
           | https://news.ycombinator.com/item?id=11799963
        
       | jefftk wrote:
       | My 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 wrote:
         | That 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 wrote:
           | 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/92779...
        
             | Jtsummers wrote:
             | 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 wrote:
               | Subtracting 1 from the user provided index isn't that
               | expensive.
               | 
               | Or, if you're willing to give up three bytes, index into
               | "ErrSunMonTueWedThuFriSat".
               | 
               | Or, and this is mildly insane but perhaps in keeping with
               | early C, have your pointer be three bytes before the
               | beginning of "SunMonTueWedThuFriSat" and use one-based
               | indexing.
        
               | Jtsummers wrote:
               | It all boils down to the fact that C's memory model is
               | meant to map closely to the physical memory model, and
               | the C and Unix developers preferred simplicity of
               | implementation over simplicity of interface. Leaky
               | abstractions (like that the weekday or months start at 0
               | so that they can reference into arrays of names) are fine
               | given that prioritization. Not everyone shares that
               | preference.
        
               | [deleted]
        
       | AndrewOMartin wrote:
       | "Should array indices start at 0 or 1? My compromise of 0.5 was
       | rejected without, I thought, proper consideration." -- Stan
       | Kelly-Bootle
        
         | pavon wrote:
         | This 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 wrote:
           | Which is how we got the dx9 half pixel offset in fragment
           | shaders. luckily not replicated in newer revisions.
        
       | Stratoscope wrote:
       | A 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
        
       | thomasahle wrote:
       | Discussion form 2013:
       | https://news.ycombinator.com/item?id=6601515
        
       | WaitWaitWha wrote:
       | I 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).
        
       | kgwxd wrote:
       | If everyone just called it offset instead of index there'd be no
       | confusion.
        
       | Schroedingersat wrote:
       | The 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.
        
       | JKCalhoun wrote:
       | > 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 wrote:
         | An assembler spillover into C.
        
           | JKCalhoun wrote:
           | Was C ever much more than a veneer on top of assembler?
           | 
           | Don't get me wrong, it's why I like C.
        
             | adwn wrote:
             | > _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".
        
       | JustSomeNobody wrote:
       | I liked how in Pascal, one had a lot more flexibility here.
       | 
       | Something like the following IIRC: Type IntArray = Array
       | [-10...10] of Integer;
        
       | drfuchs wrote:
       | Easy: 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_ wrote:
         | You 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.
        
       | Guest42 wrote:
       | I'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.
        
       | dboreham wrote:
       | Unusually 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.
        
       | patatino wrote:
       | My 4 year old starts at 0 when asked to count, so proud! Never
       | said a thing about starting at 0.
        
         | thetwentyone wrote:
         | They point at 3 apples and goes "0,1,2" naturally?
        
         | jcelerier wrote:
         | Look at your 4 year old's ruler. What's the first number on it?
        
       | zaroth wrote:
       | Simple: 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 wrote:
       | Looking 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.
        
       | OJFord wrote:
       | Why do tape measures start at 0?
        
       | hougaard wrote:
       | It 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 ...." :)
        
         | co_dh wrote:
         | Human makes a lot of inconsistent thing: We usually think the
         | 1st floor, and the basement as 1st underground floor ( -1), but
         | the floor jumps from 1 to -1!
         | 
         | Also, the time jump from 11AM to 12PM to 1PM! So I think more
         | human friendly sometimes means more confusing.
        
           | copperx wrote:
           | It's like English pronunciation, there's little logic. I gave
           | up finding logic in these things at an early age, and
           | resorted to memorizing everything instead.
        
           | luispauloml wrote:
           | That's true. But as for floor numbering, specifically, it
           | depends on the country: some places have a "ground floor"
           | between the 1st underground floor and the 1st "above ground"
           | floor.
        
           | BorisTheBrave wrote:
           | In Europe, the floor level with the ground is called "ground"
           | or "0".
        
         | bregma wrote:
         | Ah, yes. Cardinal numbers and ordinal numbers both end in the
         | word "numbers" so they're the same thing. No need to
         | distinguish between having three apples and having the third
         | apple.
        
           | Old_Thrashbarg wrote:
           | If you ask most people to just label their apples, they'd
           | call the first one "1", and so on. Very few people would say,
           | "please pass me apple #0".
        
             | goatlover wrote:
             | And if someone did say that to me, I would pass them no
             | apple, since that's how we use everyday language. And if I
             | knew they were a programmer, I'd first ask them in which
             | programming language they'd wish me to pass the apple.
        
         | Old_Thrashbarg wrote:
         | I believe there's a powerful status quo bias.
         | 
         | Doing the reversal test, if programming languages had all been
         | 1-indexed, then I doubt we'd hear much from people, in 2022,
         | saying "I think the first element should be 0, and the second
         | 1".
        
         | croes wrote:
         | If you think of the index as an offset you would start with 0.
         | 
         | BTW on which level is the 1st floor?
        
           | hougaard wrote:
           | That depends on your language and culture, "floor" is not
           | easily translated, some languages have a word describing all
           | the layers added to the base layer, so "1. sal" (Danish as an
           | example) actually means "the first layer added on top of the
           | base house".
           | 
           | Again, this is more a spoken language/culture thing, and this
           | goes back to what premises we use to communicate with the
           | machines, ours or the machines...
        
           | t_mann wrote:
           | > BTW on which level is the 1st floor?
           | 
           | in Europe or in the US?
        
             | ethbr0 wrote:
             | Does Europe has a zero floor? Please tell me Europe zero-
             | indexes their stories!
        
               | t_mann wrote:
               | They do, it's called the ground floor.
        
               | Zardoz84 wrote:
               | "Bajo" in Spain
        
               | copperx wrote:
               | I've always called floor zero and everybody understands.
        
               | espadrine wrote:
               | In France, it is called the rez-de-chaussee. The "premier
               | etage" (literally translated as "first floor") is what
               | the US calls the second floor.
        
               | mananaysiempre wrote:
               | A particularly topographically challenged building in
               | Paris has exits to two enclosing streets end up on
               | different floors. The elevator is numbered -2, -1, rez-
               | de-rue [exit north], rez-de-chaussee [exit south], 1, 2,
               | ... .
        
           | childintime wrote:
           | Nobody knows that one.
           | 
           | No elevator I've seen has yet taken a cue from UI design:
           | simply put the buttons within an outline of the building,
           | along with the local numbering scheme.
           | 
           | No more visits to the serial killer lurking in the basement.
           | 
           | The players in this market evidently have been operating at
           | T'ump levels of intelligence. /s
        
           | enobrev wrote:
           | You've got ...P3, P2, P1, G, M, 1, 2, 3...
        
           | shadowofneptune wrote:
           | In Tucson I've seen some buildings where the basement is the
           | first floor. You enter at floor two.
        
         | zajio1am wrote:
         | > 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.
         | 
         | It is more like counting from 1 is just a leftover from times
         | where zero was not commonly considered as number. Once one have
         | zero, it makes sense to use it as an initial ordinal (see e.g.
         | set theory, where zero is both initial ordinal and initial
         | cardinal number, way before computers).
         | 
         | Another example is time and date, we start counting of days
         | from 1, but counting of hours (at least in 24-hour notation)
         | and minutes from 0.
         | 
         | > Luis started explaining why Lua was 1-index with this
         | sentence: "The 1st argument ...."
         | 
         | Note that for spoken language, it is "The first argument ..."
         | and 'first' is etymologically unrelated to 'one', but related
         | to 'foremost', 'front', so it make sense to use 'first' for the
         | initial item in the sequence even when using counting from 0.
        
           | steadicat wrote:
           | When talking about discrete things, 0 has a specific meaning:
           | it is the absence of things. It does not make sense to count
           | the 'first' element as the 0th. When you encounter the
           | 'first' element, how many elements do you have? 1.
           | 
           | This is of course different for continuous quantities. When
           | counting seconds, for example, we should absolutely start
           | from 0.
        
         | kazinator wrote:
         | Is 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 wrote:
           | ... but if you have something that's 150cm, that's not 151cm,
           | that's 150cm?
        
         | bentcorner wrote:
         | > _The 1 makes a lot of sense in a human world, when we count,
         | we start at 1_
         | 
         | As a kid I learned "one one-thousand, two one-thousand, three
         | one-thousand" when counting time out loud, but at some point I
         | realized this was incorrect. The prefix is the start of the nth
         | second but it isn't complete yet, so for example stopping in
         | the middle of saying "two one-thousand" you actually haven't
         | reached two seconds yet.
         | 
         | My fix was to move the prefix to the end, so I say "one-
         | thousand one, one-thousand two, one-thousand three".
         | 
         | In retrospect maybe I should have used "zero one-thousand, one
         | one-thousand, two one-thousand".
        
           | 8note wrote:
           | None one-thousand, one one-thousand, two etc
           | 
           | Doesnt sound half bad
        
           | ziml77 wrote:
           | I don't think it's necessary incorrect to start at one there.
           | If someone asks you to count out 3 seconds, you're going to
           | say "one one-thousand, two one-thousand, three one-thousand"
           | and only at the end of the "three one-thousand" will you have
           | considered the 3 seconds to have actually elapsed. Basically
           | you're already accounting for the time it's taking you to say
           | it. Which to me seems better because if you do it the other
           | way because it gives a better heads up as to when that second
           | has been reached.
        
         | numlock86 wrote:
         | > It really comes down to a choice between a machine-focused
         | (0) or human-focused (1) approach.
         | 
         | Just think of 0-based as offset-based and 1-based as index-
         | based. Both are intuitive just like that. I never get why
         | people arguing over this bring pointers and memory (or anything
         | computer related) to the table. No normal person is going to
         | understand that, but everyone understands that if you don't
         | move at all (0 offset) you stay at the first (index 1) item.
         | Add one and ... you get the point.
        
           | kccqzy wrote:
           | I must say in this case Google does it right:
           | https://cloud.google.com/spanner/docs/reference/standard-
           | sql...
           | 
           | In Google standard SQL, to access an array it is simply not
           | allowed to put a number inside square brackets. You must
           | specify which way you mean. So `SELECT
           | some_numbers[OFFSET(1)], some_numbers[ORDINAL(1)]` is allowed
           | but not `SELECT some_numbers[1]`.
        
             | kergonath wrote:
             | That sounds actually great to avoid any ambiguity. At the
             | cost of a bit of verbosity, though.
        
           | dllthomas wrote:
           | But I think that still leaves open the question of "offset
           | from what?"
           | 
           | If you move zero from the first element, you're still at the
           | first element... but if you move zero from the fourth element
           | you're still at the fourth element. If you move one from
           | _before_ the first element, you 're at the first element.
           | 
           | I think you're more or less right, but I think we still need
           | something to motivate the first element as the point of
           | reference, and the machine focus is one way to do that.
        
             | lupire wrote:
             | In some languages/environments, the array is literally the
             | same as the pointer to the first element.
             | 
             | Other languages are more sophisticated (like humans are!)
             | and can say that position 0 does not exist. An array of
             | size 0 has no elements. An array of size 5 has elements 1at
             | through 5th. An array of size N has 1st through Nth,
             | inclusive.
        
           | lupire wrote:
           | "ordinal" is preferred to "index", as "index" doesn't
           | naturally suggest starting at "1", or even restricting the
           | key to integers. "Ordinal" starts from 1, everyone agrees
           | (except mathematicians, of course :-) ).
        
             | pb7 wrote:
             | Ask 100 random people on the street and I'd be surprised if
             | even 1 knew the definition of "ordinal". It's an uncommon
             | word.
        
               | lupire wrote:
               | So is "array". What's your point? My point is that it is
               | unambiguous once you say what you are talking about.
        
               | pb7 wrote:
               | I disagree. The CS definition of array, sure, but if you
               | were to say "we have an array of options to eat", most
               | people with a high school education would know what you
               | mean.
        
               | LudwigNagasena wrote:
               | Do people not study grammar in American schools? I
               | thought all kids learn the distinction between cardinal
               | (one, two, three) and ordinal (first, second, third)
               | numbers.
        
               | Octoth0rpe wrote:
               | The English grammar that Americans study in school is
               | likely somewhat different than the English grammar that
               | is taught outside of America as the goal of the latter is
               | likely focused on helping students map their native
               | language onto English. I would agree that `ordinal` is
               | uncommon word for many Americans, but it wouldn't at all
               | surprise me if there were languages where the equivalent
               | word was far more common, and therefore its use and
               | translation was a part of standard English as a second
               | language curriculum.
        
               | [deleted]
        
               | pb7 wrote:
               | At the age that cardinal and ordinal numbers are taught,
               | kids simply don't remember "cardinal" and "ordinal", they
               | remember "one, two, three" and "first, second, third".
               | 
               | 99% of the instances I've seen "ordinal" outside of this
               | thread has been in code/documentation. It is not a common
               | word in everyday language.
        
           | [deleted]
        
           | Joker_vD wrote:
           | And then the counting niceties come along: those perennial +1
           | mistakes are caused by the fact that, e.g. 4 and 5 are _two_
           | numbers but they are only _one_ apart.
        
           | kazinator wrote:
           | Offset-based lets you refer to an abstract location that is
           | after the last element without resorting to n + 1.
           | [ ] [ ] [ ] ...    [ ]      0   1   2   3   n-1     n
           | 
           | We can regard this n as a "virtual zero", and then make it
           | possible to index the n - 1 element also indexable as just
           | -1. The index -n then aliases to 0.
        
           | amalcon wrote:
           | "Offset-based" is bringing in pointers; that's the thing it's
           | an offset "from". "The beginning of the array" is just a
           | pointer.
           | 
           | I suppose saying that does have an advantage over explicitly
           | talking about pointers, in that the word "pointer" is a piece
           | of jargon that has a lot of baggage. That's just avoiding
           | jargon, though, not really using a different model.
        
         | thayne wrote:
         | There are a lot of cases where a zero index makes sense. In
         | physics and math there are cases where you start the index at 0
         | and others where you start at 1. And even some where you start
         | at -1. Which you use depends on what is most convenient for the
         | problem at hand.
        
         | HarHarVeryFunny wrote:
         | Yes, but "human-focused" 1-based indexing comes at a cost since
         | at the end of the day the CPU has to add (index * element-size)
         | to the array base address to get the address of the indexed
         | element. With a 1-based index there's additional overhead in
         | either having to subtract 1 from the index or to have a wasted
         | "element 0" to avoid the need to do that.
        
           | copperx wrote:
           | I assure you, that if we counted from zero, there would be an
           | instruction to add and multiply in the same number of cycles
           | as a multiply.
        
             | HarHarVeryFunny wrote:
             | That's not possible - the subtract and multiply need to be
             | consecutive (adjust index before multiply by element size),
             | so even if it was a single instruction it would still take
             | longer than a multiply that didn't have to wait for a
             | preceding subtraction.
             | 
             | The only way to avoid the speed penalty would be either to
             | have a wasted element at offset 0, or to maintain the array
             | base address as (address - (1 * element-size)) to avoid
             | having to subtract 1 from the index when accessing. In the
             | latter case for dynamically allocated arrays the code would
             | still have to do a subtraction to adjust the pointer
             | returned by the memory allocator, but at least that would
             | be a 1-time penalty rather than per-element-access.
             | 
             | Of course this is supposing a high level language where an
             | array is abstraction, not one explicity aliased to a chunk
             | of memory such as C where an array and a pointer to it's
             | first element are interchangeable.
        
               | copperx wrote:
               | That goes against my intuition. Multiplication in
               | hardware to this day relies on addition. Is one adder
               | going to add an extra cycle? Or would that time be
               | amortized? Take a look at slides 45-46 here. https://acg.
               | cis.upenn.edu/milom/cis371-Spring08/lectures/04_...
               | 
               | Do you know the answer to that question? (I don't, but if
               | someone does, it will settle this issue).
        
         | Aardwolf wrote:
         | > human-focused (1) approach.
         | 
         | TBH humans would have been better of if we were 0-based, it's
         | just a convention. And we have the confusing language where
         | "20th century" means 1900's. If we wanted to bring the
         | 1-indexing we use in language to the fullest extent here to fix
         | that particular issue, time counting would have to start at
         | 1111. Except that won't work once reaching 5-digit years.
         | 
         | If we would start with "zeroeth" instead of "1st", then this
         | would have solved itself and 20th century would mean 20xx's.
        
           | airstrike wrote:
           | > where "20th century" means 1900's
           | 
           | to this day I can't seem to be able to explain to people that
           | Jan 1 2000 was NOT the start of the new millennium, but
           | rather Jan 1 2001
           | 
           | https://www.latimes.com/archives/la-
           | xpm-2000-dec-26-mn-4810-...
        
         | analog31 wrote:
         | I always thought of the machine focus being that the location
         | of the first element was the location of the array plus zero.
        
         | jcelerier wrote:
         | At which number starts the first centimeter on a ruler ?
        
           | RunSet wrote:
           | At which number starts the zeroth centimeter on a ruler?
        
             | [deleted]
        
             | jcelerier wrote:
             | it's the first and it is 0, just like the first index in a
             | C array is 0
        
         | Aardwolf wrote:
         | > human-focused (1) approach.
         | 
         | TBH humans would have been better of if we were 0-based, it's
         | just a convention. And we have the confusing language where
         | "20th century" means 1900's. If we wanted to bring the
         | 1-indexing we use in language to the fullest extent here to fix
         | that particular issue, time counting would have to start at
         | 1111. Except that won't work once reaching 5-digit years.
         | 
         | If we would start with "zeroeth" instead of "1st", then this
         | would have solved itself and 20th century would mean 20xx's.
         | 
         | I especially don't understand why mathematicians use 1-based
         | indexing (for matrix rows/columns etc...). Like programmers,
         | they should see the advantages of starting at 0 (e.g. the
         | coordinates of subdividing into block matrices are simpler if
         | starting at 0). Mathematicians do start at 0 for the origin of
         | plots, after all.
        
           | OscarCunningham wrote:
           | > If we wanted to bring the 1-indexing we use in language to
           | the fullest extent here to fix that particular issue, time
           | counting would have to start at 1111.
           | 
           | That's funny, but there's actually an elegant way to do it
           | called Bijective numeration
           | (https://en.wikipedia.org/wiki/Bijective_numeration). We're
           | currently living in the 1A22th year.
        
         | kevin_thibedeau wrote:
         | It has nothing to do with pointers and everything to do with
         | basic computer arithmetic. You can constrain the range of an
         | integer with a bitwise AND operation providing a cheap modulus
         | by power of two. In this regime, zero-based indexing is the
         | natural result. You have to make an adjustment for 1-based.
         | There are whole host of other operations that are simpler with
         | 0-based indexing.
         | 
         | The problem it that most people, even programmers, don't
         | understand how computer arithmetic works and have fantasies of
         | mathematical number lines that the hardware only partially
         | simulates. You see this consistently in the post-Java crowd who
         | think that unsigned integers are some sort of unholy aberration
         | because the languages they've grown up went further to maintain
         | the fictional number line semantics.
        
         | tromp wrote:
         | > when we count, we start at 1
         | 
         | If I ask you to count the number of red balls in a bag with
         | only 3 yellow balls, then the initial count in your head is 0,
         | you inspect the balls one by one, never encountering a red
         | ball, and thus never incrementing the count. And then you
         | pronounce your final count of 0. So that's counting starting
         | from 0.
         | 
         | What you call "starting at 1" is not so much the start as it is
         | the first increment, which need not arise.
        
         | xxs wrote:
         | I have used 1 based in basic/pascal and 0 based (well in pretty
         | much everything), 0 based effectively no off-by one mistakes. 1
         | based - common. Most idioms - incl. forward and reverse
         | iterations work better, and are easier to remember with
         | inclusive/exclusive pattern
         | 
         | Other than that - binary AND and power of 2 sized arrays are
         | the backbone of any hashtable. Overall modulus (binary AND) is
         | actually useful.
        
         | kazinator wrote:
         | In Western music theory, intervals are one based. No pitch
         | change is "unison"; one diatonic step is a "major second" and
         | so on. As a result of this silly state of affairs, an octave
         | occurs every 7 notes, even though the root "oct" means eight.
         | Furthermore, a "rule of nines" is needed to invert an interval:
         | e.g. inversion of minor 3rd is a major 6th (exchange
         | major/minor, subtract from 9).
        
           | OscarCunningham wrote:
           | And addition also gets broken. Like a third plus a fourth is
           | a sixth.
        
         | qsort wrote:
         | I 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.
        
         | kazinator wrote:
         | > when we count, we start at 1
         | 
         | That is false; counting begins by initializing an accumulator
         | to zero. When you register the first item, the count jumps from
         | 0 to 1.
        
           | goatlover wrote:
           | Who sets an accumulator to zero and then adds one in everyday
           | language?
        
             | kazinator wrote:
             | For instance, someone who makes a fist with zero extended
             | fingers before counting.
             | 
             | Or someone who simply becomes motivated to count something,
             | without making any utterances or gestures to that effect.
             | The motivation is followed by the persistent awareness that
             | nothing has been counted yet, which then changes to 1.
        
         | randomdata wrote:
         | _> 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.
        
           | drewzero1 wrote:
           | Oddly(?) though, most parents of young children don't refer
           | to a baby as being "zero years old." Rather, we break them
           | down into smaller units: two days old, six weeks old, four
           | months old.
        
             | throwaway821909 wrote:
             | It helps that change happens particularly fast at that age,
             | so the difference between newborn and 6 months is worth
             | mentioning. Later on the units go up again and we just say
             | "I'm in my 30s" :P
             | 
             | On the other hand a computer/car/house can also be 10 years
             | old but not 0.
        
               | drewzero1 wrote:
               | True, a few weeks can mean a few milestones at that age.
               | It's still wild to me how quickly babies/kids develop.
               | Every week brings new abilities, experiences, and
               | emotions that weren't there before.
        
               | wruza wrote:
               | _On the other hand a computer /car/house can also be 10
               | years old but not 0_
               | 
               | Really? When I buy a new PC, to me it will get 1 year old
               | only after a year. Before that it is just NEW. Is that
               | what you meant?
        
           | ellen364 wrote:
           | Demographers sometimes describe age as "the number of
           | completed years", which always struck me as a wonderfully
           | simple explanation.
        
           | atwood22 wrote:
           | No, 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.
        
             | rcoveson wrote:
             | No, old calendar systems are one indexed. In those system,
             | there is literally no year zero; the first year is year
             | one. This leads to crazy things like year 100 being part of
             | the "first century" and year 101 being part of the "second
             | century".
             | 
             | That is not the case with age or birthdays which are,
             | thankfully, zero indexed. The first year of human life is
             | age=0, birthdays=0.
        
               | [deleted]
        
               | lupire wrote:
               | It's not "crazy". No one care about which century X00 is.
               | The term "century" doesn't have enough sig figs. X00 is
               | "the turn of the century".
        
               | rcoveson wrote:
               | If you don't care then sure, it's not crazy, but if you
               | did care then believe me, it is crazy. Crazy enough that
               | astronomers[0] and software engineers[1] rebelled against
               | the historian's practice and renamed the years preceding
               | 1 AD in the proleptic gregorian calendar year 0, year -1,
               | year -2, et cetera. A major benefit of this is it allows
               | the leap year pattern to stay consistent and the rule to
               | remain legibile for all years, going back before 1 AD.
               | It's also nice because it lets us say "the 90's were the
               | last ten years of the 20th century" and be correct.
               | 
               | 0.
               | https://en.wikipedia.org/wiki/Astronomical_year_numbering
               | 
               | 1. https://docs.oracle.com/javase/8/docs/api/java/time/te
               | mporal...
        
             | randomdata wrote:
             | The moment you are born you are 0 years old (or perhaps
             | 0.75 years old, but we don't usually recognize that). We
             | count from zero in this case, at least implicitly.
             | 
             | In some cultures you are considered 1 the moment you are
             | born, so the zero indexing isn't universal here, but
             | typical in North America as noted earlier.
        
               | atwood22 wrote:
               | No, we don't count from 0. That's like saying we start
               | counting a baker's cup from 0 because you can have half a
               | cup.
        
               | emaginniss wrote:
               | Ok, use the baker and cup as an example. If you have an
               | empty cup and put half of a cup of flour in it, you now
               | have 0.5 cups of flour. Notice the zero before the ".5".
               | That is us, normal humans, realizing that until you add
               | enough to have 1 of something, you have between 0 and
               | 0.999 repeating.
        
               | kazinator wrote:
               | The counting activity doesn't begin when the first item
               | is registered; it begins when the counter is initialized
               | to zero. A decision is made to begin counting, along with
               | the realization that nothing has been counting yet.
               | That's when counting has started. When the first item is
               | seen, the counting is then continuing.
               | 
               | Suppose your job is to count some events. You check in
               | for work at 8:00 a.m., but the first event has not
               | registered until noon. By your logic you should not be
               | paid for four hours, because you're paid to count, and
               | counting started at 1.
        
               | anigbrowl wrote:
               | You're still thinking like a computer. Most people think
               | of counting in terms of 'here are some apples, how many
               | exactly?'
               | 
               | If you just look at an empty space, the # of apples is
               | equivalent is equivalent to the # of dinosaurs, but
               | they're only equivalent by their absence.
        
               | atwood22 wrote:
               | No, the mathematical definition of counting (i.e. whether
               | or not a set is countable) involves mapping to the
               | natural numbers, which doesn't include 0.
        
               | kazinator wrote:
               | I don't think your definition is complete. We can count a
               | set by mapping its elements to the natural numbers, and
               | then identifying that number which is highest. However,
               | we must have a provision for identifying zero as the
               | highest when the set and mapping are empty.
        
               | 8note wrote:
               | Math counting doesn't care where you start. You could
               | start -400 if it's useful for the problem
        
               | lupire wrote:
               | You can name things however you want, but there is a
               | canonical bijection to zero-based ordinals.
               | 
               | https://en.m.wikipedia.org/wiki/Ordinal_number
        
               | goatlover wrote:
               | What counter? You're saying a counter exists before
               | people start counting? Is this a form of mathematical
               | Platonism?
        
               | kazinator wrote:
               | A counter can be lazily instantiated just before the
               | first item is counted.
        
               | lupire wrote:
               | What does your stopwatch say right now?
               | 
               | Your pedometer?
               | 
               | Your traffic clicker?
        
               | lupire wrote:
               | Are you sure?
               | 
               | We are talking about the he numbering, not the work-
               | doing.
               | 
               | You start _waiting_ at 8, and you wait between events.
               | But you only count (increment) when an event happens.
               | 
               | The 0 comes for free when you are _ready_ to count (hello
               | golang and C++, as well as human intuition).
               | 
               | When you count stars in the sky you don't say "0, 1, 2".
               | 
               | You say "..., 1, 2", or if no stars show up, you say
               | "there are 0" after timer expires.
        
               | kazinator wrote:
               | > _But you only count (increment) when an event happens._
               | 
               | Increment what?
               | 
               | > _When you count stars in the sky you don 't say "0, 1,
               | 2"._
               | 
               | No, you say, "I'm going to start counting stars now.
               | Okay, 1, 2, ...".
               | 
               | The preparation part is the zero. You counted stars
               | before and reached some number; you're not starting at
               | that number.
        
               | 8note wrote:
               | I start with a empty cup, then I fill it up to 1 cup.
               | 
               | I then put it in an initially empty bowl
        
               | bregma wrote:
               | When I'm baking I start by zeroing the scale, then adding
               | enough flour to reach 500 g (or whatever the recipe calls
               | for). That's counting from zero.
        
               | randomdata wrote:
               | If we (speaking as a North American) count from 1, does
               | that mean other cultures (e.g. Korean) count from 2?
        
               | atwood22 wrote:
               | No, it just means we have a different notion of what a
               | year is in regards to age. Similar to how different
               | cultures can use different units of measurement for
               | length, mass, etc.
        
               | randomdata wrote:
               | Yes, exactly. One of which carries an implicit zero
               | indexing. The date of birth doesn't disappear just
               | because you decided to use a different measuring device.
        
               | atwood22 wrote:
               | No, it doesn't carry an implicit 0 index. Measuring age
               | (in the West) is like measuring distance. You start at 0,
               | but that doesn't mean the first item is at index 0.
        
               | randomdata wrote:
               | If you took a standard ruler, a measurer of distance and
               | which has literal index marks painted on it, and placed
               | items along it, the item found at the head of the ruler
               | would be found at the 0th index. You're quite right that
               | we think of birth and its anniversaries in the same way.
        
               | kazinator wrote:
               | What do you do for a living, and why are they paying you
               | not to understand this?
        
               | bmacho wrote:
               | Can't they just .. disagree?
               | 
               | Birthdays are clearly 1 indexed, the first birthday is
               | indexed with 1, and not with 0.
        
               | ziml77 wrote:
               | They day you're born is birthday number 0
        
               | bmacho wrote:
               | Exactly.
               | 
               | Birthday[0] gives you an out of range exception, since
               | there is no birthday called 0th. Birthdays are
               | [first,second,..] indexed from 1: brithday[1] = first,
               | birthday[2] = second, and so on. That's what indexing a
               | series from 1 _means_.
        
               | atwood22 wrote:
               | Do you know the definition of countable? A set S is
               | countable if there is a one-to-one mapping from S to N
               | where N is the natural numbers. Do you know that 0 is not
               | a member of the natural numbers? We literally start
               | counting at 1 by definition of countable.
        
               | kazinator wrote:
               | An empty set is countable; it has an empty mapping to the
               | natural numbers. Its cardinality is zero.
        
               | lupire wrote:
               | Nope.
               | 
               | Is the empty set countable? (Yes.)
               | 
               | Dictionary:
               | 
               | nat*u*ral num*bers                 the positive integers
               | (whole numbers) 1, 2, 3, etc., and sometimes zero as well
               | 
               | Countable: https://en.wikipedia.org/wiki/Countable_set
               | 
               | Set theory:
               | 
               | https://en.wikipedia.org/wiki/Ordinal_number
        
               | atwood22 wrote:
               | From your own link on countable sets:
               | 
               | > Equivalently, a set S is countable if there exists an
               | injective function f : S - N from S to N; it simply means
               | that every element in S corresponds to a different
               | element in N.
               | 
               | Defining N is usually done via a successor set, on which
               | case 0 makes no sense to include.
        
               | themacks wrote:
               | Typical counting of things starts from 0. If you count
               | apples you implicitly start at zero and add 1 for each
               | apple. If you count age, you start at birth (0) and count
               | years; one for each birthday. That isn't zero based. The
               | difference is the index of the item between the starting
               | point and the next item. In zero based this item is
               | number 0, in one based, this item is number 1. The first
               | year of life is generally considered the year following
               | birth.
        
               | dylan604 wrote:
               | >If you count age, you start at birth (0) and count
               | years; one for each birthday.
               | 
               | nitpick: unless you were born on Feb 29.
        
               | copperx wrote:
               | I didn't know that. Do you get to be 1 year old if you
               | are born on Feb 29, to account for leap years?
        
               | dylan604 wrote:
               | You're just 1/4 of the age of everyone else born the same
               | year. You have the same number of laps around the sun as
               | those people, but you've definitely had fewer birthdays.
               | It's a common joke for leap year babies.
        
               | somat wrote:
               | I just dealt with this problem(how to store periodic
               | events(including birthdays)). It is a surprisingly
               | difficult problem. After reading up on postgres interval
               | types my latest attempt uses them to store events, where
               | a per year event(like a birthday) is stored as "2 months
               | 15 days". it turns out the postgres project has put quite
               | a bit of thought into making interval types work as
               | expected with regards to months, not an easy task when
               | you consider how difficult it is to treat dates
               | mathematically.
               | 
               | The nice part is that now February 29 "just works" the
               | downside is the impedance between how months and days are
               | numbered and a how an offset from the epoch(beginning of
               | the year) is defined. January 3rd(1-3) is stored as "0
               | months 2 days" as when it hits, 0 months have passed and
               | 2 days have passed.
               | 
               | So the specific case of February 29 hits when 1 month has
               | passed and 28 days have passed. 3 years out of 4 this
               | will be the same as "2 months 0 days"(3-1) but every
               | forth year this will be(2-28). As an aside, and the
               | specific reason I went with interval types, every event
               | past feburary 29 works just fine with or without a
               | leapyear, that is, the extra day in the middle does not
               | mess up the offset to days after it.
               | 
               | Honestly I curse a little as I wish months and days were
               | 0-based. At least clocks get this right, almost, 12 hour
               | clocks are a special breed of stupid. start at 12, then
               | go to 1 and proceed up to 11. 24 hour clocks properly
               | start at 0. The worst part about 12 hour clocks is that
               | it is almost correct, replace the 12 with a 0 and it
               | every thing be the same but now it makes sense from a
               | moduler math point of view.
               | 
               | A special curse is reserved when I think about how there
               | is no year zero.
               | https://www.postgresql.org/docs/13/functions-
               | datetime.html#F...
        
               | goatlover wrote:
               | > If you count apples you implicitly start at zero and
               | add 1 for each apple.
               | 
               | If that's the case, then how did the ancient Greeks or
               | Romans count before zero was an acceptable concept in
               | their counting system?
        
               | unbalancedevh wrote:
               | By describing it in other ways, I imagine: "How many
               | apples do you have?" "I don't have any."
        
             | brianzelip wrote:
             | So how old is a not-yet-1-year old?
        
               | atwood22 wrote:
               | N days or N months depending on how old the baby is.
        
               | rcoveson wrote:
               | And before an hour has even passed, we'd probably say
               | "minutes old" or perhaps "not even an hour/day old", all
               | to avoid saying "zero days/months/years old". But some
               | might still say zero days old, and they'd be both
               | understood and correct (at least logically if not
               | stylistically). That's the "implicit zero" everybody is
               | talking about. We avoid saying it, but that's just a
               | convention of communcation. Logically it's there. You're
               | zero days old before you're one day old.
        
               | randomdata wrote:
               | And it turns out that 0 days, 0 months is 0 years.
        
               | xxs wrote:
               | Your mistake is using years - use milliseconds (or
               | nanoseconds) when you wish to express a duration. Years
               | don't even have the same duration/length (leap years, and
               | leap seconds)
        
               | nomel wrote:
               | Elapsed time timers start at 0. Time is continuous. The
               | elapsed time being "out of the womb", that we call "age",
               | starts near 0. Five minutes after birth, the baby has
               | been in the world for, or it's age is, five minutes. If
               | someone asked how old a new baby is you could hear "3
               | weeks".
               | 
               | Another definition might be from conception. But birth
               | being "one year old" is illogical. The sperm didn't even
               | exist yet, one year before birth.
        
             | csours wrote:
             | Your birth day is the day you are born.
             | 
             | Your first birthday is the first anniversary of your birth
             | day.
             | 
             | We celebrate the anniversaries of our birth day.
        
               | treis wrote:
               | Yep, clearer in Spanish. They say cumpleanos which
               | literally means completed year.
        
             | wruza wrote:
             | Haha, this thing is messed up. Your "first birthday" is
             | technically second, because the first was at your, well,
             | day of birth. But we people love to complicate things and
             | count 1st birthday as a number of annual celebration events
             | _after_ the first mm-dd of birth. Off by one as it is.
        
           | hougaard wrote:
           | Yeah age is confusing even for non-computer-folks :)
           | 
           | If you have 4 classes in school today, you would never talk
           | about the 1st class as number 0, the last one is the 4th, not
           | the 3rd.
        
             | [deleted]
        
             | randomdata wrote:
             | Although, there is a fifth state in your example: When you
             | are not in class. Which is different to an empty set that
             | implies nothingness. When it comes to age, 0 being birth
             | works well because there is truly is nothingness (from your
             | perspective) before birth. When counting from 1 there is
             | suggestion that there are variables that aren't worth
             | speaking of because they are obvious.
        
               | goatlover wrote:
               | Assuming there is nothingness for the fetus the entire
               | nine months in the womb. For that matter, I can't recall
               | being younger than four, so it's all nothingness before
               | then.
        
               | randomdata wrote:
               | Not really. Perspective isn't scientific and often
               | cultural. Koreans, for example, famously have a different
               | take and use a different counting systems to accommodate.
               | 
               | I am assuming that the reader is biased towards the
               | average HN user. That won't always work for everyone who
               | will come across my comment, but close enough for an
               | unpaid contribution. I'm not about to write a novel to
               | make sure I catch every edge case.
        
           | yongjik wrote:
           | That's why I prefer the Superior(TM) Korean age counting. You
           | are one year old when you're born (it's your first year!).
           | You are two year old on the next New Year's day.
           | (Congratulations, it's your second your now!)
           | 
           | So, if you're born on December 31st, you're two years old the
           | next day. (I see no problem, but apparently some people are
           | hung up on such minor details. I can't fathom why.)
        
             | BeFlatXIII wrote:
             | > I see no problem, but apparently some people are hung up
             | on such minor details. I can't fathom why.
             | 
             | Americans and their alcohol laws...
        
             | galangalalgol wrote:
             | Doesn't Korea use the same new year as China? Usually
             | second new moon after winter solstice.
        
               | smegsicle wrote:
               | hung up on minor details!
        
             | dllthomas wrote:
             | There's nothing wrong with the definition per se, but
             | there's the question of what purpose you're putting it to.
             | We should expect more similarity from two "newly 2"
             | children with the "western" system than the Korean one.
        
             | tromp wrote:
             | > You are one year old when you're born (it's your first
             | year!)
             | 
             | That makes no sense to me. It's also your first century.
             | Does that make you one century old? Of course not! The
             | moment you're born, you're not even one hour old, let alone
             | one day.
        
               | BuckRogers wrote:
               | They must like rounding up. I guess it depends how they
               | refer to it in their language. If it's "he's in his 1st
               | year", that's a big difference from, "he's 1 year old".
               | I'm wondering if the parent comment simply doesn't know
               | Korean or only knows it somewhat to misconstrue the
               | culture behind this.
               | 
               | It could be though that Korea simply never encountered
               | the Mayan or Arabic civilizations as most did encounter
               | one of those two in history, who are famously known to
               | have independently discovered the concept of zero.
               | 
               | Birth of an array can only logically be defined as index
               | zero, the same as a child. The concept of zero was not
               | universal globally and Korea is pretty isolated.
        
               | OscarCunningham wrote:
               | Except that we actually do use this system for years.
               | Thus 1 BC (the first year BC) was followed by 1 AD (the
               | first year AD). Also for centuries, as in 'the 20th
               | century' being the years 1901 to 2000.
        
             | hathawsh wrote:
             | A more sensible English translation from Korean would be to
             | use the phrase "in year X" rather than the phrase "X years
             | old": a newborn is in year 1; after 12 months they are in
             | year 2; etc.
             | 
             | In fact, this whole discussion is more about a choice of
             | phrasing rather than the numbers. When indexing arrays,
             | sometimes we're talking about an _offset from the first
             | element_ (starting with  "0"), and sometimes we're talking
             | about _ordinal element numbers_ (starting with  "first").
             | Some programming language designers found that offsets are
             | more useful (because that choice tends to simplify the
             | underlying arithmetic), while others found that ordinal
             | numbers are more useful (because the word "first" should
             | mean "1", to simplify communication between people).
        
               | OscarCunningham wrote:
               | Right. I try to refer to a[n] as 'element number n'
               | rather than 'the nth element'.
        
             | gumby wrote:
             | This system is used for racehorses as well.
        
           | lupire wrote:
           | The first floor in a USA building is not where a European
           | would expect.
        
           | anigbrowl wrote:
           | No. Your age is 1-indexed. It's a 'birthday' in English and
           | German ('geburstag'); in French it's 'anniversaire', and so
           | on. But pretty much everyone indexes age from 1. The fact of
           | your birth is the transition from (legal) non-existence to
           | existence, the equivalent of a dimensionless point.
        
             | wruza wrote:
             | Age is definitely 0-indexed - a newborn and exactly 1 year
             | old differ by a year. People also count months during the
             | _first_ year, which is still 0 years old. As in 00:xx is
             | the first hour, and 01:xx is the second. If you 're 30
             | years old, it's your 31st year of life now.
             | 
             | But gregorian epoch itself is 1-based. 1AD (0001-01-01)
             | goes right after 1BC (-0001-12-31). There was no 0000-mm-
             | dd. That's why 3rd "millenium" and 21st century started at
             | 2001-01-01 and _not_ at 2000-01-01. YYYY means not how many
             | whole years already passed, but _which_ incomplete year
             | goes right now. On the other hand, your age means  "whole
             | years passed since birth [plus maybe a few months]".
        
           | ethbr0 wrote:
           | It's fundamentally a distinction between end-index and start-
           | index.
           | 
           | Most human counting uses end-index. I.e. "1" is _after_
           | 1-thing (has passed, is physically obtained, etc.).
           | 
           | Most computer counting uses start-index + length, for
           | efficiency and to better generalize. I.e. "1" is at the
           | memory address immediately _before_ the  "1"st item.
           | 
           | Which ultimately creates the "0 index is 1st thing"
           | linguistic confusion.
           | 
           | PS: Also, language predates computers by a few years, and the
           | concept of zero is hard.
        
             | smegsicle wrote:
             | good take!
             | 
             | i think a more accurate and complete idea is that humans
             | refer to a thing _in its entirety_ , with things being
             | lined up and scanned in order as only a potential
             | convenience
             | 
             | if you ask someone to identify an object, they'll point to
             | the middle (or center of the most important component) of
             | the object, not to the 'start' or 'end' of it in their
             | field of vision..
             | 
             | that said, the human perspective is subtle and convenient
             | in completely different ways to how a computer manages
             | memory, and this 'end-index' idea seems like a useful way
             | to map the human whole-object perspective to a linear
             | memory-index perspective
        
           | Stratoscope wrote:
           | Rulers too. A ruler starts at 0, not 1.
        
             | dividuum wrote:
             | Not all of them do:
             | https://twitter.com/blinry/status/1550920690529968128 %)
        
               | Stratoscope wrote:
               | Nice! I want a Lua ruler now.
        
             | anigbrowl wrote:
             | That's because it's dimensional. How long is the shortest
             | possible ruler?
        
               | dalmo3 wrote:
               | 1 planck length, and... It starts - and ends - at 1?
        
           | Tagbert wrote:
           | Birthdays are anniversaries. Anniversaries are annual
           | activities when we celebrate/honor past events. They do not
           | include the event itself. The first anniversary is 1 year
           | after the initial event.
        
             | randomdata wrote:
             | _> Birthdays are anniversaries._
             | 
             | Indeed they are, which is why I literally said so in the
             | previous comment. Did you forget to finish reading it?
             | 
             |  _> They do not include the event itself._
             | 
             | That is true because the event itself is implied
             | information. There is no value in speaking of it. If you
             | stand before us, we can be certain that you had a day of
             | birth (your 0th anniversary). We don't necessarily know how
             | many times you've gone around the sun following that,
             | however, so that is where we find value in communicating
             | additional information.
             | 
             | If you were counting apples, there is the state where you
             | have no apples (index 0), the state where you have one
             | apple (index 1), the state where you have two apples (index
             | 2), etc. When counting you don't need to worry about index
             | 0 because the no apple state is naturally implied. It only
             | becomes interesting and worthy of communication when you
             | have at least one apple to speak of, thus you start at 1.
             | The state found at index 0 is still implicitly there,
             | though.
        
               | lupire wrote:
               | If I care about apples (for my lunch, or my store), I
               | care about the difference between having 0 of them and
               | not having bothered to count yet.
               | 
               | 0!=null
        
               | randomdata wrote:
               | If no apples is the unusual state, like you expected to
               | find an apple in your lunchbox but someone ate it without
               | your knowledge, then certainly there would be reason to
               | communicate the no apples state. It is ignored in
               | communication when it does not provide useful
               | information, but it is not forgotten. The 0th index is
               | implicitly there.
        
               | anigbrowl wrote:
               | Come to the infinity store - we literally sell
               | everything! (some items may be out of stock)
        
               | randomdata wrote:
               | Yes, the infinite state is also implicitly found within
               | the state set. Conveniently found at the infinity index.
        
             | sokoloff wrote:
             | Yes, that's the explanation for _how_ we count them as we
             | do, but it has no greater weight (and I'd argue less
             | weight) as to _why_ than saying whether a[0] or a[1] should
             | be the first element in an array.
             | 
             | I say it has less weight as birthday is a compound word,
             | the root words of which suggest that your first birthday
             | could logically be the day of your birth rather than a year
             | after it.
             | 
             | My first weddingday was not a year after I got married. My
             | first graduationday was not a year after I graduated.
        
       | rmason wrote:
       | Actually 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 wrote:
         | also Lua and R.
        
         | ur-whale wrote:
         | And Julia, an otherwise nice language.
        
       | dark-star wrote:
       | Simple 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
        
       | User23 wrote:
       | Pascal's arrays start at 1, at least by default.
        
         | wvenable wrote:
         | Pretty much all variants of BASIC have arrays starting at 1.
        
           | hwayne wrote:
           | Pascal 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.
        
           | JKCalhoun wrote:
           | I 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....
        
         | unnouinceput wrote:
         | This 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).
        
       | Koshkin wrote:
       | The _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.
        
       | csours wrote:
       | This 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://medium.com/interesting-histories/interesting-histori...
        
         | zwkrt wrote:
         | I really fail to understand what the etymology of sex and
         | gender classifications has to do with array based indexing.
        
           | csours wrote:
           | > "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."
        
       | codefreeordie wrote:
       | Arrays 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.
        
         | giraffe_lady wrote:
         | That 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 wrote:
           | Or 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 wrote:
         | In 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.
        
           | yonrg wrote:
           | hehe, that was me :) when I was young.
        
         | nicoburns wrote:
         | That'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 wrote:
           | Is `(x - 1)` not a runtime cost if `x` is a runtime variable?
        
             | vikingerik wrote:
             | Not on many instruction architectures - addressing modes
             | often support adding/subtracting a constant.
        
       | demindiro wrote:
       | I 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]
        
       | bregma wrote:
       | If 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.
        
         | ajuc wrote:
         | The 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 wrote:
           | It 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...
        
             | hbn wrote:
             | You'd think if they had to go below 0 they could just
             | prefix with a letter, like B (Below? Basement?) B1, B2,
             | etc.
        
           | adrianmonk wrote:
           | Counterpoint: because floors are sum types.
           | 
           | Floors 1 through 10 are "regular" floors. L is the lobby. P1
           | through P3 are the parking (basement) levels.
           | 
           | So you have three types: regular, lobby, and parking. And the
           | elevator labels are of type regular | lobby | parking.
           | 
           | (Now you can't disagree with me because sum types are popular
           | on HN, and I have framed this in terms of sum types.)
        
             | ajuc wrote:
             | Sum types don't automatically define ordering between the
             | possible values AFAIK? So in your implementation you'd have
             | to manually define the                   up: (regular |
             | lobby | parking) -> (regular | lobby | parking)
             | down: (regular | lobby | parking) -> (regular | lobby |
             | parking)
             | 
             | and                   which_way: (regular | lobby |
             | parking) x (regular | lobby | parking) -> direction
             | 
             | If you use subset of integers you can just use operators
             | inc, dec and <.
             | 
             | Yeah I know it was a joke.
        
               | adrianmonk wrote:
               | If I build a building in the shape of a double helix,
               | what order are the two floors in?
               | 
               | Hmm, are there actually an infinite number of floors? Do
               | we need to switch to floating point?
        
               | ajuc wrote:
               | > If I build a building in the shape of a double helix,
               | what order are the two floors in?
               | 
               | Why separate the floors that are on the same level?
               | 
               | > Hmm, are there actually an infinite number of floors?
               | 
               | I assumed there isn't and that we use a subset of
               | integers. If you have infinite number of floors - feel
               | free to use full set of integers (if you have enough
               | memory that is).
               | 
               | > Do we need to switch to floating point?
               | 
               | No point, if you have more than aleph0 floors - floats
               | won't help you.
        
         | GnarfGnarf wrote:
         | The Patterson Building at Acadia University in Wolfville, NS,
         | has a basement and four floors. The rooms on the first floor
         | are numbered 1XX, second floor 2XX, etc. up to the top floor
         | 4XX.
         | 
         | The elevator, however, goes from floor '1' (the basement), to
         | floor '5' (the top or fourth floor).
         | 
         | This really confuses visitors.
         | 
         | The Elevator Mafia want $10,000 to fix it.
        
         | perlgeek wrote:
         | A 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 wrote:
           | I 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.
        
         | KineticLensman wrote:
         | When I was at Leeds University the ground floor of the Physics
         | Admin building was Level 6 (it went up to Level 11). It was
         | built on a hill and according to legend this allowed room for
         | expansion (which never happened) down the hill without
         | requiring negative floor numbers.
         | 
         | To add to the fun the only continuous corridor through the
         | entire T-shaped building was on Level 10, one end of which (the
         | base of the T) was at ground level on its part of the hill.
         | There was a famous 'kink' in the middle of the top / cross-bar
         | of the T (apparently the longest corridor in Europe) because
         | they started building from each end and were slightly off.
        
         | bluetwo wrote:
         | I always said it was an argument between the counting of things
         | versus the relative offset of things.
         | 
         | This is a great example.
        
         | levodelellis wrote:
         | I call `array[0]` the first element. I don't know what you'll
         | think of that.
         | 
         | I wonder how many multiples of people who like arguing about
         | starting from 1 vs 0 and how many people were confused for more
         | than a day
        
         | systemvoltage wrote:
         | I've been living in North America for decades. Every building
         | has G (zero). This is the floor that you walk into and has a
         | lobby. The next floor up is 1 as such is labeled in the
         | elevator.
         | 
         | So your initial assumption is incorrect from my experience.
        
           | silisili wrote:
           | This is not my experience in the US. Most places either have
           | G or 1 for the first floor. Then 2 for the next. So some
           | elevators say G, then 2, 3, and so on.
           | 
           | I've seen setups like you mention, but they definitely aren't
           | the majority in places I've lived.
        
           | jwarden wrote:
           | What city are you in, out of curiosity?
        
             | systemvoltage wrote:
             | SF Bay Area (currently), but have lived in several major
             | metro areas.
        
       | pklausler wrote:
       | Because sometimes we number things, and sometimes we count
       | things.
        
       | hcrisp wrote:
       | Dijkstra'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/E...
        
         | intrepidhero wrote:
         | It could just as easily be 1 <= i <= N and then I wouldn't have
         | to remember that the lower bound is inclusive and the upper
         | exclusive.
        
           | layer8 wrote:
           | Then the delta of both bounds (N - 1) wouldn't equal the
           | length of the range (N). The inclusive-exclusive convention
           | is used in order for `end = start + length` to hold.
        
             | Jtsummers wrote:
             | Why does that matter when the starting point is 1? In that
             | case, you don't need the delta because you have the length
             | already. In the case of a 0-based range you also don't need
             | the delta, though you will want to use the inclusive-
             | exclusive convention so that you get the length "for free".
             | 1 <= a <= N -- N = length, no delta       0 <= a < N  -- N
             | = length, no delta
             | 
             | You only calculate the length when dealing with other than
             | 0- or 1-based ranges. There, the inclusive-exclusive
             | convention is very handy as you point out. So if we're
             | fixing the initial offset at either 0 or 1, then use the
             | appropriate convention for that offset. If we let the
             | initial offset float, then the inclusive-exclusive makes
             | sense.
        
               | layer8 wrote:
               | It matters whenever you need to process a proper subrange
               | of an array, and that shouldn't be different from when
               | the subrange happens to be the whole range. It's simpler
               | if the same convention is used in all cases.
               | 
               | E.g. in Java, a typical example is that OutputStream has
               | the following two methods, where the first can delegate
               | to the second, and the second (which write the specified
               | subrange of the array) can easily calculate the number of
               | bytes to write:                 int write(byte[] bytes)
               | {           return write(bytes, 0, bytes.length);       }
               | int write(byte[] bytes, int start, int end)       {
               | int length = end - start;           ...       }
        
               | Jtsummers wrote:
               | I addressed that:
               | 
               | > If we let the initial offset float, then the inclusive-
               | exclusive makes sense.
               | 
               | But you replied to someone using inclusive-inclusive for
               | 1-based arrays and complained about the delta not
               | matching the length. Which is a nonsensical complaint,
               | you have the length already why would you need to
               | calculate anything?
        
               | layer8 wrote:
               | In case of the subrange you don't have the length (or you
               | conversely have the length but not the upper bound), and
               | you don't want to use different conventions based on
               | whether you process the subrange or the whole range. I'm
               | not sure how I can make it clearer.
        
           | thomasahle wrote:
           | Closed ranges (with both ends inclusive) are super annoying
           | to work with. You can represent the empty range (unless you
           | are willing to do [i : i-1]), and they don't compose like
           | half open ones: [a : b) + [b : c) = [a : c).
        
             | elikoga wrote:
             | cannot?
        
         | goatlover wrote:
         | I 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 wrote:
           | That would give a sequence of N+1 elements, though. Confusing
           | if you had a function like range(N), for example.
        
             | goatlover wrote:
             | Why, it would be an inclusive instead of exclusive range. N
             | is the last element, so no reason for N+1.
        
               | weavejester wrote:
               | If 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
        
       | beardyw wrote:
       | Starting at one led to the whole "2000 is not the millennium"
       | thing, as there is no year zero.
        
         | ziml77 wrote:
         | Even more painful is that the 2001 began the 21st century, not
         | the 20th.
        
       | jfmc wrote:
       | The 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'.
        
       | spullara wrote:
       | 0 is offset based. 1 is index based.
        
         | thetwentyone wrote:
         | This 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.
        
       | tomkaos wrote:
       | Worst 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 wrote:
         | You 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 wrote:
         | One of the least-loved APL features is the fact that you can
         | change the index origin at runtime.
        
       | diego_sandoval wrote:
       | Because 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 wrote:
         | The 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
        
           | anigbrowl wrote:
           | Are you sure it doesn't just look that way because you are
           | used to monospaced fonts? Ask a kid to show you their zeroth
           | finger.
        
             | TOGoS wrote:
             | As a kid, I saw these things often on multiple-choice test
             | sheets. The tens digit at the end of each row not matching
             | that at the beginning always seemed awkward, and I wondered
             | why they didn't just start at zero. This was long before I
             | did any programming.
             | 
             | The first year CE being "1" resulting in the new millennium
             | starting at 2001 instead of 2000 also seemed idiotic, and
             | the 1900s being referred to as "the 20th century" was
             | something I always had to consciously compensate for.
             | Numbering items starting at zero would have given us more
             | elegant/less confusing ways to communicate those things.
             | 
             | Zero-based indexing makes things inherently simpler because
             | it matches the way we write numbers (and becomes much more
             | noticeable once you have more than one digit). It's not
             | just an optimization for computers.
        
               | adolph wrote:
               | Well, given that year numbering system's start in Europe,
               | zero wasn't as broadly accepted as other digits at the
               | time.
               | 
               |  _By AD 150, Ptolemy, influenced by Hipparchus and the
               | Babylonians, was using a symbol for zero._
               | 
               | https://en.wikipedia.org/wiki/0#History
               | 
               | To keep it confusing: _the traditional proleptic
               | Gregorian calendar (like the Julian calendar) does not
               | have a year 0 and instead uses the ordinal numbers 1, 2,
               | ... both for years AD and BC. Thus the traditional time
               | line is 2 BC, 1 BC, AD 1, and AD 2. ISO 8601 uses
               | astronomical year numbering which includes a year 0 and
               | negative numbers before it. Thus the ISO 8601 time line
               | is -0001, 0000, 0001, and 0002._
               | 
               | https://en.wikipedia.org/wiki/Gregorian_calendar#Dual_dat
               | ing
        
             | marak830 wrote:
             | I asked my son to show me zero fingers(after show me 2
             | fingers and 5 fingers), he closed his fists.
        
               | anigbrowl wrote:
               | My point exactly - there isn't an identifiable zeroth
               | finger.
        
               | colonwqbang wrote:
               | There's not a second finger either. You can convey "two"
               | by showing any two fingers.
        
               | gitonthescene wrote:
               | And? My solution? Let the kid grow up and learn.
        
               | anigbrowl wrote:
        
               | pygy_ wrote:
               | Anecdotally, I taught my children numbers starting from
               | zero with a similar routine, based on cardinality. They
               | immediately got it.
               | 
               | My kids' school also uses zero-based tables.
               | 
               | "Natural" is a very loaded and ambiguous term, best
               | avoided if you hope to have sane discussions.
        
         | [deleted]
        
         | [deleted]
        
         | twobitshifter wrote:
         | Someone linked to your johnny decimal system earlier today.
         | https://johnnydecimal.com/ I liked the idea but I noticed that
         | it didn't seem to be 0 indexed. If I adopt this i'm definitely
         | going for zero indexing.
        
         | woojoo666 wrote:
         | I like how the article summarizes this idea:
         | 
         | > These all point to one reason why 0-indexing might be
         | preferred: it matches machine semantics more
        
           | kergonath wrote:
           | But then of course the reason why 1-indexing is better (or
           | really, arbitrary indexing, which is even better) is that it
           | matches human semantics better.
        
         | jbaczuk wrote:
         | Yeah, but then couldn't the compiler just swap the 1 with a 0
         | and 256 with 255?
        
       | kshacker wrote:
       | I 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 wrote:
         | Early 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.
        
       | anigbrowl wrote:
       | _I 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
        
       | waynecochran wrote:
       | It's an offset from the beginning. Simple as that.
        
       | 323 wrote:
       | Obligatory, there are a lot of memes on this subject:
       | 
       | https://www.google.com/search?q=arrays+start+at+zero+meme&tb...
        
       | make3 wrote:
       | I 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
        
       | twanvl wrote:
       | Other 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 N 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+width _y]`. 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.
        
         | tabtab wrote:
         | In many domains code maintenance is more important than
         | hardware costs. In many domains 1-based indexing is a better
         | fit, meaning less conversion code, meaning simpler code. Thus,
         | the best indexing choice depends on the domain and
         | circumstances, as do many controversial questions. Most tend to
         | specialize in specific kinds of domains and over-extrapolate
         | their experience into other domains.
        
           | wizofaus wrote:
           | I'd agree so why did languages that allow specifying the base
           | die (other than maybe VBA).
        
             | btilly wrote:
             | Because changing the base is a great source of bugs.
             | 
             | That said, not all languages have given up on this. For
             | example Julia allows it.
             | https://docs.julialang.org/en/v1/devdocs/offset-arrays/
             | 
             | Ironically I learned this from a discussion of Julia bugs.
             | Apparently changing offsetting of arrays has proven to be a
             | source of bugs in Julia. So maybe someday they will come to
             | the same conclusion as languages like Perl and stop
             | allowing it.
        
               | wizofaus wrote:
               | I'd argue 0-base is a source of bugs too! Ideally we'd be
               | able to catch more array indexing bugs at compile time -
               | there are definitely cases where it should be possible to
               | determine that arrays are being incorrectly indexed via
               | static analysis.
        
               | btilly wrote:
               | The problem is that libraries which assume 0-base break
               | when you have a 1-based array. And vice versa. Trying to
               | combine libraries with different conventions becomes
               | impossible.
               | 
               | Therefore changing the base leads to more bugs than
               | either base alone.
               | 
               | That said, the more you can just use a foreach to not
               | worry about the index at all, the better.
               | 
               | Of 0-based and 1-based, the only data point I have is a
               | side comment of Dijkstra's that the language Mesa allowed
               | both, and found that 0-based arrays lead to the fewest
               | bugs in practice. I'd love better data on that, but this
               | is a good reason to prefer 0-based.
               | 
               | That said, I can work with either. But Python uses
               | 0-based and plpgsql uses 1-based. Switching back and
               | forth gets..annoying.
        
         | msdrigg wrote:
         | This is the reason I always think of when I hear the question
        
         | bluetomcat wrote:
         | A 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--) ...
        
           | operator-name wrote:
           | In that specific case I'd do the following:
           | for (size_t i = n; i-- > 0 ;) ...
           | 
           | Or count from `length` to 1, but subtract 1 in the loop body,
           | or count up and subtract the length in the loop body. Any
           | modern compiler should be able to optimise these to be
           | equivalent.
           | 
           | In the majority of cases, counting down is not necessarily.
           | Nor is ordered iteration. Most languages have a `for each`
           | style syntax that's preferable anyway.
        
             | divbzero wrote:
             | Or alternatively:                 size_t i = length;
             | while (i--) ...
        
             | cylon13 wrote:
             | Ah yes, the goes-to operator -->
        
               | tomjakubowski wrote:
               | And the wink operator, so the compiler knows you know the
               | deal
        
               | wizofaus wrote:
               | Gold - have an upvote!
        
           | pwdisswordfish9 wrote:
           | You can always rip a page out of C++'s playbook:
           | for (size_t i = length; i > 0; i--) {             // ...
           | item = array[i - 1];
           | 
           | (This is how reverse iterators work in C++.)
        
           | mananaysiempre wrote:
           | As Jens Gustedt points out[1], the following _intentional_
           | unsigned overflow works perfectly for downwards iteration
           | (even when length is 0 or SIZE_MAX), though it looks a bit
           | confusing at first:                 for (size_t i = length -
           | 1; i < length; i--) ...
           | 
           | You are also free to start at any other (not necessarily in-
           | bounds) index, just like with ascending iteration.
           | 
           | [1] https://gustedt.wordpress.com/2013/07/15/a-praise-of-
           | size_t-...
        
             | xxs wrote:
             | the footnote [1] should be [0], just for the sake of this
             | very topic.
             | 
             | Seriously though, while the idiom does work for unsigned
             | integers, it's a bad idiom to learn [makes code reviews
             | harder]. The post-decrement one in the loop body works with
             | everything (signed/unsigned), and it's well known.
        
             | 411111111111111 wrote:
             | Uh I'm confused but don't know c++.
             | 
             | why doesn't that loop end instantly?
             | 
             | I mean length - 1 < length should always be true, right?
             | 
             | Or does it only terminate when the number underflows?
             | Terribly confused here
        
               | msk-lywenn wrote:
               | It's a condition to run, not a condition to stop
        
               | wizofaus wrote:
               | That was my reaction - why should anyone think it might
               | be the latter? Are there languages that do have such a
               | syntax without explicit keywords ("do...until")?
        
               | bobthepanda wrote:
               | It's an unsigned int, so past 0 it overflows back to the
               | maximum
        
               | 411111111111111 wrote:
               | Ooh, i see. I wasn't aware that they under/overflow at 0
               | when they're unsigned. Thanks for broadening my horizon!
        
               | billforsternz wrote:
               | The loop continues until i transitions from 0 to 0 minus
               | 1. 0-1 in this case actually doesn't equal -1 since
               | size_t is an unsigned type, instead it wraps around to be
               | the largest possible positive integer instead. TLDR; yes
               | as you speculate it terminates when the number
               | underflows.
        
               | naavis wrote:
               | It loops while the condition is true. When an underflow
               | happens, it stops being true.
        
               | Jtsummers wrote:
               | For loops are translatable from:
               | for(initialize; condition; increment) { ... }
               | 
               | to:                 initialize;       while(condition) {
               | ...         increment       }
               | 
               | (more or less, some scoping things not encompassed by the
               | above; this is also how pretty much every for loop in a
               | C-syntax language works) The condition of a for loop is
               | equivalent to a while loop's condition. So yes, _length -
               | 1 < length_ will be true on the first iteration, which is
               | fine because the loop continues _as long as_ that
               | condition is true.
               | 
               | What the above approach takes advantage of is that when
               | underflow eventually happens you'll have this condition:
               | MAXINT < length
               | 
               | Which will terminate it for all possible values of
               | _length_.
        
             | salawat wrote:
             | Principle of least surprise violated.
             | 
             | Also, that behavior is not guaranteed. The programmer would
             | need to be aware of how the particular machine in question
             | actually handles that.
             | 
             | Then again, that's C.
        
               | sersnth wrote:
               | Unsigned integer underflow and overflow are both
               | guaranteed to wrap by the C standard.
        
           | nemetroid wrote:
           | Unless wrapping underflow is sensible for the domain (which
           | it isn't when representing the size of something), unsigned
           | integers are usually a bad idea.
        
           | [deleted]
        
           | ncmncm wrote:
           | If you have foolishly turned off -W in your build system,
           | that could happen. Otherwise, you get a nice warning pointing
           | out your folly.
        
           | 10000truths wrote:
           | for (size_t i = 0; i < length; i++) {           size_t j =
           | (length - 1) - i;           ...       }
           | 
           | EDIT: change i to j
        
             | yuliyp wrote:
             | That'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).
        
             | Banana699 wrote:
             | You should save the old value of i somewhere and restore it
             | back at the very end of the loop. Or simply define a new j
             | like another comment says.
        
             | unwind wrote:
             | Uh no don't reassign the loop variable in the inner scope.
             | Use:                   const j = (length - 1) - i;
             | 
             | in that case. Much safer.
        
             | rabbidruster wrote:
             | I hope you haven't done this anywhere.
             | 
             | Makes my brain hurt, but I think this will only run through
             | the loop one time looking at the last element of the array.
        
           | bregma wrote:
           | In the C programming language unsigned integers do not
           | overflow. They wrap. This is well-defined behaviour and the
           | example code is simply incorrect. Most modern compilers will
           | give you a diagnostic for this.
        
           | xxs wrote:
           | the correct way/idiom to reverse iterate an array is
           | for (size_t i = length; i-- > 0; )...
           | 
           | It's surprising how often the issue pops, it works well with
           | both signed and unsigned integers.
           | 
           | (edit) I've started with one based indexing (basic)... mixed
           | with 0 based (assembly), more 1 based (pascal), then more
           | stuff (all zero based). I am, yet, to see a real advantage of
           | a one based indexing... after the initial process.
        
             | empiricus wrote:
             | Is this cache friendly?
        
               | msk-lywenn wrote:
               | It's not. It was nice on architectures were cache didn't
               | matter much and were subtracting and comparing to zero
               | was just one instruction (looking at you old core ARM)
        
               | sgtnoodle wrote:
               | Sure, why wouldn't it be? As far as a cache is concerned,
               | I don't think reverse sequential iteration would be any
               | different than forward sequential. The actual RAM
               | accesses may be less optimal if there's some speculative
               | pre-fetching with assumed forward sequential access, but
               | that's conjecture.
        
         | youor wrote:
        
         | mananaysiempre wrote:
         | A rare case where 1-based indexing is more convenient is
         | complete binary trees laid out breadth-first (as in a standard
         | binary heap): parent is i div 2 and children are 2i and 2i+1
         | when starting at one and who knows what when starting at zero.
         | But that's the only one I know.
        
           | btilly wrote:
           | With 0-based indexing the children are at 2i+1 and 2i+2. The
           | parent is at (i-1) div 2.
           | 
           | Not hard to figure out.
        
             | JadeNB wrote:
             | > With 0-based indexing the children are at 2i+1 and 2i+2.
             | The parent is at (i-1) div 2.
             | 
             | > Not hard to figure out.
             | 
             | While that's true, "you just shift by 1" is equally good at
             | all arguments for or against 0-based indexing, so deploying
             | it here probably won't convince.
        
               | btilly wrote:
               | I was not trying to convince.
               | 
               | That said, the effort of one versus the other is so
               | trivial that there is no point in ever using effort as an
               | argument either way. Doubly so because what seems like
               | effort to us is simple unfamiliarity.
               | 
               | What _is_ important is which one leads to more careless
               | errors in practice. As a trivial example, consistent
               | indentation takes effort, but failing to do it leads to
               | more careless errors. Therefore everyone indents code.
               | 
               | The only data point I've seen on that is the side remark
               | about Mesa in https://www.cs.utexas.edu/users/EWD/transcr
               | iptions/EWD08xx/E.... That remark, therefore, is the only
               | argument that I care about.
        
           | wizofaus wrote:
           | Except 1-based indexing is what we use in normal language. We
           | don't use "zeroeth" or "player (number) zero" etc. And the
           | word "first" is shortened to 1st etc. Personally I think we'd
           | be better off if programming languages stuck to the same
           | convention - off-by-1 errors aren't the hardest problems to
           | deal with but they're still annoying.
        
             | misttar wrote:
             | The 2 major blunders in programming: 1) Off by one errors.
        
             | ChickeNES wrote:
             | Well: https://www.merriam-webster.com/dictionary/zeroth
        
         | OscarCunningham wrote:
         | I think the 1-indexing folks would have to argue that a%b
         | should return a value from 1 to b inclusive. This does make the
         | same sort of intuitive sense as 1-indexing. For example we
         | number clocks from 1 to 12.
        
           | black_knight wrote:
           | But interestingly, the number at the top is 12, not 1.
        
           | cryptonector wrote:
           | 12 is zero, in 12-hour clocks.
        
           | vore wrote:
           | % is defined as (mostly) a remainder operator. I don't think
           | you want to change the semantics of division itself.
        
             | OscarCunningham wrote:
             | Right. Ultimately the 1-indexers are wrong.
        
       | ur-whale wrote:
       | Unfortunate that the Julia folks weren't exposed to this when
       | they designed the language.
        
         | Jtsummers wrote:
         | 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.
        
       | chmod775 wrote:
       | Another 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.
        
       | Gordonjcp wrote:
       | Because 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.
        
       | Grustaf wrote:
       | Simple: because we start with index 0 in mathematics.
        
       | auggierose wrote:
       | Funny, 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-...
       | 
       | 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.
        
       | glitchc wrote:
       | Array 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 wrote:
         | Yet somehow Fortran manages to be highly performant.
        
       | oh_my_goodness wrote:
       | "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.
        
       | snarfy wrote:
       | Indexes 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 wrote:
         | Arrays in the programming languages you're familiar with use
         | offsets.
         | 
         | Not all do [1].
         | 
         | 1. https://therenegadecoder.com/code/which-programming-
         | language...
        
           | snarfy wrote:
           | Of course, and I've used Lua for a long time.
           | 
           | The point is that offsets and indexes have different meaning.
        
             | anamexis wrote:
             | Where are you getting this definition of index?
        
       | tunesmith wrote:
       | I always assumed it came back to math, and that t0 or time-zero
       | is useful for the beginning state _before_ anything happens.
        
         | goatlover wrote:
         | What 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.
        
       | notpushkin wrote:
       | The _Lessons_ section is brilliant.
        
       | tejtm wrote:
       | For me it comes down to; are you enumerating intervals or items
       | to offset into.
        
       | caxco93 wrote:
       | I always thought it was because it's easier multiplying the index
       | by the size of the array item to get the correct offset
        
       | labrador wrote:
       | Because 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-origi...
        
       | ur-whale wrote:
       | So that modulo works the way god intended inside a ring buffer.
        
       | franciscop wrote:
       | I'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.
        
         | andy81 wrote:
         | English also has that "mezzanine" concept, for partial floors
         | with a balcony over the main floor. You see it sometimes on
         | elevators as an M.
        
         | onlyrealcuzzo wrote:
         | It 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 wrote:
           | I (US) don't remember seeing the second floor labeled 1. I
           | often see G, 2, 3
        
       | jschveibinz wrote:
       | I have always assumed that is just one less operation required to
       | resolve the absolute memory address.
        
         | nsajko wrote:
         | No.
         | 
         | 1. Optimizing compilers exist.
         | 
         | 2. Addressing at fixed offsets is cheap (a single instruction):
         | 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 wrote:
           | 3. 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 wrote:
           | That 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 wrote:
             | Well 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 wrote:
           | TFA = Thanks For Asking?
        
             | brobinson wrote:
             | The "Friendly" Article
        
             | layer8 wrote:
             | https://mtsknn.fi/blog/tfa-stands-for-the-featured-article/
        
           | goatlover wrote:
           | > 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 wrote:
         | The 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 wrote:
           | How 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 wrote:
             | If you're calculating indexes at runtime, you're probably
             | not worried about that level of optimization.
        
         | rhacker wrote:
         | This 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 wrote:
           | There's no reason why memory addresses had to start at 0.
        
             | [deleted]
        
       | unixbane wrote:
       | So 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.
        
       | juped wrote:
       | Zero-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.
        
         | kazinator wrote:
         | Some guitars have a zeroth fret; an actual fret at the nut.
        
         | dalmo3 wrote:
         | An ordered collection of events in time usually starts at t(0).
        
         | ryanisnan wrote:
         | I 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
        
         | Schroedingersat wrote:
         | An 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.
        
       | calibas wrote:
       | The 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.
        
       | xg15 wrote:
       | I 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?
        
         | turboponyy wrote:
         | Nats start at 0, end of discussion - it's only logical to index
         | by the naturals.
        
           | salty_biscuits wrote:
           | Where 0 is the cardinality of the empty set, i.e. some empty
           | collection. Not a convincing argument.
        
             | JadeNB wrote:
             | > Where 0 is the cardinality of the empty set, i.e. some
             | empty collection. Not a convincing argument.
             | 
             | Why not? "Every cardinality, _except of the empty set_ , is
             | a natural number" isn't very convincing to me, if we're
             | making cardinal-based arguments.
        
               | salty_biscuits wrote:
               | I'm not arguing that the natural numbers should start
               | from one, rather that the usual path for developing the
               | natural numbers starting with set theory is that zero is
               | the size of a set with nothing in it. In maths they
               | always talk about the first element in a vector, not the
               | zeroth. It is a bad argument to point to mathematics for
               | using zero based indices. It is not at all common to use
               | zero based indexing there.
        
               | thaumasiotes wrote:
               | It's not a convincing argument because you index into an
               | array if you want to retrieve an element contained in the
               | array. If 0 is the cardinality of an empty collection,
               | it's not a valid index, because you can only index into
               | non-empty collections.
        
           | mtizim wrote:
           | That's really silly - the natural numbers also famously start
           | at either 0 or 1, depending on the country, the discipline,
           | and the individual.
        
             | zzo38computer wrote:
             | It is because you mean two different things by "natural
             | numbers", even though the same words are used for things
             | that are not the same things.
             | 
             | I prefer to start by zero; I think it is more useful in
             | general, and makes more sense mathematically for many
             | (although not all) purposes, and systems that you will find
             | objects and operations that have these properties too.
        
             | thaumasiotes wrote:
             | I like to treat the naturals as starting at zero, but not
             | for any mathematical reason. I just think that since it's
             | easy to write Z+, it's more useful for N to refer to
             | something slightly different than it would be for N to be a
             | synonym for Z+ while anyone wanting to include zero in
             | their set was forced to spell out "nonnegative integers".
             | 
             | A dichotomy between "Z+" on the one hand versus "N" on the
             | other is just plain _more convenient_ than a dichotomy
             | between  "Z+" and "N" on the one hand versus "Z\Z-" on the
             | other.
        
           | JadeNB wrote:
           | > Nats start at 0, end of discussion - it's only logical to
           | index by the naturals.
           | 
           | Now you'll just bring out the people who start the naturals
           | at 1.
        
             | ajg36 wrote:
             | Starting the naturals at 1 is quite onerous.
        
           | thaumasiotes wrote:
           | > Nats start at 0, end of discussion - it's only logical to
           | index by the naturals.
           | 
           | Well, no, obviously you want to index by ordinals, and they
           | start at "first".
        
           | topaz0 wrote:
           | If there were any justice in the world, they'd start at 2, as
           | a handicap. They might even make it out of the bottom of the
           | NL east if that was the case.
        
         | Someone wrote:
         | > 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.
         | 
         | The easy way to do that is by shifting the base address. In
         | pseudo-C (I think that computing the _b_ pointer is non-
         | conforming, even if the code never tries to access _b[0]_ , but
         | compilers can do this without problems):                  int
         | a[100];      // array of 100 integers, zero-based        int *
         | b = a - 1; // array of 100 integers, one-based
         | 
         | Things only get costly when you want to check array bounds or
         | when you have multi-dimensional arrays. There also may be non-
         | standard architectures where this kind of stuff isn't possible.
        
           | twobitshifter wrote:
           | Should work 99.99999% of the time until someone tries to put
           | an array at 0x000001 :)
        
             | alexcosan wrote:
             | I think, in theory, it would work regardless of the
             | starting address. As long as you don't try to access the
             | invalid address (which you wouldn't assuming that it's
             | starting in the index 1, you would always be accessing the
             | first valid address)
        
           | [deleted]
        
         | matthewmcg wrote:
         | Amusing but probably irrelevant: the sailing yacht racing
         | handicapping calculations mentioned are almost certainly under
         | the Performance Handicap Racing Fleet (PHRF) system[0]. This
         | system is "zero based" in its own way. A sailboat's performance
         | is assessed and handicapped against a standard yacht with a
         | zero rating. Your time to complete the race course is adjusted
         | by your handicap to determine your final standing. This lets
         | you race slower and faster types of boats in a "fair" way.
         | 
         | [0] https://en.wikipedia.org/wiki/Performance_Handicap_Racing_F
         | l....
        
         | blueflow wrote:
         | That so people in this thread argue about the higher-level
         | language (missing the point) shows that few people found access
         | to the underlying machine code.
         | 
         | Which is sad, because all code is still executed as machine
         | instructions even when the developer does not see it or does
         | not want to care.
        
           | gitonthescene wrote:
           | It was just most basic example. Indices are connected with
           | math all the time. Consider implementing circular queues with
           | 1-based arrays. Any arguments about what's _possible_ miss
           | the point. Arguments about what _feels_ natural purport to
           | know the human mind which I find generally suspect. Mostly I
           | think of computers as tools and am interested in getting the
           | most functionality out as smoothly as possible not as slaves
           | whose job it is to make my life worry free.
        
           | Blikkentrekker wrote:
           | "machine code" isn't really the zero point that's special
           | nowadays.
           | 
           | The code the programmer wrote is compiled to something such
           | as LLVM IR, LLVM IR is further compiled by LLVM to Assembly,
           | this is further compiled by an assembler into machine code,
           | and then the c.p.u. further compiles this to it's internal
           | code as it executes it. "machine code" really is no more
           | special in this chain of events than, say, LLVM IR.
        
             | blueflow wrote:
             | Machine code is special because its the only thing the CPU
             | can actually execute.
        
             | [deleted]
        
           | just_boost_it wrote:
           | We're 20 years past the point where you can expect everyone
           | in tech to trace every instruction down to machine
           | instructions. Higher level languages abstract away the need
           | for it, and for the most part, we can rely on the authors of
           | those languages to make many of the decisions that impact
           | performance. The rest of us learn about these details on
           | posts like this. It's not a sad fact, in fact it's probably
           | one of the most useful things that's happened in tech. It
           | frees people to think about other problems.
        
             | ryanbrunner wrote:
             | If you're not raining about how your code translates to
             | logic gates, you're not a competent programmer. /s
             | 
             | Abstractions are good, and while we should be careful not
             | to completely trust a brand new abstraction, high level
             | languages are established enough that we don't need to
             | worry about it.
        
             | ivanhoe wrote:
             | 20 years ago ASM was just as cryptical black magic to most
             | of programers as it is today... try perhaps 40 y/a...
        
             | metafunctor wrote:
             | Not sure if you were around 20 years ago, but you sure
             | couldn't expect everyone in tech to understand machine
             | instructions as well as the layers above, all the way up to
             | corporate politics.
             | 
             | But some people, yeah, they could do it.
             | 
             | That has not changed.
        
             | [deleted]
        
             | TillE wrote:
             | I barely touch assembly in my day to day work, but I do
             | understand on a fairly deep level _how a computer works_ ,
             | which I feel is extremely important and very frequently
             | influences how I write high-level code.
             | 
             | Certainly one _can_ bang out code their entire career
             | without ever having a clue how machine code works, but I
             | really wouldn 't advise it. At worst it leads to total
             | ignorance, and at best you accumulate a disconnected set of
             | "best practices" as inscrutable lore handed down from on
             | high.
        
           | tdeck wrote:
           | If this were the primary reason, it seems odd that some of
           | the earliest popular languages used 1-based indexing in an
           | era with much slower CPUs (<= 1 MIPS) and less available
           | memory to store instruction code. If the authors of FORTRAN
           | were comfortable with 1-indexing on the IBM 704 (40 KIPS) in
           | 1957, it couldn't have been prohibitive. At the same time, as
           | computer use cases became more interactive there may have
           | been a greater focus on performance, but it likely that the
           | semantics of the high-level language were at least as
           | important.
        
         | iib wrote:
         | 0 for offsets, 1 for ordinals, that's usually the rule. Of
         | course, both are conventions.
        
         | lupire wrote:
         | Implementation matters for performance, but even beyond that,
         | the interface matters for users. 0-based offsets are convenient
         | for users doing math on indexes.
         | 
         | A pointer is just one kind of array-like indexing scheme. Good
         | pointery languages will distinguish Address from Offset from
         | Integer.
        
         | bluetomcat wrote:
         | The "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".
        
           | unilynx wrote:
           | Not sure if assembly/machine code is that relevant. If one
           | based indexing was more prevalent, the LEA instruction on x86
           | would just subtract one during execution
        
             | dboreham wrote:
             | "just subtract one" would take a long time 50-60 years ago.
        
               | Jtsummers wrote:
               | If you did this, you'd subtract one _once_ at array
               | creation. Or subtract whatever the offset is (really, you
               | 'd subtract 1 * data type size). Under the hood, using C
               | syntax instead of assembly:                 int foo[n];
               | // what the user wrote            // what happens behind
               | the scenes, after a fashion       int* foo = malloc(n *
               | sizeof(int); // or sp - n * sizeof(int) if stack
               | allocated; subtraction since stacks usually grow "down"
               | foo = foo - 1;
               | 
               | All references into _foo_ will now work just fine so long
               | as they are within the [1,n] range (same issues as with
               | 0-based there since C doesn 't carry size information for
               | checking array bounds access). This adds one extra
               | instruction per allocation (which includes allocation on
               | the stack) for all non-0 offsets, but then all access
               | will have the same cost whether 0-based, 1-based, or
               | arbitrary-based. That's a non-zero cost, but it's not
               | exorbitant since you'll be accessing much more often than
               | allocating (and if it's reversed, something weird is
               | happening).
        
               | kitkat_new wrote:
               | would it? or would it be just a differently wired
               | circuit?
        
             | cryptonector wrote:
             | u/blutomcat's point clearly (I think) was that instruction
             | sets didn't do what you suggest, so zero-based index is
             | (was and still is) what you'd do if you wrote in assembly
             | (which was not uncommon!), and on any given platform,
             | assembly was _the_ main language 50-60 years ago. It
             | follows that it 's easier to carry that over to higher
             | level programming languages.
             | 
             | Whether that's what actually happened in the cases of HLLs
             | that adopted zero-based arrays or not, I don't know. But
             | today, to me, zero-based array indexing feels very natural,
             | and the idea that zero-based arrays being simpler in
             | assembly carrying over to HLLs seems at the very least
             | plausible.
        
           | jiveturkey wrote:
           | > additional computational overhead
           | 
           | at compile time, not runtime.
        
             | saalweachter wrote:
             | For constant addressing; for arr[i] = 2, you'll still need
             | to subtract 1 from i with 1-based addressing when
             | converting to machine instructions.
        
               | [deleted]
        
               | vukgr wrote:
               | Can't say I've really thought this through, but couldn't
               | you just subtract 1 (*sizeof(X)) from the arr address?
        
               | saalweachter wrote:
               | Hmm, maybe?
               | 
               | You'd still have the odd subtract here or there, but for
               | many use patterns you could probably ignore the overhead.
        
               | tremon wrote:
               | What would memset(arr, 0, sizeof(arr)) do in that case? I
               | can see myriad problems with having arr itself point
               | outside the memory range allocated to arr[min..max].
        
         | Uptrenda wrote:
         | This is far easier and clearer than the entire article. Good
         | stuff.
        
         | vbezhenar wrote:
         | Waste 0th element or reuse it for something like length (hello,
         | pascal strings). Another option is using base_address -
         | element_size as your array value. Another option is using
         | +element_size for all array accesses, assembly languages
         | usually have this instruction. There're many options to use
         | 1-based indexing without sacrificing performance.
        
           | xg15 wrote:
           | > _assembly languages usually have this instruction_
           | 
           | Is that so? I wasn't aware of that.
        
             | vbezhenar wrote:
             | At least x86_64 can put something like `ptr[index * 4 + 4]`
             | in one instruction (assuming that variable values are in
             | registers). Not completely sure about ARM.
        
       | ottoflux wrote:
       | my 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 wrote:
       | Almost as interesting as hearing arguments for/against
       | tabs/spaces.
        
       | soheil wrote:
       | The 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.
        
       | dhosek wrote:
       | When 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.1 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 wrote:
         | Modern 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 wrote:
         | Most 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.
        
       | phaedryx wrote:
       | If it starts at zero we should call it an "offset"
       | 
       | That would fix so many of these discussions.
        
         | rcoveson wrote:
         | Maybe, 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".
        
       | korse wrote:
       | base^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.
        
       | asimpletune wrote:
       | In 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 wrote:
         | > 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.
        
       ___________________________________________________________________
       (page generated 2022-08-24 23:00 UTC)