• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

vs2019 lua_Lua在莫斯科2019:采访Roberto Ierusalimschy

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

vs2019 lua

Some time ago, the creator of Lua programming language, Roberto Ierusalimschy, visited our Moscow office. We asked him some questions that we prepared with the participation of Habr.com users also. And finally, we’d like to share full-text version of this interview.

不久前,Lua编程语言的创建者Roberto Ierusalimschy访问了我们的莫斯科办事处。 我们还问了他一些在Habr.com用户参与下准备的问题。 最后,我们想分享这次采访的全文。

-让我们从一些哲学问题开始。 想象一下,如果您从头开始重新创建Lua,那么您将在Lua中更改哪三件事? (— Let’s start with some philosophical matters. Imagine, if you recreated Lua from scratch, which three things would you change in Lua?)

— Wow! That’s a difficult question. There’s so much history embedded in the creation and development of the language. It was not like a big decision at once. There are some regrets, several of which I had a chance to correct over the years. People complain about that all the time because of compatibility. We did it several times. I’m only thinking of small things.

- 哇! 这是一个难题。 在语言的创建和开发中嵌入了太多的历史。 这不是一次重大的决定。 有一些遗憾,这些年来我有机会纠正了其中的一些遗憾。 人们总是因为兼容性而抱怨。 我们做了几次。 我只是在想小事情。

—默认情况下是全局的吗? 您认为这是这样吗? (— Global-by-default? Do you think this is the way?)

— Maybe. But it’s very difficult for dynamic languages. Maybe the solution will be to have no defaults at all, but would be hard to use variables then.

- 也许。 但是对于动态语言而言,这非常困难。 也许解决方案将是完全没有默认值,但是那时将很难使用变量。

For instance, you would have to somehow declare all the standard libraries. You want a one-liner, print(sin(x)), and then you’ll have to declare ‘print’ and also declare ‘sin’. So it’s kinda strange to have declarations for that kind of very short scripts.

例如,您将不得不以某种方式声明所有标准库。 您需要一个单行的print(sin(x)) ,然后您必须声明'print'并且还要声明'sin'。 因此,对于这种非常短的脚本进行声明有点奇怪。

Anything larger should have no defaults, I think. Local-by-default is not the solution, it does not exist. It’s only for assignments, not for usage. Something we assign, and then we use and then assign, and there’s some error — completely mystifying.

我认为,任何较大的值都应该没有默认值。 默认情况下不是本地解决方案,它不存在。 它仅用于分配,不用于使用。 我们分配的东西,然后我们使用然后分配,这有一些错误-完全是神秘的。

Maybe global-by-default is not perfect, but for sure local-by-default is not a solution. I think some kind of declaration, maybe optional declaration… We had this proposal a lot of times — some kind of global declaration. But in the end, I think the problem is that people start asking for more and more and we give up.

也许默认情况下的全局不是完美的,但是可以肯定的是默认情况下的本地不是解决方案。 我认为是某种声明,也许是可选声明…我们很多时候都提出过这项提案-某种全球声明。 但最终,我认为问题在于人们开始要求越来越多,而我们却放弃了。

(sarcastically) Yes, we are going to put some global declaration — add that and that and that, put that out, and in the end we understand the final conclusion will not satisfy most people and we will not put all the options everybody wants, so we don’t put anything. In the end, strict mode is a reasonable compromise.

(讽刺地)是的,我们将提出一些全球性声明-加上那个,那个和那个,把那个排除在外,最后我们知道最终结论不会满足大多数人的意愿,我们也不会提出每个人想要的所有选择,所以我们什么都不要放 最后,严格模式是一个合理的折衷方案。

There is this problem: more often than not we’re using fields inside the modules for instance, then you have the same problems again. It’s just one very specific case of mistakes the general solution should probably include. So I think if you really want that, you should use a statically typed language.

这是一个问题:例如,我们经常在模块内部使用字段,那么您再次遇到相同的问题。 这只是一般解决方案可能包含的错误的一种非常特殊的情况。 因此,我认为,如果您确实希望这样做,则应使用静态类型的语言。

—默认情况下,全局也适用于小型配置文件。 (— Global-by-default is also nice for small configuration files. )

— Yes, exactly, for small scripts and so on.

—是的,确切地说,适用于小型脚本等。

—这里没有权衡? (— No tradeoffs here?)

— No, there are always tradeoffs. There’s a tradeoff between small scripts and real programs or something like that.

—不,总会有取舍。 在小脚本和真实程序之间或类似的东西之间要权衡。

—因此,我们回到第一个大问题:如果有机会,您将改变三件事。 如我所见,您对我们现在拥有的产品感到非常满意,对吗? (— So, we’re getting back to the first big question: three things you would change if you had the chance. As I see it, you are quite happy with what we have now, is that right?)

— Well, it’s not a big change, but still… Our bad debt that became a big change is nils in tables. It’s something I really regret. I did that kind of implementation, a kind of hack… Did you see what I did? I sent a version of Lua about six months or a year ago that had nils in tables.

—好吧,这不是什么大的变化,但仍然……我们的坏账变成了大的变化,现在桌子上几乎没有。 我真的很后悔。 我做了那种实现,一种骇客……你知道我做了什么吗? 我发送了大约六个月或一年以前的Lua版本,该版本的表中没有任何内容。

零值? (— Nil values?)

— Exactly. I think it was called nils in tables — what’s called null. We did some hack in the grammar to make it somewhat compatible.

—没错。 我认为它在表中被称为nils-称为null。 我们在语法上做了一些改动,以使其在某种程度上兼容。

—为什么需要它? (— Why is it needed?)

— I’m really convinced that this is a whole problem of holes… I think that most problems of nils in arrays would disappear, if we could have [nils in tables]… Because the exact problem is not nils in arrays. People say we can’t have nils in arrays, so we should have arrays separated from tables. But the real problem is that we can’t have nils in tables! So the problem is with the tables, not the way we represent arrays. If we could have nils in tables, then we would have nils in arrays without anything else. So this is something I really regret, and many people don’t understand how things would change if Lua allowed nils in tables.

—我真的坚信这是一个完整的漏洞问题……我认为,如果我们可以[表中的nil],大多数数组中nil的问题都会消失……因为确切的问题不是数组中的nils。 人们说我们不能在数组中使用零,因此我们应该将数组与表分开。 但是真正的问题是我们不能在表中有nil! 因此,问题出在表上,而不是我们表示数组的方式。 如果我们可以在表中使用nil,那么我们将在数组中使用nil,而无需其他任何操作。 因此,我对此感到非常遗憾,而且很多人不了解,如果Lua允许在表中使用nil,事情将会如何改变。

-我可以告诉您一个有关Tarantool的故事吗? 实际上,我们有自己的null实现,它是null指针的CDATA。 我们在需要内存空间的地方使用它。 在进行远程调用等时填充位置参数。 但是我们通常会遭受痛苦,因为CDATA始终会转换为“ true”。 因此,数组中的nils可以解决很多问题。 (— May I tell you a story about Tarantool? We actually have our own implementation of null, which is a CDATA to a null-pointer. We use it where gaps in memory are required. To fill positional arguments when we make remote calls and so on. But we usually suffer from it because CDATA is always converted to ‘true’. So nils in arrays would solve a lot of our problems. )

— Yeah, I know. That’s exactly my point — this would solve a lot of problems for a lot of people, but there’s a big problem of compatibility. We don’t have the energy to release a version that is so incompatible and then break the community and have different documentation for Lua 5 and Lua 6 etc. But maybe one day we’ll release it. But it’s a really big change. I think it should have been like that since the beginning — if it was, it would be a trivial change in the language, except for compatibility. It breaks a lot of programs, in very subtle ways.

- 是的,我知道。 这正是我的观点-这将为很多人解决很多问题,但是兼容性存在很大的问题。 我们没有能力发布如此不兼容的版本,然后破坏社区并为Lua 5和Lua 6等提供不同的文档。但是也许有一天我们会发布它。 但这是一个很大的变化。 我认为从一开始就应该是这样的-如果是这样,除了兼容性之外,这将是该语言的一个小改变。 它以非常微妙的方式破坏了许多程序。

—除了兼容性,还有什么缺点? (— What are the downsides except for compatibility?)

— Besides compatibility, the downside is that we would need two new operations, two new functions. Like ‘delete key’, because assigning nil would not delete the key, so we would have a kind of primitive operation to delete the key and really remove it from the table. And ‘test’ to check where exactly to distinguish between nil and absent. So we need two primitive functions.

—除了兼容性之外,缺点是我们需要两个新操作,两个新功能。 就像“删除键”一样,因为分配nil不会删除键,所以我们将有一种原始操作来删除键并将其真正从表中删除。 并进行“测试”以检查准确区分零和缺失的位置。 因此,我们需要两个原始函数。

—您是否分析了这对实际实施的影响? (— Have you analyzed the impact of this on real implementations?)

— Yes, we released a version of Lua with that. And as I said, it breaks code in many subtle ways. There are people who do table.insert(f(x)) — a call to a function. And it’s on purpose, it’s by design that when a function doesn’t want to insert anything, it returns nil. So instead of a separate check «do I want to insert?», then I call a table.insert, and knowing that if it’s nil, it won’t be inserted. As everything in every language, a bug becomes a feature, and people use the feature — but if you change it, you break the code.

—是的,我们发布了Lua的版本。 正如我所说,它以许多微妙的方式破坏了代码。 有人在做table.insert(f(x))-对函数的调用。 它是有意设计的,当一个函数不想插入任何东西时,它返回nil。 因此,而不是单独检查“我是否要插入?”,而是调用table.insert,并知道如果它为nil,则不会插入它。 由于每种语言的所有内容都将成为一个功能,一个错误就会被人们使用,但是如果您更改它,则会破坏代码。

—新的void类型呢? 像零,但无效? (— What about a new void type? Like nil, but void?)

— Oh no, this is a nightmare. You just postpone the problem, if you put another, then you need another and another and another. That’s not the solution. The main problem — well, not main, but one of the problems — is that nil is already ingrained in a lot of places in the language. For instance, a very typical example. We say: you should avoid nils in arrays, holes. But then we have functions that return nil and something after nil, so we get an error code. So that construction itself assumes what nil represents… For instance, if I want to make a list of returns of that function, just to capture all of these returns.

哦,不,这是一场噩梦。 您只是推迟了问题,如果您提出了另一个问题,那么您将需要另一个问题。 那不是解决方案。 主要问题(不是主要问题,而是主要问题)是在该语言的许多地方已经根深蒂固。 例如,一个非常典型的例子。 我们说:您应该避免在数组,Kong中使用nil。 但是然后我们有了返回nil以及nil之后的函数,因此我们得到了一个错误代码。 这样,构造本身就假设nil代表什么……例如,如果我要列出该函数的返回值列表,则只是要捕获所有这些返回值。

-这就是为什么要这么做。 :) (— That’s why you have a hack for that. :))

— Exactly, but you don’t have to use hacks for so primitive and obvious [issue]. But the way the libraries are built… I once thought of that — maybe the libraries should return false instead of nil — but it’s a half-cooked solution, it solves only a small part of the problem. The real problem, as I said, is that we should have nils in tables. If not, maybe we should not use nils as frequently as we do now. It’s all kinda messy. So if you create a void, these functions would still return a nil, and we’d still have this problem unless we create a new type and the functions would return void instead of nil.

—的确如此,但是您不必针对如此原始而显而易见的[问题]使用hack。 但是库的构建方式……我曾经想到过-也许库应该返回false而不是nil-但这是半熟的解决方案,它只能解决一小部分问题。 就像我说的那样,真正的问题是我们应该在表中使用nil。 如果没有,也许我们不应该像现在这样频繁地使用nils。 都有些混乱。 因此,如果创建一个void,这些函数仍将返回nil,除非创建新类型并且这些函数将返回void而不是nil,否则我们仍然会遇到这个问题。

—可以使用Void明确地告知该**应保存在一个表中—具有空值的**。 而且nil可以像以前一样行动。 (— Void could be used to explicitly tell that the key should be kept in a table — key with a void value. And nil can act as before. )

— Yes, that’s what I mean. All the functions in the libraries should return void or nil.

—是的,这就是我的意思。 库中的所有函数应返回void或nil。

—他们仍然可以返回nil,为什么不呢? (— They can still return nil, why not?)

— Because we’d still have the problem that you cannot capture some functions.

—因为我们仍然遇到无法捕获某些功能的问题。

—但是不会有第一把钥匙,只有第二把钥匙。 (— But there won’t be a first key, only a second key.)

— No, there won’t be a second key, because the counting will be wrong and you’ll have a hole in the array.

—不,不会有第二个键,因为计数将是错误的,并且阵列中将有一个Kong。

—是的,那么您是说您需要一种错误的元方法吗? (— Yes, so are you saying that you need a false metamethod?)

— Yes. My dream is something like that:

—是的。 我的梦想是这样的:

{f(x)} {f(x)}

You should capture all returns of the function f(x). And then I can do %x or #x, and that will give me the number of returns of the function. That’s what a reasonable language should do. So creating a void will not solve that, unless we had a very strong rule that functions should never return nil, but then why do we need nil? Maybe we should avoid it.

您应该捕获函数f(x)所有返回值。 然后我可以执行%x#x ,这将给我函数返回的次数。 那就是合理的语言应该做的。 因此,除非我们有一个很强的规则,即函数永远不应该返回nil,否则创建一个void并不能解决这个问题,但是为什么我们需要nil? 也许我们应该避免它。

— Roberto,对Lua会有更强大的静态分析支持吗? 像《鲁阿检查类固醇》一样。 我知道,当然不能解决所有问题。 您是说这是6.0的功能,对吗? 因此,如果在5.x中有一个强大的静态分析工具(如果投入了工时和工年),真的有帮助吗? (— Roberto, will there be a much stronger static analysis support for Lua? Like «Lua Check on steroids». I know it won’t solve all the problems, of course. You’re saying this is a feature for 6.0, if ever, right? So if in a 5.x there will be a strong static analysis tool — if man-hours and man-years were invested — would it really help?)

— No, I think a really strong static analysis tool is called… type system! If you want a really strong tool you should use a statically typed language, something like Haskell or even something with dependent types. Then you’ll have really strong analysis tools.

—不,我认为一种非常强大的静态分析工具称为……类型系统! 如果您想要一个真正强大的工具,则应该使用静态类型的语言,例如Haskell甚至具有依赖类型的语言。 然后,您将拥有真正强大的分析工具。

—但是那时候你没有Lua。 (— But then you don’t have Lua.)

— Exactly, Lua is for…

—确实,Lua是为了……

-不精确? 我非常喜欢您的长颈鹿关于静态和动态类型的图片。 (— Imprecise? I really enjoyed your giraffe picture on static and dynamic types. )

— Yes, my last slide.

是的,我的最后一张幻灯片。

The final slide from Roberto Ierusalimschy's talk «Why (and why not) Lua?» 罗伯托·伊鲁萨利姆斯基(Roberto Ierusalimschy)的演讲的最后一张幻灯片“为什么(为什么不是)卢阿?”

at Lua in Moscow 2019 conference

在莫斯科的Lua 2019会议上

—对于下一个准备好的问题,让我们回到这张照片。 如果我做对了,您的立场是Lua是一个小型的便捷工具,可以解决非常大的任务。 (— For our next prepared question, let’s return to that picture. If I got it right, your position is that Lua is a small nice handy tool for solving not very large tasks.)

— No, I think you can do some large tasks, but not with static analysis. I strongly believe in tests. By the way, I disagree with you on coverage, your opinion is we should not chase coverage… I mean, I fully agree that coverage does not imply full test, but non-coverage implies a zero percent test. So I gave a talk about a testing room — you were there in Stockholm. So I started my test with [a few] bugs — that’s the strangest thing — one of them was famous, the other was completely non-famous. It’s something completely broken in a header file from Microsoft, C and C++. So I search the web and nobody cares about it or even noticed it.

—不,我认为您可以完成一些大任务,但不能进行静态分析。 我坚信测试。 顺便说一句,我不同意覆盖率,您的意见是我们不应该追求覆盖率……我的意思是,我完全同意覆盖率并不意味着全面测试,但是未覆盖率意味着测试率为零。 因此,我谈到了一个测试室-您在斯德哥尔摩。 因此,我从[几个]错误开始了我的测试-这是最奇怪的事情-其中一个是著名的,另一个是完全不知名的。 在Microsoft,C和C ++的头文件中,它完全被破坏了。 因此,我在网上搜索,没有人关心它,甚至没有注意到它。

For instance, there’s a mathematical function, modf(), where you have to pass a pointer to a double because it returns two doubles. We translate the integer part of the number or the fractional part. So this is a part of a standard library for a long time now. Then came C 99, and you need this function for floats. And the header file from Microsoft simply kept this function and declared another one as a macro. So it got this one into type casts. So it cast the double to float, ok, and then it cast the pointer to double for pointer to float!

例如,有一个数学函数modf() ,您必须在其中传递一个指向double的指针,因为它返回了两个double。 我们翻译数字的整数部分或小数部分。 因此,这很长一段时间以来一直是标准库的一部分。 然后是C 99,您需要此函数进行浮点运算。 Microsoft的头文件只是保留了此功能,并声明了另一个宏。 因此,这使它成为类型转换。 因此,它将double强制转换为浮点,确定,然后将指针强制为double转换为指针为float!

—这张照片出了点问题。 (— Something is wrong in this picture.)

— This is a header file from Visual C++ and Visual C 2007. I mean, if you called this function once, with any parameters, and checked the results — it would be wrong unless it’s zero. Otherwise, any other value will be wrong. You would never ever use this function. Zero coverage. And then there’s a lot of discussions about testing… I mean, just call a function once, check the results! So it’s there, it’s been there for a long time, for many years nobody cared. One very famous was in Apple. Something like "if… what… goto… ok", it was something like that. Someone put another statement here. And then everything was going to ok. And there was a lot of discussions that you should have the rules, the brackets should be mandatory in your style, etc., etc. Nobody mentioned that there are a lot of other ifs here. That has never been executed…

—这是Visual C ++和Visual C 2007的头文件。我的意思是,如果使用任何参数一次调用此函数,然后检查结果,除非为零,否则将是错误的。 否则,任何其他值将是错误的。 您将永远不会使用此功能。 零覆盖。 然后有很多关于测试的讨论……我的意思是,只调用一次函数,检查结果! 所以它在那里,已经存在了很长一段时间,多年来一直没人在意。 一个非常有名的是在苹果公司。 诸如if… what… goto… ok ”之类的东西,就是这样。 有人在这里发表另一句话。 然后一切都会好起来的。 并且有很多讨论,您应该有规则,方括号应该在您的样式中是必需的,依此类推,等等。没有人提到这里还有很多其他的ifs。 那从未执行过……

-据我所记得,还有一个安全问题。 (— There’s also a security problem as far as I remember.)

— Yes, exactly. Because they were only testing approved cases. They were not testing anything, because everything would be approved. It means there is not a single test case in the security application that checks whether it refuses some connection or whatever it is that it should refuse. So everyone discuss and say they should have brackets… They should have tests, minimum tests! Because nobody has ever tested that, that’s what I mean by coverage. It’s unbelievable how people don’t do basic tests. Because if they were doing all basic tests, then of course, it’s a nightmare to do all the coverage and execute all the lines, etc. People neglect even basic tests, so coverage is at least about the minimum. It is a way to call the attention to some parts of the program that you forgot about. It is a kind of guide on how to improve your tests a little.

- 对,就是这样。 因为他们只是测试批准的案例。 他们没有测试任何东西,因为一切都会被批准。 这意味着安全应用程序中没有一个测试用例可以检查它是否拒绝某些连接或应该拒绝的连接。 因此,每个人都讨论并说他们应该有括号…他们应该有测试,最低测试! 因为没有人测试过,所以这就是我所指的范围。 人们不做基础测试,这真是令人难以置信。 因为如果他们正在执行所有基本测试,那么当然,做所有覆盖率并执行所有代码行都是噩梦。人们甚至忽略了基本测试,因此覆盖率至少约为最小值。 这是一种将注意力吸引到您忘记的程序某些部分的方法。 这是一种有关如何稍微改善测试的指南。

— Tarantool中的测试范围是什么? 83%! Roberto,Lua的测试范围是什么? (— What’s test coverage in Tarantool? 83%! Roberto, what’s Lua test coverage?)

— About 99.6. How many lines of code do you have? A million, hundreds of thousands? These are huge numbers. One percent of hundred thousand is a thousand lines of code that were never tested. You did not execute it at all. Your users don’t test anything.

—约99.6。 您有几行代码? 一百万,几十万? 这些是巨大的数字。 十万分之一的内容是一千行未经测试的代码。 您根本没有执行它。 您的用户没有进行任何测试。

—因此,大约有17%的Tarantool功能当前未使用? (— So there are like 17 percent of Tarantool features that are not currently used?)

— I’m not sure if you want to unstack everything back to where we were… I think one of the problems with dynamic languages (and static languages for that matter) is that people don’t test stuff. Even if you have a static language, unless you have something — not even like Haskell, but Coq, — some proof system, you change that for that or that. No static analysis tool can catch these errors, so you do need tests. And if you have the tests, you detect global problems, rename misspellings, etc. All these kinds of errors. You should have these tests anyway, maybe sometimes it’s a little bit more difficult to debug, sometimes it’s not — depends on the language and the kind of bug. But the problem is that no static analysis tool can allow you to avoid tests. The tests, on the other hand… well, they never prove the absence of error, but I feel much more secure after all the tests.

—我不确定您是否要将所有内容都放回原处……我认为动态语言(与此有关的静态语言)的问题之一是人们没有测试内容。 即使您使用的是静态语言,除非您拥有某种证明系统(甚至不是Haskell,而是Coq),也要为此进行更改。 没有静态分析工具可以捕获这些错误,因此您确实需要测试。 并且,如果进行了测试,则可以检测到全局问题,重命名拼写错误等。所有这些类型的错误。 无论如何,您都应该进行这些测试,也许有时调试起来会有些困难,有时却没有-取决于语言和错误的类型。 但是问题在于,没有静态分析工具可以避免测试。 另一方面,测试……好吧,它们永远不会证明没有错误,但是经过所有测试,我感到更加安全。

—我们有一个关于测试Lua模块的问题。 作为开发人员,我想测试一些以后可以使用的局部功能。 问题是:我们希望覆盖率达到99%,但是对于此模块生成的API,它应该生成的功能案例的数量远远低于其内部支持的功能。 (— We have a question about testing Lua modules. As a developer, I want to test some local functions which may be used later. The question is: we want to have a coverage of about 99 percent, but for the API this module produces, the number of functional cases it should produce is much lower than the functionality it supports internally.)

— Why is that, sorry?

-为什么,抱歉?

—有些功能是公共接口无法实现的。 (— There is some functionality which is not reachable by the public interface.)

— If there is functionality that is not reachable by the public interface, it shouldn’t be there, just erase it. Erase that code.

—如果存在公共接口无法实现的功能,则不应删除该功能,只需删除它即可。 删除该代码。

-杀死它? (— Just kill it?)

— Yes, sometimes I do that in Lua. There was some code coverage, I couldn’t get there or there or there, so I thought it was impossible and just removed the code. It’s not that common, but happened more than once. Those cases were impossible to happen, you just put an assertion to comment on why it cannot happen. If you cannot get inside your functions from the public API, it shouldn’t be there. We should code the public API with incorrect input, that’s essential for the tests.

—是的,有时我会在Lua中这样做。 有一些代码覆盖,我无法到达那里或那里,所以我认为这是不可能的,只是删除了代码。 这并不常见,但发生了不止一次。 这些情况是不可能发生的,您只需声明一个理由就不能发生。 如果无法从公共API进入函数,则不应存在。 我们应该使用错误的输入来编码公共API,这对于测试至关重要。

—删除代码,删除很好,它降低了复杂性。 降低的复杂性提高了可维护性和稳定性。 把事情简单化。 (— Remove code, removal is good, it reduces complexity. Reduced complexity increases maintainability and stability. Keep it simple.)

— Yes, extreme programming had this rule. If it’s not in a test, then it doesn’t exist.

