Noë Flatreaud

Lua is so underrated

The more I learn about Lua's design and implementation, the more impressed I am. It's very rare to see software that does so much with so little code.

Unfortunately, Lua doesn’t have the same level of marketing and hype as some other languages. This lack of promotion means that fewer developers are aware of Lua’s capabilities and benefits. It is often perceived as a niche language, primarily used in gaming and embedded systems.

Consequently, Lua may not receive the attention it deserves, even though it has a lot to offer ;

Lua is easy to understand

Lua is a free, reflexive and imperative scripting language. Created in 1993, designed to be embedded within other applications to extend them. The interpreter was developed by Brazillian engineers and has been updated many times since.

Its design is clean, and the code is fast.

The C API is easy to use and gives good performance, and yet encapsulates enough of the VM's implementation that C modules are source and binary compatible with both Lua and LuaJIT. Its syntax is clean and minimalistic, making it accessible even for beginners, yet is incredibly easy to master.

Lua is extremely embeddable.

Lua is designed to be easily embedded into applications written in other languages, particularly C and C++. This makes it an excellent choice for scripting and extending games and embedded applications. In C for example, embedding Lua is as :

#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;
}

Multi-paradigm support

Standalone or with the right libraries, Lua supports multiple programming paradigms, including imperative, functional, and object-oriented programming. This flexibility does allow us to use the one that best suits our needs.

Yet, not everything might suit everyone...

Indexing conventions

In Lua, indexing generally starts at index 1, but is a convention. Arrays can be indexed by 0, negative numbers, or any other value (anything but nil). Lua does not really have arrays in the sense of sequences. There’s just tables, and the tables are always key-value hashes.


NB : The standard library for tables and built-ins like ipairs assume array-like tables with indexes starting at 1. So, for nearly all practical purposes, you probably want to index your array-like tables starting at 1. ~ telemachus


Error handling

While I personally like how Lua handles errors, it might be less intuitive for developers coming from other languages. In Lua, errors may be handled as values, just like in Go :

function risky_function()
    error("Something went wrong!")
end

local status, err = pcall(risky_function)
if not status then
    print("Error: " .. err)
end

Nil-Terminated Arrays

The one that bothers me the most, might be the fact that arrays (tables used as arrays) are nil-terminated, meaning the end of the array is marked by a nil value. This can lead to unexpected behavior if not handled properly:

local arr = {10, 20, 30, nil, 50}
for i, v in ipairs(arr) do
    print(v)  -- Output: 10, 20, 30 (nil terminates the array)
end

The ipairs function stops iterating when it encounters a nil value, which can be surprising if you expect it to continue iterating over the entire table. If you suspect your sequence to have gaps, you should avoid using ipairs. Instead, you can use pairs (or next) to get at the whole set of items without stopping at the first nil.

TLDR ;

Lua is a powerful, efficient, and versatile programming language that deserves more recognition. Its simplicity, embeddability, and performance make it an excellent choice for a wide range of applications like games and embedded systems. However, it may be viewed as a niche language and competition from more popular languages may have contributed.

If you’re looking for a straightforward, efficient scripting language, just give it a try, you'd be surprised.

Lua is used in nvim for plugins since 0.5.0, you bet it's efficient !