The Peterman Pod - Lua 的创作者:脚本、编程语言、预测 | Roberto Ierusalimschy 封面

Lua 的创作者:脚本、编程语言、预测 | Roberto Ierusalimschy

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

本集简介

Roberto Ierusalimschy 是 Lua 编程语言的创始人。我与他探讨了 Lua 的独特优势、编程语言设计,以及他对人工智能将如何影响编程语言的预测。 • 我在节目中提到的人体工学键盘项目,你可以在此跟进:https://read.compose.llc/ • 该项目的 Kickstarter 页面:https://www.kickstarter.com/projects/ryanlpeterman/compose-simple-ergonomics-beautifully-done 播客链接: • YouTube: https://youtu.be/jCZnFKk6M9A • Apple Podcasts: https://podcasts.apple.com/us/podcast/the-peterman-pod/id1777363835 • 文字实录:https://www.developing.dev/p/creator-of-lua-scripting-programming 感谢本期节目的赞助商对我的支持: • WorkOS:通过易于使用的 API,仅需几行代码即可为你的应用添加单点登录 (SSO)、SCIM、基于角色的访问控制 (RBAC) 等功能,让你的应用具备企业级能力,请访问 https://workos.com/ 了解详情 时间戳: (00:00) 简介 (00:43) Lua 的独特之处 (08:35) Lua 与 Python 的对比 (13:04) 关于语言设计的最佳书籍推荐 (14:20) JIT 的工作原理及其难点 (23:21) 编译 Python 与解释 C (30:31) 跨语言调用的工作原理 (36:58) Lua 独特的设计决策 (51:17) 对 AI 影响语言发展的预测 (01:00:10) 成为更优秀工程师应学习的三种顶级语言 (01:03:21) 给年轻时的自己的一些建议 (01:04:19) 结语 在哪里可以找到 Roberto: • 网站:https://www.inf.puc-rio.br/~roberto/ • 维基百科:https://en.wikipedia.org/wiki/Roberto_Ierusalimschy 如何联系 Ryan: • 通讯订阅: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 本期节目提及的内容: • Lua 的演进:https://www.lua.org/doc/hopl.pdf • LuaJIT:https://luajit.org/ • 成本有多高:https://www.youtube.com/watch?v=EUvgoxBm7uc • JavaScript 精粹(非联盟链接):https://www.amazon.com/dp/0596517742

双语字幕

仅展示文本字幕,不包含中文音频;想边听边看,请使用 Bayt 播客 App。

Speaker 0

我们完全有可能不再需要编程语言。

It's completely feasible that we won't have programming languages.

Speaker 1

这位是Roberto,Lua编程语言的创造者,我向他请教了关于编程语言设计的一切。

This is Roberto, the creator of the Lua programming language, and I asked him all about programming language design.

Speaker 0

C++就是一个很好的例子,它真的非常非常复杂。

C plus plus a good example of a language that is really, really complex.

Speaker 0

JavaScript,我觉得,甚至更糟糕。

JavaScript, I think, is even worse.

Speaker 0

我经常开玩笑说,JavaScript的精髓部分,和官方文档比起来,就是一本很薄的小册子。

I always joke that the JavaScript, the good part, a very thin book compared with the official JavaScript brief.

Speaker 1

考虑到人工智能发展得这么快,你现在还会推荐人们学习计算机科学吗?

Given how much AI has been progressing, would you still recommend people learn computer science today?

Speaker 0

如果你仔细想想,其实很难推荐人们去学任何东西。

If you really think about that, it's really difficult to recommend people learning anything.

Speaker 1

这是完整的一期节目。

Here's the full episode.

Speaker 1

2023年,根据GitHub贡献者的数据,Lua是增长第二快的编程语言。

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

Speaker 1

我还看到它被用于《魔兽世界》和《罗布乐思》这类知名游戏。

And I saw that it was also used in famous games like World of Warcraft and Roblox.

Speaker 1

所以我想问您,Lua是一种什么样的编程语言,它有什么独特之处?

And so I wanted to ask you, what kind of programming language is Lua and what sets it apart?

Speaker 0

Lua通常与其他语言配合使用,比如C或C++,这样架构上Lua负责程序中更动态的部分——那些变化频繁、对资源要求不高的部分。

Lua is a language that usually is used together, combine it with another language, like C or C plus plus 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.

Speaker 0

而繁重的部分则用C或C++来编写。

The hard parts you have written in C or C plus plus language.

Speaker 0

我觉得很多人会把脚本语言和动态语言搞混。

There is some confusion, I think, between scripting languages and dynamic languages.

Speaker 0

大家似乎认为动态语言和脚本语言差不多是一回事。

And people just, I think, consider a dynamic language to be more or less the same thing as a scripting language.

Speaker 0

但它们其实并不完全相同。

And they are not exactly the same thing.

Speaker 0

举个例子,Lua和其他几种脚本语言的一个很大区别在于,脚本语言通常有两种典型用法。

So for instance, a big difference between Lua and several other scripting languages is that for scripting you have two typical uses.

Speaker 0

一种是我所说的,由主循环来控制。

You can have the the ad that I call who has the main loop.

Speaker 0

也就是说,你可以用C语言编写程序,然后调用Lua;或者用Lua编写程序,然后调用C语言。

So you you can have the program written in C and calling Lua, or you have your program written in Lua calling C.

Speaker 0

对于很多所谓的脚本语言来说,你并不一定非要这样,但如果你用脚本语言编写程序,而C语言只用于库函数,那用起来会方便得多。

And for several called scripting languages, 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 languages only for your libraries.

Speaker 0

而LuaJIT非常适合相反的情况。

And LuaJIT's very good fit when you want the reverse.

Speaker 0

你想用C语言编写程序,然后时不时地调用Lua。

You want the the the the program written in c, and then you you have it calls Lua from time to time.

Speaker 0

关键在于,Lua在这方面非常擅长——主循环用C语言编写,然后它调用Lua来处理某些任务或你想做的任何事情。

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.

Speaker 0

比如在游戏里,这对保持游戏的帧率非常重要。

And for instance, in games, this is very important to keep the frame ratio of the game.

Speaker 0

比如说,游戏里有一个主循环,这个循环控制着游戏的节奏,维持一切运行。然后在每一帧,它会调用Lua,Lua更新所有角色、所有图像、游戏里的所有内容,然后返回给C去做随机化处理等等。

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, and then it returns to C to do the randomization, etcetera.

Speaker 0

所以它非常合适。

So it is a very good fit.

Speaker 0

但关键点是,人们有时把这种情况称为嵌入与扩展。

But the main point is that people sometimes call this the embedding versus extending.

Speaker 0

也就是说,你可以用C来扩展脚本语言,也可以把脚本语言嵌入到C中。

So you can extend the scripting language with C, or you can embed the scripting language into C.

Speaker 0

因此,有些语言只擅长扩展,而Lua在嵌入和扩展两方面都做得很好。

And so, several languages are very good only for extending, while Lua is really good for both embedding and extending.

Speaker 1

为什么Lua适合嵌入呢?

Why is Lua good for embedding?

Speaker 1

而Python几乎正好相反。

And Python, it's almost the opposite.

Speaker 0

因为从一开始,Lua就被设计成一个库。

Because Lua, since the beginning, Lua, we thought about Lua as a library.

Speaker 0

从一开始,Lua 就是作为库来编写的。

Since the beginning, Lua was written as a library.

Speaker 0

所以我觉得这就是主要的区别。

So I think that's the the main difference.

Speaker 0

Druid 有一个独立的程序,也就是说,你可以在控制台或命令行里调用 Lua。

Druid has a standalone program that, I mean, you can call Lua in your console, in your command line.

Speaker 0

但那个程序只是库的官方客户端的一个外壳,它遵循的是和其他任何程序都能用的同一套 API。

But that program is just a client of the official client of the library following the the same API that any other program can use.

Speaker 0

所以这种把语言当作库的理念,我觉得并不常见。

So this idea of language as a library, I think it's not very common.

Speaker 0

这是 Lua 非常独特的一点。

It's something that is very particular in Lua.

Speaker 1

当你把语言设计成库的时候,有哪些独特的设计决策需要考虑?

When you design a language as a library, what are the unique, I guess, design decisions?

Speaker 0

我觉得这体现在很多大大小小的细节上。

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

Speaker 0

比如,关于全局空间、变量作用域、异常处理这些概念,在 Lua 里很常见的一个情况是,你在 Lua 中抛出异常,却在 C 语言中捕获它。

For instance, your your idea of what is your global space or your 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.

Speaker 0

所以,语言中异常处理的方式就变得很重要。

So the all the things about how you do exception handling in the language.

Speaker 0

另一个例子,虽然不是什么大事,但比如大多数动态语言,这几乎就是动态语言的定义了。

Another it's not a big deal, but it's, for instance, most dynamic languages, that's almost a definition of a dynamic language.

Speaker 0

它们都有一个 eval 函数,你可以给它一段代码,然后它就会执行那段代码。

They have an eval function that you can give a piece of code, and then it executes that to code.

Speaker 0

在 Lua 中,我们没有 eval,而是用一个叫 load 的函数,你给它一段代码,它会返回一个函数,一个内部函数,就像 Lua 函数一样,当你调用那个函数时,才会执行相关的代码。

In Lua, we we don't instead of eval, 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 the associated code.

Speaker 0

它不会立即执行。

It doesn't doesn't execute immediately.

Speaker 0

所以,你有一个清晰的分离,就是编译 Lua 代码和用 C 语言处理它之间的分离。

So you have this sep this clear separation between compiling, like, the the the Lua code that you have, and then you can do that in C.

Speaker 0

因此,在 C 语言中,你可以获取一段 Lua 代码。

So in C, you can get a piece of Lua code.

Speaker 0

你可以编译它,检查有没有错误等等。

You can compile it, check if it has errors, etcetera.

Speaker 0

然后你调用那个函数,这是另一回事,或者你甚至可以多次调用。

Then you call that for in for this is a different piece, or you can even call several times.

Speaker 0

比如,你可以从Lua中加载函数到C语言里。

For instance, you can load functions from Lua into c.

Speaker 0

你可以把它们保留在Lua的空间里,然后反复调用同一个函数。

You keep them, I mean, in the Lua space, and then you can call that same function again and again.

Speaker 0

当然,这差别不大,因为如果你有eval,你可以执行一个函数声明,然后返回那个函数。

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.

Speaker 0

所以,如果你有eval,你就可以实现load的功能。

