Lua在莫斯科2019:采访罗伯托·耶路撒冷



不久前,Lua语言的作者耶路撒冷的罗伯托访问了我们的莫斯科办事处。 我们采访了他,在此期间,我们问了哈勃(Habr)读者一些问题。 最后,我们可以与您分享整个对话记录。

-让我们开始思考。 如果您要从头开始重新构建Lua,那么用此语言您将改变三件事?

-哇! 艰难的问题。 语言的创建和发展背后有一个完整的故事。 这不是一个重大决定。 有些决定令我后悔,多年来我能够解决。 程序员一直抱怨它,因为兼容性遭到破坏。 我们已经做过几次了。 我只考虑一些小任务。

-全局默认值(默认为全局)? 您认为这是正确的方法吗?

-也许吧。 但是对于动态语言来说,这条路非常困难。 也许您应该完全放弃“默认”的概念,但是使用变量将很困难。
例如,您必须以某种方式声明所有标准库。 您需要one-linerprint(sin(x)) ,然后需要声明“ print”和另一个“ sin”。 拥有如此简短的脚本的广告很奇怪。

在我看来,默认情况下,任何较大的内容都不应该具有任何内容。 默认本地不是解决方案,它根本不存在。 它仅用于分配,不用于使用。 我们分配一些东西,然后再次使用并分配,就会发生完全莫名其妙的错误。

缺省的全局性也许不是完美的,但是缺省的局部性绝对不是一个选择。 我认为是某种公告,也许是可选的……我们已经打算进行多次全球公告。 但是,如果我们盲目介绍我们所要求的所有内容,那么它就不会有任何好处。

(讽刺地)是的,我们将要引入一个全球公告,并补充说,第五,第十名,再拔出另一个,因此,我们意识到最终的解决方案不能满足大多数程序员的需求,因此我们不会添加要求的所有功能,因此我们什么都不做。 毕竟,严格模式是一种合理的折衷方案。

有一个问题:例如,我们经常使用模块内部的字段,然后又遇到了同样的问题。 这只是错误的一种非常特殊的情况,在一般解决方案中应考虑在内。 因此,如果您确实需要它,则最好使用静态类型的语言。

-对于小配置文件,默认全局性仍然很方便。

“是的,是的,对于小的脚本之类的东西。”

-在这种情况下没有妥协吗?

-总会有妥协。 在这种情况下,小脚本和实际程序之间会折衷,类似的事情。

-在这里,我们回到第一个大问题:如果有这样的机会,您将改变三件事? 在我看来,您对目前的状况非常满意,对吗?

“好吧,我不会说这是一个大的变化,但是...变成大变化的一个不成功的决定之一就是表中没有零。” 对此我感到抱歉。 我做了这个骇客...您知道我在说什么吗? 在半年或一年前的C中,我发布了一个Lua版本,其中表中没有零。

-没有值?

没错 我认为这在表中称为nil-即null。 我们进行了语法修改,以确保兼容性。

-为什么需要?

“我真的坚信这是整个问题……我认为,如果我们可以在表中使用nil,那么数组中nil的大多数问题就会消失……更确切地说,问题不在于数组中的nil。” 他们告诉我数组不能为nil,因此应将数组与表分开。 真正的问题是我们不能在表中保持零! 因此,问题不在于我们如何表示数组,而在于表。 如果我们在表中可以包含nil,那么在没有其他所有内容的情况下,我们可以在数组中具有nil。 因此,对此我感到非常抱歉,许多人不了解如果Lua允许将零放在表中,情况可能会发生变化。

-我能告诉您一个有关Tarantool的故事吗? 我们有自己的null实现,它是指向null指针的CDATA。 如果您需要在内存中创建空片段以插入用于远程调用的定位参数等,我们将使用它。 但是通常这是一个问题,因为CDATA总是转换为true。 而零数组将解决很多问题。

-是的,我知道。 这就是我要说的-它可以解决许多问题,但这会导致更大的兼容性问题。 我们没有勇气发布不兼容的版本,然后销毁社区并发布Lua 5,Lua 6等的其他文档。 但是也许有一天我们会发布这样的版本。 这些将是非常大的变化。 我认为应该从一开始就做到这一点,然后我们会谈论该语言的一个小变化,除了兼容性。 今天,它将破坏许多程序。

-除了兼容性问题,您还看到哪些缺点?

-将需要两个新的原始函数。 类似于“删除键”,因为分配nil不会删除键,因此您将需要一个基本操作将其从表中实际删除。 您将需要“测试”以准确检查零和缺少数据之间的区别。

-您是否分析了这些创新对实际实施的影响?

-是的,我们发布了这样的Lua版本。 正如我所说,这悄悄地破坏了代码。 有些使用table.insert(f(x))函数调用。 并有意这样做,以便如果该函数不想插入任何内容,则返回nil。 因此,代替单独检查,“我要嵌入吗?” 我调用table.insert ,如果得到nil,那么我知道它不会被插入。 与其他任何语言一样,该错误已变成一种功能,人们开始使用它。 但是,如果您更改功能,它将破坏代码。

-空类型呢? 像零一样,只有虚无?

“好吧,不,这是一场噩梦。” 您只是推迟解决问题。 如果输入一个“拐杖”,那么您将需要一个或更多。 这不是解决方案。 问题之一是nil已在语言的许多地方扎根。 这是一个典型的例子:我们说“避免在数组中使用nil,即空洞”。 然后,我们编写一个返回nil及其后的内容的函数,然后得到一个错误代码。 这样的构造本身已经暗示了nil是什么。例如,如果我要列出该函数返回的结果的列表,只需将它们全部捕获即可。

-为此,您有一个技巧:)

“是的,但是您不需要使用黑客来解决如此简单而明显的任务。” 但是,库确实这样做了……我想了一下:也许库应该返回false而不是nil,尽管这是一个粗略的选择,但只能解决一小部分问题。 正如我所说,真正的问题是我们需要在表中添加零。 否则,我们不应该像我想的那样频繁使用nil。 一般来说,还不清楚。 因此,如果您创建了void,这些函数仍将返回nil,并且直到创建新类型并且这些函数将返回void而不是nil时,我们才能解决问题。

-使用void时,您可以明确地说必须将键存储在表中,键的值应为void。 而且nil可以像以前一样工作。

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

“他们也可以返回零,为什么不呢?”

-因为这样在某些情况下,我们将无法解决无法捕获函数返回的所有值的问题。

“但是我们没有第一把钥匙,只有第二把钥匙。”

-不,没有秒,因为计算将不正确,并且阵列中会出现孔。

-所以您想说您需要一种伪造的元方法?

-是的 我梦到这个:

{f(x)}

您需要截获f(x)返回的所有结果。 然后我可以说%x#x ,这样我就知道返回结果的数量。 这就是正常语言应如何工作。 因此,除非有一个非常严格的规则,即函数永不返回nil,否则创建一个void不会解决问题。 但是,为什么我们甚至需要零? 也许值得放弃。

-Roberto,Lua中对静态分析的支持会更大吗? 像Lua检查类固醇吗? 当然,我知道这并不能解决所有问题。 您说过,此功能将在6.0版中出现,对吧? 如果在5.x中将有一个强大的静态分析工具-如果在其中投入了工时,这会有帮助吗?

“不,我相信一个真正强大的静态分析工具被称为……类型系统!” 如果您需要真正强大的工具,请使用静态类型的语言(例如Haskell)或某种具有依赖类型的语言。 这样,您肯定会拥有一个强大的分析工具。

“但是那时候我就没有Lua了。”

-是的,Lua需要...

-不确定性? 我喜欢长颈鹿关于静态和动态类型的照片。

-是的,这是我从演示文稿中获得的最后一张幻灯片。


罗伯托·耶路撒冷(Roberto Jerusalem)演讲“为什么要露娜(Lua Lua? (以及为什么不参加)“在Lua in Moscow 2019会议上。

-要问下一个问题,让我们回到这张照片。 如果我理解正确,您会认为Lua是解决不太大任务的便捷工具。

-不,我相信您可以解决一些大问题,但不涉及静态分析。 我全心全意地进行测试。 顺便说一句,我不同意覆盖率,我们不应该追逐覆盖率。我想说,我完全同意以下观点:覆盖率无法提供完整的测试,但是缺乏覆盖率根本无法进行测试。 我在斯德哥尔摩谈到测试室,您当时在那儿。 我开始使用[几个]错误进行测试-这是最奇怪的事情-其中一个众所周知,而其余的则完全未知。 Microsoft,C和C ++头文件中的某些内容完全损坏。 我搜索了网络,但没人担心它,甚至没有注意到它。

例如,有一个数学函数modf() ,需要将其传递给double值的指针,因为它返回了两个double。 我们转换数字的整数或小数部分。 长期以来,此功能一直是标准库的一部分。 然后是C 99,浮点数现在需要此功能。 Microsoft头文件只是保存了此函数,并声明了另一个宏。 也就是说,第一个函数进行了隐式类型转换。 Double被转换为浮点数,然后double的指针被转换为浮点数的指针!

-这张图片有问题。

-这是Visual C ++和Visual C 2007的头文件。如果使用任何参数一次调用此函数,然后检查结果,则除非是0,否则它将是错误的。其他任何值都不是true。 您永远不能使用此功能。 零覆盖。 然后,关于测试的讨论很多。只需调用一次函数并检查结果! 这个问题已经存在了很长时间,多年来一直没有困扰任何人。 苹果有一个非常著名的错误, 类似于if… what… goto… ok ”。 有人在这里插入了另一个表达,一切都变得正常了。 然后,他们就是否需要规则,是否应在代码样式中使用花括号等问题争论不休。 没有人提到还有许多其他“如果”。 没有人做过...

-我记得还有一个安全问题。

-是的 毕竟,他们只测试已确认的情况。 他们不会连续测试所有内容,因为所有内容都会得到确认。 这意味着在检查安全性的应用程序中,没有一个测试可以检查任何连接是否失败或应该拒绝哪些连接。 每个人都在争论是否需要括号...我们需要测试,至少需要测试! 毕竟,没有人甚至测试过我所说的“涂层”的含义。 这简直令人难以置信,人们甚至没有进行基本测试。 当然,要提供基本测试,运行所有代码行将非常困难。 人们甚至避免基本测试,因此覆盖范围很小。 我想敦促您注意您忘记的程序部分。 有点像提示如何稍微改善您的测试。

-您知道Tarantool中的测试范围吗? 83%! Lua的覆盖范围是什么?

-大约99.6%。 您有几行代码? 一百万,几十万? 这是一个巨大的数目。 十万分之一的代码是一千行未经测试的代码。 您根本没有执行它们。 您的用户没有进行任何测试。

-也就是说,现在不使用大约17%的Tarantool函数?

-您不太可能希望回到我们刚才讨论的内容……我认为动态语言(以及静态语言)的问题之一是人们没有测试他们的代码。 即使使用静态语言-不是像Haskell,而是像Coq-直到拥有验证系统,您都将其更改为该语言。 而且没有静态分析工具可以捕获这些错误,因此您需要进行测试。 如果有它们,则可以识别全局问题,名称中的错别字等各种错误。 您肯定需要测试。 有时很难调试,否则很简单-这取决于语言和错误类型。 但最重要的是,没有静态分析工具可以替代测试。 另一方面,它们不能保证没有错误,但是有了它们,我感到更加自信。

-我们有一个关于测试Lua模块的问题。 作为开发人员,我想测试一些以后可以使用的局部功能。 问题:您需要99%的覆盖率,但是API模块应该生成的功能情况数量远远少于其内部支持的功能数量。

-对不起,为什么?

-有些功能不适用于公共接口。

“她不应该在那里,只需删除此代码即可。”

-删除它?

-是的,有时我会在Lua这样做。 涉及到某种代码,我无法到达这里,那里或那里,我认为这是不可能的,因此删除了代码。 很少,但是它确实发生了。 如果某些情况是不可能的,只需在注释中写出为什么这是不可能的。 如果您不能通过公共API进入该函数,则不应这样做。 必须使用错误的输入数据编写公共API,这对于测试很重要。

-删除代码是好的,它降低了复杂性。 复杂性更低-更高的稳定性和易于维护。 不要复杂化。

-是的,在极限编程中有这样的规则。 如果无法测试,则不存在。

-您启发了哪些语言来创建Lua? 您喜欢什么范例,功能或部分语言?

-我设计Lua的目的很狭窄,这不是一个学术项目。 因此,当您问我关于重新创建语言的问题时,我回答说它背后有一个完整的故事。 我并不是以“我将创建一种我喜欢或想要使用的语言,或者每个人都需要的语言”来开发Lua。 我有一个问题:这里我需要地质学家和工程师的配置语言,它必须小巧且具有简单的界面,以便他们可以使用它。 因此,API一直是该语言的组成部分。 那是任务。 至于灵感,那时候我熟悉大约十种不同的语言。

“我想知道您想在Lua中加入哪些语言。”

-我从许多语言中借来了想法,所有适合解决我的问题的想法。 尽管很难说,Modula语言的语法影响最大,因为存在多种语言。 AWK采取了一些措施。 当然,从Scheme和Lisp出发……自从我开始编程以来,我对Lisp并不陌生。

-而且Lua中仍然没有宏!

-是的,语法完全不同。 可能第一语言是Fortran ...不,我的第一语言是汇编语言,然后是Fortran。 我学习了,但从未使用过CLU。 在Smalltalk和SNOBOL上进行了大量编程。 也曾研究过,但并未使用Icon,这也是一种非常有趣的语言。 我从Pascal和C那里借了很多东西。当我创建Lua时,C ++对我来说已经太复杂了,这早于模板和其他东西。 我从1991年开始工作,并于1993年发布Lua。

-苏联解体,您开始创建Lua :)启动Lua时,您不喜欢分号和对象吗? 在我看来,它的语法类似于C,因为Lua已集成到其中。 但是...

-我认为语法应该有所不同,因此您不会感到困惑,因为这是两种不同的语言。

这真的很有趣,并且与关于以1开头的数组的答案有关,您没有允许我在会议上表达它。 我的回答太长了。

当Lua发行时,世界就不同了。 并非所有语言都类似于C。仍然没有Java和JavaScript,Python是婴儿,并且没有超过1.0版。 因此,并非所有语言都类似于C;它的语法是许多语言中的一种。

数组也一样。 有趣的是,其中大多数都不知道。 以0和1开头的数组各有优点。

多亏了C语言,当今大多数流行语言都使用以0开头的数组。其创建者受到C语言的启发。而且很有趣的是C语言中没有索引。 , , . , — , (offset). , , , , .

, , . Java, JavaScript — . 0, . , « ».

— , , . -, , , - , , . , Lua ? ?

— ?

— .

— . , , . . ? , , . . .

— Lua C.

— , , . , , … , , - . : , … .

, . , ? , - … ?

— .

— . ? C , , … ?

— 16 ?

— , .

— , , .

— , . , , … , , . — , . , , . , … : ?

— C++ .

— , C++ .

— ? ptrdiff_t ?

ptrdiff_t — (signed type). , , . ?

, diff , . . , ? 没办法 , , . 2 , .

, . , . diff , .

, ++.

— Lua ?

— , C++, - , . , - ++, … .

— , ?

— . , . , , . , .

— JVM?

— , JVM. , … — , . JVM , .NET, . JVM , Lua. , . JVM, . JVM . Java-, 10 . , JVM , .

— JVM, , Mobile JVM?

— , JVM. - Java, Java.

— , Go Oberon? Lua, ?

— Oberon… … Go , runtime- Lua. Oberon , . , , . , , const Pascal Oberon. , . .
, 1994- Oberon Self. Self? JIT- . Self , , . - , — ! — , - . , …

Oberon, , 10 Self, . Oberon , , .

, .

— Haskell?

— Haskell, , Lua.

— Python, R Julia Lua?

— , .

R . , .

Python , . , . , .

Python , , . , , - . API… , Python, . , , « ».

, -: , , , -. . , API , - . , . , , …

- , (pattern matching). , , , . , , .

: Perl. Lua, . , Python . , , . - .

— ?

— Python. Perl : $1, $2, $3. Perl, …

— Python, , ( Tarantool).

— , , , API, . Python , .

Julia, LuaJIT, , . , , . , . , , , . , , . : , - . , , - , .

Julia, : , , . , - . , double, []… . .

() «, , , , , . , ». , , .

. R, Python.

— Erlang?

— . , . , , , - . Erlang , , . , .

, . , . ? , . .

— , Erlang , Python . Lua?

— , . Lua , , Lua , .

— ?

— Forth, .

— Lua?

— , . , . - , . Lua, Lua, .

Java. Java, ? 不行 (reflection)? 不行 ? Java, , Java. , , Java, .

, Lua, … , , FFI.

— Lua?

— , .

— Lua ? ?

— , . , Haskell. , , … Lua, , , , , .

— , Lua.

— , , . . , .

— , . Lua ?

— , , …

— « »? , ?

— , . , , , . , .

— Lua?

— . , , LaTex DocBook. , … LaTex, . @, . Gsub , , - - . , , , .

— LaTeX?

— LaTeX? -, , . , , LaTex. , inline-. /, . — . , , , . , . , .

— LaTeX?

— , . , , . , 3+1, . , , . , . , , . , 1 «and», . . , .

— ?

— , git . 2html . HTML… , . , , . , , . , TeX. TeX- TeX.

— ?

— , . , TeX. , . DocBook, . , .

— 2html DocBook?

— , DocBook.

— , , !

— .



- , Lua Mailing List .

Source: https://habr.com/ru/post/zh-CN459464/


All Articles