@ryanlpeterman: Roberto Ierusalimschy is the creator of the Lua programming language. I interviewed him about Lua's unique strengths, p…

X AI KOLs Following News

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.

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
Original Article
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

视频来源:@ryanlpeterman: Roberto Ierusalimschy is the creator of the Lua programming language. I interviewed him about Lua’s unique strengths, p…

Similar Articles