So you you can if you have a val, you can do load.

Speaker 0

如果你有load,你也可以实现eval的功能。

If you have load, you can do eval.

Speaker 0

但我认为,对于那种情况,比如考虑库的时候,load用起来更简单。

But I think load, it's it's simpler to use for that kind of thing that is when you think about libraries, for instance.

Speaker 0

在 Lua 里,它没有全局状态。

In Lua, you it doesn't have a global state.

Speaker 0

我觉得我忘了说,这是一个非常重要的区别。

I think that's I forgot that that that's a very important difference.

Speaker 0

当 C 启动时,第一件事就是调用函数创建一个新的 Lua 状态。

When c starts, the first thing it has to do is to call create a new Lua state.

Speaker 0

然后你做的所有操作都在那个状态上进行,而且这个状态完全独立于其他任何东西。

And then everything you do, you do on that state, and that state is completely independent of everything else.

Speaker 0

所以 C 可以创建另一个 Lua 状态,两个状态完全独立,互不干扰。

So c can, for instance, create another Lua state, and both states are completely independent, complete.

Speaker 0

它们之间没有任何通信。

There is no communication between them.

Speaker 0

这也再次说明,你可以用一个状态做很多事情,然后关闭这个状态,Lua 占用的所有内存都会被释放。

And so this, again, shows that if and so far, it says he can use a state to do a lot of stuff, and then he can close the state, and all memory used by Lua is released.

Speaker 0

Lua 使用的所有东西都会被释放。

Everything that Lua was using is released.

Speaker 0

比如,如果C语言不再需要用Lua来解决某个问题,就可以释放Lua占用的所有资源,然后继续C语言的编程,之后还可以再创建另一个状态,等等。

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, then later it can again create another state, etcetera.

Speaker 0

所以,就像我说的,语言中有几个或大或小的决策。

So there's, as I said, there is several small or not so small decisions in the language.

Speaker 0

但我们始终在思考,这个语言是否适合嵌入?

But all the time we think about the language as, is that good for embedding?

Speaker 0

是否能够实现嵌入之类的功能?

Is that possible to do embedding and things like that?

Speaker 1

说到编程社区,大家普遍对Python很熟悉,但对Lua就没那么熟悉了。

When you think of the programming community, generally, everyone is quite familiar with Python, but not as familiar with Lua.

Speaker 1

我觉得把这两种语言做个对比可能会挺有意思的。

I thought it might be interesting to compare the two languages.

Speaker 1

如果把Lua和Python相比,两种语言设计各有什么优缺点呢?

So if you compared Lua to Python, what are the pros and cons of each language design?

Speaker 0

Lua是一种旨在用于脚本架构的语言。

Lua is a language that is intended to be used in in this idea of of scripting architecture.

Speaker 0

所以,比如 Lua,它并不追求拥有大量不同的库。

So the the Lua, for instance, it doesn't drive having a lot of different libraries.

Speaker 0

如果你想要快速写个小程序,那 Python 就好得多。

If you have something that, oh, I want to write a a quick program for something, that Python is much better.

Speaker 0

它有你想要的所有库。

It has all the libraries you can dream about.

Speaker 0

它内置了很多库,所以语言本身非常庞大。

It has a lot of libraries built in already into the language, so the language is huge.

Speaker 0

我是说,安装包下载量也很大,等等。

I mean, the the the installation, it's it's a huge download, etcetera.

Speaker 0

但它就是,哦,我需要这个。

But it has exactly, oh, I need that.

Speaker 0

哦,它就在那儿。

Oh, it's there.

Speaker 0

我需要那个,它也在那儿。

I need that, it's there.

Speaker 0

而Lua则几乎完全相反。

And Lua is almost the opposite.

Speaker 0

它是一种非常精简的语言,因为设计初衷是嵌入到你的程序里,几乎不占用什么资源。

It's a very minimalistic language, because they did that in embed Lua into your program, it doesn't use almost any resources.

Speaker 0

大多数重要的库,你实际会用到的那些,都是由程序本身提供的,比如移动角色、语音合成之类的功能,这些都来自游戏引擎。

Most of the libraries, the important libraries that you 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 of the game.

Speaker 0

比如说,你可以想象游戏场景,但也不仅限于此。

For for instance, if you think about games, but whatever it is.

Speaker 0

所以我认为,这就是Lua和Python之间最主要的区别。

So Lua, I think that's the the main big difference.

Speaker 0

它们的目标完全不同。

It's they they have very different goals.

Speaker 1

我看到一些基准测试,发现Lua比Python快得多。

I saw some benchmarks and I saw that Lua is much faster than Python.

Speaker 1

这是为什么呢?

Why is that?

Speaker 0

那些基准测试不一定完全准确,但我觉得关键点在于,Lua确实注重性能——当然,是在脚本语言的范畴内,它并不想跟C或C++竞争,但在动态语言(现在更多叫动态语言,而不是脚本语言)的领域里,它确实对性能有所侧重。

Those 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 language, it doesn't want to compete with C or C plus plus but in the real of dynamic, mostly now it's dynamic language, not scripting languages, we have some focus on performance.

Speaker 0

所以我认为这是第一个区别。

So I think this is a first difference.

Speaker 0

而Python呢,我觉得更多是他们的一个设计选择。

Python exactly is much more, I think, it's a decision that they make.

Speaker 0

性能没那么重要,更重要的是灵活性,让你能轻松做你想做的事。

Performance is not that important, it's more important to be flexible, to be easy to do whatever you want to do.

Speaker 0

在Lua里,有时候我们会放弃某些特性,因为觉得没法高效实现它们。

In Lua sometimes we do not put some features because we think that there is no way to implement that efficiently.

Speaker 0

不过,我觉得性能差异的一部分也恰恰来自Lua的体积小。

But also, I think some part of the performance difference comes exactly because of the size of Lua.

Speaker 0

比如,它的整个虚拟机几乎都能放进缓存里。

So most of the virtual machine fits in your cache, for instance.

Speaker 0

我觉得主要就是这两点。

I think there is these two big things.

Speaker 0

一方面,Lua 的功能没有那么多。

One is that Lua doesn't have so many features.

Speaker 0

它不像 Python 那样动态。

It's not so dynamic as Python.

Speaker 0

所以在 Python 里有很多间接调用,因为任何东西都可能代表别的含义,而我们在这一点上更保守一些。

So in Python there is a lot of indirections because everything can mean something else, and we are a little more conservative on that side.

Speaker 0

但我觉得,体积小本身也让它自然更快。

But I think also this thing of being small also makes it naturally faster.

Speaker 1

所以关于脚本语言和动态语言的区别,我猜动态语言是更大的范畴,脚本语言是它的子集。

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.

Speaker 1

按你的说法,JavaScript 是动态语言,而不是脚本语言,我理解得对吗?

Am I understanding that JavaScript is a dynamic language, not a scripting language from your perspective.

Speaker 0

对,没错。

Yes, exactly.

Speaker 0

对,就是这样。

Yes, exactly.

Speaker 0

因为脚本语言这个概念,最早是从Bash或者Unix的Shell来的,核心思想就是有一种语言用来协调其他东西。

Because the scripting, it came, the original scripting language was Bash or the shells from Unix, of this idea that there is a language that coordinates other stuff.

Speaker 0

比如说,它可以用来扩展,但关键是你有两种不同的语言——就像Shell之所以有用,是因为有很多用C写的程序由Shell来控制。

So for instance, it can be extending, again, can use, but this idea that you have two different language, for instance, the shell is only useful because you have a lot of problems written in C that are controlled by shell.

Speaker 0

所以脚本语言有一个非常强的概念,就是双语言架构。

So the scripting language have this very strong idea that you have this idea of a dual language architecture.

Speaker 0

所以“脚本”这个名字本身就意味着,你是在协调或者给那些东西提供一个脚本去执行。

So sweetness is like, it's the name scripting, it means you, it's like the, you coordinate or you give a script to be executed by those things.

Speaker 0

你之前

You gave

Speaker 1

在一次演讲中,有人问你推荐哪些书来学习编程语言。

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?

Speaker 1

你当时说,你其实很喜欢研究其他编程语言的设计。

And you said actually that you enjoyed studying the language design of other programming languages.

Speaker 0

我喜欢读那些描述语言设计思路的书。

I like reading books that describe the design of the languages.

Speaker 0

我觉得最好的书就是语言作者自己写的那本,讲的是这门语言的设计。

I think the best books are those written by the author of a language about the design of that language.

Speaker 1

那你觉得哪本书在语言设计方面最值得推荐?

What book recommendation do you think is best on language design?

Speaker 0

比如《JavaScript语言精粹》。

JavaScript, The Good Parts, for instance.

Speaker 0

虽然现在有点老了,但我还是觉得它是一本很有意思的书。

It's kind of old now, but I think that's I think it's a very interesting book.

Speaker 0

不过我总开玩笑说,《JavaScript语言精粹》这本书很薄,跟官方JavaScript书比起来,大概只有十分之一的内容是精华部分。

Although I always joke that the JavaScript, the good part, very thin book comparative the official JavaScript books, like, one tenth of the language is the good parts.

Speaker 0

但我觉得那本书真的很有意思,因为它正好讨论了这门语言,连不好的部分也讲了,然后重点放在好的部分,还解释了为什么会有那些设计、为什么那样做等等。

But but I I think that book is really interesting, like, because exactly it it discusses the language, 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.

Speaker 0

那是我喜欢的一本书。

That is a book that I like.

Speaker 1

刚才聊到Lua的时候,感觉Lua的一个特点就是性能好,而且非常精简。

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.

Speaker 1

我在看Lua的资料时,看到了LuaJIT。

And when I was reading about Lua, I saw that there's LuaJIT.

Speaker 1

LuaJIT是怎么工作的?

How does the LuaJIT work?

Speaker 0

LuaJIT首先是一个完全不同的项目。

LuaJIT is the first thing that's completely different project.

Speaker 0

它和我们没什么关系,但它是一个非常了不起的软件,是Lua的一个即时编译器。

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.

Speaker 0

我觉得它能在Lua上运行得这么好,其中一个原因就是Lua本身很简单。

And I think exactly one of the reasons it works so well on top of Lua is because of the simplicity of Lua.

Speaker 0

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 indirections or things that, so it's not that dynamic.

Speaker 0

意思是,它可能代表完全不同的东西。

Mean, can mean something completely different.

Speaker 0

所以我认为这对JIT来说是一个非常合适的语言。

