Creator of Lua: Scripting, Programming Languages, Predictions | Roberto Ierusalimschy

3 Aug 2026 · 1 h 5 min · 19 chapters

Ask about this episode

Ask anything about it. ChatGPT or Claude reads this page and answers with the times it was said.

Connect VO and ask about every podcast you hear, including the moments you saved. Add to ChatGPT · Add to Claude

In short

Roberto Ierusalimschy (creator of Lua) explains Lua’s design for embedding as a “scripting” language alongside C/C++, clarifies scripting vs dynamic languages, and discusses language design tradeoffs, performance, JIT vs interpretation/AOT compilation, type systems, and security/sandboxing. He also comments on AI’s impact on programming and why simplicity and conceptual integrity matter.

Guest background

Roberto Ierusalimschy is the creator of Lua and discusses its implementation (C-based interpreter, bytecode VM, Lua state model) and related projects like LuaJIT (by Mike Pall).

Key claims

Lua is designed as a library for embedding (C main loop calling Lua each frame, or Lua calling C libraries). Lua supports both embedding and extending, unlike many scripting languages. Lua’s minimal, regular design helps LuaJIT trace compilation. Adding language features has hidden costs; simplicity aids human understanding, especially with AI-generated code. Security benefits come from Lua states/sandboxing (Lua can be restricted to only registered C functions).

Notable examples

Game loop calling Lua per frame (update characters/images, return to C for rendering); Lua used in World of Warcraft and Roblox; Python financial app sandboxed via Lua; CPU fan hardware control via Lua.

Written by AI. May contain mistakes. Listen to the episode to check what was said.

Chapters

Tap a time to open that second in VO

Lua's Role and Characteristics

0:41 to 2:53

Exploring what makes Lua unique as a scripting language used with C or C++.

“In 2023, Lua was the second highest programming language by growth, according to contributors on GitHub.”

Embedding vs Extending in Lua

2:53 to 4:49

The differences between embedding and extending scripting languages, particularly Lua and Python.

“So the point is that Lua, it's very good at this that you have the main loop, the program written in C and then it calls Lua for some tasks or for whatever you want to do.”

Comparison of Lua and Python

4:49 to 8:06

Discussing the pros and cons of Lua and Python in terms of design and performance.

“I think that goes in a lot of small and big details.”

Dynamic vs Scripting Languages

8:06 to 12:18

Understanding the distinctions between dynamic languages and scripting languages, with examples.

“For a problem, you release all resources used by Lua, and your programming C continues, and then later you can again create another state, etc.”

Recommended Reading on Language Design

12:18 to 14:01

Roberto shares insights on books that best discuss programming language design.

“or the shells from Unix, of this idea that there's a language that coordinates other stuff.”

Understanding Lua and Its JIT Compiler

14:01 to 21:01

Learn about the unique features of Lua and the complexities of its JIT compiler.

“it discusses even the bad parts and it focuses on the good parts, but then explains why it's there, why it was made that way, etc.”

Compilation Techniques and Type Systems

21:02 to 28:00

Explore the differences between compilation strategies and the role of type systems in programming languages.

“All portability of Lua comes on top of portability of C.”

Challenges of Type Inference in Dynamic Languages

28:00 to 29:50

Explore the complexities of type inference in dynamic programming languages and its impact on performance.

“I mean that's not computable but a lot of people try to do type inference for dynamic languages and it's a really hard problem and it's very difficult to do anything useful in terms of performance.”

Integrating Lua with C and Other Languages

30:29 to 37:10

Understand the mechanisms allowing Lua to interface with C and other programming languages.

“Earlier, you mentioned that Lua can call C and C could call Lua.”

The Importance of Design Integrity in Programming Languages

37:11 to 40:04

Discuss the significance of having a small team design programming languages for better coherence and integrity.

“Does that mean that you think the best programming languages are designed by as few people as possible?”
Show all 19 chapters

The Evolution of Booleans in Lua

40:08 to 42:01

Learn about the historical context and reasoning behind the absence of Boolean types in the original Lua language.

“I saw in the original Lua programming language that there was no Boolean type.”

Dynamic Language Design: Truthiness and Flexibility

42:01 to 45:06

Explore the implications of truthy and falsy values in programming languages and their design trade-offs.

“and it's completely different from being absent.”

The Case for One-Indexed Arrays in Lua

45:07 to 50:00

Discuss why Lua uses one-based indexing and its advantages over zero-based indexing.

“I saw that Lua is one indexed instead of zero indexed.”

AI's Impact on Programming Languages

50:01 to 54:28

Consider the future of programming languages in the context of AI advancements and code generation.

“I'm sure you can learn to program with one or minus one or whatever it is.”

Navigating Complexity in Programming Languages

54:29 to 56:01

Examine the spectrum of programming language complexity and its implications for learning and usage.

“to be understandable, for you to be able to really understand that the code that you are seeing does what you think it should do, you really understand what the code is doing.”

The Complexity of Programming Languages

56:01 to 58:14

Explore the balance between simplicity and complexity in programming languages and the challenges of choosing a career in tech today.

“lambda calculus or Turing machines and said, oh, that's really simple.”

Reflections on Lua and Success Metrics

58:14 to 1:00:10

Roberto Ierusalimschy discusses the journey of Lua, the pressures of client demands, and how success is measured in programming.

“I mean, you've worked on Lua for such a long time.”

Essential Programming Languages for Engineers

1:00:10 to 1:03:01

Ierusalimschy shares his insights on the top programming languages every engineer should learn, including Haskell and Scheme.

“And so the question is, what are the top three programming languages that you think every engineer should learn in 2026 to kind of become better at programming?”

Advice for Aspiring Programmers

1:03:01 to 1:04:16

