@ryanlpeterman: Roberto Ierusalimschy is the creator of the Lua programming language. I interviewed him about Lua's unique strengths, p…
Summary
Interview with Lua creator Roberto Ierusalimschy covering Lua's unique embedding-oriented design, its differences from Python, LuaJIT's workings, and predictions for AI's impact on programming languages.
View Cached Full Text
Cached at: 08/04/26, 12:16 PM
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.
In this episode:
• Lua design choices that set it apart • JIT basics and why it is hard • Cross-language calls and how they work • Predictions for AI’s impact on programming languages
Where to watch:
• YouTube - https://youtu.be/jCZnFKk6M9A • Spotify - https://open.spotify.com/episode/3SWEjGkoNCdgSEvOA1sU1A?si=8VrcgJWHQkm8suGWO-Ud8Q… • Apple Podcasts - https://podcasts.apple.com/us/podcast/the-peterman-pod/id1777363835… • Transcript - https://developing.dev/p/creator-of-lua-scripting-programming…
Thank you to the sponsor of this episode 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
Chapters:
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
TL;DR: Lua 创造者 Roberto Ierusalimschy 在采访中解释了 Lua 作为嵌入式脚本语言的独特设计、与 Python 的差异、LuaJIT 的工作原理,并推荐了编程语言设计书籍。
引言
Roberto Ierusalimschy 是 Lua 编程语言的创造者。在这次采访中,他谈到了 Lua 的定位、它与 Python 的区别、LuaJIT 如何工作,以及他对编程语言设计书籍的看法。
Lua 在 2023 年是 GitHub 贡献者统计中增长率第二高的编程语言,也用在《魔兽世界》《Roblox》等知名游戏中。那么 Lua 到底是一种什么样的语言?
Lua 是什么?它为何特别?
Lua 通常和另一种语言一起使用,比如 C 或 C++。典型架构是:Lua 负责程序中更动态、变化更频繁、不那么消耗资源的部分;而困难的部分用 C 或 C++ 来写。所以它常被称为脚本语言。
Roberto 指出,人们对“脚本语言”和“动态语言”之间存在混淆。两者并不是同一回事。脚本有两种典型用法,关键在于“谁拥有主循环”:
- 主程序用 C 编写,然后调用 Lua;
- 或者主程序用 Lua 编写,然后调用 C。
对许多脚本语言来说,把主程序写成脚本语言、C 只用于提供库,会容易得多。而 Lua 非常适合相反的情况:主程序用 C 编写,它不时调用 Lua。
这在游戏里非常重要——为了保持帧率。主循环用 C 维持游戏节奏,控制一切,每一帧调用 Lua 更新角色、图像和游戏里的所有内容,然后返回 C 去做渲染。
这被称为“嵌入”与“扩展”的区别:你可以用 C 来扩展脚本语言,也可以把脚本语言嵌入到 C 中。很多语言只擅长扩展,而 Lua 在嵌入和扩展两方面都非常擅长。
为什么 Lua 擅长嵌入,而 Python 几乎相反?
因为从一开始,Lua 就被当作一个库来思考、编写。Lua 有一个独立的程序,你可以通过命令行调用它,但那个程序只是这个库的一个客户端——一个官方客户端,它使用任何其他程序都可以使用的同一个 API。
这种“语言即库”的想法并不常见,这正是 Lua 非常独特的地方。
具体设计决策:没有 eval,用 load
将语言设计成库,会涉及很多或大或小的细节。例如全局空间、变量作用域、异常处理——在 Lua 中很常见的做法是在 Lua 里抛出异常,在 C 里捕获异常。
另一个例子是 eval 与 load:
大多数动态语言几乎都有
eval:你给一段代码,它就执行。在 Lua 里没有eval,取而代之的是load:你给它一段代码,它返回一个函数。当你调用那个函数时,才执行相关联的代码,而不是立即执行。
这样就能清晰分离“编译”步骤:你可以在 C 中处理 Lua 代码、编译它、检查错误,然后针对不同部分调用那个函数,甚至可以多次调用。当然,这不是巨大区别,因为 eval 和 load 在理论上可以互相实现。但 load 对嵌入用途来说更简单,这正是从库的角度思考时想到的设计。
无全局状态
Lua 没有全局状态。当 C 开始时,第一件事就是调用创建一个新的 Lua state(状态),之后所有操作都基于这个 state,它与其它一切完全独立。C 可以再创建另一个 state,两个 state 完全独立、没有任何通信。
如果 C 在某个程序中不再需要 Lua,可以关闭这个 state,Lua 使用的所有内存都会释放。之后还可以再创建另一个 state。这些决定始终围绕同一个问题:这对嵌入是否有利?
Lua 与 Python:目标不同
Lua 是一种为脚本架构设计的语言,它并不追求拥有大量不同的库。如果你说“我想快速写个程序做点什么事”,Python 好得多——它有你能想到的所有库,语言本身也内置了大量库。
Lua 几乎相反。它是一种非常极简的语言,因为 Lua 的理念是嵌入到程序中。它不占用什么资源;你将会使用的大部分重要库,都由程序本身提供,比如游戏引擎里的移动角色、说话、游戏场景等功能。
所以最大的区别是:两者目标非常不同。
至于性能,Roberto 认为“那些基准测试未必完全准确”,但 Lua 确实非常重视性能:
在脚本语言领域,Lua 并不想跟 C 或 C++ 竞争;但在动态语言领域,我们确实对性能有一些关注。
Python 则偏向“性能不是那么重要,更重要的是灵活性”。而 Lua 有时会不加某些特性,因为“没有高效实现的方式”。
性能差异也来自 Lua 的体积小。大部分虚拟机都能塞进 CPU 缓存。另外,Lua 没有那么多特性,不像 Python 那样动态——Python 里有很多间接跳转,因为任何东西都可能表示别的东西;Lua 在这方面更保守。体积小本身也让它自然而然地更快。
脚本语言与动态语言
Roberto 确认:脚本语言是动态语言的子集,动态语言是超集。JavaScript 是动态语言,而不是脚本语言。
“脚本”这个词来自最早的脚本语言,比如 bash 或 Unix shell。核心思想是:这是一种协调其他东西的语言。关键在于“双语言架构”——shell 之所以有用,是因为你有很多用 C 写的程序,由 shell 来控制。脚本语言带有一种很强的观念:你给出一个脚本,让其他东西去执行。
Roberto 推荐的编程语言设计书
Roberto 喜欢研究编程语言设计,也喜欢读描述语言设计的书。他认为最好的书,是语言作者自己写的、关于该语言设计的书。
他特别推荐了《JavaScript 语言精粹》(JavaScript: The Good Parts):
它现在有点老了,但我认为它是一本非常有趣的书。虽然我经常开玩笑说,它非常薄,和官方 JavaScript 书籍比起来。它确实在讨论这门语言,甚至讨论了“糟粕部分”,并聚焦在“精华部分”,同时解释它为什么存在、为什么那样设计。
LuaJIT:为什么它在 Lua 上这么成功?
LuaJIT 是一个与 Lua 官方没有关系的完全独立的项目,但它是一个令人难以置信的软件——Lua 的即时编译器。它能在 Lua 上运行得这么好,其中一个原因恰恰是 Lua 的简单性。
Lua 是一种非常规则的语言:没有很多例外,也没有太多交互,不够动态。这为 JIT 提供了非常好的语言基础。LuaJIT 的创造者 Mike Pall 仍在做最初的 LuaJIT,他的工作令人难以置信。
什么是追踪编译器?
Mike Pall 为了获得那样的性能,做了一个“trace compiler”(追踪编译器)。追踪编译器的想法是:不是拿一个函数然后编译它,而是像任何 JIT 一样工作——它试图检测那些频繁执行的代码,然后开始追踪。
它会记录代码所做的一切,包括函数调用等,直到闭合一个循环。然后编译那个循环,包括函数调用等一切都被内联进去。它针对特定情况编译,比如说“这个数字恰好是整数”,于是编译成:如果这个数字又是整数,就用这种方式执行。还有很多检查确保一切和假设一致,然后执行这个循环,速度非常非常快。
但一旦有不同——比如之前频繁用整数调用,突然传了一个浮点数——条件就被破坏了,就得回到解释器部分。
Roberto 认为最麻烦的部分之一,是把状态转换回来:
那个状态已经被压缩到寄存器等里面了。比如说,你甚至没有调用栈,因为你没有执行调用,你只是把它内联了。然后,出问题了。现在你必须继续解释执行。所以你不得不重新创建你原本没有创建的栈。
光是想想这件事,Roberto 就头疼。
标准 Lua 是怎么执行代码的?
标准 Lua 是可移植的,但在一台机器上执行,最终总得在某个层面转换成机器指令。Lua 是用 C 写的;解释器也是用 C 写的。编译后得到机器码。
当 Lua 解释器拿到 Lua 代码时,会做“预编译”——把它翻译成一种内部语言。然后解释器就是一个大循环,一个带 switch 的循环。大致上就是获取一条指令,做 switch,看这条指令是什么——指令与 CPU 指令很像,但它是执行那条指令。比如“move A to B”,它就执行 A 到 B 的移动,然后继续下一条指令。
人们称之为“取指令”。跳转就是跳转:你有一个字节码数组,跳转就是去到那个位置——你有一个计数器,记录你在数组中的位置;跳转就是更新那个计数器,让它指向数组中你要去的另一个位置。这就像在用软件模拟 CPU。
解释器的主循环是用 C 写的。如果你在 Linux 上编译它,它就能在 Linux 上运行;如果你在 x86 架构上编译,它就在那个架构上运行。
Source
Similar Articles
Lua as a practical "soft-bedrock" language
The article discusses Lua as a practical 'soft-bedrock' language, exploring its role in software development.
@ryanlpeterman: Xavier Leroy (creator of OCaml) is an expert in compilers, formal verification of software and functional programming. …
Xavier Leroy, creator of OCaml, discusses OCaml's features compared to Rust and JavaScript, formal verification, type inference, and the impact of LLMs on programming in a podcast interview.
@ryanlpeterman: Leonardo de Moura (@Leonard41111588) is the creator of Lean and the Z3 theorem prover. I talked with him about how Lean…
An interview episode with Leonardo de Moura, creator of Lean and Z3, discussing how Lean works, the role of LLMs in formal verification, and how AI-assisted proofs could transform software development and mathematics.
@ryanlpeterman: My goal was to record a conversation completely free of "AI doomer" takes as a timeline cleanser. For this episode, I i…
Ryan Peterman interviews Casey Muratori about computer history, software engineering, and programming practices in a podcast episode focused on balanced tech discussion.
Lunacy - Lua 5.1 interpreter with Lazy Basic Block Versioning and JIT
Lunacy is a Lua 5.1 interpreter written in Rust, implementing Lazy Basic Block Versioning and a Just-in-Time compiler, as detailed in a technical blog post.