So I think that gives a very good language for a JIT.

Speaker 0

不过,那个Mike Paul就是开发第一个JIT编译器的人,我觉得他到现在还在继续做这个项目。

But the the the the the Mike Paul is the name of the the the guy that made the the I think he's still working on that, on the first JIT.

Speaker 0

他的工作真是令人难以置信。

He's it's unbelievable, his work.

Speaker 1

编写JIT编译器难在哪里?

What makes writing a JIT difficult?

Speaker 0

对我来说,不想碰JIT的首要原因就是它依赖于特定的机器架构。

The first thing that for me I don't want to get involved with JIT is because it's machine dependent.

Speaker 0

这样效率不高。

It's not very productive.

Speaker 0

就是说,你花了很多功夫,结果只能在那一种架构上运行。

I mean, you do a lot of work on those, only work on that architecture.

Speaker 0

然后,哎呀,我又想换到另一种架构上运行。

And then, oh, I want to run-in another architecture.

Speaker 0

但Mike Paul发明了一种伪汇编语言,他用这种汇编语言写代码,然后再把它翻译成不同机器的真实机器码,这样就能统一不同的架构了。

But might Paul, he created a kind of a pseudo assembler that he writes in this assembly, and then he translates that assembler through real machine code of the different machines, so trying to unify the different architectures.

Speaker 0

所以工作量很大,但我不喜欢。

So there is a lot of work, but I don't like it.

Speaker 0

我觉得架构,我喜欢研究,但不喜欢做实际工作,因为我觉得它很不稳定。

I think architecture, I like to study, but I don't like to work with, because I think it's very unstable.

Speaker 0

每个新版本,他们改这个,改那个,比如改个ABI,然后栈又得按某种特定方式对齐。

Each 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.

Speaker 0

当然,为了达到他那样的性能,他做了一个叫追踪编译器的东西。

And so And of course, also to get that performance that he gets, he made what's called a trace compiler.

Speaker 0

追踪编译器的思路是,不是拿到一个函数就去编译它,而是像其他JIT一样,先检测哪些代码执行得频繁。

The idea of a trace compiler that instead of getting a function and compiling a function, it go it it works like any JIT that it tries to detect things that are executing frequently.

Speaker 0

然后它就开始所谓的追踪。

And so it starts what is called a trace.

Speaker 0

它会记录代码所做的一切,包括函数调用等等,直到形成一个循环。

It gets recording everything that the code is doing, including function calls, etcetera, until it closes the loop.

Speaker 0

然后它编译那个循环,包括函数调用等等,全部内联进去。

And then it compiles that loop, including function calls, etcetera, everything in line.

Speaker 0

它针对那种特定情况编译,比如那个数恰好是整数,所以它编译f时,会假设这个数还是整数。

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.

Speaker 0

然后会有很多检查,确保一切符合预期,接着再执行循环。

And there is a lot of checks, just check if everything is as assumed, and then it executes the loop.

Speaker 0

这样一来,速度就非常非常快。

And then it's very, very, very fast.

Speaker 0

但一旦出现变化,比如你频繁用整数调用它,突然有一次传了个浮点数,那代码的某个地方就会打破条件,你就得回到解释器那部分。

But anything that is different, for instance, you call again that, but you call it frequently with integers, and suddenly you call through with a float, then at some part of the code it breaks the condition, and you have to return to the interpreter part.

Speaker 0

我觉得最麻烦的地方之一就是,你得把压缩在寄存器里的状态全部还原出来。

And I think that's one of the worst parts, that you have to translate the state that it's all compressed into registers, etcetera.

Speaker 0

比如说,你连调用栈都没有,因为你根本没做函数调用,直接内联了。

For instance, you don't even have a call stack because you didn't do the calls, you just inlined it.

Speaker 0

但突然,哎呀,出问题了。

But then, oops, something went wrong.

Speaker 0

现在你得继续解释执行,所以必须重新创建那个你原本没创建的栈,等等。

Now you have to continue interpreting, so you have to recreate the stack that you didn't create originally, etc.

Speaker 0

光是想想这个,我就头疼。

So even to think about that, I have headaches.

Speaker 1

标准 Lua 是可移植的,但要在机器上执行,它最终总得在某个环节转换成机器指令。

Standard Lua is portable, but to execute on a machine, it eventually gets converted into machine instructions somewhere.

Speaker 1

那在堆栈的哪个环节,它最终被翻译成机器指令呢?

Where in the stack is it eventually translated to machine instructions?

Speaker 0

Lua 是用 C 写的,解释器也是用 C 写的,然后你把解释器和 Lua 代码一起编译成机器码。

Lua is written in C, the interpreter is written in C, and then so you compile that into machine code, the interpreter, the Lua code.

Speaker 0

然后当你拿到一些 Lua 代码时,我的意思是,Lua 解释器代码。

Then the point when you get some some some I mean, the Lua code, the Lua interpreter code.

Speaker 0

当你拿到一些 Lua 代码时,我们会做一个所谓的预编译,就是把它翻译成一种内部语言,然后解释器就是一个大循环。

When you get some Lua code, you do what is we call a precompilation that is we we translate to an internal language, and then the interpreter is just a big loop.

Speaker 0

就是一个带 switch 的循环。

It's a loop with a switch.

Speaker 0

当然,这是个非常简化的说法,但大致上就是一个带 switch 的循环,它拿到指令,然后通过 switch 判断,哦,这个指令——这些指令跟 CPU 的指令挺像的。

I mean, that's a very big simplification, but in general terms, a loop with a switch that get instruction does a switch and see, oh, this instruction is the instructions are quite similar to a CPU.

Speaker 0

执行那个操作,但不会创建新内容,而是直接执行那条指令。

Move that, but then instead of creating, it executes that instruction.

Speaker 0

把a移动到b。

Move move a to b.

Speaker 0

所以它执行a到b的移动,然后重复,继续执行下一条指令。

So it it does a move a to b and executes that, and again repeats, execute the next instruction.

Speaker 0

这就是解释器的工作原理,基本上我们会对Lua进行预编译。

So this is how an interpreter works and basically so we we precompile Lua.

Speaker 0

确实有编译这一步,但我们是针对这个虚拟机进行编译,然后有一个主解释循环,大家称之为取指令循环。

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 it instruction.

Speaker 0

所以跳转就是单纯的跳转。

So a jump is just a jump.

Speaker 0

你有一个字节码数组。

You have an array of byte codes.

Speaker 0

跳转指令就直接跳到那个位置。

A jump will just go to that.

Speaker 0

你有一个计数器,用来记录你在数组中的位置。

You have a counter that tells where you are in this array.

Speaker 0

执行跳转时,你只需要更新这个计数器。

A jump, you just update that counter.

Speaker 0

它会跳到数组的另一个位置,然后继续执行。这就像在软件中模拟CPU一样。

It goes to another position of that array where you're going to So it's like emulate the CPU in software.

Speaker 0

这个解释器是用C语言写的。

It's written in C, the the interpreter.

Speaker 0

这个主循环是用C语言写的。

This main loop is written in C.

Speaker 0

所以如果你在Linux上编译它,它就会在Linux上运行;如果在x86架构上编译,它就会在那个架构上运行。

So if you compile it in Linux, it will run-in Linux or in a x86 architecture, it will run-in that architecture.

Speaker 0

如果你在Mac上编译它,它就会在Mac上运行。

If you compile that in the Mac, it will run-in the Mac.

Speaker 0

它就是一个C程序。

It's a C program.

Speaker 1

明白了。

Got it.

Speaker 1

好的。

Okay.

Speaker 1

所以这部分就是不可移植的,而C编译器会处理它。

So that's that's the part that's not portable, and the C compiler handles that.

Speaker 0

对,对,对。

Yes, yes, yes.

Speaker 0

Lua的所有可移植性都建立在C的可移植性之上。

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

Speaker 1

在性能方面,JIT和提前编译相比怎么样?

How does JIT compare to ahead of time compilation in terms of performance?

Speaker 0

提前编译,或者说任何形式的编译,虽然不容易,但可以比解释执行快10倍,甚至100倍,具体取决于你在做什么。

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.

Speaker 0

但10倍已经是一个非常不错的数字了。

But 10 times is a very good figure.

Speaker 0

至于提前编译和追踪编译哪个更好,很大程度上取决于你在做什么。

Between ahead of time and trace compilation then depends a lot of what you are doing.

Speaker 0

追踪编译在跑基准测试时尤其出色。

After trace compilation, it's particularly good for benchmarks.

Speaker 0

因为基准测试基本上是在重复执行,模式非常一致,你一遍又一遍地做完全相同的事情。

Because you're repeating it more or less, they are very uniform, you are doing exactly the same thing again and again and again.

Speaker 0

所以这时候追踪编译器就大放异彩了,这是它们最擅长的场景。

So then trace compilers shine, mean, this is the best they can do.

Speaker 0

在实际问题中,情况就复杂多了,我觉得两者之间没有明显的赢家。

In real problems, that depends a lot, but I wouldn't say there is a clear winner between the two.

Speaker 0

我认为这很大程度上取决于具体的问题类型。

I think depends a lot of the kind of problem.

Speaker 1

有没有可能为 Lua 写一个提前编译器?

Is it possible to write an ahead of time compiler for Lua?

Speaker 0

可以。

Yes.

Speaker 0

有好几个呢。

There are there are several.

Speaker 0

不过,我不确定有没有达到生产级别的,但研究用的还是有几个的。

None I mean, I I don't I'm not sure if there is anyone on production quality, but for research, etcetera, there are several.

Speaker 0

我有个学生写过,是他的硕士论文。

I I have a student who wrote one, like, a master thesis.

Speaker 0

一个特别简单的 Lua 编译器,提前编译的那种。

A ridiculous simple Lua compiler, ahead of time Lua compiler, something like that.

Speaker 0

对。

Exactly.

Speaker 0

它就是把那些操作码提取出来,展开成 C 代码,然后交给 C 编译器去编译,这样就做出了一个 Lua 的提前编译器,性能提升了大概三到五倍。

It was just it gets these opcodes and expands into into C code, and then you send that through to a c compiler, and then you have a head of time comp head of time compiler for Lua, and it gave, like, three, five times boost in performance.

Speaker 0

就像标题说的,这真是个极其简单的编译器。

It's very, very, as the title said, it's like a ridiculous, simple compiler.

Speaker 1

我总听人说有编译型语言,还有动态或解释型语言,大概是这样吧。

