Lua é uma linguagem subestimada
(nflatrea.bearblog.dev)- Quanto mais se aprende sobre o design e a implementação de Lua, mais impressionante ela parece. É raro ver um software que faz tanto com tão pouco código
- No entanto, Lua não recebeu o mesmo marketing e atenção que outras linguagens. Por isso, poucos desenvolvedores conhecem seus recursos e vantagens
- Ela costuma ser vista como uma linguagem de nicho, usada principalmente em jogos e sistemas embarcados
[Características e vantagens de Lua]
Uma linguagem fácil de entender
- Lua é uma linguagem de script gratuita, reflexiva e imperativa. Foi criada em 1993 e projetada para ser embutida em outras aplicações e torná-las extensíveis.
- Seu design é limpo e o código é rápido. A API em C é fácil de usar e tem bom desempenho.
- Sua sintaxe é concisa e minimalista, o que facilita o acesso até para iniciantes.
Excelente capacidade de embedding
- Lua foi projetada para ser facilmente embutida em aplicações escritas em outras linguagens, especialmente C e C++.
- É uma escolha excelente para scripting e extensão de jogos e aplicações embarcadas.
- Exemplo: embutindo Lua em um programa C
#include <lua.h> #include <lauxlib.h> #include <lualib.h> int main() { lua_State *L = luaL_newstate(); luaL_openlibs(L); luaL_dofile(L, "./myscript.lua"); lua_close(L); return 0; }
Suporte a múltiplos paradigmas de programação
- Lua oferece suporte a programação imperativa, funcional e orientada a objetos, tanto de forma independente quanto com bibliotecas apropriadas.
- Isso oferece flexibilidade para escolher o estilo de programação que melhor atende às necessidades do usuário
[Possíveis desvantagens de Lua]
Convenção de indexação
- Em Lua, a indexação normalmente começa em 1, mas isso é apenas uma convenção. Arrays podem ser indexados por 0, números negativos ou outros valores.
- Na prática, Lua não tem arrays de verdade; existem apenas tabelas, que são sempre hashes de chave-valor, permitindo indexação com 0, negativos e outros valores
- A biblioteca padrão e as funções embutidas assumem tabelas do tipo array com índices começando em 1.
Tratamento de erros
- O tratamento de erros em Lua pode não parecer intuitivo para desenvolvedores vindos de outras linguagens.
- Em Lua, erros podem ser tratados como valores. É possível capturá-los com
pcall.function risky_function() error("Something went wrong!") end local status, err = pcall(risky_function) if not status then print("Error: " .. err) end
Arrays terminados por nil
- Em Lua, arrays (tabelas usadas como arrays) terminam ao encontrar um valor nil, o que pode causar comportamentos inesperados
local arr = {10, 20, 30, nil, 50} for i, v in ipairs(arr) do print(v) -- saída: 10, 20, 30 (para no nil) end - A função
ipairsinterrompe a iteração ao encontrar um valor nil - Quando houver lacunas no array, é melhor usar
pairsem vez deipairs. Assim é possível percorrer todos os itens, inclusive em estruturas com nil
[Resumo]
- Lua é uma linguagem de programação poderosa, eficiente e versátil que merece mais reconhecimento.
- Sua simplicidade, capacidade de embedding e desempenho a tornam adequada para várias aplicações, como jogos e sistemas embarcados.
- Apesar de subestimada, vale a pena experimentá-la por causa de sua simplicidade e desempenho
- É usada no sistema de plugins do nvim e é eficiente.
7 comentários
> Na verdade, em Lua não existem arrays; só existem tabelas, que são sempre hashes de chave-valor, permitindo indexação com vários tipos de valores, como 0 ou números negativos.
Usei Lua por um tempo por causa dos addons de WoW, e lembro que essa foi a parte que mais me impressionou. Eles usavam tabelas para praticamente todas as estruturas de dados.
Eu só conhecia o nome do Lua, mas depois de ler este texto passei a achar que ele não é tão bom assim kkk...
Não sei muito bem, mas ouvi dizer que a compatibilidade entre versões é terrível..
Pessoalmente, em comparação com Ruby... na pergunta "o código antigo ainda roda, pelo menos?", ele até se sai melhor, mas especialmente no 5.3 a forma de lidar com
numbermudou em relação às versões anteriores, então ao subir do 5.1 para o 5.3 surgem um monte de bugs difíceis de rastrear internamente...E também há muitos lugares que usam LuaJIT, e como a interface dele também é sutilmente diferente, acho que os problemas causados por essas diferenças sutis são os mais graves. Há várias partes em que o funcionamento interno mudou, então também não tem muito o que fazer... =m =.
Tenho experiência escrevendo drivers Edge do SmartThings em Lua.
Era utilizável até que razoavelmente, mas não era uma linguagem do meu gosto.
Eu considero que o ambiente de desenvolvimento e a IDE/DE também fazem parte da linguagem,
e, antes de tudo, me parece que a comunidade é um pouco fragmentada.
Também existem vários
language servers, mas sempre falta alguma funcionalidade em cada um, ou a indexação de código é lenta e, quando há alguma modificação, eles refazem tudo do zero.Também não gosto muito de indexação começando em 1 nem de escrever dicas de tipo em comentários,
e essas dicas de tipo também não pareciam ter um padrão, já que cada
language serverparecia fazer de um jeito diferente.As corrotinas também me lembram aquela implementação antiquada do Python...
Embedding e FFI, por outro lado, certamente parecem bem práticos.
Hoje em dia, o language server de Lua feito pelo pessoal do sumneko é sensacional
'm '... (acho que foi feito em 22 ou 23). A indexação dele é bem inteligente.A vantagem (e também desvantagem) do Lua, na minha opinião, aparece quando você começa a fazer umas coisas estranhas: é absurdamente fácil sobrescrever métodos de outros objetos. Por causa disso, acho que é uma linguagem ótima para sair usando de qualquer jeito, do jeito que as ideias vão surgindo.
Quanto a type hinting... como você disse, até existem muitas soluções, mas quase nenhuma se consolidou de verdade, então estou colocando minhas esperanças no Luau, feito pelo time do Roblox..
Comentários do Hacker News
Lua é boa para embedding, mas houve muito arrependimento por ela ter sido escolhida como linguagem de script no Redis. Não gosto da linguagem em si. Parece haver atrito em comparação com o que se espera no nível de abstração. Pequenas decisões de design se acumulam e tornam a linguagem um tanto hostil. Ainda assim, continua valendo a pena escolhê-la por ser rápida, fácil de integrar, usar pouca memória e ser confiável. Até no nível da C-API existe essa hostilidade por causa da abordagem de acesso via pilha. Já tive contato com linguagens de pilha como FORTH, mas ainda assim era preciso fazer um esforço mental ao escrever bindings.
Se você gosta de Lua, recomendo dar uma olhada em Terra. Terra é uma linguagem de programação de sistemas de baixo nível embutida em Lua e metaprogramada por ela. É uma linguagem compilada e com tipagem estática, como C/C++, e permite gerenciamento manual de memória. Mas, ao contrário de C/C++, foi projetada desde o início para ser metaprogramada com Lua. Programas em Terra usam o mesmo backend LLVM usado no compilador C da Apple. Isso significa que o código em Terra apresenta desempenho semelhante ao de código C equivalente.
Recentemente trabalhei na integração de Lua com uma engine de jogo customizada e concordo com o quão limpa é a integração com outras linguagens. A interface é limpa, então é fácil gerar bindings automaticamente. Usei Roslyn Incremental Source Generators para gerar automaticamente os bindings entre C# e Lua, e graças ao design da interface isso não foi nada difícil. Por causa da pilha do Lua, da tipagem dinâmica e das "tabelas", foi fácil gerar marshallers para classes de dados arbitrárias entre C# e Lua. No entanto, há muitas críticas válidas à linguagem em si. Em especial, não gosto da indexação baseada em 1. Estou considerando projetar uma linguagem de script embarcada com interface semelhante, mas resolvendo esses problemas.
Não passei a gostar mais de Lua. Na verdade, minhas insatisfações ficaram ainda mais fortes. Faz tempo que escrevi Lua, mas eu já achava pouco intuitiva. Não consigo entender por que arrays são tabelas, por que terminam em nil e por que começam em 1. Não acho que Lua seja subestimada. Ela é muito popular para escrever scripts em engines de jogo (antigas).
Criei um chatbot com comandos de plugin em Lua, mas tive uma experiência horrível ao integrá-lo a um programa em C++. Não consigo entender por que dizem que embedding é fácil. É preciso manipular muito a pilha. A linguagem em si é incômoda e não ajuda em nada quando você comete erros. Nunca mais usarei Lua e evitarei projetos que usem Lua.
Lua dificulta escrever uma quantidade considerável de código por causa da tipagem fraca, da ausência de type hints e da falta de tratamento de erros. Ela não é subestimada. Com o tempo, passei a gostar cada vez mais de linguagens com tipagem estática e type hints (Python, TypeScript). Escrever código Python ou JS sem hints em comunidade é prejudicial. Recentemente reescrevi 1.5k cloc de JS para TypeScript. Havia sempre dezenas de casos de null ausente, acesso a propriedade de null ou null semanticamente suspeito.
Acho que a maioria dos aplicativos que precisa de scripting deveria embutir JavaScript. Há uma grande vantagem no ecossistema existente. As pessoas nem sempre gostam, mas milhões já conhecem a linguagem. Não é preciso reaprender as peculiaridades da indexação de arrays, da terminação com nil e de dezenas de outras coisas que o Lua só revela em tempo de execução. Existem engines JS de todos os tamanhos, e a maioria dos sistemas operacionais oferece engines de alta qualidade e frameworks de embedding acessíveis sem instalação. Em vez de fazer o usuário aprender uma linguagem nova, é melhor usar uma linguagem padrão. Isso pode economizar tempo tanto para os usuários quanto para você.
Gostei de trabalhar com Lua e acho que é uma linguagem muito boa. Em especial, a interface para embedding em C/C++ é limpa e flexível. Existem problemas de desempenho, mas considerando que Lua é amplamente usada para lógica de jogo em videogames de alto desempenho, esses problemas parecem solucionáveis. No entanto, há outros problemas que confundem e tornam a linguagem mais difícil. Aprender Lua e sua interface com C acaba sendo quase a mesma quantidade de esforço, então mudar entre distribuições é mais confuso do que em outras linguagens. Ainda assim, acho que a linguagem é subestimada.
Embutir Lua foi divertido, mas, assim como com wasm, raramente houve necessidade de executar código novo sem recompilar todo o binário. A experiência mais divertida foi criar uma engine de jogo em C++ e usar Lua para toda a lógica do jogo. O ciclo rápido de depuração foi muito útil. A segunda experiência mais divertida foi criar um bot de IRC capaz de recarregar a lógica em Lua. A terceira mais divertida foi usar Lua como uma linguagem de configuração Turing-completa. Quando eu precisava de arrays, eu os criava em Lua. A experiência menos divertida foi um plugin do Blender que exportava modelos 3D em Lua gerado.
Acho que Lua é superestimada, porque é amplamente usada na indústria de jogos. A única vantagem de Lua é que ela pode ser embutida facilmente em C++. Fora isso, é um pesadelo.