Filosofia de engenharia: Roberto Ierusalimschy

Pontos Principais
- Ele projetou a linguagem de scripts escondida dentro de uma enorme fatia do software que você usa. Roberto Ierusalimschy liderou o projeto de Lua, criada em 1993 no laboratório Tecgraf da PUC-Rio com Luiz Henrique de Figueiredo e Waldemar Celes. Ela roda a lógica de jogo de World of Warcraft, Roblox (via seu dialeto Luau), Dota 2 e Garry’s Mod, faz scripting de Redis e nginx (através do OpenResty), move o Adobe Lightroom e o Wireshark, e se embute em dispositivos até robôs sem nenhum sistema operacional por baixo.127
- Mecanismos, não políticas. A escolha que define Lua é a recusa – ela não traz um sistema de classes, um modelo de objetos nem um paradigma. Ela lhe dá alguns mecanismos poderosos e gerais (tabelas, metatabelas, corrotinas) e deixa você construir suas próprias abstrações em cima. “Lua não força nenhum modelo de objeto ou de classe sobre o programador”, escreveram os projetistas; em vez disso, eles “fornecem mecanismos flexíveis” para que você construa qualquer modelo que se ajuste à aplicação.3
- A pequenez é uma qualidade, não uma limitação. A implementação de referência é minúscula e limpa – o código-fonte de Lua 5.1 tem cerca de 17.000 linhas de C, a distribuição inteira cabe num disquete, e o interpretador compilado tem aproximadamente 143 KB. A maioria das linguagens de scripts é uma ordem de magnitude maior; Lua permanece pequena justamente porque foi feita para ser embutida, e a simplicidade é o que torna possível uma implementação pequena e rápida.3
- Portabilidade e facilidade de embutir foram metas de projeto desde o primeiro dia. Lua é escrita em “C limpo” – a interseção de C e C++ – e “compila de imediato na maioria das plataformas”, de Linux e Windows a dispositivos portáteis e microcontroladores. Uma API C bem definida permite que um programa hospedeiro controle e estenda Lua por completo, que é exatamente por que a indústria de jogos a adotou como um quase-padrão.34
O Princípio
“Não quisemos transformar Lua numa linguagem orientada a objetos porque não quisemos fixar um paradigma de programação para Lua… Lua não força nenhum modelo de objeto ou de classe sobre o programador. Em vez disso… decidimos fornecer mecanismos flexíveis que permitissem ao programador construir qualquer modelo que fosse adequado à aplicação.” – Roberto Ierusalimschy, Luiz Henrique de Figueiredo e Waldemar Celes, The Evolution of Lua3
A maior parte do projeto de linguagens é o acúmulo de políticas. Uma equipe decide que os objetos devem funcionar deste jeito, que o tratamento de erros deve parecer daquele, que concorrência significa threads ou async ou atores – e cozinha essas decisões dentro da linguagem, de modo que todo programa escrito nela herda essas escolhas. As decisões em geral são razoáveis. O problema é que são decisões, tomadas uma vez, para todo mundo, por pessoas que não tinham como conhecer a sua aplicação. O instinto de Ierusalimschy seguiu na direção contrária. Em vez de decidir por você, Lua lhe entrega um pequeno conjunto de mecanismos gerais e sai do caminho, para que você construa a política de que seu problema de fato precisa.3
O caso mais claro é a orientação a objetos. No início dos anos 1990, quando a programação orientada a objetos vivia o auge de seu hype, os usuários pressionavam a equipe de Lua para adicionar classes e herança. Eles recusaram – não porque OOP estivesse errada, mas porque fixar um modelo estava errado para uma linguagem feita para ser embutida em aplicações radicalmente diferentes. Objetos e classes “poderiam ser implementados com tabelas, se necessário”, raciocinaram, já que uma tabela pode guardar tanto dados quanto métodos e as funções são valores de primeira classe.3 Então, em vez de um sistema de objetos, eles construíram a semântica extensível – um mecanismo que permite intervir em como as tabelas se comportam – e deixaram os usuários montarem herança, valores-padrão, visões somente leitura e hierarquias de classes completas por conta própria. “A semântica extensível tornou-se uma marca registrada de Lua”, escreveram, e eles “não mudaram de ideia até hoje”.3
Essa recusa só é viável por causa de outros três compromissos que caminham junto com ela. Simplicidade – a linguagem permanece pequena o bastante para que os mecanismos sejam compreensíveis e a implementação seja correta. Pequenez como qualidade – a implementação de referência inteira tem cerca de 17.000 linhas de C limpo, pequena o suficiente para que adicionar Lua a uma aplicação “não a incha”.3 E portabilidade – escrever na interseção de C e C++ significa que o mesmo código-fonte compila em toda parte, de um supercomputador a um sensor.3 Dê às pessoas algumas alavancas afiadas e gerais em vez de um armário cheio de botões já decididos, e mantenha tudo pequeno o bastante para carregar a qualquer lugar. Esse é o princípio, e todo o resto em Lua é uma consequência dele.
Contexto
Roberto Ierusalimschy nasceu em 21 de maio de 1960, no Rio de Janeiro, e toda a sua carreira permaneceu perto de uma única instituição – a Pontifícia Universidade Católica do Rio de Janeiro (PUC-Rio), onde fez seu doutorado em ciência da computação em 1990 e onde é professor titular de informática. Fez um pós-doutorado na Universidade de Waterloo e uma temporada como professor visitante em Stanford, mas a PUC-Rio é sua casa, e a história de Lua é inseparável de um laboratório específico de lá.5
Esse laboratório é o Tecgraf, o Grupo de Tecnologia em Computação Gráfica, fundado em 1987 para construir ferramentas de software para clientes industriais – um dos maiores deles era, e ainda é, a empresa petrolífera brasileira Petrobras.3 A origem de Lua é, em parte, uma história sobre a política comercial brasileira. De 1977 a 1992, o Brasil manteve uma política de fortes barreiras comerciais – uma “reserva de mercado” – para hardware e software de computador, movida por uma convicção nacionalista de que o país podia e devia construir os seus próprios. Nesse clima, os clientes do Tecgraf “não podiam, nem política nem financeiramente, comprar software customizado do exterior”. Comprar ferramentas estrangeiras significava um “processo burocrático complicado para provar que suas necessidades não podiam ser atendidas por empresas brasileiras”. Essas restrições, combinadas com o isolamento geográfico do Brasil em relação a outros centros de pesquisa, “levaram o Tecgraf a implementar do zero as ferramentas básicas de que precisava”.3 Lua é, pela própria descrição dos projetistas, “a única linguagem criada num país em desenvolvimento a alcançar relevância global”.3
Antes de Lua havia duas pequenas linguagens, ambas construídas para a Petrobras. A DEL – “data-entry language” (linguagem de entrada de dados) – gerava interfaces gráficas para que os engenheiros pudessem inserir entradas de simuladores clicando num diagrama em vez de editar colunas de números.3 A SOL – “Simple Object Language” (linguagem simples de objetos) – era uma linguagem de configuração para um gerador de relatórios, com uma sintaxe de declaração de tipos influenciada pelo BibTeX.3 No início de 1993, ambas haviam ultrapassado seu escopo original; os usuários de DEL queriam controle de fluxo de verdade, e SOL precisava de poder procedural. Em meados de 1993, Ierusalimschy, de Figueiredo e Celes concluíram que as duas poderiam ser substituídas por uma única linguagem mais poderosa – e a equipe de Lua nasceu.3 O nome é uma pequena piada que pegou. SOL significa “sol” em português; um amigo no Tecgraf, Carlos Henrique Levy, sugeriu chamar a sucessora de ‘Lua’ – “lua” em português.3 Em julho de 1993, Waldemar Celes havia terminado a primeira implementação, construída como um projeto de disciplina supervisionado por Ierusalimschy e seguindo o preceito da Programação Extrema de “a coisa mais simples que poderia possivelmente funcionar”.3
O Trabalho
Tabelas e metatabelas: uma estrutura de dados, um mecanismo
Comece pela tabela, porque ela é a linguagem inteira em miniatura. Lua oferece um único mecanismo de estruturação de dados – a tabela, seu termo para arranjo associativo – e essa única estrutura faz o trabalho de registros, vetores, conjuntos, listas, módulos e objetos.3 “Embora a maioria das linguagens de scripts ofereça arranjos associativos”, observam os projetistas, “em nenhuma outra linguagem os arranjos associativos desempenham um papel tão central”.3 Um registro é uma tabela com chaves de nomes de campos; um vetor é uma tabela com chaves inteiras; um objeto é uma tabela que por acaso guarda tanto dados quanto métodos. Um mecanismo, muitos usos – que é exatamente a aposta de “mecanismos, não políticas” aplicada aos dados.
A alavanca que torna as tabelas programáveis é a metatabela. Normalmente, procurar uma chave que a tabela não tem retorna nil. Mas você pode dar a uma tabela uma metatabela – uma segunda tabela que descreve como a primeira deve se comportar em situações incomuns. A entrada mais importante é __index: quando uma busca falha, Lua consulta o __index da metatabela, que pode apontar para outra tabela a ser pesquisada em seguida. Encadeie isso e você terá herança construída a partir de nada além de tabelas e um único redirecionamento. O mesmo mecanismo, sob diferentes metamétodos, lhe dá sobrecarga de operadores, valores-padrão, proxies somente leitura e campos preguiçosos. Nada disso é um recurso da linguagem no sentido usual – é tudo um só mecanismo, usado em formas diferentes.3
Esse mecanismo não chegou inteiro – sua evolução é, ela própria, uma lição de contenção. Começou em Lua 2.1 (1995) como “fallbacks”: ganchos que Lua chamava quando uma operação era aplicada ao tipo “errado” de valor, para que o programador pudesse decidir o que aconteceria em seguida.3 O fallback de indexação de tabelas permitia que userdata e outros valores “se comportassem como tabelas”, dando suporte a “muitas formas de herança (por delegação)”.3 Os fallbacks eram globais – um gancho por evento – o que tornava desajeitado compartilhá-los entre bibliotecas, então Lua 3.0 (1997) os substituiu por “tag methods” por tipo, e Lua 5.0 (2003) unificou tudo em metatabelas e metamétodos, a forma que Lua usa hoje. (O termo “metatabela” foi sugerido por Rici Lake em 2001.)3 Cada passo generalizou o mecanismo em vez de empilhar novos recursos – o mesmo instinto que manteve a linguagem recusando-se a trazer um sistema de classes.
Facilidade de embutir, a API C, e por que os jogos adotaram Lua
Lua, na verdade, não foi feita para ser uma linguagem autônoma. Os projetistas a chamam de “linguagem de extensão extensível” – uma linguagem de extensão porque estende uma aplicação hospedeira por meio de configuração e scripting, e extensível porque ela própria pode ser estendida com funções C.3 A dobradiça é uma API C bem definida que “permite a comunicação total entre código Lua e código externo”, construída em torno de uma metáfora limpa de pilha para passar valores de um lado a outro entre Lua e o hospedeiro. A API permite que Lua faça interface não só com C e C++, mas, através deles, com Fortran, Java, C# e outras linguagens inteiramente distintas.3
O retorno chegou nos jogos, e a história é específica. Em janeiro de 1997, Bret Mogilefsky – programador-chefe da aventura Grim Fandango da LucasArts – contou à equipe de Lua que havia substituído a linguagem de scripts caseira do jogo por Lua, e que “uma quantidade tremenda do jogo foi escrita em Lua”.3 Mogilefsky falou sobre isso numa mesa-redonda de uma Game Developers’ Conference, e a partir daí “Lua se espalhou de boca em boca entre desenvolvedores de jogos a ponto de se tornar uma habilidade definitivamente comercializável na indústria de jogos”.3 O encaixe é estrutural. Um motor de jogo é exatamente o tipo de hospedeiro que se beneficia de uma camada de scripting embutida – o trabalho pesado (renderização, física) permanece em C++ rápido, enquanto a lógica de jogo, as missões e o comportamento vivem em pequenos scripts Lua que os designers podem editar e recarregar sem recompilar o motor. Pequena, rápida, portável e fácil de embutir era precisamente o perfil de que um jogo precisava, e Lua fora construída para isso desde a primeira versão.34
Corrotinas, e uma implementação pequena e rápida
O terceiro grande mecanismo é a corrotina – e, como a OOP, é a recusa deliberada de uma política por parte da equipe. Ao longo do fim dos anos 1990, os usuários empurravam por multithreading, e o movimento óbvio era adotar o modelo padrão de threads preemptivas e memória compartilhada. A equipe de Lua declinou, por dois motivos: implementar threads preemptivas em C exige primitivas “que não fazem parte do ANSI C”, o que teria quebrado a portabilidade de Lua, e – mais fundamentalmente – “não acreditávamos (e ainda não acreditamos) no modelo padrão de multithreading”, em que “ninguém consegue escrever programas corretos numa linguagem onde ‘a=a+1’ não é determinístico”.3 Então, em vez de threads, eles entregaram corrotinas em Lua 5.0 (2003): um mecanismo para multitarefa cooperativa e não preemptiva em que uma função pode suspender a si mesma e mais tarde retomar exatamente de onde parou.3 As corrotinas lhe dão a expressividade da concorrência – geradores, escalonadores cooperativos, máquinas de estado – sem o não determinismo que torna as threads de memória compartilhada tão difíceis de acertar. Um mecanismo, não uma política, mais uma vez.
Por baixo de tudo isso há uma implementação que é rápida justamente por ser pequena. A máquina virtual de Lua foi baseada em pilha até Lua 4.0; com Lua 5.0 ela passou a ser baseada em registradores, o que deu ao gerador de código mais espaço para otimizar e reduziu o número de instruções da VM que um programa típico executa. Os projetistas observam que “a máquina virtual de Lua 5.0 foi a primeira máquina virtual baseada em registradores a ter amplo uso”.3 A memória é gerenciada por um coletor de lixo incremental (introduzido em Lua 5.1) que faz seu trabalho em pequenos passos em vez de longas pausas que param o mundo – importante para os laços em tempo real de um jogo.3 Benchmarks independentes colocam Lua entre as mais rápidas das linguagens de scripts interpretadas, rápida o bastante para que, pela descrição dos projetistas, “mais de 40% do Adobe Lightroom seja escrito em Lua”, cerca de 100.000 linhas dela.3

O alcance de Lua: de World of Warcraft a um robô sem SO
Some tudo e Lua se tornou a camada invisível de scripting de uma fatia enorme de software. Em jogos, World of Warcraft expõe toda a sua interface a Lua para que os jogadores possam escrever add-ons; Roblox construiu Luau, um dialeto de Lua, como a linguagem na qual milhões de jovens criadores aprendem a programar; Dota 2, Crysis e Garry’s Mod também a embutem.1 Fora dos jogos, o Redis roda scripts Lua de forma atômica dentro do banco de dados; o nginx, por meio da distribuição OpenResty, usa Lua para programar o próprio servidor web; o Adobe Lightroom e o Wireshark são construídos substancialmente sobre ela; o Neovim adotou Lua como linguagem de configuração e de plugins de primeira classe.1 E, como o interpretador é pequeno e portável, Lua chega a hardware que quase não tem mais nada – os projetistas contam o caso do Crazy Ivan, um robô vencedor do RoboCup cujo “cérebro” rodava Lua “diretamente num processador Motorola Coldfire 5206e sem nenhum sistema operacional; em outras palavras, Lua era o sistema operacional”.7 Uma pequena linguagem, construída num laboratório do Rio sob restrições comerciais, acabou em toda parte – porque pedia quase nada e lhe dava as alavancas para construir o resto.
O Método
Leia transversalmente DEL, SOL, a metatabela, as corrotinas e trinta anos de recusa a inchar a linguagem, e os mesmos movimentos se repetem. O método de Ierusalimschy é menos um slogan do que um conjunto de compromissos permanentes.
Entregue mecanismos, não políticas. O hábito que o define é fornecer uma alavanca geral e recusar-se a decidir como ela deve ser usada. Nenhum sistema de classes embutido, nenhum modelo fixo de concorrência – apenas tabelas, metatabelas e corrotinas, a partir das quais você constrói o que sua aplicação precisar. A lição geral vai muito além do projeto de linguagens: as ferramentas mais duradouras são as que concedem capacidade sem ditar a forma da solução. É o oposto do “deve haver um jeito óbvio de fazer” de Guido van Rossum, e o contraste é o ponto – ambos são coerentes, e saber qual filosofia sua ferramenta deve encarnar é a verdadeira decisão.3
Mantenha-a pequena o bastante para ser correta e para carregar a qualquer lugar. A implementação de referência de Lua tem cerca de 17.000 linhas de C limpo, uma ordem de magnitude menor que outras linguagens de scripts, e essa pequenez é uma qualidade deliberada – é o que torna a linguagem fácil de embutir, portável e confiável. A disciplina é continuar cortando até que remover mais uma coisa a quebre, o que faz de Lua o espelho em software do minimalismo implacável de Sophie Wilson no ARM – reduza à essência que sustenta a carga e deixe a eficiência cair de graça. É o produto mínimo digno no nível do ambiente de execução de uma linguagem.3
Resista ao recurso que lhe pedem até encontrar o mecanismo por baixo dele. Quando os usuários exigiram objetos, Lua lhes deu semântica extensível; quando exigiram threads, deu-lhes corrotinas. Cada vez, a equipe declinou a política específica e entregou o mecanismo mais geral que permitia aos usuários construir a política eles mesmos – e, crucialmente, não mudou de ideia anos depois.3 Essa é a barreira da evidência aplicada a pedidos de recurso: não adicione a coisa porque foi pedida; descubra que problema ela resolve e se um mecanismo que você já tem consegue resolvê-lo.
Generalize, não acumule. A metatabela não chegou inteira – cresceu de fallbacks a tag methods e a metamétodos, e cada passo substituiu o mecanismo anterior por um mais geral em vez de aparafusar um novo recurso ao lado.3 A lição é evoluir por unificação, não por adição, para que a linguagem fique mais capaz enquanto permanece do mesmo tamanho – a mesma economia de meios que Thompson e Ritchie usaram para construir o Unix a partir de pequenas partes combináveis.
Deixe a restrição projetar a ferramenta. Lua existe porque as barreiras comerciais do Brasil forçaram o Tecgraf a construir o próprio software, e sua portabilidade existe porque os clientes do laboratório rodavam “uma coleção muito diversa de plataformas de computador”.3 Em vez de tratar essas restrições como deficiências, Ierusalimschy deixou que elas conduzissem o projeto rumo a algo menor, mais limpo e mais portável do que uma equipe bem-financiada provavelmente teria construído – a lição de que a escassez, levada a sério, é uma ferramenta de projeto e não uma desculpa.3
Cadeia de Influência
Quem o formou
Scheme e a tradição Lisp. Os projetistas são explícitos: “a influência de Scheme sobre Lua aumentou gradualmente”, tornando-se “uma fonte de inspiração, especialmente com a introdução de funções anônimas e escopo léxico completo”.3 Como Scheme, Lua é dinamicamente tipada, trata funções como valores comuns de primeira classe e mantém o núcleo pequeno – a convicção de que uma linguagem pode ser poderosa por ser minimal em vez de grande. (Influência formativa)
DEL e SOL, as duas pequenas linguagens. Lua não brotou da teoria; cresceu a partir de duas linguagens de domínio específico construídas para a Petrobras. SOL contribuiu com a sintaxe de construtor de tabelas para descrever dados, e a experiência de ambas ensinou à equipe que “grandes partes de aplicações complexas podiam ser escritas usando linguagens de scripts embutíveis” – a constatação sobre a qual, em suas palavras, repousou o nascimento de Lua.3 (Influência direta)
A reserva de mercado do Brasil. As barreiras comerciais que vigoraram de 1977 a 1992 são uma influência improvável, mas genuína: são a razão pela qual o Tecgraf construiu suas próprias ferramentas, e a diversidade das plataformas de seus clientes é a razão pela qual a portabilidade se tornou uma meta de projeto de primeira ordem. A política fez a linguagem. (Influência formativa)
Quem ele formou
A camada de scripting da indústria de jogos. De Grim Fandango em diante, Lua tornou-se um quase-padrão para embutir lógica de jogo, e o padrão que ela popularizou – motor rápido em C++, comportamento editável num script embutido – é hoje prática corrente. O Luau do Roblox ensinou uma geração de crianças a programar num dialeto de Lua. (Influência que define o campo)
Software embarcado e de sistemas. Redis, nginx/OpenResty, Wireshark, Neovim e incontáveis dispositivos adotaram Lua como camada de scripting precisamente porque ela pede tão pouco. Poucas linguagens alcançam de um banco de dados a um analisador de rede e a um robô rodando em bare metal.
Projetistas de linguagens que prezam a pequenez. Lua se mantém como a prova viva de que um núcleo minúsculo e agnóstico quanto a paradigmas pode superar linguagens grandes e cheias de opiniões no nicho de embutir – um argumento que ecoa em todo projeto de ambiente de execução minimal e de “mecanismo em vez de framework” desde então.
O Fio Condutor
Ierusalimschy se posiciona num polo do longo debate desta série sobre quanto uma ferramenta deve decidir por você. Guido van Rossum construiu Python sobre “deve haver um jeito óbvio de fazer” e a entregou com baterias incluídas – a linguagem tem opiniões, e segui-las é o caminho de menor resistência. Bjarne Stroustrup construiu C++ rica o bastante para expressar quase qualquer paradigma, pagando por essa riqueza em tamanho e complexidade. Ierusalimschy foi pelo caminho oposto ao de ambos: entregar quase nenhuma política, quase nenhum recurso, apenas alguns mecanismos gerais e um ambiente de execução de 17.000 linhas, e deixar o usuário construir o resto. Ele é o espelho em software de Sophie Wilson, cujo ARM venceu por ter sido reduzido a menos de 25.000 transistores – Lua é a mesma pequenez implacável em C, e, como o consumo acidentalmente baixo do ARM, sua pequenez acabou sendo justamente o que a deixou conquistar um domínio (o de embutir) que ninguém projetou para ela. Onde van Rossum diz aqui está o jeito óbvio e Stroustrup diz aqui estão todos os jeitos, Ierusalimschy diz: aqui estão as alavancas – você decide o que construir, e eu manterei tudo pequeno o bastante para carregar a qualquer lugar. (Ponte da série)
O Que Eu Levo Disto
A lição que guardo de Ierusalimschy é que a coisa mais forte que você pode entregar a alguém é um mecanismo, não uma política. É tentador, quando você constrói uma ferramenta, embutir sua opinião sobre como ela deve ser usada – entregar o sistema de classes, o framework, o único fluxo de trabalho abençoado. A carreira inteira de Lua é um argumento de que o oposto envelhece melhor. Ao recusar-se a fixar um modelo de objetos e entregar a metatabela no lugar, a linguagem deixou os usuários construírem esquemas de herança que seus projetistas nunca imaginaram, em jogos, bancos de dados e editores que eles nunca anteciparam. Quando construo algo hoje, a pergunta que tomo emprestada de Lua é se estou entregando uma decisão ou uma capacidade – porque a decisão serve aos casos que consigo ver hoje, e a capacidade serve aos que não consigo.
A segunda lição é que a pequenez não é uma restrição que você tolera – é uma qualidade que você protege. Teria sido fácil, ao longo de trinta anos de pressão dos usuários, deixar Lua crescer numa linguagem grande, com uma palavra-chave de classe, uma biblioteca de threads e um framework-padrão para tudo. A equipe recusou, e a recusa é por que Lua cabe num disquete, compila em toda parte e se embute no cérebro bare-metal de um robô. A disciplina de permanecer pequena – de generalizar em vez de acumular, de declinar o recurso até encontrar o mecanismo por baixo dele – é mais difícil do que a disciplina de adicionar, e muito mais valiosa. É a qualidade ser a única variável lida como contenção: a coisa pequena e certa, defendida por décadas, torna-se a infraestrutura sobre a qual todo o resto pode se apoiar.
Perguntas Frequentes
Quem é Roberto Ierusalimschy e o que ele criou?
Roberto Ierusalimschy é um cientista da computação brasileiro, nascido em 1960 no Rio de Janeiro e professor titular de informática na PUC-Rio. Ele é o projetista principal de Lua, a linguagem de scripts pequena, rápida e fácil de embutir que criou em 1993 no laboratório Tecgraf da PUC-Rio com Luiz Henrique de Figueiredo e Waldemar Celes. É também autor do livro Programming in Lua e criador de LPeg, uma biblioteca de casamento de padrões, e coautor da principal história da linguagem, “The Evolution of Lua”.356
O que “mecanismos, não políticas” significa em Lua?
Significa que Lua lhe dá alguns mecanismos poderosos e gerais em vez de impor decisões fixas. O exemplo mais claro é a orientação a objetos: Lua não tem um sistema de classes embutido. Em vez disso, ela oferece tabelas (que podem guardar tanto dados quanto métodos) e metatabelas (que permitem customizar como uma tabela se comporta), e você constrói herança, classes ou qualquer outro modelo de objetos por conta própria. Os projetistas escreveram que “Lua não força nenhum modelo de objeto ou de classe sobre o programador” e optaram por “fornecer mecanismos flexíveis” no lugar – uma postura que mantêm desde 1993.3
Por que Lua é tão usada em jogos e sistemas embarcados?
Porque foi projetada desde o início para ser pequena, rápida, portável e fácil de embutir. A implementação de referência tem cerca de 17.000 linhas de C ANSI limpo que compila quase em qualquer lugar, o interpretador compilado tem aproximadamente 143 KB, e uma API C bem definida permite que um programa hospedeiro o controle por completo. Esse perfil é exatamente o que um motor de jogo ou um dispositivo embarcado precisa – trabalho pesado em C/C++, lógica editável em pequenos scripts – razão pela qual ela faz o scripting de World of Warcraft, Roblox (via Luau), Redis, nginx/OpenResty, Adobe Lightroom e dispositivos até robôs em bare metal.137
De onde veio o nome “Lua”?
Lua significa “lua” em português. Foi nomeada como sucessora de uma linguagem anterior do Tecgraf chamada SOL – “Simple Object Language”, e também “sol” em português. Um colega no Tecgraf, Carlos Henrique Levy, sugeriu o nome “Lua” para a nova linguagem, completando a progressão de sol para lua. O projeto todo cresceu a partir de duas pequenas linguagens, DEL e SOL, construídas para a empresa petrolífera brasileira Petrobras.3
Fontes
-
“Lua (programming language),” Wikipedia. Lua foi criada em 1993 por Roberto Ierusalimschy, Luiz Henrique de Figueiredo e Waldemar Celes no Grupo de Tecnologia em Computação Gráfica (Tecgraf) da Pontifícia Universidade Católica do Rio de Janeiro (PUC-Rio), Brasil; implementada em C ANSI, sob licença MIT, com máquina virtual baseada em registradores desde Lua 5.0, coleta de lixo, corrotinas e funções de primeira classe. As implementações de referência recentes permanecem pequenas (o artigo observa que Lua 5.5.0 compreende aproximadamente 32.000 linhas de C). Usuários documentados incluem os jogos World of Warcraft, Roblox (que desenvolveu Luau, um derivado de Lua), Dota 2, Crysis e Garry’s Mod, e software fora dos jogos incluindo Redis, nginx (via OpenResty), Adobe Lightroom, Wireshark e Neovim. ↩↩↩↩
-
“Roberto Ierusalimschy: Known for Lua Programming Language,” machaddr (perfil biográfico). Resume o papel de Ierusalimschy como criador e arquiteto principal de Lua, desenvolvida com Luiz Henrique de Figueiredo e Waldemar Celes na PUC-Rio, lançada pela primeira vez em 1993; observa o uso mundial de Lua em software incluindo World of Warcraft e Adobe Lightroom, sua autoria de Programming in Lua e sua criação da biblioteca LPeg. ↩
-
Roberto Ierusalimschy, Luiz Henrique de Figueiredo e Waldemar Celes, “The Evolution of Lua,” Proceedings of the Third ACM SIGPLAN Conference on the History of Programming Languages (HOPL III), 2007. Fonte primária. “Lua is a scripting language born in 1993 at PUC-Rio.” “From the start, Lua was designed to be simple, small, portable, fast, and easily embedded into applications.” A estrutura de dados única: “it offers a single kind of data structure, the table.” Implementada em “clean C”, “the intersection of C and C++”, e “compiles out-of-the-box on most platforms”. Tamanho pequeno: o código-fonte de Lua 5.1 tem “around 17,000 lines of C”, o tarball “fits comfortably on a floppy disk”, e “the Lua interpreter built with all standard Lua libraries takes 143K”. “over 40% of Adobe Lightroom is written in Lua (that represents around 100,000 lines of Lua code)”. Sobre a política comercial do Brasil: “From 1977 until 1992, Brazil had a policy of strong trade barriers (called a ‘market reserve’) for computer hardware and software”, e “those reasons led Tecgraf to implement from scratch the basic tools it needed”; Lua é “the only language created in a developing country to have achieved global relevance”. Predecessoras DEL (“data-entry language”) e SOL (“Simple Object Language”). Nomeação: SOL é sun em português, e “a friend at Tecgraf (Carlos Henrique Levy) suggested the name ‘Lua’ (moon in Portuguese), and Lua was born”. Primeira implementação concluída em julho de 1993 seguindo “the simplest thing that could possibly work”. Sobre “mechanisms, not policy”: “we did not want to turn Lua into an object-oriented language because we did not want to fix a programming paradigm for Lua”; “Lua does not force any object or class model onto the programmer”; “we decided to provide flexible mechanisms that would allow the programmer to build whatever model was suitable to the application”; “Extensible semantics has become a hallmark of Lua”. Evolução do mecanismo: fallbacks (Lua 2.1, 1995) → tag methods (Lua 3.0, 1997) → metatables and metamethods (Lua 5.0, 2003); os fallbacks de indexação de tabelas davam suporte a “many forms of inheritance (through delegation)”; o termo “metatable” foi sugerido por Rici Lake em 2001. Lua como “an extensible extension language” com uma API C que permite “full communication between Lua code and external code”. Jogos: em janeiro de 1997, Bret Mogilefsky, programador-chefe de Grim Fandango da LucasArts, relatou que “a tremendous amount of the game was written in Lua”, após o que “Lua spread by word of mouth among game developers to become a definitely marketable skill in the game industry”. Concorrência: implementar threads preemptivas requer primitivas “not part of ANSI C”, e “we did not (and still do not) believe in the standard multithreading model… no one can write correct programs in a language where ‘a=a+1’ is not deterministic”; a multitarefa cooperativa via corrotinas foi fornecida em Lua 5.0 (2003). VM: “Since Lua 5.0, the virtual machine is register-based”, e “the virtual machine of Lua 5.0 was the first register-based virtual machine to have wide use”; a coleta de lixo incremental aparece em Lua 5.1. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩
-
“Lua: about,” Lua.org (site oficial). “Lua is a powerful, efficient, lightweight, embeddable scripting language.” Ela é “implemented as a small library of C functions, written in clean C, the common subset of Standard C and C++”, e “runs on all kinds of Unix and Windows systems, as well as on mobile devices… embedded microprocessors… and IBM mainframes”. Descreve Lua como combinando “simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics”, com tipagem dinâmica, gerenciamento automático de memória com coleta de lixo incremental, e sendo “fast” e “portable”. ↩↩
-
“Roberto Ierusalimschy,” Wikipedia, corroborado por seu “faculty profile,” Departamento de Informática, PUC-Rio. Nascido em 21 de maio de 1960 no Rio de Janeiro, Brasil; doutorado em ciência da computação pela PUC-Rio (1990); professor titular de informática na PUC-Rio; pós-doutorado na Universidade de Waterloo e professor visitante em Stanford (2012). Criador e arquiteto principal da linguagem de programação Lua, autor de Programming in Lua (quatro edições), e desenvolvedor de LPeg, uma biblioteca Lua para implementar gramáticas de expressão de análise. ↩↩
-
“Programming in Lua,” por Roberto Ierusalimschy, Lua.org. O livro oficial sobre Lua, escrito por seu projetista principal, descrevendo o projeto e o uso da linguagem; a primeira edição está disponível gratuitamente online. Reforça o projeto de Lua em torno de tabelas como o único mecanismo de estruturação de dados, metatabelas para comportamento extensível, funções de primeira classe e corrotinas para multitarefa cooperativa. ↩
-
Roberto Ierusalimschy, Luiz Henrique de Figueiredo e Waldemar Celes, “The Evolution of Lua,” HOPL III, 2007, nota de rodapé sobre uso embarcado. “Crazy Ivan, a robot that won RoboCup in 2000 and 2001 in Denmark, had a ‘brain’ implemented in Lua. Lua ran directly on a Motorola Coldfire 5206e processor without any operating system (in other words, Lua was the operating system). Lua was stored on a system ROM and loaded programs at startup from the serial port.” Ilustra o alcance de Lua a dispositivos embarcados em bare metal, uma consequência de sua implementação pequena e portável. ↩↩↩