Roberto Ierusalimschy reveals that Lua's core principle is being a library for embedding in other applications. This "language as a library" approach dictates its core features, including having no global state and enabling cross-language exception handling between Lua and C.
The creator of Lua clarifies that a scripting language's defining feature is its role in a "dual-language architecture," coordinating components written in another language (like Bash coordinating C programs). This distinguishes it from the broader category of dynamic languages like JavaScript.
Small design teams create better languages with "conceptual integrity." Committees tend to add features endlessly, as members fight more fiercely to include their own ideas than to prevent overall complexity. The default should always be to not add a feature if in doubt.
Lua's speed advantage over languages like Python isn't just from targeted optimization, but also from its small size. This minimalism allows the entire virtual machine to fit within a CPU's cache, leading to significant, natural performance gains that larger runtimes cannot achieve.
A trace compiler like LuaJIT identifies and records frequently executed code paths, or "traces," often inlining function calls. It then compiles these specific paths based on assumptions (e.g., a variable is an integer). The major complexity is reverting to the interpreter when an assumption fails.
By embedding a scripting language, a host application can create a secure sandbox. The host explicitly grants access to specific functions, preventing the script from accessing sensitive resources (like hardware ports) or violating application logic, as seen in a financial app using Lua to script Python.
Lua's 1-based indexing is a deliberate choice for usability, reflecting how people count in the real world. Roberto Ierusalimschy argues 0-based indexing is not a fundamental principle but a historical artifact from C, where it's a consequence of pointer arithmetic, that other languages needlessly copied.
As AI writes more code, language simplicity becomes more critical, not less. Humans must be able to verify the AI's output, and languages with complex, hidden mechanisms make this harder, as an AI might use an obscure feature without considering human readability.
The line between compiled and interpreted languages is a toolchain choice—you can interpret C or compile Python. The key hallmark of a truly dynamic language is an `eval` function, which requires shipping a compiler within the runtime to generate and execute new code on the fly.
