Question

I don't understand the rationale behind the decision of this part of Lua. Why does indexing start at 1? I have read (as many others did) this great paper. It seems to me a strange corner of a language that is very pleasant to learn and program. Don't get me wrong, Lua is just great but there has to be an explanation somewhere. Most of what I found (on the web) is just saying the index starts at 1. Full stop.

It would be very interesting to read what its designers said about the subject.

Note that I am "very" beginner in Lua, I hope I am not missing something obvious about tables.

Was it helpful?

Solution

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.

OTHER TIPS

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.

There is one very significant reason to NOT count arrays from 1: If arrays start from zero, you can use them as algebraic rings in a natural way. E.g. we have the days of a week (day={'mo', 'tu', 'we'...) and we want to CYCLE through them. Then it would be much less mindbending to write:

nextday = day[(i+1)%7]  as it is in almost every other language

Than:

nextday = day[i%7+1] as it is in lua

doesn't seem to be that bad at first, but try to cycle the week the other way.

Or more generally: if the index set lacks the zero, it lacks the neutral element of addition. Whenever it is needed in index calculations, indices have to be shifted.

I'm a mathematican, but I have accepted the fact that when it comes to programming, counting from zero is just the better option..

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.

table[0] WILL ALWAYS return nil(null), UNLESS you assign value to it yourself table[0]='some value' and then table[0] will return 'some value' that YOU assigned.

Here an example:

tbl={'some'}
print('tbl[0]='..tostring(tbl[0]))
print('tbl[1]='..tostring(tbl[1]))
nothing={}
print('nothing[0]='..tostring(nothing[0]))
print('nothing[1]='..tostring(nothing[1]))
nothing[0]='hey'
print('(after assign)\nnothing[0]='..tostring(nothing[0]))

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 real reason is that the language is an implementation of the definition in a law of Portugal and the major development centre was in Brazil and their preference is to avoid the use of zero or empty or nothing as an index or subscript. However the language does permit the use of a start index other than 1 in a table creating function in some versions.

It makes sense to every one, that if a

table = {}

At the moment, table is empty. So, when

table == {something}

The table contains something so what it contains is index 1 in table if you know what I mean.

What I meant its that table[0] exists, and its table = {}, which its empty, now a programmer won't call a empty table, it sets them, and then fills it, it will be useless to find an empty table everytime you want to call it, so its simpler to just create an empty table.

My English won't get better and that's my best grammar. If you don't like it, your free to not keep reading it, but giving -rep for someone trying to help makes people not want to help at all, especially for something like grammar. I'm a man of numbers and vars, not grammar. Sorry.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top