It's easy, we should have simply started counting centuries from zero. Centuries should be zero-indexed, then everything works.
We do the same with people's ages. For the entire initial year of your life you were zero years old. Likewise, from years 0-99, zero centuries had passed so we should call it the zeroth century!
At least this is how I justify to my students that zero-indexing makes sense. Everyone's fought the x-century vs x-hundreds before so they welcome relief.
When we refer to 'the first year of life', we mean the time from birth until you turn 1.
Similarly, you'd say something like 'you're a child in the first decade of your life and slowly start to mature into a young adult by the end of the second decade', referring to 0-9 and 10-19, respectively.
But practically speaking we usually do. I always hear people refer to events in their life happening “when I was 26” and never “in the 27th year of my life”. Sure you could say the latter, but practically speaking people don’t (at least in English).
“Half one” is archaic English, and common German, for 12:30. Similarly “my 27th year” just sounds archaic to me: I wonder if you went through a bunch of 19th century writing if you’d see ages more often be “Xth year” vs “X-1 years old”.
There may be something cultural that caused such a shift, like a change in how math or reading is taught (or even that it’s nearly universally taught, which changes how we think and speak because now a sizeable chunk of the population thinks in visually written words rather than sounds).
Isn’t “half one” used as a short form of “half past one” these days, I.e. 01:30? That has been a source of confusion for someone used to the Germanic way.
I had this exact topic with an Irish coworker who lives in Germany and has issues to convey the right time. For me as a German „half one“ is half of one so 12:30. Same for „Dreiviertel eins“ -> „threequarter one“ being 12:45 and „Viertel eins“ -> „quarter one“ being 12:15.
To be fair the logic behind this is also under constant confusion as some parts of Germany rather use „viertel vor“ or „viertel nach“ -> „quarter to“ „quarter after“ and have no understanding of the three quarter business.
I think of the age number "practically" as the number of "birthday celebrations" I have experienced, excluding the actual day of birth. That's the same as the amount of completed years I've lived on this earth, and one less than the year I'm living in, because that year is not yet completed. (Except of course on birthdays)
But I think this also illustrates just how averse our culture is to using zero-indexing in counts: The age number absolutely is zero-indexed - a baby before before the first birthday is zero years old. But no one calls it like that, instead we drop the year count entirely and fall back to the next-largest nonzero unit, i.e. we say the baby is so-and-so-many months old. And for newborns not yet a month old, we count in weeks, etc.
I think, culturally, it's not that surprising as this method of counting is older than the entire concept of "zero". But I think it shows that there is little hope of convincing a large number of non-nerd people to start counting things with zeros.
That's not really indexing from 0 though. It's just rounding the amount of time you've lived down to the nearest year. You get the same number, but semantically you're saying roughly how old you are, not which year you're in. This becomes obvious when you talk to small children, who tend to insist on saying e.g "I'm 4 and a half". And talking about children in their first year, no one says they're 0. They say they're n days/weeks/months old.
In an indirect manner, we do mark having lived the 27th year in the following forms, we just don’t say it exactly the way you phrased it:
1. On your 26th Birthday, when you say you turned 26 what it means is that you have now lived 26 years. People generally understand this, even if they are going to be spending the next year saying they are 26.
2. It is not uncommon for people to demarcate their age on their birthday in revolutions around the Sun, as a kind of meme. “I’ve now traveled around the Sun twenty-six times.” or something like that, when reflecting on their lives on their Birthday.
The colloquial usage is our legally-defined age. A shortcut for our laws to take, the age-gating ones anyway. It hasn’t replaced our cultural understanding of what the first year of our life actually was.
> Sure, but no one ever uses that phrasing after you turn one.
Heck, few people say anything about 'the first year of life' even when talking about someone that young. It is too imprecise, because things change so rapidly. In my experience the most common convention is to use months to describe age before someone turns 2.
On your sixth birthday we put a big 5 on your cake and call you a 5 year old all year.
Can't say I've ever had to refer to someone's first year or first decade of their life, but sure I'd do that if it came up. Meanwhile, 0-indexed age comes up all the time.
The number we put on the cake represents the number of "years old" (i.e. the number of birthday anniversaries) not the number of birth days someone had (obviously). Zero year-olds are 0, one year-olds are 1, ...
My preference is semi-compatible with both conventions:
First = 0
Second = 1
Toward = 2
Third = 3
…
This way, the semantic meaning of the words “first” (prior to all others) and “second” (prior to all but one) are preserved, but we get sensical indexing as well.
In "figure of speech", or conventual use, people start drinking in their 21st year, not their 22nd. In common parlance, they can vote in their 18th year, not their 19th.
We talk of a child in their 10th year as being age 10. Might even be younger. Try asking a people if advice about a child in their "5th year of development" means you're dealing with a 5 year old. Most will say yes.
So perhaps it's logical to count from zero when there's no digit in the magnitude place, because you haven't achieved a full unit till you reach the need for the unit. Arguably a baby at 9 months isn't in their first year as they've experienced zero years yet!
Similarly "centuries" don't have a century digit until the 100s, which would make that the 1st century and just call time spans less than that "in the first hundred years" (same syllables anyway).
It's unsatisfying, but solves the off by one errors, one of the two hardest problems in computer science along with caching and naming things.
> In "figure of speech", or conventual use, people start drinking in their 21st year, not their 22nd. In common parlance, they can vote in their 18th year, not their 19th.
That’s not the case, though. They can vote (and drink, in quite a few countries) when they are at least 18 years old, not when they are in their 18th year (who would even say that?)
People are 18 years old (meaning that 18 years passed since their date of birth) on their 18th birthday. There is no need of shoehorning 0-based indexing or anything like that.
> Most will say yes.
Most people say something stupid if you ask tricky questions, I am not sure this is a very strong argument. Have you seriously heard anybody talking about a child’s “5th year of development”, except maybe a paediatrician? We do talk about things like “3rd year of school” or “2nd year of college”, but with the expected (1-indexed) meaning.
> So perhaps it's logical to count from zero when there's no digit in the magnitude place, because you haven't achieved a full unit till you reach the need for the unit. Arguably a baby at 9 months isn't in their first year as they've experienced zero years yet!
It’s really not. To have experienced a full year, you need a year to have passed, which therefore has to be the first. I think that’s a cardinal versus ordinal confusion. The first year after an event is between the event itself and its first anniversary. I am not aware of any context in which this is not true, but obviously if you have examples I am happy to learn.
> It's unsatisfying, but solves the off by one errors, one of the two hardest problems in computer science along with caching and naming things.
Right. I know it is difficult to admit for some of us, but we are not computers and we do not work like computers (besides the fact that computers work just fine with 1-indexing). Some people would like it very much if we counted from 0, but that is not the case. It is more productive to understand how it works and why (and again cardinals and ordinals) than wishing it were different.
What? No. When you are 0, it is your first year. When you are 21, you have begun your 22nd year. In the US you are legal to drink in your 22nd year of life.
You are correct that nobody says "22nd year" in this context, but nobody says "21st year" either. The former is awkward but the latter is just incorrect.
It's just not true. You've completed being 17 years old on your 18th birthday, when you enter your 19th year and can count 18 years under your belt.
Consider a newborn. As soon as they're squeezed out they are in their first year of life. That continues until the first anniversary of their decanting, at which point they are one year old and enter their second year of life.
There is nobody, nobody, who refers to a baby as being in their zeroth year of life. Nor would they refer to a one-year-old as still being in their first year of life as if they failed a grade and are being held back.
The pattern continues for other countable things. Breakfast is not widely considered the zeroth meal of the day. Neil Armstrong has never been considered the zeroth man on the moon nor is Buzz Aldrin the first. The gold medal in the Olympics is not awarded for coming in zeroth place.
No one's saying it's true! All that's being claimed is that writers will often use phrases like "became an adult in their 18th year" or "was legally allowed to drink in their 21st year".
It's completely incorrect, but some people use it that way, and ultimately everyone understands what they actually mean.
The top response in your Quora link is that your 21st year "means you’re 20. You have had your 20th birthday, but not yet your 21st." That is the conventional definition.
People commonly make the mistake of thinking otherwise, but that's all it is. A mistake.
Yeah we do, because their 'first year' isn't their age. We do their age in (also zero-indexed) months/weeks/days.
In Indian English terms, we do 'complete' age - aiui more common in India is to one-index, i.e. you're the age of the year you're in, and to disambiguate you might hear someone say they're '35 complete', meaning they have had 35 anniversaries of their birth (36 incomplete).
I don't think it is a mistake for Lua. The convention to zero-index arrays is not sacrosanct, it's just the way older languages did it (due to implementation details) and thus how people continue to do it. But it's very counter-intuitive, and I think it's fair game for new languages to challenge assumptions that we hold because we're used to past languages.
Zero-based arrays are counter-intuitive for a while, but if you deal with a lot of data, you typically realize that it's a small price to pay to make manipulation much easier in many contexts. For instance, if you have a ring buffer of size N and an unwrapped position P, the wrapped position is:
Zero-based: P % N
One-based: ((P - 1) % N) + 1
It might seem trivial, but each +/-1 is an opportunity for confusion and a bug nest. With zero-based arrays, it's often the case that the only required +/-1's are when producing and consuming human-readable one-based text.
The next stop on the zero-based epiphany train is the realization that a convenient way to store a range is a { first, first_past } tuple. The size of the range is (first_past - first). The whole-array range is { 0, size }, while a simple empty range is { 0, 0 } (zero is often the default initialization, simplifying things further.)
Both elements are indices, so they can be similarly manipulated, compared and range-checked, making many 'if' clauses easier to think about and verify. If there is a bug, it often ends up being harmless because of the arithmetic properties of this scheme.
Once you start dealing with multiple ranges, the advantages are even more obvious. Two ranges are adjacent iff (first_a == past_b || first_b == past_a). The intersection of two ranges is { max(first_a, first_b), min(past_a, past_b) }, which is nonempty iff they overlap. An array of M adjacent ranges is stored as a uniform (M+1)-tuple.
This realization has become so second-nature for me that I'm probably overlooking four or five even better examples here.
It's a C family (predecessors and descendants) idiosyncrasy that very unfortunately got out of hand. Most other old languages had either 1-based indexing or were agnostic. Most notably FORTRAN, which is the language for numerical calculations is 1-based.
The seminal book Numerical Recipies was first published as 1- based for FORTRAN and Pascal and they only latter added a 0-based version for C.
Personally, coming from Pascal, I think the agnostic way is best. It is not only about 0-based or 1-based but that the type system encodes and verifies the valid range of index values, e.g. in Pascal you define an array like this:
temperature = array [ -35 .. 60 ] of real;
You will get an immediate compule-time error if you use
temperature[61];
At least with Turbo Pascal you could chose if you wanted run-time checks as well.
I have a hard time wrapping my head around the fact that this feature is pretty much absent from any practically used language except ADA.
It is the best choice, but the difference is mostly in working manually with slices and offsets and array windows, for indexing and iterating they are mostly the same with maybe a small benefit for mathy notation (the reason why Julia is 1 indexed)
It's not counter-intuitive at all, it only seems that way because people are now used to languages with zero-based indexing. That's almost entirely because of the C language, which used pointer offset arithmetic with its arrays.
Outside of that machine context, where an array is a contiguous block of RAM that can be indexed with memory pointers, there's no particular reason to do offset indexing. 1-based works just fine - "first element, second element" - works just fine and is perfectly intuitive.
Different types of indexing can make sense in different situations. Some languages even allow that. In Ada, for example, arrays can start at whatever index you define.
There are reasons unrelated to pointer implementations such as the interval argument from Dijkstra's article or conversions between flat and multidimensional array indexes. There's a reason why most mathematical sequences start at zero: it leads to simpler expressions. Vec (and especially matrix) indexing should have been zero-based.
It really doesn't. You can make it work obviously but you end up with much less elegant code, with +1 and -1 all over the place. E.g. for accessing a row of a matrix you get [width(i-1)+1, widthi+1) instead of the far saner [widthi, (width+1)i)
Both are less elegant in different scenarios. In many business scenarios with zero-based indexes, you need i+1 everywhere because no-one talks about the e.g. the zeroth year of a company's operation.
Neither is a true one-size-fits-all solution. They're different kinds of indexes that serve different purposes. The choice of zero-based everywhere is an engineering tradeoff, nothing more.
> In many business scenarios with zero-based indexes, you need i+1 everywhere because no-one talks about the e.g. the zeroth year of a company's operation.
Perhaps, but this is extremely rare compared to tasks that are far more elegant with 0-based indexing. Also the worst you can get there is a single +1 in the display code, while trying to shoe-horn algorithms into 1-based code can get much more awkward.
Your metaphor is comparing apples and oranges. When we could life, it's "one year old" or "aged one year," both of which mark the completion of a milestone. Using the term "18th century" is all-encompassing of that year, which is a different use case. When one recollects over the course of someone's life, like in a memoir, it would be normal to say "in my 21st year", referring to the time between turn 20 years old and 21 years old.
We do the same with people's ages. For the entire initial year of your life you were zero years old. Likewise, from years 0-99, zero centuries had passed so we should call it the zeroth century!
At least this is how I justify to my students that zero-indexing makes sense. Everyone's fought the x-century vs x-hundreds before so they welcome relief.
Izzard had the right idea: https://youtu.be/uVMGPMu596Y?si=1aKZ2xRavJgOmgE8&t=643