Ierusalimschy reflects on his early career and emphasizes the importance of time and dedication in mastering programming skills.

“zero indexing that people they copy a lot they tend to be uniform in some aspects.”
Hear the part that matters, and keep it.Open this episode in VO. Double tap your headphones to save a moment as you listen.
Get VO free

Transcript

Automatic transcript. May contain errors.

0:00Roberto Ierusalimschy:It's completely feasible that you won't have programming languages. This is Roberto, the creator of the Lua programming language, and I asked him all about programming language design. C++ I think is a good example of a language that is really, really complex. JavaScript I think is even worse. I always joke that JavaScript, the good part, a very thin book compared to the official JavaScript book. Given how much AI has been progressing, would you still recommend people learn computer science today? If you really think about that, it's really difficult to recommend people learning anything. Here's the full episode.

0:45Roberto Ierusalimschy:In 2023, Lua was the second highest programming language by growth, according to contributors on GitHub. And I saw that it was also used in famous games like World of Warcraft and Roblox. And so I wanted to ask you, what kind of programming language is Lua and what sets it apart? Lua is a language that you usually use together, combine it with another language like C or C++. and then you have an architecture where Lua takes care of the more dynamic part of your program, things that change more frequently, things that are not so resource intensive, the hard parts you have written in C or C++. So it's typically what is called the scripting language.

1:39There is some confusion, I think, between scripting languages and dynamic languages. And people just, I think, consider a dynamic language to be more or less the same thing as a scripting language. And they are not exactly the same thing. So for instance, a big difference between Lua and several other scripting languages is that for scripting, you have two typical uses. You can have the ad that I call who has the main loop. So you can have the program written in C and calling Lua, or you have your program written in Lua calling C. And for several called scripting languages are actually, you don't have to, but it's much more easy to use if you have your program written in the scripting language and the C language is only for your libraries.

2:42And Lua, it's a very good fit when you want the reverse. You want the program written in C and then you have, it calls Lua from time to time. So the point is that Lua, it's very good at this that you have the main loop, the program written in C and then it calls Lua for some tasks or for whatever you want to do. And for instance, in games, this is very important to keep the frame ratio of the game. So for instance, you have the loop. The loop keeps the rhythm of the game and keeps everything. And then at every frame, it calls Lua. Lua updates all characters, all images, everything in the game.

3:30and then it returns to C to do the renderization, etc. So it's a very good fit. But the main point is that people sometimes call this the embedding versus extending. So you can extend the scripting language with C or you can embed the scripting language into C. And so several languages are very good only for extending while Lua is really good for both embedding and extending.

4:05Roberto Ierusalimschy:Why is Lua good for embedding? And Python, it's almost the opposite. Because Lua, since the beginning, we thought about Lua as a library. Since the beginning, Lua was written as a library. So I think that's the main difference. Lua has a standalone program that, I mean, you can call Lua in your console, in your common line. But that program is just a client of the official client of the library following the same API that any other program can use. So this idea of language as a library, I think it's not very common. It's something that is very particular in Lua. When you design a language as a library, what are the unique, I guess, design decisions?

4:55I think that goes in a lot of small and big details. For instance, your idea of what is your global space about scopes of variables, about exception handling, for instance. it's very important that it's very common in Lua that you raise an exception in Lua, but you catch the exception in C. So all these things about how you do exception handling in the language. Another, it's not a big deal, but it's, for instance, most dynamic languages. That's almost a definition of a dynamic language. They have an eval function that you can give a piece of code, and then it executes that code. In Lua, we don't, instead of a value, we have a function that we call load that you give a piece of code and it returns a function, an internal function like it was a Lua function that when you call that function, then you execute the associated code.

6:06It doesn't execute immediately. So you have this clear separation between compiling the Lua code that you have, and you can do that in C. So in C, you can get a piece of Lua code. You can compile it, check if it has errors, etc. Then you call that for, for instance, a different piece, or you can even call several times. You can load functions from Lua into C. You keep them, I mean, in the Lua space, and then you can call that same function again and again. It's not a big difference, of course, because if you have a val, you can evaluate a function declaration and then returns that function. So you can, if you have a val, you can do load.

6:56If you have load, you can do a val. But I think load, it's simpler to use for that kind of thing that is, when you think about libraries, for instance. In Lua, it doesn't have a global state. I think that's a very important difference. When C starts, the first thing it has to do is to create a new Lua state. And then everything you do, you do on that state, and that state is completely independent of everything else. So C can, for instance, create another Lua state, and both states are completely independent, completely, there is no communication between them. And so this, again, shows that, and so, for instance, C can use a state to do a lot of stuff, and then it can close the state, and all memory reused by Lua is released.

7:59Everything that Lua was using is released. For instance, if C doesn't need to use Lua anymore For a problem, you release all resources used by Lua, and your programming C continues, and then later you can again create another state, etc. So, as I said, there are several small, or not so small, decisions in the language, but all the time we think about the language as, is that good for embedding? Is that possible to do embedding and things like that?

8:34Roberto Ierusalimschy:When you think of the programming community, generally, everyone is quite familiar with Python, but not as familiar with Lua. I thought it might be interesting to compare the two languages. So if you compared Lua to Python, what are the pros and cons of each language design? Lua is a language that is intended to be used in this idea of scripting architecture. So Lua, for instance, it doesn't thrive having a lot of different libraries. If you have something that, oh, I want to write a quick program for something, that Python is much better. It has all the libraries you can dream about. It has a lot of libraries built in already into the language so the language is huge is i mean the the the installation it's it's a huge download etc but it it has exactly oh i need that oh it's there i need that it's there and louis almost the opposite some very minimalistic language because they did that in bad lure into your program it doesn't use almost any resources most of the libraries the important libraries that you will use will be provided by the program itself will be the comments like move a character or do some speech or things like that from the engine of the game for instance if you think about games but whatever it is so lua i think that's the the main big difference it's that they have very different goals i saw some benchmarks and i saw that lua is much faster than python Why is that?