—是的,极限编程有此规则。 如果它不在测试中,那么它就不存在。

—创建Lua时,什么语言启发了您? 您喜欢这些语言的哪些范例或功能专业或部分语言? (— What languages inspired you when you created Lua? Which paradigms or functional specialties or parts of these languages did you like? )

— I designed Lua for a very specific purpose, it was not an academic project. That’s why when you ask me if I’d create it again, I say there’s lots of historical stuff on the language. I did not start with ‘Let me create the language I want or want to use or everybody needs etc. My problem was ‘This program here needs a configuration language for geologists and engineers, and I need to create some small language they could use with an easy interface. That’s why the API was always an integral part of the language, because it’s easier to be integrated. That was the goal. What I had in my background, it’s a lot of different languages at that time… about ten. If you want all of the background…

—我为Lua设计了一个非常特定的目的,这不是一个学术项目。 这就是为什么当您问我是否要再次创建它时,我说这种语言有很多历史性的东西。 我不是从“让我创建我想要或想要使用的或每个人都需要的语言开始的。我的问题是”这里的程序需要地质学家和工程师的配置语言,我需要创建一些他们可以使用的小语言。一个简单的界面。 这就是API始终是语言不可分割的一部分的原因,因为它更易于集成。 那是目标。 在我的背景中,当时有很多不同的语言……大约十种。 如果您想要所有背景...

—我对您想包含在Lua中的语言感兴趣。 (— I was interested in languages that you wanted to include in Lua. )

— I was getting things from many different languages, whatever fitted the problem I had. The single biggest inspiration was the Modula language for syntax, but otherwise, it’s difficult to say because there are so many languages. Some stuff came from AWK, it was another small inspiration. Of course, Scheme and Lisp… I was always fascinated with Lisp since I started programming.

—无论我遇到什么问题,我都从许多不同的语言获得东西。 最大的启发是使用Modula语法,但是由于语言太多,很难说。 一些东西来自AWK,这是另一个小的灵感。 当然,Scheme和Lisp…自从开始编程以来,我一直对Lisp着迷。

-而且在Lua中仍然没有宏! (— And still no macros in Lua!)

— Yes, there is much difference in syntax. Fortran, I think, was the first language… no, the first language I learned was Assembly, then came Fortran. I studied, but never used CLU. I did a lot of programming with Smalltalk, SNOBOL. I also studied, but never used Icon, it’s also very interesting. A lot came from Pascal and C. At the time I created Lua, C++ was already too complex for me — and that was before the templates, etc. It was 1991, and in 1993 Lua was started.

—是的,语法上有很大差异。 我认为Fortran是第一语言,不,我学习的第一语言是汇编语言,然后是Fortran。 我学习了,但是从未使用过CLU。 我使用SNOBOL的Smalltalk进行了大量编程。 我也研究过,但从未使用过Icon,这也非常有趣。 Pascal和C带来了很多东西。当我创建Lua时,C ++对我来说已经太复杂了–那早于模板等等。那是1991年,1993年Lua开始了。

—苏联陷落,您开始创建Lua。 :)在开始使用Lua时,您是否对分号和对象感到无聊? 我希望Lua具有与C类似的语法,因为它已集成到C。但是…… (— The Soviet Union fell and you started creating Lua. :) Were you bored with semicolons and objects when you started working on Lua? I would expect that Lua would have a similar syntax to C, because it is integrated to C. But…)

— Yes, I think it’s a good reason not to have similar syntax — so you don’t mix them, these are two different languages.

—是的,我认为没有相似的语法是一个很好的理由—因此,请不要混用,这是两种不同的语言。

It’s something really funny and it’s connected to the answer you didn’t allow me [at the conference] to give on arrays starting at 1. My answer was too long.

这确实很有趣,它与您(在会议上)不允许我给出从1开始的数组的答案有关。我的答案太长了。

When we started Lua, the world was different, not everything was C-like. Java and JavaScript did not exist, Python was in an infancy and had a lower than 1.0 version. So there was not this thing when all the languages are supposed to be C-like. C was just one of many syntaxes around.

当我们开始Lua时,世界就不同了,并不是所有东西都像C。 Java和JavaScript不存在,Python处于起步阶段,版本低于1.0。 因此,当所有的语言都应该是C语言时,就没有这件事了。 C只是周围许多语法中的一种。

And the arrays were exactly the same. It’s very funny that most people don’t realize that. There are good things about zero-based arrays as well as one-based arrays.

并且数组完全相同。 有趣的是,大多数人没有意识到这一点。 从零开始的数组和从一开始的数组都有很多好处。

The fact is that most popular languages today are zero-based because of C. They were kind of inspired by C. And the funny thing is that C doesn’t have indexing. So you can’t say that C indexes arrays from zero, because there is no indexing operation. C has pointer arithmetic, so zero in C is not an index, it’s an offset. And as an offset, it must be a zero — not because it has better mathematical properties or because it’s more natural, whatever.

事实上,由于C,当今大多数流行的语言都是从零开始的。它们是C的启发。有趣的是,C没有索引。 因此,您不能说C从零开始索引数组,因为没有索引操作。 C具有指针算法,因此C中的零不是索引,而是偏移量。 作为偏移量,它必须为零-并不是因为它具有更好的数学特性,或者因为它更自然(无论如何)。

And all those languages that copied C, they do have indexes and don’t have pointer arithmetic. Java, JavaScript, etc., etc. — none of them have pointer arithmetic. So they just copied the zero, but it’s a completely different operation. They put zero for no reason at all — it’s like a cargo cult.

并且所有复制C的语言都具有索引,并且没有指针运算。 Java,JavaScript等,等等-它们都没有指针算法。 因此他们只是复制了零,但这是完全不同的操作。 他们根本没有理由放零-就像是一个狂热的货。

—您是说如果您将某种语言嵌入C语言中并使其具有类似C的语法,这是合乎逻辑的。 但是,如果您使用的是C嵌入的语言,那么我假设您有C程序员,他们希望代码使用C而不是其他语言(看起来像C,但不是C)。因此,Lua用户从不应该使用C日常? 为什么? (— You’re saying it’s logical if you have a language embedded in C to make it with C-like syntax. But if you have a C-embedded language, I assume you have C programmers who want the code to be in C and not some other language, which looks like C, but isn’t C. So Lua users were never supposed to use C daily? Why?)