I always hear there's compiled languages and there's dynamic or interpreted languages, I guess.

Speaker 1

但实际上,这个区别在于工具链,而不在于源代码中符号的布局方式。

But really, that distinction is in the tool chain, not necessarily in the way that the symbols are laid out on the source code.

Speaker 1

比如,我可以写一个编译器或程序,把Python代码转换成机器码,这样就有了编译后的Python。

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.

Speaker 0

C语言也可以解释执行。

And you can interpret C code too.

Speaker 0

你可以为C语言写一个解释器。

You can write an interpreter for C.

Speaker 0

是的。

Yes.

Speaker 0

但主要的区别恰恰在于哪些功能容易实现。

But the main difference is exactly what it's easy to do.

Speaker 0

比如,我刚才提到,解释型语言的一个标志性特性就是eval。

For instance, as I said, one of the hallmarks of interpreted languages is eval.

Speaker 0

所以,如果你想编译语言并保留eval功能,就必须在运行时中内置一个编译器库,因为可能在执行过程中需要编译代码。

So if you want to compile the language and keep eval, you have to have a compiler as a library of your of your runtime because you may want to compile things during execution.

Speaker 0

这就是动态语言的典型特征。

This is the hallmark of a dynamic language.

Speaker 0

你可以在运行代码的同时创建代码。

You can create code while running code.

Speaker 0

所以正因如此,大多数情况下语言都是解释型的。

So that part is that's why much more often than not, languages are interpreted.

Speaker 0

但也可以编译,不过有些编译器根本不处理 eval。

But you can compile, but then sometimes for some compilers do not handle eval at all.

Speaker 0

他们会说,只要你的程序里没有 eval,就可以编译。

They say, oh, you can compile as long as your program doesn't have evals.

Speaker 0

所以还是有一些限制的。

So there is some restrictions.

Speaker 0

而且就像我说的,你可以解释执行 C 代码,但速度会非常慢,不过……

And as I said, you can interpret C code, you'll be extremely slowly, doesn't but.

Speaker 1

我觉得一个很大的区别是,当我看到静态语言或编译型语言时,它们似乎都有类型系统或类型注解。

I think one big difference, when I look at statically, or static languages or compiled languages, they seem to have type systems in them, or the type annotations.

Speaker 1

类型系统在编译过程中扮演什么角色?

What is the role of a type system in the compilation process?

Speaker 0

这很大程度上取决于类型系统本身。

Depends a lot on the type system.

Speaker 0

有些类型系统,比如C语言中的,就是编译过程中非常重要的一部分。

Several type systems, like in C, for instance, are written to be a very important part of the compilation process.

Speaker 0

所以,如果你有一个合适的类型系统,编写编译器就会容易得多。

So if you have the right type system, it's much, much easier to write a compiler.

Speaker 0

举个简单的例子,变量的内存空间分配。如果你知道这个是整数,这个是浮点数,这个是双精度浮点数,你就能精确知道每个变量需要多少字节的内存。

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 unique to that.

Speaker 0

否则,就会变得非常复杂。

Otherwise, it's a massive.

Speaker 0

大多数情况下,你不得不把所有东西都动态分配到堆上,这会导致巨大的性能损失。

More often than not, you have to keep everything in the heap dynamically allocated, and so huge penalty in performance.

Speaker 0

再比如,就像我刚才说的,一个简单的加法运算。

And for instance, when you see, as I said, a trivial, you have an addition.

Speaker 0

比如 r 加 b。

The r plus b.

Speaker 0

如果你知道 a 的类型,a 加 b,你知道 a 的类型和 b 的类型,在编译时就能确定,哦,这个加法是两个整数相加,我直接生成整数相加的机器码就行了,一切都很顺利。

If you know the type of a, the a plus b, you have the type of a, the type of b, you have a compile time, you know, all these plus is adding two integers, I just generate the machine code to add integers, and there everything is fine.

Speaker 0

在动态语言里,我看到一个加法,我……我编译成虚拟语言,它只是一个加法操作,但运行时怎么处理呢?你得检查 a 是什么,哦,a 是整数,b 是浮点数,那我得转换,或者 b 是字符串,根据语言不同,可能根本不是在做加法。

In a dynamic language, I see a plus, I don't I I I compile to a the virtual language, it's just piece of 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, I have to convert, or b is a string, or depending on the language, you're not doing addition.

Speaker 0

它可能是拼接,或者调用某个方法,所有这些都得在运行时处理。

It can be doing concatenation, or you can just call in some and you have to do all that at run time.

Speaker 0

所以类型对于高效编译非常重要,当然,前提是你得有一个合适的类型系统。现在有些语言,比如 TypeScript,它的类型并不能保证所有东西都符合你声明的类型。

So types can be very, very important to compile efficiently, but, of course, you have to have a type system that that there are several language now like TypeScript, that types are kind of you do not guarantee that everything has the types you said they have.

Speaker 0

这样的话,就不可能用它们来编译了,因为,哦,a 可能是个整数,但如果不是,那就麻烦了——如果我给整数分配了寄存器,那 a 必须是整数,否则就行不通。

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 an integer register to boot for anything, a must be a register or things will not work.

Speaker 0

所以,如果你有正确的类型系统,它们对于好的编译来说是必不可少的。

So but if you have the right type system, they are essential for a good compilation.

Speaker 1

我知道有些编程语言,它们有类型推断。

I know some programming, then you just have type inference.

Speaker 1

那如果你先做类型推断,得到一组明确的类型,然后再用这些类型去编译呢?

What if you did, you ran type inference and you got an unambiguous set of types, and then you used that in compilation?

Speaker 1

比如说,能不能对 Lua 这么做?

Like, could you do that for Lua?

Speaker 0

不行。

No.

Speaker 0

我是说,这其实不可计算,但很多人尝试给动态语言做类型推断,这是个非常难的问题,而且很难在性能上做出什么有用的成果。

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

Speaker 0

有时候你能做到,但前提是你得用一种非常受限的方式写程序。也就是说,你虽然没有类型,但写代码时心里得想着类型,如果程序恰好符合那种特定格式,那么类型推断就能成功,一切顺利。

What you sometimes you get, but you have a very restrict if you write your program in that specific way, you fall 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.

Speaker 0

否则的话,要么类型推断不工作,要么它虽然工作,但推断出来的都是非常泛化的类型,这样你就没法利用类型优势了。

Otherwise, either time inference doesn't work, or, I mean, it works, but it actually infers very generic types for everything, and so you cannot take advantage of the types.

Speaker 0

因为语言的动态特性,这种情况在即时编译中也会出现。

Because exactly the dynamic nature of the language, This also happens through a JIT, for instance.

Speaker 0

如果你脑子里有一个类型系统,那性能就能提升很多。

You can get much, much better performance if you have a kind of a type system in your mind.

Speaker 0

我们通常都会这么做,即使没有编译器或语言强制要求,你也会自觉遵循那些类型规则。你会告诉自己,我要遵守这些规则,保持一定的纪律性。

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, some time discipline, discipline.

Speaker 0

我不会用同一个变量来存整数和字符串之类的,这样就能获得更好的效果。

I'm not going to to to use the same variable to store integers and strings, etcetera, and then you can have much better results.

Speaker 1

OpenAI、Anthropic、Cursor 和 Vercel 都在用这个产品来提升工作效率。

OpenAI, Anthropic, Cursor, and Vercel all use this product to make their lives better.

Speaker 1

它解决的问题是,当你开发 SaaS 或 AI 产品,并想卖给其他公司时,你需要满足一大堆要求。

And the problem it solves is when you're building SaaS or an AI product and you wanna sell to other companies, there's all these requirements you need to meet.

Speaker 1

比如单点登录、跨域身份管理系统、基于角色的访问控制,还有审计日志。

There's SSO, there's SCIM, there's RBAC, There's audit logs.

Speaker 1

这些功能集成起来很耗时,但它们并不是你应用的核心重点。

These are all things that take time to integrate but aren't the main focus of your app.

Speaker 1

WorkOS 是一个 API 层,让你只需几行代码就能满足所有这些要求。

WorkOS is an API layer that lets you meet all of these requirements in just a few lines of code.

Speaker 1

假设你有一个新的 SaaS 产品,想卖给其他公司,WorkOS 会帮你解决所有这些关键的功能缺口。

So let's say you have a new SaaS product and you wanna sell to other companies, WorkOS will solve all of these critical feature gaps for you.

Speaker 1

你可以去 workos.com 看看,了解更多并开始使用。

You can check them out at workos.com to learn more and get started.

Speaker 1

我很感谢他们支持我的工作,并赞助了这个播客。

And I appreciate them for supporting my work and sponsoring this podcast.

Speaker 1

之前你提到 Lua 可以调用 C,C 也可以调用 Lua。

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

Speaker 1

你还提到我们聊了编译器和解释器。

And you mentioned we talked about the compiler and the interpreter.

Speaker 1

那在串联不同编程语言的情况下,这些部分是如何协同工作的呢?

And how do these pieces work together in the case where you're chaining different programming languages?

Speaker 0

对,主要技巧——其实也不算技巧——Lua 调用 C 的方法就是 C 指针,函数指针。

Yeah, the main trick, I mean, it's not a trick, the technique for Lua calling C is C pointers, function pointers.

Speaker 0

就是有一个指向函数的指针。

There is a pointer to a function.

Speaker 0

这是 C 语言官方标准的一部分。

This is part of the official c language.

Speaker 0

所以当你启动 Lua 时,假设你在 C 语言里,就像我说的,你创建一个库。

So when you start Lua, suppose you are in c, as I said, you create a library.

Speaker 0

你创建一个状态,一个 Lua 状态,然后你可以注册,把 C 指针、函数指针以及指向你 C 库中函数的指针连同名字一起发送给 Lua,它会把这些存储在某些数据结构里。

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 stores that in some data structure.

Speaker 0

明白吗?

Okay?

Speaker 0

所以它就会说,哦,这个函数名对应那个指针,等等。

So it says, oh, the function sign is associated with that pointer, etcetera.

Speaker 0

所以在解释执行时,哦,这条指令被调用了,指令被调用了。

So when it's doing the interpretation, oh, this instruction is called, instruction called.

Speaker 0

看看它调用的是什么。

Let's see what it's calling.

Speaker 0

哦,它调用的是 a。

Oh, it's calling a.

Speaker 0

a 的值是什么?

What is the value of a?

Speaker 0

哦,那是一个指针,然后它就会调用那个指针。

Oh, it's a pointer to and then it it calls that pointer.