10:23Those benchmarks are not exactly, but I think that the main point is exactly, one thing is that Lua does have this focus on performance, again, in the realm of scripting languages, doesn't want to compete with C or C++, but in the realm of dynamic, mostly now it's dynamic language, not scripting languages, we have some focus on performance. So I think this is a first difference. Python is actually much more, I think, it's a decision that they make. Performance is not that important. It's more important to be flexible, to be easy to do whatever you want to do. In Lua, sometimes we do not put some features because we think that there is no way to implement that efficiently.

11:13But also, I think some part of that performance difference comes exactly because of the size of Lua. So most of the virtual machine fits in your cache, for instance. I think there is these two big things. One is that Lua doesn't have so many features. It's not so dynamic as Python. So in Python, there is a lot of interactions because everything can mean something else. In Lua, we are a little more conservative on that side. But I think also this thing of being small also makes it naturally faster.

11:52Roberto Ierusalimschy:So on the distinction between scripting languages and dynamic, or I guess it seems like dynamic language is a superset, scripting language is a subset of that. Am I understanding that JavaScript is a dynamic language, not a scripting language from your perspective? Yes, exactly. Yes, exactly. Because scripting, it came, the original scripting language was Bash, or the shells from Unix, of this idea that there's a language that coordinates other stuff. So, for instance, it can be extending, again, you can use, but this idea that you have two different languages, The shell is only useful because you have a lot of programs written in C that are controlled by shell.

12:43So the scripting language has this very strong idea that you have this idea of a dual language architecture. So scripting is like, it's the name scripting. It means it's like you coordinate or you give a script to be executed by those other things.

13:03Roberto Ierusalimschy:You gave a talk a while ago and someone asked you a question of what books do you recommend for studying programming languages? And you said actually that you enjoyed studying the language design of other programming languages. I like reading books that describe the design of the languages. I think the best books are those written by the author of a language about the design of that language. What book recommendation do you think is best on language design? JavaScript, The Good Parts, for instance. It's kind of old now, but I think it's a very interesting book. Although I always joke that JavaScript, The Good Parts, a very thin book comparative to the official JavaScript books.

13:57One hand of the languages, The Good Parts. But I think that book is really interesting because exactly it discusses the language, it discusses even the bad parts and it focuses on the good parts, but then explains why it's there, why it was made that way, etc. That is a book that I like.

14:19Roberto Ierusalimschy:When we were talking about Lua, it sounds like one of the things that sets Lua apart is the performance and how minimal it is. And when I was reading about Lua, I saw that there's a Lua JIT. How does the Lua JIT work? Lua JIT, the first thing that's completely different project. It doesn't have anything to do with us, but it's a incredible piece of software that is a just-in-time compiler for Lua. That's, and I think exactly one of the reasons it works so well on top of Lua is because of the simplicity of Lua. It's a very regular language. I mean, it has a very, as I said, it doesn't have many exceptions or too many interactions or things that, so it's not that dynamic.

15:12I mean, everything can mean something completely different. So that, I think that gives a very good language for Ajit. But Mike Paul is the name of the guy that made the... I think he's still working on that on the first Logite. It's unbelievable, his work.

15:33Roberto Ierusalimschy:What makes writing a JIT difficult? The first thing that for me, I don't want to get involved with JIT is because it's machine dependent. It's not very productive. I mean, you do a lot of work, and it only works on that architecture. and then, oh, I want to run in another architecture. But Paul, he created a kind of pseudo-assembler that he writes in this assembly, and then he translates that assembler to real machine code of the different machines, so trying to unify the different architectures. So there is a lot of, but I don't like, I think architecture, I like to study, but I don't like to work with, because I think it's very unstable.

16:24Each new version, they change that, or they change that. I mean, they change the ADI for something, and then now the stack has to be aligned in some very particular way. And so, and of course, also to get that performance that he gets, He made what's called a trace compiler. The idea of a trace compiler that instead of getting a function and compiling a function, it works like any JIT that it tries to detect things that are executing frequently. And so it starts what's called a trace. It gets recording everything that the code is doing, including function calls, etc. until it closes the loop. And then it compiles that loop, including function calls, etc., everything in line, it compiles that for that specific, for instance, so that number happens to be an integer, so it compiles f, the number will be an integer again, and there is a lot of checks, just check everything is as assumed, and then it executes the loop.

17:42and then it's very, very, very fast. But anything that is different, for instance, you call again that, you call it frequently with integers. Suddenly you call it with a float. Then at some part of the code, it breaks the condition and you have to return to the interpreter part. And I think that's one of the worst parts is that you have to translate the state that it's all compressed into registers, etc. For instance, you don't even have a call stack because you didn't do the calls, you just inline it. But then, oh, something went wrong. Now you have to continue interpreting. So you have to recreate the stack that you didn't create originally, etc.

18:33So even to think about that, I have headaches.

18:39Roberto Ierusalimschy:standard lua is portable but to execute on a machine it eventually gets converted into machine instructions somewhere where in the stack is it eventually translated to machine instructions louis written in c the interpreter is written in c and then you so you you compile that into machine code the interpreter the lua code then the point when you get some some some i mean the the Lua interpreter code. When you get some Lua code, you do what we call a pre-compilation, that is, we translate to an internal language, and then the interpreter is just a big loop, is a loop with a switch. I mean, that's a very big simplification, but in general terms, a loop with a switch that gets instruction, does a switch, and see, oh, this instruction, The instructions are quite similar to a CPU.

19:40Move that, but then instead of creating, it executes that instruction. Move A to B. So it does move A to B and executes that. And again, repeats, executes the next instruction. So this is how an interpreter works. And basically, so we pre-compile a Lua. There is a compilation, but we compile it for this virtual machine. And then we have this main interpreter loop that people call that just fetch hit instruction. A jump is just a jump. You have an array of bytecodes. A jump will just go to that. You have a counter that tells where you are in this array. A jump, you just update that counter. It goes to another position of that array.

20:33Where you're going to, so it's like, uh, you, you emulate the CPU in software. It's written in C, the interpreter. This main loop is written in C. So if you compile it in Linux, it will run in Linux or in a X 86 architecture. It will run in that architecture. If you compile that in the Mac, it will run in the Mac. It's a C program. Got it.

21:00Roberto Ierusalimschy:Okay. So, and that's the part that's not portable and the C compiler handles that. Yes. Yes. Yes. All portability of Lua comes on top of portability of C. How does JIT compare to ahead of time compilation in terms of performance? Both ahead of time. Any kind of compilation is easily, not easily, but it can be 10 times faster than interpreting or even a hundred times faster than interpreting depending what you are doing. But ten times is a very good figure. Between ahead of time and trace compilation then depends a lot of what you are doing. After trace compilation is particularly good for benchmarks because you repeating it more or less they are very uniform you are doing exactly the same thing again and again and again so then trace compilers shine they i mean this is the best they can do in real programs that's depends a lot but the but but you i wouldn't say there is a clear winner between the two i think depends a lot of the kind of program is it possible to write in a Ahead of time compiler for Lua?

22:24Yes, there are several. None, I mean, I'm not sure if there is anyone on production quality, but for research, et cetera, there are several. I have a student who wrote one, like a master thesis, ridiculous, simple Lua compiler, ahead of time Lua compiler, or something like that, exactly. It was just it gets this up codes and expands into C code and then you send that to a C compiler and then you have a head of time compiler for Lua and it gave like three, five times boosting performance. It's a very, very, as the title said, it's like ridiculous, simple compiler.

23:20Roberto Ierusalimschy:I always hear there's compiled languages and there's dynamic or interpreted languages, I guess. But really that distinction is in the tool chain, not necessarily in the way that the symbols are laid out on the source code. Like I could write a compiler or a program that takes in Python code and then converts it into machine code. And then I would have compiled Python. And you can interpret C code too. you can write an interpreter for C. Yes. But the main difference is exactly what it's easy to do. For instance, as I said, one of the hallmarks of interpreted languages is the eval. So if you want to compile the language and keep eval, you have to have a compiler as a library of your runtime because you may want to compile things during execution.

24:17This is the hallmark of a dynamic language. So you can create code while running code. So that part is, that's why much more often than not, dynamic languages are interpreted. But you can compile, but then sometimes, or some compilers do not handle a val at all. they say you can compile as long as your program doesn't have a vowels so there is some restrictions and as i said you can interpret c code i mean but you be extremely slowly we it doesn't but

25:01Roberto Ierusalimschy:i think one big difference and when i look at uh statically or you know static languages or compiled languages they they seem to have type systems in them or the type annotations what is the role of a type system in the compilation process? Depends a lot on the type system. Several type systems like NC, for instance, are written to be a very important part of the compilation process. So if you have the right type system, it's much, much easier to write a compiler. A trivial example is one, the space for variables, because if you know oh, this is an integer, this is a float, this is a double, you know exactly how many bytes of memory you need to that.

25:52Otherwise, it's a mess. More often than not, you have to keep everything in the heap dynamically allocated, and so huge penalty in performance. And for instance, when you see, as I said, a trivial, you have an addition, A plus B. If you know the type of A, A plus B, you have the type of A, the type of B, you have a compile time, you know, oh, this plus is, I'm adding two integers, I just generate the machine code to add integers, and everything is fine. In a dynamic language, I see a plus, I compile to a, in the virtual language, it's just a piece of plus, but then how do I, at runtime, time you have to check what is A, oh, A is an integer, B is a float, oh, I have to convert, or B is a string, or depending on the language, if you're not doing addition, it can be doing concatenation, or you can just calling someone, and you have to do all that at runtime.

26:57So, types can be very, very important to compile efficiently, but, of course, you have to

27:09that there are several languages now, like TypeScript, that the types are a kind of... You do not guarantee that everything has the types you said they have. So then it's impossible to use them to compile because oh, probably A will be an integer, but if it's not, I mean, if I have an integer register to boot through it, A must be a register or things do not work. But if you have the right type system, they are essential for a good compilation.

27:45Roberto Ierusalimschy:I know some programming languages have type inference. What if you ran type inference and you got an unambiguous set of types and then you use that in compilation? Could you do that for Lua? No. I mean that's not computable but a lot of people try to do type inference for dynamic languages and it's a really hard problem and it's very difficult to do anything useful in terms of performance. What sometimes you get but you have a very restricted... If you write your program in that specific way, so it's like you don't have the type, but you write the program thinking about types. And then if the program is that very particular format, then you can do type inference and everything goes well.

28:48Otherwise, either time inference doesn't work or, I mean, it works, but actually it infers very generic types for everything. And so you cannot take advantage of the types because exactly the dynamic nature of the language. This also happens through a JIT, for instance. You can get much, much better performance if you have a kind of a type system in your mind. Usually we do that and you follow that type rules even without, I mean, the compiler, the language does not impose them on you, but you assume, oh, I'm going to follow those sometime discipline. I'm not going to use the same variable to store integers and strings, et cetera.

29:39And then you can have much better results.

29:43Roberto Ierusalimschy:OpenAI, Anthropic, Cursor, and Vercel all use this product to make their lives better. And the problem it solves is when you're building SaaS or an AI product and you want to sell to other companies, there's all these requirements you need to meet. There's SSO, there's SCIM, there's RBAC, there's audit logs. These are all things that take time to integrate, but aren't the main focus of your app. WorkOS is an API layer that lets you meet all of these requirements in just a few lines of code. So let's say you have a new SaaS product and you want to sell to other companies, WorkOS will solve all of these critical feature gaps for you.

30:20Roberto Ierusalimschy:You can check them out at workos.com to learn more and get started. And I appreciate them for supporting my work and sponsoring this podcast. Earlier, you mentioned that Lua can call C and C could call Lua. and you mentioned, we talked about the compiler and the interpreter and how do these pieces work together in the case where you're chaining different programming languages? Yeah, the main trick, I mean, it's not a trick, the technique for Lua calling C is C pointers, function pointers. There is a pointer to a function. this is part of the official C language so when you start Lua suppose you are in C as I said you create a library you create a state a Lua state and then you can register you send to Lua C pointers function pointers and pointers to functions in your C library associated with names Lua stores that in some data structure okay so it says oh the function sign is associated with that pointer etc so when it's doing the interpretation oh this instruction is called instruction called let's see what it's calling oh it's calling a what is the value of a oh it's a pointer And then it calls that pointer.

31:53And then we call the C function to do that. And when C wants to call Lua, I mean, a Lua function is just a data structure from the point of view of C. It's just an array of bytecodes, of opcodes. And then it calls the Lua interpreter function. please interpret that function for me. So C can call Lua to interpret that function and that function is running and then can call a C function using a pointer and you can have that in the stack at several levels. So we are running a Lua function that calls C and C calls Lua again and Lua calls C you have recursive stuff in that etc. and everything works.

Read the full transcript

32:45It just works.

32:48Roberto Ierusalimschy:In one of your talks on Lua, you mentioned that there's security benefits to using a scripting language. What are those benefits and how does it protect the hardware? It's not only hardware. Once I gave a talk here in Brazil, I was called to give a talk in a PyCon conference. PyCon, they called it, the Python conference in Brazil. They called me for a talk. at the end of the talk, I said, oh, Lua, it's used as a scripting language. As I said, emphasizing that thing that you have this dual language architecture. And I know of cases of Lua being used with C, with C++, with Fortran, with several different languages.

33:33And then someone in the audience says, oh, we also use Lua for scripting Python programs. And what's the case? They have a huge Python program for financial stuff that has to do a lot of financial transactions, etc. And they wanted to have a common line where you could write instructions to be executed at runtime, for instance, for debugging or for inspecting, for whatever you need, some kind of end user programming. but they said exactly what I was talking about spaces. In Python, basically if you have a common line and you are going to run Python, that Python can do whatever it wants to do in your program.

34:28There is no way to protect it. So if you gave that to the user, the user could do whatever it wanted to do for the program. So the program would break a lot of invariance of a lot of important stuff in the files it kept, etc. And so what they did, they gave the thinking Lua, because as I said, Lua you create a state. For instance, as I just mentioned, you can only call C functions. That is true in Python again, but in that particular case. You can only call C functions if you give the C pointer to Lua. so have a very strict and there is very as I said there is a library when you create a Lua state it has no functions at all you cannot open files everything there are we call standard libraries usually you open a state and you register those standard libraries in Lua so you have the minimum like you have mathematical functions etc But it can open a state and has no functions at all in Lua.

35:40It can only do things calling those specific functions you gave. So they use Lua to have this kind of control. You can write Lua code here, but that Lua code can only do very specific things in the Python program. You cannot call any Python function or build any kind of Python data structure, etc. So this is a nice example. In the case of hardware, it's the same thing. You cannot just go in, for instance, there is a port, a hardware port, that controls the speed of the fan that keeps the temperature of the CPU. And if you put that very low, you can really burn the CPU, I mean, because the CPU gets very hot.

36:29And so you cannot call it C directly. You must call Lua and only Lua has access to that. So if you can only program in Lua, it's a Lua, then you check whether the numbers you are giving are precise or whatever it has to check. And then it calls.

36:50Roberto Ierusalimschy:It's kind of like a sandbox environment. Yes, exactly. Yes. Sandbox is the exact word for that. I saw there was this, I guess, paper, maybe it was an article you wrote on the history of Lua with several other people. And I thought there were some interesting quotes in there I kind of wanted to ask you about. So one of them, it says that there's this old joke that says that a camel is a horse designed by a committee. Yes, that's not mine. That's a real old joke. Does that mean that you think the best programming languages are designed by as few people as possible? Yes, I do. Because one thing that it's easy to observe is this.

37:41If you have a committee writing a language, everyone wants to put something from themselves into the language. So you have that your favorite mechanism and you will fight whatever it takes to put your favorite mechanism into the language. And very few people will fight against putting anything in the language. I mean, some people say, oh, no, this is too much. This is too complicated. but people fight much more fiercely for putting something they want in the language than against putting something in the language. So when you have a committee, the tendency, so let's keep adding stuff, let's keep adding stuff, and people sometimes even do not understand, I mean, they're not sure if everybody there is really know the language well, I'm not putting that, but that fits with other parts of it.

38:47Oh, I didn't even know the language has this other part. I mean, so things sometimes do not fit together very well, etc. So first you have what's called the conceptual integrity. It's a name that gives that everything fits together, everything is designed with everything else in mind, etc. It's much easier to... I'm not saying, I mean, Lua has several wrong stuff regarding, because with time, etc., you make mistakes. But it's much easier to get things right if you have a small group of people that everybody knows what everybody else is thinking. I mean, you are deciding whether to put something in the language or not.

39:35It's much easier to change your mind if you do not put something, and then later you decide to add it to the language. Then to add something, and then later you decide, oh, I shouldn't have. That was not a good idea. So when in doubt or the fall is always, don't put it. If you're not very sure, don't put it. We can always add that later. And so keep the door open to change your mind.

40:08Roberto Ierusalimschy:I saw in the original Lua programming language that there was no Boolean type. And I've never seen that before. Why was there no Boolean in the original Lua? C doesn't have Booleans. I mean, the original C and up to C99 use integers. if it's zero is false, if it's different from zero is true. And people lived quite well with that lisp. And there are several languages that don't have booleans. And actually we only put booleans in Lua because we wanted false. True is completely useless in Lua. Nobody uses true. and nobody is a joke, but it's too strong, but it's not very useful. You can use almost any other value for true.

41:03But the problem is that in Lua, that special value, nil is in a table, it is equivalent to the key not being present. You already think whether that was a good decision, but it's very embedded in the design of the language and it has this strong concept that a table, a key that is not present in a table, there is an associative array, it has a nil value, it's completely indistinguishable whether it's absent I mean absent means it has a nil value, nil valent means it's absent. So sometimes you want to have a false value but you want to know it is there in the table and so we needed a false to have.

41:59A false you can put in the table and it's completely different from being absent. You know that is a key and the key has a false value. So we needed a false value. And if you are going to have a false, then we added true. True, maybe it would make sense to have false without true. But with true, it's almost useless.

42:22Roberto Ierusalimschy:Why not use zero as false if you're okay with one as true? We could have used it. But that, among other things, that would be a big change because exactly it didn't was that way. so we added that later in the language, so changing zero to false would be a very big incompatibility. But it could be, for instance, in Python, I think a lot of stuff are false. Zero is false, empty list is false, and in JavaScript I think it's even worse. I don't recall exactly, but I mean... This is kind of arbitrary. I mean, we could have, for instance, nil, false, zero, empty string. I mean, it just depends the kind of test that you use.

43:18It's not in dynamic languages. It's very easy.

43:22Roberto Ierusalimschy:Python has the, like you're describing, the truthy values and the false values. I guess they can be interpreted as false. and but it's it's more implicit less explicit and i know javascript is even further on that spectrum where you can do some really weird stuff that implicitly has some behavior do you think that design direction is uh good or bad it's like a small compact it's more easy to write stuff and but you always have this balance in any languages almost anything the more flexible you you the more flexibility you have, the less protection you have. In C, you have something like that. People do not notice, because C is typed.

44:13But you can check whether an integer is true or false. You can check whether a float is true or false directly, because again, it checks whether the float is zero or different from zero. You can check whether a pointer is nil or different from null, because in C null is a magic zero. So it's kind of, if you do not write any test, it has an implicit test like different from zero. And this zero can be an integer, can be a float, can be a pointer. So in C also you have this kind of flexibility. It's just that you have to be more explicit. Usually these avoid the errors, but so this, you have always this balance between easy to write and easy to make mistakes.

45:09Roberto Ierusalimschy:I saw that Lua is one indexed instead of zero indexed. And I, I had never seen a programming language like that in my experience. There was a lot of programming languages like that. So yeah. Why, why is it one indexed? Because everything in the real world is one indexed. If you have a book, you have the chapter 1, chapter 2, nobody numbered chapters as 0, 1, 2, 3. Programmers are the only, even mathematicians, if you get a book of mathematics, any sequence, it's A1 and A2, A3. If you get a matrix, the first element is A11, A12, and then everything is written in reform. Only in programming language there is this idea of zero.

46:03And the funniest part is that, for instance, Fortran, now it's a very old language, but to index it from one, in Pascal you can choose, I mean, you write an array, you can say this array is indexed from minus five to five, And so it's indexed from whatever value you want to whatever value you want. Zero became extremely popular because of C. C uses zero and a lot of languages copied, are kind of inspired by C. They have the same operators, the same syntax for expressions. The Boolean operators, for instance, that is not standard mathematics, almost all languages chose the same operators as they are written in C.

47:00And so a lot of languages copied C and then zero indexed became very popular. And what is funny is that in C there is no indexing. In C, indexing is just an illusion because what you have is pointer arithmetic. And C, when you write A indexed by I, actually what you are saying, get the contents of A plus Y. And so because in C you don't have indexing, you have displacements or deltas, I don't know how, offsets, then it must have indexed by zero because then the first element is the element that is at the original address. So C doesn't have indexing so when you say it's indexed by zero it doesn't index by zero because it doesn't index by anything but it has this illusion of indexing and then it's easy to see that.

48:04And then a lot of languages that do not use pointer arithmetic do not have this restriction, do not have this semantics, copy C and cap the zero indexing as the thing. If you get a 12-year-old and try to explain to them zero indexing, I assure it's much, much easier for them to write, oh, I have a list of the first element. I always joke that the first element is zero. and you write 40 for 1 but the first element 1 is not 1 it's 0 so it has advantages 0 for some specific operators mathematically for instance you want to do a circular buffer 0 is better there are some small advantages but it's much much more confusing and as Muir has this idea of end user programming we always joke it's much easier to make life easier for the non-programmers and I am sure that programmers can program whatever index they have to do because they are supposedly they are professional they can learn that oh indexing from then to put on the end user the burden of using something completely different from them indexing by zero.

49:36What does it mean the element index zero? And I never saw the chapters in the book. Yes, the first chapter is at zero. The second chapter is at one. No, I'm not joking. When you try to explain that to non-programmer, even don't then need to be 12 year olds, I mean, just get anyone that is not. And the programmer think, oh, I have the absolute. I mean, you are grown up. You are, I mean, okay, zero, you are with zero. I'm sure you can learn to program with one or minus one or whatever it is. The base you have to use, I'm sure.

50:15Roberto Ierusalimschy:But do you think you see a lot of bugs? Cause maybe someone thinks it's zero. Unfortunately, I see some bugs, but as I always say, that's are the kind of bugs that just shows that you didn't do minimum testing. Because that kind of bug is not a kind of that kind of bug that all if you try to anything you try to do in an array. If you start from zero or start from one, you have a bug. So the most simple test that you can imagine to test anything related to an array, to a list, etc. And if you mistake zero to one, you detect that. So if you have that kind of bug, it just shows that you didn't test that code at all.

51:16Roberto Ierusalimschy:There was this talk that you gave on the cost of adding language features to Lua. and how there's a lot of hidden costs. And I think today, implementation costs of software is going down due to AI code generation or LLMs. And I was wondering if that changes your thinking on, I guess, the cost of adding features to a programming language. AI is something that we don't really know what is going to happen. If you go to an extreme, it's completely feasible that we won't have programming languages. And I mean, because if the AI is writing all your code and is checking all your code and doing everything, in a few years, maybe we don't need programming.

52:11The AI can write machine code directly. It doesn't need programming languages. it's easier for them to compile or even generate the code directly. I mean, I don't know what's going to happen in a few years. So I think it's very hard for me to talk anything about AI because I have, and I think nobody has a clear idea what, I mean, people have maybe a clear idea what happens in one year or two years, but in five years, I mean, anyone that says, oh, that's going to happen in five years, it's just, I mean, just guess. So I think it's hard to say anything. This is all because of AI. So keeping the minimum thing, I mean, that still have differences there, oh, why you still use programming languages?

53:10because you want the user or some human to be able to check the result of what the AI is doing, et cetera. So I still think that most of the things about programming language still hold. For instance, the cost of complexity of you understanding, I mean, the AI creates a code for you, and then you're really understanding what that code does. I mean, it's even worse. I mean, it's much more important that the language should be clear and it has no hidden mechanisms, because the AI may use a hidden mechanism. It doesn't have the concept, oh, that will be difficult for a human to understand that what is really happening here is something.

54:01It says something that, for instance, oh, I can use that, but I'm for sure it's going to put a comment here because I'm sure that someone that reads that in one month, it's not going to understand. EA doesn't have that kind of thinking. And so you just use that trick or that thing. And it's so, I think if you think about this idea of AI generating code, I think it's even more important for the language to be simple, to be understandable, for you to be able to really understand that the code that you are seeing does what you think it should do, you really understand what the code is doing. So this thing about simplicity, I think it's very important.

54:49And I think the other parts, maybe I may facilitate documentation, I'm not sure if I mean this thing about conceptual integrity, for instance, to keep things, oh, that makes sense, etc. I really think that one of the main costs is that it's the burden you put on the user to learn one more thing about your language. So there's the other cost. I have said that implementation is the part that AI can really help you.

55:27Roberto Ierusalimschy:It's not a really, really important cause. If you think about like a spectrum of simple to complex, what programming languages are, you know, the most simple ones that you think of that are easy to understand, less confusing side effects and what programming languages are the most complex and have the most foot guns. This, this famous quote also of, I don't know from whom that the simplest possible, but not simpler than that. Because if you go to the extreme of simplicity, you could get, for instance, lambda calculus or Turing machines and said, oh, that's really simple. I mean, this is really simple, but it's completely impossible to write any program in that.

56:17I mean, if you have really simple stuff, I think the extremes will be like that, but you don't want to be there. But for the other side, I think C++ is a good example of a language that I think is really, really complex.

56:33Roberto Ierusalimschy:A question that comes up a lot is, given how much AI has been progressing, would you still recommend people learn computer science today? If you really think about that, it's really difficult to recommend people learning anything for a profession. I mean, we have no idea what AI will do in five years. If someone is entering university now, they're going to graduate in four years, five years, or at minimum three, three and a half years, then nobody has any idea what the world is that they do. Your profession will be like in four years from now. So it's really hard to say, oh, yes, you can be still going to, because now people say, oh, no, the manual tasks, the AI is very good, but it still needs the whole architecture.

57:31You need like a software engineer to see the big picture, et cetera. That is now, but you have no idea that that will be true in four years or five years. So I enjoy programming. I could do, I mean, some people say, oh, you use AI for that. I mean, I probably because I like that, but exactly. But so we choose something that you like, but really for if you're really thinking about how am I going to live with that? I have no idea. It's really, I think it's a really hard time to be choosing the profession. Yeah.

58:14Roberto Ierusalimschy:I mean, you've worked on Lua for such a long time. When you look back on it, what went well and what didn't go well? We had this privilege of not having to satisfy clients. So you do not have, as I said, for instance, you can choose to add some feature to the language because you do not have a pressure. Oh, we need that feature, whatever it takes, etc. So we have this privilege of, oh, we are not sure whether to put that. We don't put that, we can wait one year or so I think that it's much easier to do a good project, a beautiful project. So I'm not, I'm not sure this is a recommendation. Try to work without much pressure.

59:03People usually do not have this choice.

59:07Roberto Ierusalimschy:What was your measure of success if you're working on a programming language? Like, you know, how did you know it was good? It's more important to listen sometimes that good people that I recognize as would like the result than a lot of people that I have no idea who they are, etc. So I think this metric of quantity that is the standard metric nowadays in the web, it's got much worse, that everything is just in the number of followers that doesn't care who is following you, just as many people as possible. So sometimes it's much more important if someone that I really admire of things that say something good about Lua, then, oh, we have that many.

1:00:00But of course, it's good also to have some number of users and to be recognized, but I think it's a balance between all of this.

1:00:09Roberto Ierusalimschy:Do you recommend people study other programming languages to get better at programming? And so the question is, what are the top three programming languages that you think every engineer should learn in 2026 to kind of become better at programming? Haskell, I think, is an incredible language. and it has everything you need to really learn about functional programming. I think one of the main benefits is much, there is an old joke seen in the Haskell community that if you write a program in Haskell and in C, in C, really spend one week to make it efficient and then you spend one year to make it correct.

1:01:07In Haskell, you spend one week to make it correct and then you may spend one year to make it efficient. Again, it's not my joke, but it has some truths not always true, etc. But I think it gives the idea. I think this is maybe the main, the most important lesson of Haskell. But Haskell has many other values. This thing about type inference, for instance, that in the entire language, types are optional everywhere, and yet it can do type inference for everything. It can infer the types correctly, etc. CIT or some low language, I mean, you can also have to learn some assembler or to see you. But assemblers now are becoming too much complex.

1:02:04It would be to learn like the 80-80 assembler, very old assembler of various, but to have this exactly this idea of what a machine does, how it does stuff at exactly the basic level, to have this understanding. Scheme is a language that I like very much because of this economy of ideas. There are very few concepts and you can do some amazing things with very few concepts. One language that is very, very, very old, but I still think it is Snowball. I think one of the first languages to have pattern matching and this idea of doing really strong patterns etc. And I think sometimes it's interesting to see old languages because exactly nowadays a lot of languages tend to, like I said, zero indexing that people they copy a lot they tend to be uniform in some aspects.

1:03:11It's interesting to see some older languages that have some ideas that maybe not even good ideas, but it's really interesting.

1:03:21Roberto Ierusalimschy:Last question for you. is knowing everything you know now, if you could go back to when you had just started your career and give yourself some advice, what would you say? To know a lot of stuff, you really have to study a lot of stuff. It takes time. I also joke about that. People say, oh, learn Lua in 30 minutes or learn Python in five minutes. and always says that they wanted to learn programming in five years.

1:03:58That's really, take your time, you have to learn that. And that is a lot of stuff to learn. There is no magic there. You really have to learn a lot of different things.

1:04:12Roberto Ierusalimschy:Thank you so much for your time, Professor. I really appreciate it. It was a lot of fun. Thank you. It's my pleasure. Hey, thank you for watching this podcast. If you liked it and you want to see the show grow, please support with a comment or a like. Also, if you have any recommendations for people you want me to bring on, please drop a comment. Guests like Barbara Liskov, Mike Stonebreaker, Mark Brooker, these were all people that I brought on because someone left a comment. On another note, aside from the podcast, I'm working on building the ergonomic keyboard that I wish existed. Here's a glance at the prototype.

1:04:47Roberto Ierusalimschy:It's a split keyboard. So there's two sides. This is in the case. But yeah, we launched on Kickstarter and we hit our goal within eight hours of launching. I really appreciate it if you were one of the people who grabbed one of the early units. We're now working on the long journey of building the tooling now. And so if you still want to pick one up, I've left the late pledges open on Kickstarter. So you can grab one there. I'll put a link in the description. Thank you again for watching the podcast and I'll see you in the next episode.

From the publisher

Roberto Ierusalimschy is the creator of the Lua programming language. I interviewed him about Lua's unique strengths, programming language design and predictions for how AI will impact programming languages.


• My ergonomic keyboard project I mentioned, you can follow along here: https://read.compose.llc/

• The Kickstarter page for it: https://www.kickstarter.com/projects/ryanlpeterman/compose-simple-ergonomics-beautifully-done


Podcast links:


• YouTube: https://youtu.be/jCZnFKk6M9A

• Apple: https://podcasts.apple.com/us/podcast/the-peterman-pod/id1777363835

• Transcript: https://www.developing.dev/p/creator-of-lua-scripting-programming


Thank you to this episode's sponsor for supporting my work:


• WorkOS: makes your app Enterprise Ready with easy to use APIs to add SSO, SCIM, RBAC, and more in just a few lines of code, check them out at https://workos.com/


Timestamps:


(00:00) Intro

(00:43) What sets Lua apart

(08:35) Comparing Lua with Python

(13:04) Top book recommendation on language design

(14:20) How JIT works and why it is hard

(23:21) Compiling Python and interpreting C

(30:31) How cross language calls work

(36:58) Lua unique design decisions

(51:17) Predictions for AIs impact on languages

(01:00:10) Top 3 languages to learn to become a better engineer

(01:03:21) Advice for his younger self

(01:04:19) Outro


Where to find Roberto:


• Website: https://www.inf.puc-rio.br/~roberto/

• Wikipedia: https://en.wikipedia.org/wiki/Roberto_Ierusalimschy


Where to find Ryan:


• Newsletter: https://www.developing.dev/

• X/Twitter: https://x.com/ryanlpeterman

• LinkedIn: https://www.linkedin.com/in/ryanlpeterman/

• Threads: https://www.threads.com/@ryanlpeterman

• Instagram: https://www.instagram.com/ryanlpeterman

• TikTok: https://www.tiktok.com/@ryanlpeterman


Referenced in this episode:


• The Evolution of Lua: https://www.lua.org/doc/hopl.pdf

• LuaJIT: https://luajit.org/

• How much does it cost: https://www.youtube.com/watch?v=EUvgoxBm7uc

• JavaScript: The Good Parts (not an affiliate link): https://www.amazon.com/dp/0596517742

More from The Peterman Pod

All 60 episodes
Creator of Lua: Scripting, Programming Languages, PredictionsThe Peterman Pod · 1 h 5 min
Listen in VO