The Peterman Pod - Creator of Lua: Scripting, Programming Languages, Predictions | Roberto Ierusalimschy

Episode Date: August 3, 2026

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-donePodcast 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-programmingThank 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) OutroWhere to find Roberto:• Website: https://www.inf.puc-rio.br/~roberto/• Wikipedia: https://en.wikipedia.org/wiki/Roberto_IerusalimschyWhere 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/@ryanlpetermanReferenced 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

Transcript
Discussion (0)
Starting point is 00:00:00 It's completely feasible that you won't have programming languages. This is Roberto, the creator of the Lua programming language, and I asked them all about programming language design. C++, I think, is a good example of a language that it's really, really complex. JavaScript, I think, is even worse. I always joke that the JavaScript, the good part, a very thin book, comparative, the official JavaScript boost. Given how much AI has been progressing, would you still recommend people learn computer science today?
Starting point is 00:00:34 If you really think about that, it's really difficult to recommend people learning anything. Here's the full episode. 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 Roblo. And so I wanted to ask you, what kind of programming language is Lua and what sets it apart? Lua is a language that usually use together, combined 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.
Starting point is 00:01:30 the hard parts you have written in C or C++. So it's typically what is called the scripting language. There 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 that I call who has the main loop. So you can have the program written in C and calling Lua or you
Starting point is 00:02:18 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. And Lou it's 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 Lou, it's very good at this that you have the main loop, the program written in C, and then it calls Loua 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.
Starting point is 00:03:21 and then at every frame it calls Lua, Lua updates, all characters, all images, everything in the game, and then it returned to see, to do their renderization, et cetera. So it is a very good fit. But the main point is that, the people sometimes call this the embedding versus extending. So you can extend the scripting language you see, or you can embed 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.
Starting point is 00:04:05 Why is Lua good for embedding? And Python, it's almost the opposite. Because Lua since the beginning, Lua, 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.
Starting point is 00:04:48 When you design a language as a library, what are the unique, I guess, design decisions? I think that goes 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. It's very common in lieu that you raise an exception. in lure, 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,
Starting point is 00:05:33 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 to code. In Lue, we don't, instead of Eval, we have a function that we called load that you give a piece of code and it returns a function, an internal function, like it was a lure function, that when you call that function, then you execute the associated code. It doesn't execute immediately. So you have this clear separation between compiling, like the lure code that you have, and then you can do that in C. So on some,
Starting point is 00:06:18 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 Eval, you can. evaluate a function declaration and then returns that function. So you can, if you have Eval, you can do load. If you have load, you can do Eval. But I think load, it's simpler to use for that kind of thing that is when you think about libraries. In Lua, it doesn't
Starting point is 00:07:11 have a global state. I think that's a, I forgot that, 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 if 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 used by Lua is released.
Starting point is 00:07:59 Everything that Lua was using is released. For instance, if C doesn't need to use Lua anymore for a problem, you release all all resources used by Lua in your program in C continues and then later it can again create another state, etc. So there's, as I said, there is 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? 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.
Starting point is 00:08:47 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 the 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. It has a lot of libraries built in already into the language. So the language is huge. I mean, the installation is a huge download, etc.
Starting point is 00:09:34 But it has exactly, oh, I need that. Oh, it's there. I need that. It's there. And Louie is almost the opposite. Some very minimalistic language because the idea that you embed Lua into your program, it
Starting point is 00:09:47 doesn't use almost any resources. Most of the libraries, the important libraries, that you will use. We'll be provided by the program itself. It will be the comments like and move a character or do some speech or things like from the
Starting point is 00:10:03 engine of the game. For instance, if you think about games, but whatever, it is. I think that's the main big difference. They have very different goals. I saw some benchmarks and I saw that Lua is much faster than Python. Why is that? Those benchmarks are not exactly,
Starting point is 00:10:26 but I think that the main point is exactly the one thing is that Lua does have this focus on performance again in the realm of scripting language. doesn't want to compete with C or C++, but in the wheel 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.
Starting point is 00:10:54 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. But also I think some part of that performance difference
Starting point is 00:11:17 comes exactly because of the size of Lerun. So most of the virtual machine fits in your cache, for instance, I think there is these two big things. One is that Rue 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 rule, we are a little more conservative on that side.
Starting point is 00:11:46 But I think also this thing of being small also makes it naturally faster. 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. And my understanding that JavaScript is a dynamic language, not scripting language from your perspective. Yes, exactly. Yes, exactly.
Starting point is 00:12:13 Because it's 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 language, the shell is only useful because, you have a lot of problems written in C that are controlled by Shell. So the scripting language has this very strong idea that you have this idea of a dual-language
Starting point is 00:12:48 architecture. So sweetening is like the name scripting. It means it's like the coordinator. You give a script to be executed by those other things. You gave a talk a while ago and someone asked you a question of, you know, what books do you recommend for, you know, 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?
Starting point is 00:13:37 JavaScript, the good parts, for instance. It's kind of old now, but I think that I think it's a very interesting book, although I always joke that the JavaScript, the good part, a very thin book comparative, the official JavaScript, it's like one hand of the language is the good part. But I think that book is really interesting, because exactly it discussed the language. It discuss even the bad parts and it focused 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.
Starting point is 00:14:20 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 said, I saw that there's Lua Jit. How does the Lua Jit work? Lua Jit, the first thing, it's completely different project. It doesn't have anything to do with us. But it's an incredible piece of software that is a just-in-time compiler for Lua. And I think exactly one of the reasons it works so well on top of Lua
Starting point is 00:14:55 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. I mean, everything can mean something
Starting point is 00:15:15 completely different. So that, I think that gives a very good language for a judge. But the, the, the, 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.
Starting point is 00:15:33 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 drew a lot of work and only works on that architecture. And then, oh, I want to run in another architecture.
Starting point is 00:15:52 But, my, Paul, he created a kind of a 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 architecture so there is a lot of work but I don't like I think architecture I like to study but I don't like to work with
Starting point is 00:16:22 because I think it's very unstable each new version they change that or they change that. I mean, they change the ADA for something, and then now the stack has to be aligned in some various particular way. And so, 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,
Starting point is 00:16:55 It works like any JIT that it tries to detect things that are executably 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,
Starting point is 00:17:28 so that number happens to be an integer, so it compiles 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. And then it's very, very, very fast. But anything that is different, for instance, you call again that,
Starting point is 00:17:49 you call it frequently with integers. Suddenly you call it. suddenly you call to 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 that you have to translate the state that it's all compressed into register, et cetera. For instance, you don't even have a call stack because you didn't do the calls, you just inline it.
Starting point is 00:18:23 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, et cetera. So even to think about that, I have headaches. 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 instruction? instructions. Lou is written in C, the interpreter is written in C, and then so you compile that
Starting point is 00:19:00 into machine code, the interpreter, the LUA code. Then the point when you get some, some, I mean, the LUA interpreter code, when you get some LUA code, you do what it we call a pre-compilation, that is we translate to an internal language, and then the interpreter is just a big link. 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,
Starting point is 00:19:34 oh, this instruction, the instructions are quite similar to a CPU. Move that, but then instead of creating, it executes that structure. Move A to B, so it does a move A to B and executes that and again repeats, execute the next instruction. So this is how an interpreter works. And basically, so we pre-compile a loop. There is a compilation, but we compiled for this virtual machine. And then we have this main interpreter loop that people call that just fetch hit instruction.
Starting point is 00:20:17 A jump is just a jump. You have an array of byte. codes a jump or 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 where you're going to. So it's like 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. 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.
Starting point is 00:21:00 Got it. Okay. 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.
Starting point is 00:21:12 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 can be 10 times faster than interpreting or even 100 times faster than interpreting depending what you are doing. But 10 times is a very good figure. Between a head of time and trace compilation, then depends a lot of what you are doing. After trace compilation is particularly good for benchmarks because you're repeating it more or less they are very uniformed you are doing exactly the same thing again and again and again so then trace compilers shine the
Starting point is 00:22:04 i mean this is the best they can do in real programs that's depends a lot but but but i wouldn't say there is a clear winner between the two. I think depends a lot of the kind of problem. Is it possible to write an ahead-of-time compiler for Lua? Yes, there are several. 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, a head of time Lua compiler or something like that. Exactly. It was just, it gets this upcodes and expands into C code.
Starting point is 00:22:58 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. very, very, as the title said, it's like ridiculous, simple compiler. 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.
Starting point is 00:23:46 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 their hallmarks of interpreted languages, the vowel. So if you want to compile the language and keep a vowel, you have to have a compel.
Starting point is 00:24:09 compiler as a library of your runtime because you may want to compile things during execution. This is the hallmark of a dynamic language. So you can create code while running code. So that part is that 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 eval at all. They say, you can compile as long as our program doesn't have evolves. So there is some restrictions.
Starting point is 00:24:51 And as I said, you can interpret C code, I mean, but you be extremely slowly. It doesn't, but. I think one big difference, when I look at statically, or static language is a compiled language, which is 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 of the on the type system.
Starting point is 00:25:22 Several type systems like in C, for instance, are written to be an 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 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. Otherwise, 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 plus B, you have the type of A, the type of B, you have a compile time. You know, all this plus is a, I'm adding two integers.
Starting point is 00:26:22 I just generate the machine code to add integers. And there everything is fine. In a dynamic language, I see a plus, I compile to a virtual language. language is just a plus, but then how do I, at runtime, you have to check what is a, oh, A is an integer, B is a float, oh, yeah, 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. So types can be very, very important to compile efficiently, but
Starting point is 00:27:04 of course you have to have a type system that there are several languages now like a type script that the types are 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 it's if I have an integer register to boot It must be a rest or things do not work. But if you have the right type system, they are essential for a good compilation. I know some programming language just have type inference. What if you did, you ran type inference and you got an unambiguous set of types and then you
Starting point is 00:27:54 use that in compilation? Could you do that for Lua? No. not computable, but a lot of people try to do in type in 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 restrict. If you write your programming that specific way, use, follow. So it's like you don't have the type, but you write the program thinking about types.
Starting point is 00:28:38 And then if the problem is that very particular format, then you can do type inference and everything goes well. Otherwise, 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 all of the types. Because exactly the dynamic nature of the language, this also happens with Lujit, for instance. You can get much, much better performance. If you have a kind of 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.
Starting point is 00:29:31 some time discipline. I'm not going to use the same variable to store integers and strings, et cetera, and then you can have much better results. Open AI, Anthropic, Cursor, and Versel
Starting point is 00:29:46 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 SCM, there's R-back, there's audit logs. These are all things that take time to integrate, but aren't the main
Starting point is 00:30:06 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. 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 did these pieces work together in the case where you're chaining different programming languages.
Starting point is 00:30:47 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 it will stores that in some data structure okay so it says oh the function sign is associated with that pointer etc so when it's
Starting point is 00:31:40 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 to and then it calls that pointer and then we did 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 bytecoles of upcodes. 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.
Starting point is 00:32:31 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, et cetera, and everything works. It just works. And one of their 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?
Starting point is 00:32:58 It's not only hardware. Once I gave a talk here in Brazil, I was called it to give a talk in a Pi conference, a Pi-Con, they called the Python Conference in Brazil. They called me for a talk. At the end of the talk, I said, oh, Louis, we use it as a scripting language, as I said, emphasizing that thing that you have these
Starting point is 00:33:22 dual language architecture. And I know of case of Lua being used with C++, we 4-plus-plus, with several different languages. And 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 a do a lot of financial transactions, etc. And they, they, they have a huge Python program for financial. wanted to do script, I mean, to have like a common line where you could write instructions to be executed by the, 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 in you are going to run Python,
Starting point is 00:34:22 that Python can do whatever it wants to do in your program. There is no way to protect it. So if you gave that to the user, the user could do whatever it wanted to do, I mean, for the program. So the program would break a lot of invariance of a lot of important stuff in the files it kept, et cetera. And so what they did, they gave the thinking,
Starting point is 00:34:48 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 with that particular date. 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 Lue state, it has no functions at all. There is nothing, I mean, you cannot open files.
Starting point is 00:35:21 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. It can only do things calling those specific functions you get. So they use Lua to have this kind of control. You can write lua code here, but that law code can only do very specific things in the Python program. You cannot call any Python function or, I mean, build any kind of Python data structure, etc. So this is a nice example. In the case of hardware is the same thing. You cannot just go, for instance, there is a port, a harder port that controls the speed of the fun.
Starting point is 00:36:20 that keeps the temperature of the CPU. If you put that very low, you can really burn the CPU, I mean, because the CPU gets very hot. And so you have a C, you cannot call C directly. You must call Lua, and only Lua has access to that. So if you can only program in Lua, it's a dog, Lua, then you check whether the numbers you are giving are precise or whatever it has to check, and then it calls.
Starting point is 00:36:51 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. I thought there were some interesting quotes in there. I kind of wanted to ask you about.
Starting point is 00:37:10 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
Starting point is 00:37:29 are designed by as few people as possible? Yes, I do see. Yes. Because one thing that it's easy to observe is this. If you have a committee writing a language, everyone wants
Starting point is 00:37:47 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. Some people say, oh no, this is too much, this is too complicated, but people fight much more fiercely for put something they'd want in the language than against putting something in the language.
Starting point is 00:38:26 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, you're not sure if everybody there is really know the language well. I'm not putting that, but that fits with other parts of the, oh, I didn't even know the language has this other part. I mean, so things sometimes do not fit together very well, et cetera. So first, you have what's called the conceptual integrity.
Starting point is 00:39:00 It's a name that gives that everything fits together, everything. It's designed with everything else in mind, et cetera. It's much easier to. I'm not saying, I mean, Lua has several, wrong stuff regarding because with time, etc., there 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.
Starting point is 00:39:35 It'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, but that was not a good idea. So when in doubt our default 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. I saw in the original Lua programming language that there was no bullion type and I've never seen that before. Why was there no bullion in the original Lua? Well, C doesn't have bullions. I mean, the original C and C 90 up to C 99,
Starting point is 00:40:28 they 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 bullions. And actually, we only put bullions in Lua because we wanted false. True is completely useless in Lua. Nobody used true. I mean, nobody is a joke, but it's too strong. But it's not very useful. You can use almost any other value for true. But the problem is that in lieu, that nil, that special value, is in a table, it is equivalent to the key not being present. You all think better that was a good decision,
Starting point is 00:41:23 but it's very embedded in the design of the language and it has the strong concept that a table, a key that is not present in a, in a table, In a table, there is an associative array, it has a new value. It's completely indistinguishable whether it's absent. I mean, absent means it has a new value, nil valent means is absent.
Starting point is 00:41:49 So sometimes you want to have a false value, but you want to know what it is there in the table. And so we needed a false to have a 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 need a false value and if you are going to have a false then we added true to make sense we have false without true. But the truth is almost useless. Why not use zero as false if you're okay with one as true?
Starting point is 00:42:26 It could we could have used but that among other things that would be a big change because a 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 Titan, I think a lot of stuff are false. I mean, zero is false, empty list is false, empty. In JavaScript, I think it's even worse. I don't recall exactly, but I mean,
Starting point is 00:43:04 This is kind of arbitrary. I mean, you could have, for instance, nil, false, zero, empty string. I mean, it just depends the kind of test that you use. It's not in dynamic languages. It's very easy. Python has the, like you're describing, the truthy values and the falsely values. I guess they can be interpreted as false. but 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 good or bad? It's like a more compact, it's more easy to write stuff.
Starting point is 00:43:54 But you always have this balance in any language, it's almost anything. The more flexible you, you, the flexibility you have the less protection you have. In C, you have something like that. People do not notice because C is typed. But 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.
Starting point is 00:44:28 You can check whether a pointer is. is nil or different from nul 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 are avoids.
Starting point is 00:45:00 errors. So you have always this balance between easy to write and easy to make mistakes. I saw that Lua is one indexed instead of zero indexed. And I had never seen a programming language like that in my experience. There was a lot of programming languages like that. So, yeah, why is it one indexed? Because everything in the real world are one indexed. If you have a book, you have the chapter one, chapter two, nobody number chapters as zero, one, two, three. All the programmers are the only, even mathematicians, if you've got a mathematics book, a book of mathematics, any sequence, it's A1 and A2, A3.
Starting point is 00:45:50 If you have a matrix, the first element is A1, A1, A12, and then A, everything is written we thought only in programming language that is this idea of zero. And the funniest part is that, for instance, Fortran, that now it's 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.
Starting point is 00:46:35 C used 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.
Starting point is 00:47:00 And so a lot of language copied C and then zero indexed became very popular. And what it's 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 why. And so because in seed you don't have indexing, you have displacements or deltas, I don't know offsets, then it must have indexed by zero because of the, 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 zero. Because it doesn't
Starting point is 00:47:57 indexed by anything. But it has this illusion of indexing and then it's easy to sing that. And then a lot of language that do not use pointer arithmetic, do not have this restriction, do not have these semantics, copy it C
Starting point is 00:48:14 and cap the zero indexing as this 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.
Starting point is 00:48:38 And you write first you for one, but the first element one is not one is zero. So it has advantage of zero. For some specific operators mathematically, for instance, you want to do a circular buffer, zero is better. There are some small advantage, but it's much, much more confusing. And as Mua has this idea of end-user programming, we always joke, it's much easier to make life easier
Starting point is 00:49:10 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 all indexing reform. Then to put on the end user the burden of using something completely different from them indexing by zero. What does this mean the element index zero? And I never saw the chapters in the boy. Yes, the first chapter is at zero.
Starting point is 00:49:43 The second chapter is at one. No, I'm not joking. When you try to explain that to non-programmer, even don't. Then they need to be 12 year olds. I mean, just get anyone that is not. And the programmer think, oh, I have the apps. You're grown up. You are, I mean, okay, you are a question.
Starting point is 00:50:04 You are with zero. I'm sure you can learn to program if one or minus one or whatever it is the base you have to use. I'm sure. But do you think you see a lot of bugs? Because maybe someone thinks it's zero. Unfortunately, I see some bugs, but as I always say, that 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 always 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.
Starting point is 00:50:53 So the most simple test that you can imagine to test anything related to an array, to a list, et cetera. And if you mistake zero to one, you detect. So if you have that kind of bug, it just shows that you didn't test that code at all. 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, you know, 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 it's going to happen.
Starting point is 00:51:49 If you go to an extreme, it's completely feasible that we won't have programming languages. 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. I can write machine code directly. It doesn't need programming languages. It's easier for them to compare 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
Starting point is 00:52:33 because I have, and I think nobody have a clear idea. what, I mean, people have a maybe idea what it 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,
Starting point is 00:52:52 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
Starting point is 00:53:06 have, for instance, why you still use programming languages because you want the user or some human to be able to check the result of what the AI is doing, etc. So I still think that most
Starting point is 00:53:23 of the things about programming language still hold. For instance, the cost of complexity of you understanding, I mean, I create a code for you and then you 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 has no hidden mechanisms, because the AI may use a hidden mechanism.
Starting point is 00:53:52 It doesn't have the concept, oh, that will be difficult for a human to understand that what is really happening here is something that, 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 just use that trick or that thing. And 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
Starting point is 00:54:36 that the code that you have seen does what you think it should do it. You really understand what the code is doing. So this thing about simplicity, I think it's very important. And I think the other parts from the need, 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, et cetera. I really think one of the main costs is that it's the burden you put on the user to learn one more thing about your language.
Starting point is 00:55:17 So there's the other cost. I have said that implementation is the part that AI can really help you. It's not a really important cost. 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 footguns? This famous quote also, I don't know from whom,
Starting point is 00:55:54 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 programming in that. I 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++, I think is a good example of a language that I think it's really, really complex. A question that comes up a lot is, Given how much AI has been progressing, would you still recommend people learn computer science today?
Starting point is 00:56:43 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 and a half years or then nobody have any idea what the world is the world you stay there your profession will be like in four years from now. So it's really hard to, I mean, to say, oh, yes, you can still going to, I mean, because now people say, oh, no, the manual tasks, the AI is very good, but you need the whole architecture. you need like a software engineer to do to see the big picture, etc. That is now, but you have no idea that will be true in four years or five years. So I think, I like, I enjoy programming.
Starting point is 00:57:49 I could do, I mean, some people say, or use AI for that. I mean, I probably because I like that. So choose something that you like, but really for us, you're really thinking, 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. I mean, you've worked on Lua for such a long time. When you look back on it, what went well
Starting point is 00:58:20 and what didn't go well? We had this privilege of not having to satisfy clients. So we all did 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, that feature, whatever it takes or etc. So we have this privilege of, oh, we are not sure whether to put that. We don't put that. You can wait one year or so I think that it's much easier to do a good project, a beautiful project.
Starting point is 00:58:55 So I'm not sure this is a recommendation. try to work without much pressure. People usually do not have this choice. 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 sometimes that good people that I recognize as we like the result than a lot of people that I have no idea what's there. who they are, et cetera, like.
Starting point is 00:59:30 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 follows that me doesn't care who is following you, just as many people as possible. So sometimes for me it's much more important if someone that I really admire of things
Starting point is 00:59:53 of this, that say something good about Lua, then oh, we have that many, but of course this would also to have some number of users and to be recognized but I think it's a balance between all of this. 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 incredible language.
Starting point is 01:00:32 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 in the Haskell community that if you write a program in Haskell and in C, In C, we'll spend one week to make it efficient, and then you will spend one year to make it correct. In Hasker, you spend one week to make it correct, and then you may spend one year to make it efficient. Again, this is not my joke, but it has some truths,
Starting point is 01:01:19 not always true, et cetera, but I think it gives the idea. I think this is maybe the, the, main, the most important lesson of Haskell. But Haskell has many other, this thing about type inference, for instance, that the entire language is, types are optional everywhere, and yet it can do type inference for everything. It can infer the types correctly, et cetera. C or some low language.
Starting point is 01:01:54 I mean, you can also have a, to learn some assembler or I mean to see you. But assemblers now are becoming too much complex. It would be to learn like the 80-80 assemble, very old assembler of a very, but to have exactly this idea of what a machine does, how it does stuff, exactly the basic level, to have this understanding.
Starting point is 01:02:20 Skin is a language that I like very much because of this, exactly 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 it was the first language is to have pattern matching in this idea of doing a, I mean, it's really strong patterns, et cetera. And I think it's sometimes it's interesting to see all. languages because exactly nowadays a lot of languages tend to like I said zero indexing that people
Starting point is 01:03:04 they copy a lot they tend to be true uniform in some aspects and it's interesting to see some older languages that have some ideas that may maybe not even good ideas but it's interesting last question for you is knowing everything you know now if you could 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 or, and I always say that they wanted to learn programming in five years.
Starting point is 01:03:57 That's really take time. You have to learn that. That is a lot of stuff to learn. There's no magic. There's no. You really have to learn a lot of different things. Thank you so much for your time, Professor. I really appreciate it.
Starting point is 01:04:15 It was a lot of fun. Thank you. 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.
Starting point is 01:04:32 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. It's a split keyboard. So there's two sides. This is in the case.
Starting point is 01:04:51 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.
Starting point is 01:05:08 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.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.