Speaker 0

然后我们就调用了那个C函数来做这件事。

And then we did call the the c function to do that.

Speaker 0

当C想要调用Lua时,我的意思是,从C的角度来看,Lua函数只是一个数据结构。

And when when c wants to call Lua, I I mean, a Lua function is just a data structure from the point of view of c.

Speaker 0

它只是一串字节码和操作码的数组,然后它会调用Lua解释器函数,说‘请帮我解释这个函数’。

It's just an array of byte codes of opcodes, and then it calls the Lua interpreter function of do please interpret that function for me.

Speaker 0

所以C可以调用Lua来解释那个函数,那个函数运行起来后,又可以通过指针调用一个C函数。

So c can call Lua to interpret that function, and that function is running and then can call a c function using a pointer.

Speaker 0

而且你可以在栈的多个层级上实现这种调用。

And you can have that in the stack at several levels.

Speaker 0

所以我们正在运行一个Lua函数,它调用C,C又调用Lua,Lua再调用C,这样就会形成递归,等等,一切都能正常工作。

So we are running a Lua function that calls c and c calls Lua again, and Lua calls C, and you have recursive stuff in that, etcetera, and everything works.

Speaker 0

它就是能正常工作。

It just works.

Speaker 1

你在一次关于 Lua 的演讲中提到,使用脚本语言有安全方面的好处。

In one of your talks on Lua, you mentioned that there's security benefits to using a scripting language.

Speaker 1

具体有哪些好处?它又是如何保护硬件的呢?

What are those benefits, and how does it protect the hardware?

Speaker 0

其实不只是硬件。

It's not only hardware.

Speaker 0

有一次我在巴西做演讲,被邀请去一个 Python 大会——他们叫它 PyCon,就是巴西的 Python 会议。

Once I gave a talk here in in Brazil, I was called to to give a talk in a py conference, a pycon, they they call it the Python conference in Brazil.

Speaker 0

他们请我去做了一场演讲。

They called me for a talk.

Speaker 0

演讲结束后,有人说,哦,Lua,我们把它当脚本语言用。

At the end of the talk, said, oh, Lua, we use it as a scripting language.

Speaker 0

就像我说的,重点在于这种双语言架构。

As I said, emphasizing that thing that you have this dual language architecture.

Speaker 0

据我所知,Lua 被用于和 C、C++、Fortran 以及好几种其他语言配合使用。

And I know of cases of Lua being used with C, with C plus plus with Fortran, with several different languages.

Speaker 0

然后观众里有人说,哦,我们也用Lua来给Python程序写脚本。

And then someone in the audience says, oh, we also use Lua for scripting Python programs.

Speaker 0

那是什么情况呢?

And what's the case?

Speaker 0

他们有一个很大的Python金融程序,要处理大量金融交易等等,他们想弄一个命令行,可以在运行时输入指令让程序执行,比如用来调试、检查,或者做任何需要的事情,算是某种终端用户编程。

They have a huge Python program for financial stuff that has a do a lot of financial transactions, etcetera, and they wanted to do I mean, to have a, like, a common line where you could write instructions to be executed by the at run time, for instance, for debugging or for inspecting, for whatever you need, some kind of end user programming.

Speaker 0

但他们说的正好就是我之前提到的那个安全问题。

But they said exactly what I was talking about spaces.

Speaker 0

在Python里,如果你有一个命令行,然后你运行Python代码,那这个Python代码可以对你的程序为所欲为。

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.

Speaker 0

根本没有办法保护它。

There is no way to protect it.

Speaker 0

所以如果你把这个功能交给用户,用户就能对程序想做什么就做什么。

So if you gave that to the user, the user could do whatever it wanted to do, I mean, for the program.

Speaker 0

这样一来,程序里很多重要的东西,比如它维护的文件里的各种不变量,都会被破坏掉。

And so the program would break a lot of invariants of a lot of important stuff in the files it kept, etcetera.

Speaker 0

所以他们是怎么做的呢?他们想到了 Lua,因为就像我说的,Lua 可以创建一个状态。

And so what they did, they gave the thinking Lua, because as I said, Lua, you create a state.

Speaker 0

比如,我刚才提到,你只能调用 C 函数。

For instance, as I just mentioned, you can only call c functions.

Speaker 0

这在 Python 里其实也一样,不过在那个具体场景下。

That is true in Python again, but in that particular thing.

Speaker 0

你只有把 C 指针传给 Lua,才能调用那些 C 函数。

You can only call c functions if you give the c pointer to Lua.

Speaker 0

所以它的限制非常严格,而且就像我说的,它有一个库。

So have a very strict and there is very as I said, there is a library.

Speaker 0

当你创建一个 Lua 状态时,它里面什么函数都没有。

When create a Lua state, it has no functions at all.

Speaker 0

什么都没有,也就是说,你连文件都打不开,所有功能都靠我们所说的标准库。

There is nothing, I mean, you cannot open files, everything there are what we call standard libraries.

Speaker 0

通常你会创建一个状态,然后注册那些标准库,在 Lua 里,你只有最基本的东西,比如数学函数之类的。

Usually you open a state and you register those standard libraries in Lua, you have the the minimum, you have mathematical functions, etcetera.

Speaker 0

但你可以创建一个状态,而Lua里完全没有函数。

But it can open a state and has no functions at all in Lua.

Speaker 0

它只能调用你指定的那些函数来做事情。

It can only do things calling those specific functions you you gave.

Speaker 0

所以他们用Lua来实现这种控制,或者你可以在里面写Lua代码,但这些代码在Python程序里只能做非常特定的事情。

So they they use Lua to have this kind of control, or you can write Lua code here, but that Lua code can only do very specific things in the Python program.

Speaker 0

它不能调用任何Python函数,也不能构建任何Python数据结构之类的。

It cannot call any Python function or, I mean, build any kind of Python data structure, etcetera.

Speaker 0

所以这是个很好的例子。

So was this a nice example.

Speaker 0

在硬件方面也是同样的道理。

In the case of hardware, it's the same thing.

Speaker 0

你不能随便操作,比如有一个硬件端口,它控制着风扇转速,用来维持CPU温度。

You cannot just go in the for instance, there is a port, a hardware port, that controls the speed of the fan that keeps the temperature of the CPU.

Speaker 0

如果你把转速调得很低,真的会把CPU烧坏,因为CPU会变得非常热。

And if you put that very low, you can really burn the CPU, I mean, because the CPU gets very hot.

Speaker 0

所以我们不能直接调用C语言。

And so we've you have a c you cannot call c directly.

Speaker 0

必须通过Lua来调用,只有Lua才有权限访问那个接口。

You must call Lua, and only Lua has access to that.

Speaker 0

所以如果你只能用Lua编程,Lua会先检查你给的数值是否精确,或者需要检查的其他东西,然后才会去调用。

So if you can only program in Lua, it says, oh, Lua, then you check whether the numbers you are giving are precise or whatever it has to check, and then it calls

Speaker 1

这有点像沙盒环境。

It's kind of like a sandbox environment.

Speaker 0

对,没错。

Yes, exactly.

Speaker 0

是的,沙盒这个词用得很准确。

Yes, sandbox is the exact word for that.

Speaker 1

我看到你好像和几个人一起写过一篇关于Lua历史的文章或者论文,里面有些挺有意思的引用,我想问问你。

I saw there was this, I guess, paper, or 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.

Speaker 1

其中有一条说,有个老笑话讲,骆驼就是委员会设计出来的马。

So one of them, it says that there's this old joke that says that a camel is a horse designed by a committee.

Speaker 0

是的。

Yes.

Speaker 0

那不是我的原创。

That's not mine.

Speaker 0

那是个老掉牙的笑话了。

That's a real old joke.

Speaker 1

那是不是意味着,你认为最好的编程语言应该由尽可能少的人来设计?

Does that mean that you think the best programming languages are designed by as few people as possible?

Speaker 0

是的。

Yes.

Speaker 0

我确实这么认为。

I do think.

Speaker 0

对。

Yes.

Speaker 0

因为有一点很容易观察到,那就是——

Because one thing that that it's easy to to observe is is is this.

展开剩余字幕(还有 229 条)
Speaker 0

如果是一个委员会来设计语言,每个人都想把自己喜欢的东西加进去。

If you have a committee writing a language, everyone wants to put something from themselves into the language.

Speaker 0

所以,你会有自己偏爱的机制,并且会不惜一切代价把它塞进语言里。

So you have that your favorite mechanism, and you will fight whatever it takes to put your favorite mechanism into the language.

Speaker 0

而很少有人会反对往语言里添加东西。

And very few people will fight against putting anything in the language.

Speaker 0

我的意思是,有些人会说,哦不,这太多了,太复杂了,但人们为自己想要的东西争取的劲头,远比反对添加东西要大得多。

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.

Speaker 0

所以,当有一个委员会时,趋势就是,哦,我们继续加东西吧,继续加东西吧,而且有时候,即使他们并不完全理解——我的意思是,他们不确定在场的每个人是否真的精通这门语言——但这又和别的部分吻合,比如,哦,我甚至不知道这门语言还有这个功能。

So when you have a committee, the tendency is, oh, let's keep adding stuff, let's keep adding stuff, and people sometimes, even though they don't understand, I mean, they're not sure if everybody there is really know the language well, but that fits with other parts of, oh, I didn't even know the language has this other part.

Speaker 0

所以,有些东西之间可能并不协调,等等。

So things sometimes do not fit together very well, etcetera.

Speaker 0

所以,首先你要有所谓的“概念完整性”。

So first you have what's called the conceptual integrity.

Speaker 0

这个概念就是说,所有东西都相互契合,每个部分在设计时都考虑到了其他部分,等等。

It's a name that gives that everything fits together, everything is designed with everything else in mind, etcetera.

Speaker 0

当然,我不是说Lua就没有问题,随着时间推移,难免会犯一些错误。

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.

Speaker 0

但如果是一小群人,彼此都清楚对方的想法,那就更容易把事情做对。

But it's much easier to get things to write if you have a small group of people that everybody knows what everybody else is thinking.

Speaker 0

我的意思是,你在决定是否往语言里加某个功能。

I mean, you are deciding whether to put something in the language or not.

Speaker 0

如果不加,后来再决定加进去,这很容易改变主意。

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.

Speaker 0

但如果加了,后来发现‘哎呀,这主意不好’,那就麻烦了。

Then to add something, and then later you decide, oh, I shouldn't have That was not a good idea.

Speaker 0

