Hacker News new | past | comments | ask | show | jobs | submit login

The reason why 0 makes sense for pointers isn't due to some arcane implementation detail of programming but because of how one conceptualizes ranges and distance and pointers just so happen to be a place where that comes up very directly in programming. Any time you attempt to develop an algorithm that needs to think about multiple ranges of a collection at the same time or needs to scale ranges through a collection, 1-based indexing causes you to have to throw in a bunch of +/-1 compensation factors to prevent you from double-counting or scaling past an edge. Life is just too short to have to constantly debug the issues that come from 1-based indexing when developing complex algorithms, even if it means beginners feel a bit confused by "counting from 0".



No, it actually does originate from 1960's era programming practices. Not to say there weren't also 1-based or N-based numbering, but you're historically misled here.

You could also say the same about counting collections. No regular person counts 0... 1... 2... 3... and ends counting N-1. It, too, is a workaround.


I don't think 0-based was ever as common a practice as it is today, especially in the 60s. In the beginning there were two camps fighting which system was to be preferred and there were many more 1-based or agnostic languages (like the whole Pascal family). "Numerical Recipes" a pretty popular book for some time even came in two editions, a 0-based and a 1-based version. I think the victory of C had a big influence on 0-based winning.

Personally I find it very sad that the agnostic approach of Pascal did not prevail. Let the programmer decide what they think fits the situation best and let the compiler deal with the technicalities. This, and I also miss range types... for like 40 years now...


> Personally I find it very sad that the agnostic approach of Pascal did not prevail. Let the programmer decide what they think fits the situation best and let the compiler deal with the technicalities. This, and I also miss range types... for like 40 years now...

I am with you there. However, Pascal, a toy Algol, was designed to be a language for a compiler course. It took its ideas like "where does an array start" from other Algol implementations and added a broken type system. Pascal gets the love now, as witnessed by the Lua designers referring to Pascal and not to Algol.


Surely everything was 0-based initially, when everything was written in assembly? Are there any 1-based ISAs?


I wouldn't call assembly 0-based. Sure, the zero flag is convenient for branching on zero when counting backwards but what makes assembly 0-based apart from that? I'd say having a pointer to the first element of an array is pure convention and you could as easily point it to the imaginary element before, similar to how the program counter always points to the next imaginary instruction on most architectures.


The offset addressing modes all start from zero. You could hack around it in some places by storing the pointer to an element before but that's clearly going against how it is intended to be used.

For example if you have an array that you cast between different sized types (e.g. uint64 to uint8) then you have to change the pointer value!


I don't think saurik is talking about history, so you're talking past each other in that sense.


I think so, too, but my point is that it makes sense for other historical reasons—not the one the poster mentions. Those decisions weren't made due to mathematics.


Agree. I came here to say that 0-based is more sensible, but as I thought through my arguments, I realised that I’m wrong. I do most of my coding in TS, Go and plpgsql. PL is 1 based, but the only time I find it frustrating is when translating between language boundaries. The rest of the time it’s just convention (eg, using <= instead of < in loops).

But I realised that I frequently want to get the last element in an array, and of course it’s easier with 1-based arrays.

So ultimately I don’t think it matters, except that most people are used to 0-based which can cause cognitive friction.


We aren't talking about counting. We are talking about indexing.

Most programs don't need numeric indexing. They can either treat indices as opaque keys or they can use a foreach loop to avoid touching indices at all (or friends like map, filter, zip, and so forth). Even in an old language like C the only place indices usually matter is in the first line of a for loop. But sometimes you really do need numeric indices, and when you do zero-based indices are almost always cleanest.

Just think of how gnarly a flat 2D array would be if you had to use one-based indices. Gross!


If the 1st element is [0], something's conceptually wrong.


You are right, but the thing that is wrong is that the word "first" is associated with the number 1!

Think about it. Natural language could easily have associated the initial ordinal with 0. Let's call it the Nilth (zeroth is really hard to say).

The nilth element is element 0, the first element is element 1, etc.

The winner of a race is in nilth place. Silver goes to the person who came first. Bronze so second.

You walk in to a building on the nilth floor, climb the stairs to the first floor (that might sound weird to Americans but it's how it works in other parts of the world).

This is probably all sounding crazy to you but it's way more elegant and self-consistent.

Which century is the year 2023 in again?


Some of us Americans know our elevator numbers are wrong — zero / nilth is the correct ground floor by far! — but that doesn’t mean when you pick up the first apple in a bowl of apples you should rename it to nilth. Counting order is different from Indexing order. One is the order of objects in a list and the other is the offset (2nd floor is two floors up from zero). They are just different things and that is why they sound right in different contexts!

(It’s 2023, and we both are right)


Correct, counting and indexing are different things. But the "first apple" is an index not a count.


[0] just means the address of the element is ptr+0. The first element is at the address from a memory addressing perspective it makes sense that it would be at [0]


Why care about the memory address for higher level languages like Lua?


The current element is at distance 0 from iter[].


When did the 21st century begin?


> 1-based indexing causes you to have to throw in a bunch of +/-1 compensation factors to prevent you from double-counting or scaling past an edge.

Way back then, I started with Algol 68, moved on to Turbo Pascal, and finally Fortran (I was young and needed the money). My vectors and arrays started at 1, as was the default, and I do not even know what you allude to. The first element has the index 1. Since there is no zeroth element - neither in language nor in thinking -, starting at 0 is what causes problems. You always have to use a corrective term in your head - the element five elements after the third one has index 7.

Yes, whatever.


My experience is that the +-1s come up less often in 1-based languages if you're writing high-level code, and when they do they're more intuitive to catch, even after years and years of coding 0-based.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: