在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
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, 例如,您将不得不以某种方式声明所有标准库。 您需要一个单行的 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 您应该捕获函数 — 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. 是的,我的最后一张幻灯片。 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 " —这是Visual C ++和Visual C 2007的头文件。我的意思是,如果使用任何参数一次调用此函数,然后检查结果,除非为零,否则将是错误的。 否则,任何其他值将是错误的。 您将永远不会使用此功能。 零覆盖。 然后有很多关于测试的讨论……我的意思是,只调用一次函数,检查结果! 所以它在那里,已经存在了很长一段时间,多年来一直没人在意。 一个非常有名的是在苹果公司。 诸如 “ -据我所记得,还有一个安全问题。 (— 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 ++存在相同的问题。 —声明的类型是什么?
|
请发表评论