所以,拿不准的时候,我们的默认选择就是不加。

So when in doubt, our default is always, don't put it.

Speaker 0

如果不确定,就别加。

If you're not very sure, don't put it.

Speaker 0

以后随时可以再加,这样就能保留改变主意的余地。

We can always add that later, and so keep the door open to change your mind.

Speaker 1

我看到最初的Lua编程语言里没有布尔类型,这我以前从没见过。

I saw in the original Lua programming language that there was no boolean type, and I've never seen that before.

Speaker 1

为什么最初的Lua没有布尔类型呢?

Why was there no boolean in the original Lua?

Speaker 0

C语言就没有布尔类型。

C doesn't have booleans.

Speaker 0

我是说,最初的C语言一直到C99,都是用整数来表示的。

I mean, the original C and up to C99, they use integers.

Speaker 0

如果是零,就是假。

If it's zero, it's false.

Speaker 0

如果不是零,就是真。

If it's different from zero, it's true.

Speaker 0

大家用这种方式也过得挺好的。

And people lived quite well with with that lisp.

Speaker 0

而且有好几种语言都没有布尔类型。

And there are several languages that don't have booleans.

Speaker 0

实际上,我们在Lua里加入布尔类型,纯粹是为了表示假值。

And actually, we only put booleans in Lua because we want it false.

Speaker 0

在Lua里,真值完全没用。

True is completely useless in Lua.

Speaker 0

没人用真值。

Nobody use true.

Speaker 0

我是说,说没人用是开玩笑,但确实有点夸张。

I mean, nobody is a joke, but it's too strong.

Speaker 0

不过它确实不太实用。

But it's it's not very useful.

Speaker 0

你几乎可以用任何其他值来代替真值。

You could use almost any other value for true.

Speaker 0

但问题在于,在Lua里,那个特殊值nil,如果出现在表里,就相当于这个键不存在。

But the problem is that in Lua, new, that special value new, is in a table, it is equivalent to the key not being present.

Speaker 0

你总在想这个设计到底好不好,但它已经深深嵌入语言的设计中了,而且它有一个很强的概念:在作为关联数组的表里,不存在的键对应的值是nil。

You always 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 that is an associative array, it has a nil value.

Speaker 0

完全分不清它到底是不存在。

It's completely indistinguishable whether it's absent.

Speaker 0

我的意思是,不存在就意味着它的值是nil,而值是nil就意味着它不存在。

I mean, absent means it has a nil value, nil valent means it's absent.

Speaker 0

所以有时候你想存一个false值,但又想知道表里到底有没有这个键,因此我们需要一个false值。

And so sometimes you want to have a false value, but you want to know what is there in the table, and so we needed a false to have.

Speaker 0

你可以把false放进表里,这样它就和键不存在完全不同了。

A false you can put in the table, and it's completely different from being absent.

Speaker 0

你看,键是存在的,只是它的值是false。

You know, there is a key, and the key has a false value.

Speaker 0

所以我们确实需要一个false值。

So we need a false value.

Speaker 0

既然要有false,那加上true可能也说得通,虽然光有false没有true也行。

And if you're going to have a false, then we add the true to maybe it would make sense to have false without true.

Speaker 0

但有了true之后,它几乎没什么用。

But with true, it's almost useless.

Speaker 1

既然可以用1表示真,那为什么不用0表示假呢?

Why not use zero as false if you're okay with one as true?

Speaker 0

我们其实可以用,但那样的话,改动会非常大,因为之前不是这么设计的,这个特性是后来才加进语言的。

It we we could have used it, but that, among other things, that would be a a big change because exactly it didn't was that way, so we we added that later in the language.

Speaker 0

所以把0改成假的话,会带来很大的不兼容问题。

So changing zero to false would be a very big incompatibility.

Speaker 0

不过,比如说在Python里,很多东西都被视为假。

But it it could be, for instance, in Python, I think a lot of stuff are are false.

Speaker 0

对,0是假,空列表是假,空JavaScript对象也是假,我觉得那边更夸张。

I mean, zero is false, empty list is false, empty JavaScript, think it's even worse.

Speaker 0

具体细节我记不太清了,但说实话,这其实挺随意的。

I I don't don't recall exactly, but I mean, this is kind of arbitrary.

Speaker 0

比如说,我们也可以把nil、假、0、空字符串都视为假。

I mean, you you we could have, for instance, nil false zero empty string.

Speaker 0

这完全取决于你用什么方式来判断真假。

I mean, it it it just depends the kind of test that you use.

Speaker 0

在动态语言里,这很简单。

It's not in dynamic languages, it's very easy.

Speaker 1

Python 就像你说的那样,有真值和假值的概念。

Python has the like you're describing, the truth y values and the false y values.

Speaker 1

我觉得它们可以被当作假值来处理。

I guess they can be interpreted as false.

Speaker 1

但这更隐晦,没那么明确。

But it's more implicit, less explicit.

Speaker 1

而且我知道 JavaScript 在这方面走得更远,你可以做一些非常奇怪的事情,隐含着某种行为。

And I know JavaScript is even further on that spectrum where you can do some really weird stuff that implicitly has some behavior.

Speaker 1

你觉得这种设计方向是好还是坏?

Do you think that design direction is good or bad?

Speaker 0

这就像一个小而紧凑的东西,写起来更容易,但任何语言都需要平衡,几乎都是这样。

It's like a small compact, it's more easy to write stuff, and but you always have this balance in any language, it's almost anything.

Speaker 0

你越灵活,灵活性越大,保护就越少。

The more flexible you you the more flexibility you have, the less protection you have.

Speaker 0

在C语言里,也有类似的情况。

In c, you have something like like that.

Speaker 0

人们可能没注意到,但因为C语言是强类型的。

People do not notice, but because c is typed.

Speaker 0

但你可以检查一个整数是真是假。

But you can check whether an integer is true or false.

Speaker 0

你可以直接检查一个浮点数是真是假,因为它会判断这个浮点数是否为零。

You can check whether a float is true or false directly because, again, it checks whether the float is zero or different from zero.

Speaker 0

你可以检查一个指针是否为空,因为在C语言里,空指针就是零。

You can check whether a pointer is nil or different from lul because in c, lul is a magic zero.

Speaker 0

所以,如果你不写任何测试,它其实隐含了一个测试,就是判断是否不为零。

So it's kind of if you do not write any test, it has an implicit test, like, different from zero.

Speaker 0

而这个零可以是整数、浮点数,也可以是指针。

And this zero can be a integer, can be a float, can be a pointer.

Speaker 0

所以C语言其实也有这种灵活性。

So in c also, you have this kind of flexibility.

Speaker 0

只是你需要更明确一些。

It's just that you have to be more explicit.

Speaker 0

通常这能避免错误,但就是这样,你总得在易于编写和容易出错之间权衡。

Usually, these avoids errors, but so this you have always this balance between easy to write and easy to make mistakes.

Speaker 1

我看到Lua是从1开始索引而不是0,我之前从没见过这样的编程语言。

I saw that Lua is one indexed instead of zero indexed, and I had never seen a programming language like that in my experience.

Speaker 0

其实有很多编程语言都是这样的。

There was a lot of programming languages like that.

Speaker 1

那为什么它是从1开始索引呢?

So, yeah, why is it one indexed?

Speaker 0

因为现实世界中的事物都是从1开始编号的。

Because everything in the real world are one indexed.

Speaker 0

比如一本书,有第一章、第二章,没人会把章节编号成第零章、第一章、第二章、第三章。

If you have a book, you have this chapter one, chapter two, nobody number chapters as zero, one, two, three.

Speaker 0

所有程序员,甚至数学家,如果你拿一本数学书,任何序列都是a1、a2、a3这样的。

All the programmers are the only even mathematicians, if you got a mathematic book, a book of mathematic, any sequence, it's a one and a two, a three.

Speaker 0

比如矩阵,第一个元素是(1,1)、(1,2),然后所有东西都按这个顺序写。

If you get a matrix, the first element is a one one, a one two, and then a, everything is written before.

Speaker 0

只有在编程语言里才有从零开始这种概念。

Only in programming language that is this idea of zero.

Speaker 0

最有趣的是,比如Fortran,现在是很古老的语言了,但它从1开始索引;而在Pascal里,你可以自己选。

And the funniest part is that, for instance, Fortran, that now it's it's very old language, but to index it from one, in Pascal, you can choose.

Speaker 0

就是说,你写一个数组,可以指定它从-5到5索引。

I mean, you write an array, you can say this array is indexed from minus five to five.

Speaker 0

所以它可以从你想要的任何值开始,到你想要的任何值结束。

And so it's it's indexed from whatever value you want to whatever value you want.

Speaker 0

从零开始之所以变得极其流行,是因为C语言。

Zero became extremely popular because of C.

Speaker 0

C语言用了从零开始,然后很多语言都跟着学。

C used zero and a lot of languages copied.

Speaker 0

我其实也是受了C语言的影响。

I I kind of inspired by by by C.

Speaker 0

它们有相同的运算符和表达式语法。

They have the same operators, the same syntax for expressions.

Speaker 0

比如布尔运算符,这在标准数学里是没有的。

The Boolean operators, for instance, that is not standard mathematics.

Speaker 0

几乎所有语言都选择了和C语言一样的运算符写法。

Almost all languages chose the same operators as they are written in c.

Speaker 0

所以很多语言都模仿了C,然后从零开始索引就变得非常流行。

And so a lot lot of language copied c and then zero index became very popular.

Speaker 0

有趣的是,在C语言里其实并没有真正的索引。

And what is funny is that in c, there is no indexing.

Speaker 0

C语言里的索引只是一种假象,因为实际上你用的是指针运算。

In c indexing is just an illusion because what you have is point error arithmetic.

Speaker 0

在C语言里,当你写A[I]的时候,实际上是在说取A加上I这个地址的内容。

And C when you write A indexed by I, actually what you are saying get the contents of A plus Y.

Speaker 0

因为C语言没有索引,只有位移或者偏移量,所以它必须从零开始索引,因为第一个元素就在原始地址上。

And so because in seed you don't have indexing, you have displacements or deltas, I don't know how, 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.

Speaker 0

所以C语言其实没有索引。

So c doesn't have indexing.

Speaker 0

所以当你说它从零开始索引,其实它并不是从零开始索引,因为它根本就没有索引这回事。

So when you say it's indexed by zero, it doesn't index by zero because it doesn't index by anything.

Speaker 0

