Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do Lua arrays(tables) start at 1 instead of 0?

People also ask

Does Lua array start at 1?

In Lua, indexing generally starts at index 1. But it is possible to create objects at index 0 and below 0 as well. Array using negative indices is shown below where we initialize the array using a for loop.

Why is Lua counted from 1?

Contrary to the most popular languages today, Lua array indices represent an ordinal position within the array rather than an offset from the head of the array. (This scheme was unfortunately referred to as "counting from one", leading many to defend it as the natural way to count.

Why must we start the array index at 0 instead of 1?

The first element of the array is exactly contained in the memory location that array refers (0 elements away), so it should be denoted as array[0] . Most programming languages have been designed this way, so indexing from 0 is pretty much inherent to the language.

Where do Lua arrays start?

any attempt to access a field outside the range 1-1000 will return nil, instead of zero. However, it is customary in Lua to start arrays with index 1. The Lua libraries adhere to this convention; so, if your arrays also start with 1, you will be able to use their functions directly.


Lua is descended from Sol, a language designed for petroleum engineers with no formal training in computer programming. People not trained in computing think it is damned weird to start counting at zero. By adopting 1-based array and string indexing, the Lua designers avoided confounding the expectations of their first clients and sponsors.

Although I too found them weird at the beginning, I have learned to love 0-based arrays. But I get by OK with Lua's 1-based arrays, especially by using Lua's generic for loop and the ipairs operator—I can usually avoid worrying about just how arrays are indexed.


In Programming in Lua's first discussion of tables, they mention:

Since you can index a table with any value, you can start the indices of an array with any number that pleases you. However, it is customary in Lua to start arrays with 1 (and not with 0, as in C) and several facilities stick to this convention.

Later on, in the chapter on data structures, they say almost the same thing again: that Lua's built-in facilities assume 1-based indexing.

Anyway, there are a couple conveniences to using 1-based indexing. Namely, the # (length) operator: t[#t] access the last (numeric) index of the table, and t[#t+1] accesses 1 past the last index. To someone who hasn't already been exposed to 0-based indexing, #t+1 would be more intuitive to move past the end of a list. There's also Lua's for i = 1,#t construct, which I believe falls under the same category as the previous point that "1 to the length" can be more sensible than indexing "0 to the length minus 1".

But, if you can't break the mindset of 0-based indexing, then Lua's 1-based indexing can certainly be more of a hindrance. Ultimately, the authors wanted something that worked for them; and I'll admit I don't know what their original goal was, but it's probably changed since then.


My understanding is that it's that way just because the authors thought it would be a good way to do it, and after they rolled the language out to the public that decision calcified considerably. (I suspect there would be hell to pay were they to change it today!) I've never seen a particular justification beyond that.


Perhaps a less significant point, but one I haven't heard mentioned yet: there is better symmetry in the fact that the first and last characters in a string are at 1 and -1 respectively, instead of 0 and -1.


Lua libraries prefer to use indices which start at 1. However, you can use any index you want. You can use 0, you can use 1, you can use -5. It is even in their manual, which can be found at (https://www.lua.org/pil/11.1.html).

In fact, something cool here is internal lua libraries will treat SOME passed 0's as 1's. Just be cautious when using ipairs.
So that: ("abc"):sub(0,1) == "a" and ("abc"):sub(1,1) == "a" will be true.

 You can start an array at index 0, 1, or any other value:

-- creates an array with indices from -5 to 5
a = {}
for i=-5, 5 do
  a[i] = 0
end

The specific definitions of array index in C and Lua, are different.

In C array, it means: item address offset of the array address.

In Lua array, it means: the n-th item in array.

Why most languages use 0-based index? Because the compiler code with offset definition is more convenient and effective. They mostly handle addresses.

And the Lua. This is the code of lua 5.3.5 for table index with C:

const TValue *luaH_getint (Table *t, lua_Integer key) {
  if (l_castS2U(key) - 1 < t->sizearray)
    return &t->array[key - 1];
  else {
    Node *n = hashint(t, key);
    for (;;) {
      if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key)
        return gval(n);
      else {
        int nx = gnext(n);
        if (nx == 0) break;
        n += nx;
      }
    }
    return luaO_nilobject;
  }
}

We should focus on the code &t->array[key - 1], it have a subtraction operation. It is not effective compared with 0-based index.

But, the 1-based index is more neared with human being languages. We focus more on n-th item in English, Chinese, Japanese and also.

So, I guess the Lua designers choose 1-based index, they choose easy understanding for pure newer of program, give up the convenience and effectiveness.