— Who uses C every day?

—谁每天都使用C?

—系统程序员。 (— System programmers.)

— Exactly. That’s the problem, too many people use C, but should not be allowed to use it. Programmers ought to be certified to use C. Why is software so broken? All those hacks invading the world, all those security problems. At least half of them is because of C. It is really hard to program in C.

—没错。 这就是问题所在,太多的人使用C,但不应允许使用它。 程序员应该被证明可以使用C。为什么软件这么坏? 所有入侵世界的黑客,所有这些安全问题。 至少有一半是由于C造成的。用C编程确实很困难。

—但是Lua在C中。 (— But Lua is in C.)

— Yes, and that’s how we learned how hard it is to program in C. You have buffer overflows, you have integer overflows that cause buffer overflows… Just get a single C program that you can be sure that no arithmetic goes wrong if people put any number anywhere and everything is checked. Then again, real portability issues — maybe sometimes in one CPU it works, but then it gets to the other CPU… It’s crazy.

—是的,这就是我们了解如何用C编程的方式。您有缓冲区溢出,您有导致缓冲区溢出的整数溢出...只要获得一个C程序,您就可以确定如果有人把C程序弄错了,任何地方的任何数字,所有内容都会检查。 再说一遍,真正的可移植性问题-也许有时在一个CPU中可以工作,但后来又转移到另一个CPU中……这很疯狂。

For instance, very recently we had a problem. How do you know your C program does not do stack overflow? I mean stack depth, not stack overflow because you invaded… How many calls you have a right to do in a C program?

例如,最近我们遇到了问题。 您如何知道您的C程序不会发生堆栈溢出? 我的意思是堆栈深度,不是堆栈溢出,因为您入侵了...您有权在C程序中进行多少次调用?

—取决于堆栈大小。 (— Depends on a stack size.)

— Exactly. What the standard says about that? If you code in C and then you do this function that calls this function that calls this function… how many calls can you do?

—没错。 标准怎么说? 如果您使用C编写代码,然后执行此函数,该函数调用此函数,则该函数调用此函数……您可以执行多少次调用?

— 16000? (— 16 thousand?)

— I may be wrong, but I think the standard says nothing about that.

—我可能是错的,但是我认为标准对此没有任何说明。

—我认为标准中没有任何内容,因为它过于依赖大小。 (— I think there is nothing in the standard because it’s too dependent on the size.)

— Of course, it depends on the size of each function. It may be huge, automatic arrays in the function frame… So the standard says nothing and there is no way to check whether a call will be valid. So you may have a single problem if you have three step calls, it can crash and still be a valid C program. Correct according to the standard — though it’s not correct because it crashes. So it’s very hard to program in C, because there are so many… Another good example: what is the result when you subtract two pointers? No one here works with C?

—当然,这取决于每个功能的大小。 函数框架中可能有巨大的自动数组……因此,该标准什么也没说,也没有办法检查调用是否有效。 因此,如果您有三个步骤调用,则可能会遇到一个问题,它可能崩溃并且仍然是有效的C程序。 根据标准更正-尽管它不正确,因为它会崩溃,因此不正确。 因此,使用C进行编程非常困难,因为有太多…另一个很好的例子:减去两个指针会得到什么结果? 这里没有人可以和C合作吗?

—不,所以不要烧烤。 但是C ++支持不同的类型。 (— No, so don’t grill them. But C++ supports different types. )

— No, C++ has the same problem.

—不,C ++存在相同的问题。

—声明的类型是什么? ptrdiff_t(— What’s the type of declaration? ptrdiff_t?)

— Exactly, ptrdiff_t is a signed type. So typically, if you have a standard memory the size of your word and you subtract two pointers in this space, you cannot represent all the sizes in the signed type. So, what does the standard say about that?

—确实, ptrdiff_t是带符号的类型。 因此,通常,如果您有一个标准的内存,即字的大小,并且在此空间中减去了两个指针,则无法以带符号的类型表示所有大小。 那么,标准对此有何看法?

When you subtract two pointers, if the answer fits in a pointer diff, then that is the answer. Otherwise, you have undefined behavior. And how do you know if it fits? You don’t. So whenever you subtract two pointers, usually you know that’s out of standard, that if you’re pointing to anything larger than at least 2 bytes, then the larger size would be half the size of the memory, so everything is ok.

当您减去两个指针时,如果答案适合于指针差异,则为答案。 否则,您将具有未定义的行为。 您怎么知道是否合适? 你不知道 因此,每当减去两个指针时,通常就知道这是不合标准的,如果您指向大于至少2个字节的任何内容,则较大的大小将是内存大小的一半,因此一切正常。

So you’re only having a problem if you’re pointing to bytes or characters. But when you do that, you have a real problem, you can’t do pointer arithmetic without worrying that you have a string larger than half of the memory. And then I can’t just compute the size and store in a pointer diff type because it’s wrong.

因此,仅在指向字节或字符时才有问题。 但是,当您这样做时,您将遇到一个真正的问题,即不必担心指针的字符串大于内存的一半就不能执行指针算术。 然后我不能只计算大小并存储在指针diff类型中,因为这是错误的。

That’s what I mean about having a secure C or C++ program that’s really safe.

我的意思是拥有真正安全的安全C或C ++程序。

—您是否考虑过用其他语言实现Lua? 将其从C更改为其他内容? (— Have you considered implementing Lua in a different language? Change it from C to something else?)

— When we started, I considered C++, but as I said I gave up using it because of complexity — I cannot learn the whole language. It should be useful to have some stuff from C++ but… even today I don’t see any language that would do.

—刚开始时,我考虑过C ++,但正如我所说,由于复杂性,我放弃了使用它—我无法学习全部语言。 拥有C ++的一些东西应该很有用,但是…即使到了今天,我仍然看不到任何可以使用的语言。

—你能解释为什么吗? (— Can you explain why?)

— Because I have no alternatives. I can only explain why against other languages. I’m not saying C is perfect or even good, but it’s the best. To explain why, I need to compare it with other languages.