但它给人一种有索引的错觉,然后这个错觉就很容易被传递下去。

But it have this illusion of indexing, and then it's easy to send that in.

Speaker 0

然后很多不使用指针运算、没有这种限制和语义的语言,也照搬了C语言,保留了零索引这个特性。

And then a lot of language that do not use pointer arithmetic, do not have this restriction, do not have this semantics, copied c and kept the zero indexing as this thing.

Speaker 0

如果你找一个12岁的孩子,试着跟他们解释零索引,我敢说他们更容易理解“我有一个列表,第一个元素”这种说法。

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.

Speaker 0

我经常开玩笑说,第一个元素是零,你写“第一个”的时候指的是“一”,但第一个元素“一”并不是一,而是零。

I always joke that the first element is zero, and you write first you for one, but the first element one is not one, it's zero.

Speaker 0

所以零索引确实有它的好处。

So it has advantages zero.

Speaker 0

对于某些特定的运算,比如数学上的循环缓冲区,零索引就更合适。

For for some specific operators, mathematically, for instance, you want to do a circular buffer, zero is better.

Speaker 0

虽然有一些小优势,但这样会让人更加困惑。

There are some small advantages, it's much, much more confusing.

Speaker 0

而且Lua的理念是面向终端用户编程,我们经常开玩笑说,让非程序员的生活更轻松才是正道。

And as Lua has this idea of end user programming, we always joke it's much easier to make life easier for the non programmers.

Speaker 0

我相信程序员能适应任何索引方式,毕竟他们算是专业人士。

And I am sure that programmers can program whatever index they have to do because they are, supposedly they are professional.

Speaker 0

他们可以学会从1开始索引,而不是把从0开始索引的负担强加给终端用户。

They can learn that indexing from them to put all the end user the burden of using something completely different from them indexing by zero.

Speaker 0

元素索引为0到底是什么意思?

What does it mean, the element index zero?

Speaker 0

他们从没见过哪本书的章节是从0开始的。

They never saw the chapters in the BOYAS.

Speaker 0

第一章是第0章,第二章是第1章?

The first chapter is at zero, the second chapter is at one.

Speaker 0

不,我没在开玩笑。

No, I'm not joking.

Speaker 0

当你试图向非程序员解释这个,甚至不需要是12岁的孩子。

When you try to explain that to non programmers, even don't need to be 12 year olds.

Speaker 0

我是说,随便找个不是互联网程序员的人,想想,哦,我完全明白,我是说,你已经成年了。

I mean, just get anyone that is not Internet programmer, think, oh, I have the absolute I mean, you're grown up.

Speaker 0

你,我是说,好吧,你是个基督徒。

You are, I mean, okay, you are a Christian.

Speaker 0

你,如果你不确定,你可以学习用1或-1或任何基数编程,我相信你一定能学会。

You are, if you're unsure, you can learn to program with one or minus one or whatever it is, base you have to use, I'm sure.

Speaker 1

但你觉得你会看到很多bug吗?

But do you think you see a lot of bugs?

Speaker 1

因为可能有人以为它是从0开始的。

Because maybe someone thinks it's zero.

Speaker 0

不幸的是,我确实看到一些bug。

Unfortunately, I see some bugs.

Speaker 0

但就像我一直说的,那种bug恰恰说明你连最基本的测试都没做,因为那种bug不是那种你尝试对数组做任何操作时总会遇到的bug。

But as I always say, that's the kind of bugs that just shows that you didn't do minimum testing because that kind of bug is not the kind of that kind of bug that always you try to anything you try to do in an array.

Speaker 0

不管你是从零开始还是从一开始,都会出bug。

If you start from zero or start from one, you have a bug.

Speaker 0

所以,最简单的测试方法就是,任何跟数组、列表相关的东西,你都能想到去测一下。

So the the most simple test that you can imagine to test anything related to an array to a list, etcetera.

Speaker 0

如果你把零和一搞混了,你就能发现这个问题。

And if mistake zero to one, you you detect that.

Speaker 0

所以,如果你有这种bug,那只能说明你根本没测试过那段代码。

So if you have that kind of bug, it just shows that you didn't test that code at all.

Speaker 1

你之前有个演讲,讲的是给Lua加语言特性的成本,以及很多隐藏成本。

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.

Speaker 1

我觉得现在,由于AI代码生成或者大语言模型,软件的实现成本正在下降。

I think today implementation costs of software is going down due to AI code generation or LLMs.

Speaker 1

我想知道,这是否会改变你对给编程语言添加特性成本的看法。

And I was wondering if that changes your thinking on, I guess, the cost of adding features to a programming language.

Speaker 0

AI这个东西,我们真的不知道未来会怎样。

AI is something that we don't really know what is going to happen.

Speaker 0

如果走向极端,完全有可能我们不再需要编程语言。

If you go to an extreme, it's completely feasible that we won't have programming languages.

Speaker 0

我的意思是,如果人工智能能帮你写所有代码、检查所有代码、做所有事情,那么几年后,也许我们就不需要编程了。

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.

Speaker 0

人工智能可以直接写机器码,它不需要编程语言。

AI can write machine code directly, it doesn't need programming languages.

Speaker 0

对它们来说,直接编译甚至生成代码更容易。

It's easier for them to compile or even generate the code directly.

Speaker 0

我是说,我不知道几年后会发生什么。

I mean, I don't know what's going to happen in a few years.

Speaker 0

所以我觉得很难谈论人工智能,因为我自己——而且我觉得没人——有清晰的想法。人们可能对一两年后的事有概念,但五年后,任何说‘五年后一定会这样’的人,都只是在猜测。

So I think it's very hard for me to talk anything about AI because I have, and I think nobody have a clear idea what, I mean, people have a, 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.

Speaker 0

所以我觉得很难说什么。

So I I think it's hard to to say anything.

Speaker 0

这一切都是因为人工智能。

This is all because of AI.

Speaker 0

所以,意思还是那个意思,但这里还是存在一些差异。

So keeping the meaning, I mean, that is still have differences there.

Speaker 0

哦,那为什么还要用编程语言呢?

Oh, why you still use programming languages?

Speaker 0

因为如果你希望用户或者某些人能够检查AI生成的结果等等。

Because if you want the user or the some human to be able to check the result of what the AI is doing, etcetera.

Speaker 0

所以我仍然认为,编程语言的大部分特性还是成立的。

So I still think that most of the things about programming language still hold.

Speaker 0

比如说,你理解代码的复杂度——AI给你生成了一段代码,然后你真的要弄明白那段代码在做什么。

For instance, the the cost of complexity of you understanding, I mean, AI create a code for you and then you really understanding what that code does.

Speaker 0

我觉得这反而更糟糕了。

I mean, it's even worse.

Speaker 0

我是说,语言更应该清晰明了,不能有隐藏机制,因为AI可能会使用隐藏机制,它没有这个概念。

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.

Speaker 0

哦,那对人类来说就很难理解这里到底发生了什么——比如,哦,我可以这么用,但我肯定得在这加个注释,因为我敢肯定,一个月后有人读到这段代码肯定看不懂。

Oh, that will be difficult for a human to understand that what is really happening here is something that 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 is not going to understand.

Speaker 0

EA没有那种思维方式,所以你就直接用了那个技巧或那个东西。

EA doesn't have that kind of thinking, and so you just use that trick or that thing.

Speaker 0

所以如果你考虑AI生成代码这个想法,我认为语言更简单、更易理解就变得更加重要了,这样你才能真正理解你看到的代码是否如你所想的那样运行。

And it's so 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 do.

Speaker 0

真正理解代码在做什么。

Really understand what the code is doing.

Speaker 0

所以简洁性这一点,我觉得非常重要。

So this thing about simplicity, think it's very important.

Speaker 0

至于其他方面,也许我可以简化文档,但我不确定是否需要概念完整性这种东西,比如让所有东西都保持一致、合理等等。

And I think the other parts, maybe I may facilitate documentation, I'm not sure if I need this thing about conceptual integrity, for instance, to keep things all that makes sense, etcetera.

Speaker 0

我真的认为,主要成本之一是你给用户带来的负担,让他们多学一个关于你语言的东西。

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.

Speaker 0

所以还有其他成本。

So there's the other costs.

Speaker 0

不过话说回来,实现部分确实是AI能真正帮上忙的地方。

Have said that implementation is the part that AI can really help you.

Speaker 0

这其实并不是一个特别重要的成本。

It's not a really important cost.

Speaker 1

如果从简单到复杂这个范围来看,你觉得哪些编程语言是最简单的,容易理解、副作用少、不容易让人困惑?

If you think about a spectrum of simple to complex, what programming languages are the most simple ones that you think of, the easy to understand, less confusing side effects?

Speaker 1

哪些编程语言又是最复杂的,最容易让人踩坑?

And what programming languages are the most complex and have the most foot guns?

Speaker 0

有句名言,不知道是谁说的,就是‘尽可能简单,但不要过于简单’,因为如果你追求极致的简单,比如像lambda演算或图灵机那样,确实很简单。

This famous quote, 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 say, oh, that's really simple.

Speaker 0

但问题是,这种简单的东西根本没法用来写任何程序。

I mean, this is really simple, but it's completely impossible to to write any program in that.

Speaker 0

所以说,如果太简单了,极端情况就是这样,但你肯定不想走到那一步。

I mean, if you have really simple stuff, I think the extremes will be like that, but you don't want to be there.

Speaker 0

而另一边,我觉得C++就是一个很好的例子,它真的非常非常复杂。

But to the other side, think C plus plus I think is a good example of a language that I think it's really, really complex.

Speaker 1

一个经常被问到的问题是,既然人工智能发展这么快,你现在还会推荐人们去学计算机科学吗?

A question that comes up a lot is, given how much AI has been progressing, would you still recommend people learn computer science today?

Speaker 0

如果你仔细想想这个问题,真的很难建议别人为了职业去学任何东西。

If you really think about that, it's really difficult to recommend people learning anything for a profession.

Speaker 0

我的意思是,我们完全不知道五年后人工智能会发展成什么样。

I mean, we have no idea what AI will do in five years.

Speaker 0

如果有人现在上大学,他们要四年、五年,或者至少三年、三年半才能毕业,谁也不知道四年后的世界和职业会是什么样子。

If someone is entering university now, they're going to graduate in four years, five years, or minimum three, three and a half years, nobody have any idea what the world is, profession will be like in four years from now.

Speaker 0

所以很难说,哦,是的,还是值得推荐,因为现在人们会说,哦,不,重复性任务AI很擅长,但你仍然需要整个架构,需要软件工程师来把握大局等等。

So it's really hard to say, oh yes, still going to admit, because now people say, oh no, manual tasks, the AI is very good, but you still need the whole architecture, you need like a software engineer to see the big picture, etcetera.

Speaker 0

但那是现在的情况,你根本不知道四五年后是否还会如此。

That it's now, but you have no idea that that will be true in four years or five years.

Speaker 0

所以我看,而且我本人也很喜欢编程。

So I see, and I like, I enjoy programming.

Speaker 0

我可以做,有些人会说,哦,用AI来写AI程序,因为我喜欢那样。

I could do, I mean, some people say, oh, use AI for the AI program because I like that.

Speaker 0

所以如果你选择自己喜欢的事情,但对我们来说,你真正要考虑的是,我该怎么靠这个谋生?

So if choose something that you like, but really for us, you're really thinking how am I going to live with that?

Speaker 0

我也不清楚。

I have no idea.

Speaker 0

我觉得现在真的是很难选择职业的时候。

It's really I think it's a really hard time to be choosing a profession.

Speaker 1

对。

Yeah.

Speaker 1

你在Lua上工作了那么久。

Mean, you've worked on Lua for such a long time.

Speaker 1

回顾过去,你觉得哪些地方做得好,哪些地方不太顺利?

When you look back on it, what went well and what didn't go well?

Speaker 0

我们有个优势,就是不用去满足客户的需求。

We had this privilege of not having to satisfy clients.

Speaker 0

所以就像我说的,比如你可以选择给语言加个功能,因为你没有那种压力。

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.

Speaker 0

比如‘哦,我们非得要这个功能,不管怎样都得做’之类的。

Oh, we need that feature, whatever it takes or etcetera.

Speaker 0

所以我们有这个特权,就是不确定要不要加某个功能。

So we have this privilege of, oh, we are not sure whether to put that.

Speaker 0

那就不加。

We don't put that.

Speaker 0

我们可以等一年左右,我觉得这样更容易做出一个优秀、漂亮的项目。

We can wait one year or so I think that it's it's much easier to do a good project, a beautiful project.

Speaker 0

所以我不确定这算是个建议。

So I'm not I'm not sure this is a recommendation.

Speaker 0

尽量在压力不大的环境下工作。

Try to work with without much pressure.

Speaker 0

但人们通常没有这种选择。

People usually do not have this choice.

Speaker 1

你在开发编程语言时,用什么来衡量成功?

What was your measure of success if you're working on a programming language?

Speaker 1

比如,你怎么知道它好不好?

Like, you know, how did you know it was good?

Speaker 0

有时候,我觉得得到我认可的那些优秀人士的肯定,比得到一大群我不认识的人的认可更重要。

It's more important to read 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, etcetera.

Speaker 0

所以我认为,现在网络上那种以数量为标准的衡量方式,

So I think this metric of quantity that is the standard metric nowadays in the web.

Speaker 0

已经变得很糟糕了,一切都只看粉丝数,不在乎关注你的人是谁,只追求数量越多越好。

It's got much worse and everything is just the number of follows that me doesn't care who is following you, just as many people as possible.

Speaker 0

所以对我来说,有时候,一个我真正敬佩的人对Lua说几句好话,比我们有多少用户更重要。

So sometimes for me it's much more important if someone that I really admire of seeing all this that say something good about Lua, then, oh, we have that many.

Speaker 0

当然,有一定的用户数量和知名度也是好事,但我觉得这需要平衡。

But, 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 these.

Speaker 1

你建议人们通过学习其他编程语言来提升编程能力吗?

Do you recommend people study other programming languages to get better at programming?

Speaker 1

那么问题来了,你认为到2026年,每个工程师为了提升编程能力,应该学习哪三种编程语言?

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

Speaker 0

我觉得Haskell是一门非常棒的语言。

Haskell, I think, is an incredible language.

Speaker 0

它包含了学习函数式编程所需的一切。

Has everything you need to really learn about functional programming.

Speaker 0

我觉得最大的好处之一是,Haskell社区有个老笑话:如果你用Haskell和C语言写程序,用C的话,花一周时间让程序跑得快,然后花一年时间让它正确;

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 in Haskell and in c, in c, we'll spend one week to make it efficient, and then you spend one year to make it correct.

Speaker 0

而在Haskell里,你花一周时间让程序正确,然后可能花一年时间让它跑得快。

In Haskell, you spend one week to make it correct, and then you may spend one year to make it efficient.

Speaker 0

当然,这不是我编的笑话,但里面有些道理,虽然不总是成立,不过我觉得它点出了核心。

Again, it's not my joke, but I it has some truths not gonna be always true, etcetera, but I think it gives the the idea.

Speaker 0

我认为这可能是Haskell最重要的一课。

I think this is maybe the the the main the most important lesson of Haskell.

Speaker 0

但Haskell还有很多其他优点,比如类型推断——整个语言中类型都是可选的,但它却能推断出所有类型。

But Haskell has many other this thing about type inference, for instance, the entire language is types are optional everywhere, and yet it can do type inference for everything.

Speaker 0

它能正确推断出类型,等等。

It can infer the types correctly, etcetera.

Speaker 0

C语言或者某种底层语言。

C or some low language.

Speaker 0

我的意思是,你还需要学一些汇编语言或者C语言,但现在汇编语言已经变得太复杂了。

I mean, you can also have to learn some assembler or to see you, but assemblers now are becoming too much complex.

Speaker 0

最好是学像8086汇编这种非常古老的汇编语言,这样才能真正理解机器在做什么,它是如何在最底层运作的,从而建立起这种认知。

It would be to learn like the the eighty eighty assembler, very old assembler of a very 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.

Speaker 0

SCIM是我非常喜欢的一门语言,因为它那种经济的概念设计。

SCIM is a language that I I like very much because of this executive this economy of of ideas.

Speaker 0

它的概念非常少,却能用很少的概念做出一些令人惊叹的事情。

There are very few concepts, and it can do some amazing things with with very few concepts.

Speaker 0

有一门语言非常非常古老,但我仍然觉得它很出色。

One language that this is very, very, very old, but I still think it is snowball.

Speaker 0

我认为它是最早拥有模式匹配和这种处理方式的语言之一,它的模式匹配能力真的很强。

I think one of the first languages to have pattern matching and this idea of doing a I mean, it's really strong patterns, etcetera.

Speaker 0

我觉得有时候看看老语言是件好事,因为现在很多语言,就像我说的,都复制了从零开始索引这种特性,但很多方面它们变得太同质化了。

And I think it's in sometimes it's to see old languages because exactly nowadays, a lot of language tend to, like I said, the zero index ing that they copy, but a lot of they tend to be too uniform in some aspect.

Speaker 0

看看一些老语言挺有意思的,它们有些想法可能甚至不是好主意,但确实很有趣。

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

Speaker 1

最后一个问题,以你现在的经验来看,如果能回到刚入行的时候,给自己一些建议,你会说什么?

Last question for you is, you know, 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?

Speaker 0

要真正掌握很多东西,你就得花大量时间去学习。

To know a lot of stuff, you really have to study a lot of stuff.

Speaker 0

这需要时间。

Takes time.

Speaker 0

我经常拿这个开玩笑。

Also joke about that.

Speaker 0

有人说,三十分钟学会Lua,五分钟学会Python,我总说,想学编程,得花五年时间。

People say, oh, learn Lua in thirty minutes or learn Python in five minutes or and I always say that they wanted to learn programming in five years.

Speaker 0

这才是真正的学习,慢慢来,你得一点一点去学。

That's really learn, take your time, you have to learn that and that.

Speaker 0

要学的东西太多了。

That is a lot of stuff stuff to learn.

Speaker 0

没有捷径可走。

There is no magic.

Speaker 0

没有捷径,你真的得学很多东西,我是说,各种各样的东西。

There is no you really have to learn, I mean, a lot of different things.

Speaker 1

教授,非常感谢您抽出时间。

Thank you so much for your time, professor.

Speaker 1

我真的很感激。

I really appreciate it.

Speaker 1

这次聊得很开心。

It was a lot of fun.

Speaker 0

谢谢。

Thank you.

Speaker 0

这是我的荣幸。

It's my pleasure.

Speaker 1

嘿,感谢你收看这期播客。

Hey, thank you for watching this podcast.

Speaker 1

如果你喜欢这期节目,想看到它越做越好,请点赞或留言支持一下。

If you liked it and you want to see the show grow, please support with a comment or a like.

Speaker 1

另外,如果你有想让我邀请的嘉宾推荐,也请留言告诉我。

Also, if you have any recommendations for people you want me to bring on, please drop a comment.

Speaker 1

像芭芭拉·利斯考夫、迈克·斯通布雷克、马克·布鲁克这些人,都是因为有人留言推荐,我才请来的。

Guests like Barbara Liszkoff, Mike Stonebreaker, Mark Brooker, these were all people that I brought on because someone left a comment.

Speaker 1

另外,除了播客之外,我还在开发一款我一直想要的人体工学键盘。

On another note, aside from the podcast, I'm working on building the ergonomic keyboard that I wish existed.

Speaker 1

这是原型机的样子。

Here's a glance at the prototype.

Speaker 1

这是一款分体式键盘,所以分成左右两部分。

It's a split keyboard, so there's two sides.

Speaker 1

这个还不是最终的外壳。

This isn't the case.

Speaker 1

对,我们在Kickstarter上发起了众筹,上线八小时内就达成了目标。

But, yeah, we launched on Kickstarter, and we hit our goal within eight hours of launching.

Speaker 1

如果你是最早入手的那批人之一,我真的很感激。

I really appreciate it if you were one of the people who grabbed one of the early units.

Speaker 1

我们现在正忙着搭建生产工具,这是个漫长的过程。

We're now working on the long journey of building the tooling now.

Speaker 1

如果你还想入手一个,我在Kickstarter上保留了后期支持通道。

And so if you still wanna pick one up, I've left the late pledges open on Kickstarter.

Speaker 1

你可以在那里下单。

So you can grab one there.

Speaker 1

我会把链接放在视频描述里。

I'll put a link in the description.

Speaker 1

再次感谢你收看这期播客,我们下期再见。

Thank you again for watching the podcast, and I'll see you in the next episode.

关于 Bayt 播客

Bayt 提供中文+原文双语音频和字幕,帮助你打破语言障碍,轻松听懂全球优质播客。

继续浏览更多播客