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

Having never used a language that indexes from 1 I'd expect that would make a ton of common math used in programming either break or be more complicated.

How is it in practice?




Pascal and derivatives (Delphi) indexes from 1, and it has pluses and minuses.

For loops are more natural when indexing from one; for loops in most languages specify inclusive ranges, but indexed containers typically advertise their, rather than their maximum index. You don't notice this much in C and derived languages because the for loop in those languages is more flexible (and more open to abuse).

More concretely, this is a very common idiom in Delphi when dealing with 0-based containers:

    for i := 0 to list.Count - 1 do
The '- 1' on the end is ugly. What's needed is a way of expressing a half-closed interval, but that's not common in programming languages (despite it being a great aid to correctly expressing many algorithms concisely).

Let's say you want to insert into the middle of an array, at x, with count elements (and presumed free space at the end). You need to move all the elements from x to the end up one. Let's suppose you have a move(array, fromIndex, toIndex, count) function that can do that. In 0-based languages:

    move(array, x, x + 1, count - x)
But you need to adjust it for 1-based languages:

    move(array, x, x + 1, count - x + 1)
However, you can mitigate it by changing how the move() function takes its parameters:

    move(array, startIndex, endIndex, newIndex)
    move(array, x, count, x + 1)
If everyone is consistent, and APIs are designed with 1-based indexing in mind, most of the issues go away. It's when there are mixed styles that things get painful.


>What's needed is a way of expressing a half-closed interval, but that's not common in programming languages (despite it being a great aid to correctly expressing many algorithms concisely).

A slightly lesser known construction in Ruby, the ... Range operator does this.


Neither better nor worth by itself, honestly. The reason why it sucks is that integration with C is one of Lua's key selling points: peeking a convention different from C's is a gratuitous pain.

It won't be fixed, because it would break existing programs in too subtle ways. Lua compatiility is sometimes broken, but only if it breaks into easy-to-find-and-fix ways.


I never found it to be a big deal, unless you're trying to copy algorithms from another language nearly verbatim. There's not really any math that relies on 0 indexing,


I guess it depends on what you mean by "relies"

Using a single dimensional array as a 2 dimensional array relies on zero indexing.

    index = y * width + x
    array[index]
Using modulo to covert an index back to 2 dimensions relies on 0 indexing

    x = index % width
    y = index / width
Skipping a prefix in a string.

    prefix = "ABC"
    string = "ABCdef"
    unprefixed = string[prefix.length:]
    
I'm sure there are tons of others. Yes, you can add 1 or subtract 1 in the right places. That's the annoying part of it though.


Eh, for every use case where it's more convenient that arrays start at zero, there's one where it's more convenient that arrays start at one, and vice versa.

For example, to get a prefix of length 'n', you need characters 0 through n-1 with zero-based indexing and 1 through n with one-based indexing. (That Python hides the -1 when using a [0:n] range is a convenience; the subtraction still happens internally.)

Similarly, to get the last element of a one-based array with a[length(a)] and the last element of a zero-based array with a[length(a)-1].

What it comes down to is that sometimes you have to write +1 or -1 for zero-based indexing where you can avoid it for one-based indexing and vice versa. What is not the case is that it only universally happens for one of those schemes.


Good points. I was thinking that there are probably an equal number of array arrithmatic tricks that also require a +-1 here and there, but it was just a hunch. As I said though, never found it to be a problem in practice.


The first two examples already work in lua if you just put something at 0.


Well lua doesn't even have an operator for integer division.


Mathematically, starting with zero is more consistent, because it leads to the fact that the length of a range is the difference between its bounds (length x..y == y-x).

More elaborate and rigorous: http://www.cs.utexas.edu/~EWD/transcriptions/EWD08xx/EWD831....


It is a noticeable annoyance.

Whether it's a very mildly annoying annoyance or it's the most annoying thing in the world seems to depend entirely on your personality.


I haven't had a problem with it. If you want to index from zero you can just do

    arr[0] = n
and write your own for loops, e.g.

    for i=0,10 do print arr[i] end
The only catch being that the length operator (#arr) will be off by one.


Most of the times I use foreach loops like

   for i, x in ipairs(mylist) do
so the 0 vs 1 based indexing is made irrelevant. There are some times where mess up but overall most Lua users don't think its much of an issue. (Personally, I find the lack of a ternary conditional operator much more annoying)


ipairs is deprecated in 5.2, no? What is the alternative?


where'd you get that from? it's not deprecated: http://www.lua.org/manual/5.2/manual.html#8.2



Hmm, weird. It definitely isn't deprecated now, according to the docs[1] and I haven't seen anyone complain about ipairs recently ever since I learned the language ^^. But anyway, the only real downside about ipairs is efficiency so even if they removed it I would probably just add it back myself as a regular function.

[1] http://www.lua.org/manual/5.2/manual.html#pdf-ipairs



Fantastically annoying - an opinion that was sadly beaten in to me rather than being plucked out of thin air. Any language that indexes starting from 1, and can't be configured to index starting from 0, is broken as supplied. Lua makes a number of very poor decisions, in my view, with this being among the worst. I don't think it's quite the worst, but it might be... at index 1, perhaps.


You can override it. LuaJIT allocates the memory from the 0 index.


I think ordinary Lua does the same? - this was all a while ago now - but the result isn't arraylike, because the indexes aren't starting from zero. Of course, you can keep on top of the indexes yourself, because tables are tables, and you can use whatever indexes you like and/or track the size by hand... but you might then feel that Lua isn't really being much help here...




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: