Por que matrizes Lua (tabelas) começam em 1 em vez de 0?

125

Eu não entendo a lógica por trás da decisão desta parte de Lua. Por que a indexação começa em 1? Eu li (como muitos outros) este grande artigo . Parece-me um canto estranho de uma língua que é muito agradável de aprender e programar. Não me interpretem mal, Lua é simplesmente ótima, mas tem que haver uma explicação em algum lugar. A maior parte do que encontrei (na web) está apenas dizendo que o índice começa em 1. Ponto final.

Seria muito interessante ler o que seus designers disseram sobre o assunto.

Note que eu sou "muito" iniciante em Lua, espero não estar perdendo algo óbvio sobre tabelas.

AraK
fonte
23
O escopo padrão também é global. As duas maiores características incorretas de Lua.
Yann Ramin
37
Eu não chamaria de 1 uma característica incorreta. Na verdade, faz mais sentido - os programadores são tão bem treinados para pensar em termos de indexação baseada em 0 de outros idiomas que não gostamos. Também somos treinados para pensar 5/2 = 2. Isso não faz tudo certo.
BlueRaja - Danny Pflughoeft
54
@ BlueRaja-DannyPflughoeft: não. A indexação zero faz mais sentido - os seres humanos são tão bem treinados para começar a contar com 1 que os idiomas que começam com 0 são inicialmente confusos. Mas eu adoraria encaminhá-lo para Edsger Dijkstra aqui: cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
orlp
11
@ nightcracker: Quando você conta maçãs em uma mesa, conta a primeira como "uma", a segunda como "duas", etc. Ninguém conta a primeira como "zero" e depois adiciona uma no final; contar do zero é simplesmente, indiscutivelmente, contra-intuitivo. Sim, eu sei que é assim que a indexação funciona internamente, mas é por isso que chamamos de abstração.
BlueRaja - Danny Pflughoeft 25/02
9
Eu nunca entendi todo o amor pela indexação baseada em 0. É bom para compensações (quantos itens saltar desde o início?) E subsequências (0 ≤ x <n), mas parece errado para coisas básicas (o segundo elemento é chamado um? O décimo elemento corresponde ao índice nove? WAT?) . Programadores mesmo contar a partir de 1 quando tentam encontrar uma linha relatado pelo compilador ...
marcus

Respostas:

143

Lua é descendente do Sol, uma linguagem projetada para engenheiros de petróleo sem treinamento formal em programação de computadores. Pessoas que não são treinadas em computação acham estranho começar a contar a zero. Ao adotar a indexação de matriz e string baseada em 1, os designers da Lua evitaram confundir as expectativas de seus primeiros clientes e patrocinadores.

Embora eu também os tenha achado estranhos no começo, aprendi a amar matrizes baseadas em 0. Mas eu entendi bem com as matrizes baseadas em 1 de Lua, especialmente usando o forloop genérico e o ipairsoperador de Lua - geralmente posso evitar me preocupar com a maneira como as matrizes são indexadas.

Norman Ramsey
fonte
7
Esta é apenas uma razão histórica de marketing. Nenhuma razão racional, especialmente no momento atual. E parece mesmo que você está tentando evitar indexação baseada em 1 em vez de usá-lo :)
eonil
27
O @Eonil, na verdade, evitar a indexação explícita reduz os erros de indexação.
Dan D.
8
As razões históricas da @Eonil geralmente são as relevantes. Você começa com algo e nunca pode alterá-lo, porque isso quebraria todo o código existente. Particularmente ruim para a indexação 0 vs. 1, já que a forma como ela é quebrada é bastante sutil.
CodesInChaos
5
A diferença está entre ir de 1 para comprimento e de 0 para comprimento -1, mas em um loop < lengthfor é muito mais útil e fácil de ler nos "idiomas estranhos baseados em 0". Confesso quando vejo uma iteração de loop a partir de 1, eu imediatamente assumir que começa a partir do 2º elemento: S
Felype
45

Na primeira discussão de tabelas de Programação em Lua , eles mencionam:

Como você pode indexar uma tabela com qualquer valor, é possível iniciar os índices de uma matriz com qualquer número que lhe agrade. No entanto, é comum em Lua iniciar matrizes com 1 (e não com 0, como em C) e várias instalações aderem a essa convenção.

Posteriormente, no capítulo sobre estruturas de dados, eles dizem quase a mesma coisa novamente: que as instalações internas de Lua assumem indexação baseada em 1.

De qualquer forma, existem algumas conveniências no uso da indexação baseada em 1. Ou seja, o #operador (comprimento): t[#t]acessa o último índice (numérico) da tabela e t[#t+1]acessa 1 após o último índice. Para alguém que ainda não foi exposto à indexação baseada em 0, #t+1seria mais intuitivo passar do final de uma lista. Há também a for i = 1,#tconstrução de Lua , que acredito estar na mesma categoria do ponto anterior, que "1 ao comprimento" pode ser mais sensível do que indexar "0 ao comprimento menos 1".

Mas, se você não pode quebrar a mentalidade da indexação baseada em 0, a indexação baseada em 1 de Lua certamente pode ser mais um obstáculo. Por fim, os autores queriam algo que funcionasse para eles ; e admito que não sei qual era o objetivo original , mas provavelmente mudou desde então.

Mark Rushakoff
fonte
16

Meu entendimento é que é assim apenas porque os autores pensaram que seria uma boa maneira de fazê-lo, e depois que eles lançaram a linguagem ao público, essa decisão se calcou consideravelmente. (Eu suspeito que haveria um inferno a pagar se eles mudassem hoje!) Eu nunca vi uma justificativa específica além disso.

traço-tom-bang
fonte
6
Possível justificativa: C só fez isso porque uma matriz é basicamente apenas um ponteiro e array[0] == array + 0;, e a contagem baseada em 1 é mais natural quando a matriz é realmente uma tabela de hash.
Maygarden do juiz
19
Os índices Lua são realmente índices. Em C, quando você diz index, o que você realmente quer dizer é um deslocamento.
6288 Alex
8

Talvez um ponto menos significativo, mas que eu não ouvi falar ainda: há melhor simetria no fato de que o primeiro e o último caractere de uma string estão em 1 e -1 respectivamente, em vez de 0 e -1.

VXZ
fonte
8
Enquanto isso é bom, era não a razão para a partir de 1.
LHF
3

As bibliotecas Lua preferem usar índices que começam em 1. No entanto, você pode usar qualquer índice que desejar. Você pode usar 0, você pode usar 1, você pode usar -5. Está incluso no manual, que pode ser encontrado em ( https://www.lua.org/pil/11.1.html ).

De fato, algo interessante aqui é que as bibliotecas internas da lua tratam ALGUNS 0s passados ​​como 1's. Apenas tenha cuidado ao usar ipairs.
Então isso: ("abc"):sub(0,1) == "a" and ("abc"):sub(1,1) == "a"será verdade.

 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
user2262111
fonte
Existe uma maneira de fazer ({'a', 'b'})[1]avaliar para 'b'não 'a'embora? Isso parece embutido para mim.
remram 07/06
1
({[0] = 'a', 'b'})[1]
User2262111 17/06
0

O verdadeiro motivo é que a linguagem é uma implementação da definição em uma lei de Portugal e o principal centro de desenvolvimento estava no Brasil e sua preferência é evitar o uso de zero ou vazio ou nada como índice ou índice. No entanto, o idioma permite o uso de um índice inicial diferente de 1 em uma tabela, criando a função em algumas versões.

Desenvolvedor
fonte
5
Mesmo se isso for verdade, não é de todo relevante para como Lua foi projetada.
Lhf 20/04
-1

tabela [0] SEMPRE retornará nulo (nulo), A menos que você atribua valor a ela mesma tabela [0] = 'algum valor' e, em seguida, a tabela [0] retornará 'algum valor' que você designou.

Aqui está um exemplo:

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]))
BladeMight
fonte
-11

Faz sentido para todos, que se um

table = {}

No momento, tableestá vazio. Então quando

table == {something}

A tabela contém algo, então o que ela contém é o índice 1, tablese você entende o que quero dizer.

O que eu quis dizer é que essa tabela [0] existe e sua tabela = {}, que está vazia, agora um programador não chama uma tabela vazia, define-a e preenche-a, será inútil encontrar uma tabela vazia sempre que desejar chamá-lo, portanto, é mais simples criar uma tabela vazia.

Meu inglês não vai melhorar e essa é minha melhor gramática. Se você não gostar, estará livre para não continuar lendo, mas dar -rep para alguém que tenta ajudar faz com que as pessoas não queiram ajudar, especialmente para algo como gramática. Sou um homem de números e vars, não de gramática. Desculpe.

Wesker
fonte
4
Não entendo o conceito de uma tabela com valor 0. Uma tabela pode ter um comprimento igual a 0. Mas isso independe da escolha do primeiro índice. Não me preocupo com pequenos erros gramaticais, mas simplesmente não entendo o ponto de sua resposta, e foi por isso que votei mal.
CodesInChaos
é isso que eu quero dizer, uma tabela não pode ser mantida com um índice ou valor 0, já que a usamos como uma tabela vazia <, <quando você tem algo desse algo representado por 1, "n", então quando você não tem nada, seu vazio de alguma coisa, que nos leva a um cero, mas o cero não conta, é uma linguagem que se torna prática, você não sai e diz a seus amigos que sabe o que eu tenho 0 músicas desses artistas, mais você tem alguns, ou você não. ponto sua tabela de = {} eis cero uma tabela vazia
Wesker
5
Uma matriz que usa o índice 0como único elemento ainda não está vazia. De fato, lua suporta isso, simplesmente não é a convenção padrão.
CodesInChaos
Sim, eu concordo com você, em alguns outros idiomas, mas não lua, o índice lua 0 não existe, então podemos imaginá-lo como um vazio = 0 ou é assim que eu imagino, mesmo quando você pode forçar o índice a 0, ele não funcionará com os valores da tabela #table não lerá um índice 0, então minha resposta ainda é que lua é basicamente feita como um evento regular; agora, se eles pretendem isso ou não, não é realmente relevante, você não escreverá o código do furo novamente e nós não podemos fazer nada sobre isso: /, eu ainda acredito que o seu justo dizer que em lua uma tabela vazia tem um 0 index
Wesker