—因为我别无选择。 我只能解释为什么反对其他语言。 我并不是说C是完美的,甚至不是很好,但它是最好的。 为了解释原因,我需要将其与其他语言进行比较。

— JVM呢? (— What about JVM?)

— Oh, JVM. Come on, it doesn’t fit in half the hardware… Portability is the main reason, but performance too. In JVM it’s a little better than .NET, but it’s not that different. A lot of things that Lua does we can’t do with JVM. You cannot control the garbage collector for instance. You have to use JVM garbage collector because you can’t have a different garbage collector implemented on top of JVM. JVM is also a huge consumer of memory. When any Java program starts to say hello, it’s like 10 MB or so. Portability is an issue not because it wasn’t ported, but because it cannot be ported.

—哦,JVM。 来吧,它不适合一半的硬件...可移植性是主要原因,但性能也是如此。 在JVM中,它比.NET更好,但是没有什么不同。 Lua所做的很多事情我们都无法通过JVM完成。 例如,您无法控制垃圾收集器。 您必须使用JVM垃圾收集器,因为您无法在JVM之上实现其他垃圾收集器。 JVM还是内存的巨大消耗者。 当任何Java程序开始打声招呼时,大约10 MB左右。 可移植性不是一个问题,不是因为它没有被移植,而是因为它不能被移植。

—像移动JVM这样的JVM修改如何? (— What about JVM modifications like Mobile JVM?)

— That’s not JVM, that’s a joke. It’s like a micro edition of Java, not Java.

—不是JVM,这是个玩笑。 它就像是Java的微型版本,而不是Java。

—其他静态语言(如Go或Oberon)如何? 如果您今天创建了Lua,它们可以成为Lua的基础吗? (— How about other static languages like Go or Oberon? Could they be the basis for Lua if you created it today?)

— Oberon… might be, it depends… Go, again, has a garbage collector and has a runtime too big for Lua. Oberon would be an option, but Oberon has some very strange things, like you almost don’t have constants, if I recall correctly. Yeah, I think they removed const from Pascal to Oberon. I had a book on Oberon and loved Oberon. Its system was unbelievable, it’s really something.

— Oberon…可能取决于,…Go又有了一个垃圾收集器,并且运行时对于Lua来说太大了。 Oberon是一个选择,但是Oberon有一些非常奇怪的东西,例如,如果我没记错的话,您几乎没有常数。 是的,我认为他们已将const从Pascal移至Oberon。 我有一本关于Oberon的书,并且喜欢Oberon。 它的系统令人难以置信,这确实是一件事情。

I remember that in 1994 I saw a demonstration of Oberon and Self. You know Self? It’s a very interesting dynamic language with jit-compilers etc… I saw these demos a week apart, and Self was very smart, they used some techniques from cartoons to disguise the slowness of the operations. Because when you opened something, it was like ‘woop!’ — first it reduces a little, then expands with some effects. It was implemented very well, these techniques they used to simulate movement…

我记得在1994年,我看到了Oberon和Self的表演。 你知道自己吗? 这是与jit编译器等一起使用的一种非常有趣的动态语言。我隔一周看了这些演示,而Self很聪明,他们使用了卡通技术来掩盖操作的缓慢性。 因为当您打开某件东西时,它就像是“哇!” -首先减少一点,然后扩大一些效果。 实施得非常好,他们用来模拟运动的这些技术……

Then a week later we saw a demo of Oberon, it was running on like 1/10th of hardware for Self — there was this very old small machine. In Oberon you click and then just boom, everything works immediately, the whole system was so light.

然后一个星期后,我们看到奥伯伦的演示,它是在像1/10硬件自运行-有一位很老的小机器。 在Oberon中,单击然后只是弹出即可,一切立即生效,整个系统非常轻便。

But for me it’s too minimalistic, they removed constants and variant types.

但是对我来说太简单了,他们删除了常量和变量类型。

— Haskell? (— Haskell?)

— I don’t know Haskell or how to implement Lua in Haskell.

—我不了解Haskell或如何在Haskell中实现Lua。

—您对Python,R或Julia这样的语言作为将来实现Lua的基础持什么态度? (— And what’s your attitude to languages like Python or R or Julia as a basis for future implementations of Lua?)

— I think every one of these has its uses.

-我认为其中每一个都有其用途。

R seems to be good for statistics. It’s very domain specific, done by people in the area, so this is a strength.

R似乎适合统计。 它是特定领域的,由该地区的人员完成,因此这是一种优势。

Python is nice, but I had personal problems with it. I thought I mentioned it in my talk or the interview. That thing about not knowing the whole language or not using it, the subset fallacy.

Python很不错,但是我遇到了个人问题。 我以为我在谈话或访谈中提到了它。 关于不了解整个语言或不使用它的事情,即子集谬误。

We use Python in our courses, teaching basic programming — just a small part, loops and integers. Everybody was happy, and then they said it would be nice to have some graphical applications, so we needed some graphical library. And almost all graphical libraries, you get the API… But I don’t know Python enough, this is much-advanced stuff. It has the illusion it’s easy and I have all these libraries for everything, but it’s either easy or you have everything.

我们在课程中使用Python,教授基本编程-仅一小部分,即循环和整数。 每个人都很高兴,然后他们说拥有一些图形应用程序会很好,因此我们需要一些图形库。 几乎所有图形库都可以使用API​​ ...但是我对Python不够了解,这是非常先进的东西。 它有一个简单的错觉,我拥有所有所有这些库,但它要么简单,要么就拥有一切。

So when you start using the language, then you start: oh, I have to learn OOP, inheritance, whatever else. Every single library. It looks like authors take pride in using more advanced language features in their API to show I don’t know what. Function calls, standard types, etc. You have this object, and then if you want another thing then you have to create another object…

因此,当您开始使用该语言时,便会开始:哦,我必须学习OOP,继承以及其他内容。 每个图书馆。 看来作者为在其API中使用更高级的语言功能而感到自豪,以表明我不知道是什么。 函数调用,标准类型等。您有这个对象,然后如果您想要其他东西,则必须创建另一个对象……

Even the pattern matching, you can do some simple stuff, but usually the standard pattern matching is not something you do. You do a matching, an object returns a result and then you call methods on that object result to get the real result of the match. Sometimes there is a simpler way to use but it’s not obvious, it’s not the way most people use.

即使是模式匹配,您也可以做一些简单的事情,但是通常标准的模式匹配不是您要做的。 您进行匹配,一个对象返回一个结果,然后在该对象结果上调用方法以获取匹配的真实结果。 有时候,有一种更简单的使用方法,但并不明显,这不是大多数人使用的方法。

Another example: I was teaching a course on pattern matching and wanted to use Perl-like syntax, and I couldn’t use Lua because of a completely different syntax. So I thought Python would be the perfect example. But in Python there are some direct functions for some basic stuff but for anything more complex you’d have to know objects and methods etc. I just wanted to do something and have the result.

另一个例子:我正在教一门模式匹配的课程,想使用类似Perl的语法,由于语法完全不同,所以我不能使用Lua。 所以我认为Python将是一个完美的例子。 但是在Python中,有一些针对某些基本内容的直接函数,但对于更复杂的任何事情,您都必须了解对象和方法等。我只是想做点事情并得到结果。

—您最终使用了什么? (— What did you end up using?)

— I used Python and explained to them. But even Perl is much simpler, you do the match and the results are $1, $2, $3, it’s much easier, but I don’t have the courage to use Perl, so…

-我使用Python并向他们解释。 但是,即使Perl更加简单,您也可以进行匹配,结果分别是$ 1,$ 2,$ 3,这要容易得多,但是我没有勇气使用Perl,所以……

—我使用Python两年后才发现有装饰器。 (Tarantool团队的Yaroslav Dynnikov的问题) (— I was using Python for two years before I noticed there were decorators. (question by Yaroslav Dynnikov from Tarantool team))

— Yes, and when you want to use a library, then you have to learn this stuff and you don’t understand API etc. Python gives an illusion that it’s easy but it’s quite complex.

—是的,当您想使用一个库时,您必须学习这些知识并且不了解API等。Python带来了一个幻觉,即它很简单,但却很复杂。

...And Julia, I don’t know much about Julia, but it reminded me of LuaJIT in the sense that sometimes it looks like user’s pride. You can have very good results but you have to really understand what’s going on. It’s not like you write code and get good results. No, you write code and sometimes the results are good, sometimes they are horrible. And when the results are horrible, you have a lot of good tools that show you the intermediate language that was once generated, you check it and then you go through all this almost assembly code. Then you realize: oh, it’s not optimizing that because of that. That’s the problem of programmers, they like games and sometimes they like stuff because it’s difficult, not because it’s easy.

...而且Julia,我对Julia不太了解,但从某种意义上来说,它使我想起了LuaJIT,有时看起来就像用户的骄傲。 您可以获得非常好的结果,但是您必须真正了解正在发生的事情。 这不像您编写代码并获得良好的结果。 不,您编写代码,有时效果不错,有时效果很糟。 当结果令人震惊时,您将有很多不错的工具向您展示曾经生成的中间语言,您对其进行了检查,然后遍历了几乎所有的汇编代码。 然后,您意识到:哦,它并没有因此而优化。 那是程序员的问题,他们喜欢游戏,有时他们喜欢东西,因为这很困难,而不是因为容易。

I don’t know much about Julia, but I once saw a talk about it. And the guy talking, he was the one to have this point of view: see how nice it is, we wrote this program and it’s perfect. I don’t remember much, something about matrix multiplication I guess. And then the floats are perfect, then the doubles are perfect, and then they put complex [numbers]… and it was a tragedy. Like a hundred times slower.

我对Julia(Julia)不太了解,但是我曾经看到过有关它的话题。 那个家伙在说,他就是有这种观点的人:看看它有多棒,我们编写了这个程序,它是完美的。 我不太记得,我猜是关于矩阵乘法的。 然后花车是完美的,然后双打是完美的,然后他们放置复杂的[数字] ...这是一个悲剧。 像慢一百倍。

(sarcastically) ‘See how nice it is, we have this tool, we can see the whole assembly [listing], and then you go and change that and that and that. See how efficient this is’. Yes, I see, I can program in assembly directly.

(讽刺地)“看看它有多棒,我们有了这个工具,我们可以看到整个程序集(列表),然后您就可以改变那个那个那个了。 看看这有多有效”。 是的,我知道,我可以直接在汇编中编程。

But that was just one talk. I studied a little R and have some user experience with Python for small stuff.

但这只是一个话题。 我学习了一点R,并对一些小东西有使用Python的用户经验。

—您如何看待Erlang? (— What do you think of Erlang?)

— Erlang is a funny language. It has some really good uses, fault tolerance is really interesting. But they claim it’s a functional language and the whole idea of the functional language is that you don’t have a state.

— Erlang是一种有趣的语言。 它有一些很好的用途,容错性确实很有趣。 但是他们声称这是一种功能语言,而功能语言的整个思想就是您没有状态。

And Erlang has a huge hidden state in the messages that are sent and not yet received. So each little process is completely functional but the program itself is completely non-functional.

而且,Erlang在已发送和尚未接收的消息中具有巨大的隐藏状态。 因此,每个小进程都完全可以运行,但是程序本身却完全不运行。

It’s a mess of hidden data that is much worse than global variables because if it were global variables, you would print them. Messages that are the real state of your system. Every single moment, what’s the state of the system? There are all these messages sent here and there. It’s completely non-functional, at all.

这是一堆乱七八糟的隐藏数据,比全局变量差很多,因为如果是全局变量,则将其打印出来。 消息是系统的真实状态。 每时每刻,系统的状态是什么? 所有这些消息在这里和那里发送。 完全不起作用。

—因此,Erlang在于发挥功能,而Python则在于简单。 Lua说谎了什么? (— So Erlang lies about being functional and Python lies about being simple. What does Lua lie about?)

— Lua lies a bit about being small. It’s still smaller than most other languages, but if you want a really small language then Lua is larger than you want it to be.

— Lua有点小。 它仍然比大


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
学习Lua的意义发布时间:2022-07-22
下一篇:
OpenWrt之lua网络编程_luci下的luasocket安装发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap