← 所有文章

工程哲学:Roberto Ierusalimschy

Roberto Ierusalimschy,Lua 的创造者

核心要点

  • 他设计的脚本语言,藏身于你日常接触的海量软件之中。 Roberto Ierusalimschy 主导了 Lua 的设计。这门语言于 1993 年诞生于 PUC-Rio 的 Tecgraf 实验室,与他一同设计的还有 Luiz Henrique de Figueiredo 和 Waldemar Celes。它驱动着《魔兽世界》、《Roblox》(通过其 Luau 方言)、《Dota 2》和《Garry’s Mod》中的游戏逻辑,为 Redisnginx(通过 OpenResty)编写脚本,支撑着 Adobe LightroomWireshark,甚至嵌入到底层连操作系统都没有的机器人当中。127
  • 提供机制,而非政策。 Lua 最具标志性的选择是一种拒绝——它不附带类系统,不附带对象模型,也不附带任何范式。它只给你少数几样强大而通用的机制(表、元表、协程),让你在此之上构建自己的抽象。设计者们写道:”Lua 不会把任何对象或类模型强加给程序员”;相反,他们”提供灵活的机制”,让你能够构建任何适合应用的模型。3
  • 小巧是一种特性,而非局限。 参考实现既精简又干净——Lua 5.1 的源码约为 17,000 行 C 代码,整个发行版可以装进一张软盘,构建出的解释器约为 143 KB。大多数脚本语言要大上一个数量级;Lua 之所以保持小巧,正是因为它被设计为可嵌入,而简洁正是小而快的实现得以成立的前提。3
  • 可移植性与可嵌入性从第一天起就是设计目标。 Lua 用”干净的 C”——即 C 与 C++ 的交集——编写,”在大多数平台上开箱即可编译”,从 Linux、Windows 到掌上设备和微控制器无不如此。一套定义明确的 C API 让宿主程序得以完全掌控并扩展它,这也正是游戏行业将其奉为准标准的原因。34

核心原则

“我们不想把 Lua 变成一门面向对象的语言,因为我们不想为 Lua 固定某种编程范式……Lua 不会把任何对象或类模型强加给程序员。相反……我们决定提供灵活的机制,让程序员能够构建任何适合应用的模型。”——Roberto Ierusalimschy、Luiz Henrique de Figueiredo 和 Waldemar Celes,The Evolution of Lua3

大多数语言设计都是政策的层层累积。一个团队决定对象应该这样工作、错误处理应该那样呈现、并发意味着线程、异步抑或 actor——然后把这些决定烘焙进语言之中,于是用它写出的每个程序都继承了这些选择。这些决定通常合情合理。问题在于,它们终归是决定,由一群无从了解你应用场景的人,一次性替所有人做出。Ierusalimschy 的直觉恰恰相反。Lua 不替你做决定,而是把一小组通用机制交到你手里,然后让开,让你去构建问题真正需要的政策。3

最清晰的例子莫过于面向对象。20 世纪 90 年代初,面向对象编程的炒作正值顶峰,用户敦促 Lua 团队加入类和继承。他们拒绝了——并非因为 OOP 是错的,而是因为对一门要嵌入到千差万别应用中的语言来说,固定某一种模型才是错的。他们的理由是,对象和类”如有需要,用表就能实现”,因为表既能存放数据又能存放方法,而函数是一等值。3 于是,他们没有去做对象系统,而是构建了可扩展的语义——一种让你能介入表行为方式的机制——并让用户自行拼装出继承、默认值、只读视图乃至完整的类层级。他们写道:”可扩展语义已成为 Lua 的一大标志”,而且”直到今天我们都没有改变主意”。3

这种拒绝之所以负担得起,全靠另外三项与之相伴的承诺。简洁——语言保持得足够小,机制因而可理解,实现也因而正确。以小巧为特性——整个参考实现约为 17,000 行干净的 C 代码,小到把 Lua 加进应用”不会让它臃肿”。3 还有可移植性——用 C 与 C++ 的交集来编写,意味着同一份源码无论在超级计算机还是传感器上都能编译。3 给人们几根锋利而通用的操纵杆,而不是一柜子预先设定好的按钮,并把整个东西保持得足够小,随处都能带着走。 这就是那个原则,而 Lua 中其余的一切都是它的推论。

背景

Roberto Ierusalimschy 于 1960 年 5 月 21 日生于里约热内卢,他的整个职业生涯都紧贴着同一个机构——里约热内卢天主教大学(PUC-Rio)。他于 1990 年在那里取得计算机科学博士学位,如今是该校的信息学正教授。他曾在滑铁卢大学做博士后研究,也曾在斯坦福担任访问教授,但 PUC-Rio 才是他的根,而 Lua 的故事与那里的一间特定实验室密不可分。5

那间实验室就是 Tecgraf,即计算机图形技术组,成立于 1987 年,专为工业客户开发软件工具——其中最大的客户之一,当年是、如今仍是巴西石油公司 Petrobras。3 Lua 的起源,某种程度上是一个关于巴西贸易政策的故事。从 1977 年到 1992 年,巴西对计算机硬件和软件维持着严厉的贸易壁垒政策——所谓的”市场保留”,其背后是一种民族主义信念:这个国家能够、也应当自建产业。在这种氛围下,Tecgraf 的客户”无论从政治上还是财务上都负担不起从国外购买定制软件”。购买外国工具意味着要走一套”繁复的官僚流程,以证明本国公司无法满足其需求”。这些限制,再加上巴西与其他研究中心在地理上的隔绝,”促使 Tecgraf 从零开始实现自己所需的基础工具”。3 用设计者自己的话说,Lua 是”唯一一门诞生于发展中国家却取得全球影响力的语言”。3

在 Lua 之前,先有两门小语言,都是为 Petrobras 而建的。DEL——“数据录入语言”(data-entry language)——能生成图形化前端,让工程师可以通过在图示上点击来输入模拟器参数,而不必去编辑一列列数字。3 SOL——“简单对象语言”(Simple Object Language)——则是一门用于报表生成器的配置语言,其类型声明语法受到 BibTeX 的影响。3 到 1993 年初,两者都已超出各自最初的范畴;DEL 的用户想要真正的控制流,而 SOL 需要过程式的能力。1993 年年中,Ierusalimschy、de Figueiredo 和 Celes 得出结论:这两者可以由一门更强大的单一语言取而代之——于是 Lua 团队就此诞生。3 这个名字是个流传下来的小玩笑。SOL 在葡萄牙语中意为”太阳”;Tecgraf 的一位朋友 Carlos Henrique Levy 建议把它的继任者叫做 ‘Lua’——葡萄牙语中的”月亮”3 到 1993 年 7 月,Waldemar Celes 完成了第一个实现,它作为一个由 Ierusalimschy 指导的课程项目构建而成,遵循极限编程的信条:”可能行得通的最简单的东西”。3

这项工作

表与元表:一种数据结构,一种机制

就从表说起,因为它是整门语言的缩影。Lua 只提供一种数据组织机制——,也就是它对关联数组的称呼——而这一种结构就承担了记录、数组、集合、列表、模块和对象的全部活计。3 设计者们指出:”虽然大多数脚本语言都提供关联数组,但没有哪门语言让关联数组扮演如此核心的角色。”3 记录是以字段名为键的表;数组是以整数为键的表;对象则是恰好同时存放数据和方法的表。一种机制,多种用途——这正是把”提供机制,而非政策”的赌注应用到数据上的结果。

让表变得可编程的那根操纵杆,是元表。通常,查找一个表中不存在的键会返回 nil。但你可以给表赋予一个元表——第二张表,用来描述第一张表在异常情况下应当如何表现。其中最重要的条目是 __index:当查找落空时,Lua 会去查阅元表的 __index,而它可以指向另一张表,接着去那里继续查找。把这些串联起来,你就得到了完全用表和单次重定向搭建出的继承。同一套机制,换用不同的元方法,就能带来运算符重载、默认值、只读代理和惰性字段。这些都不是通常意义上的语言特性——全都是同一种机制,只是以不同的形态被使用。3

这套机制并非一蹴而就——它的演进本身就是一堂关于克制的课。它最初在 Lua 2.1(1995)中以”回退”(fallbacks)的形式出现:当某个操作被施加于”错误”类型的值时,Lua 会调用这些钩子,让程序员来决定接下来发生什么。3 表索引回退让 userdata 和其他值”表现得像表一样”,从而支持”多种形式的继承(通过委托实现)”。3 回退是全局的——每个事件只有一个钩子——这使得它在多个库之间共享起来很别扭,于是 Lua 3.0(1997)用按类型划分的”标签方法”(tag methods)取而代之,而 Lua 5.0(2003)则把一切统一为元表和元方法,也就是 Lua 沿用至今的形态。(”元表”这个术语由 Rici Lake 于 2001 年提出。)3 每一步都是在泛化这套机制,而非堆砌新特性——正是这种直觉,让这门语言始终拒绝附带类系统。

可嵌入性、C API,以及游戏为何选择了 Lua

Lua 其实并不打算做一门独立语言。设计者们称它为“可扩展的扩展语言”——说它是扩展语言,是因为它通过配置和脚本来扩展宿主应用;说它可扩展,是因为它反过来又能用 C 函数来扩展。3 枢纽在于一套定义明确的 C API,它”允许 Lua 代码与外部代码之间充分通信”,并围绕一个干净的栈隐喻来构建,用以在 Lua 与宿主之间来回传递值。这套 API 不仅让 Lua 能与 C 和 C++ 对接,还能通过它们与 Fortran、Java、C# 等完全不同的语言对接。3

回报在游戏领域如约而至,而这个故事很具体。1997 年 1 月,LucasArts 冒险游戏《Grim Fandango》的首席程序员 Bret Mogilefsky 告诉 Lua 团队,他已经用 Lua 替换了游戏自研的脚本语言,而且”游戏中极大一部分都是用 Lua 写成的”。3 Mogilefsky 在一次游戏开发者大会的圆桌讨论上谈起了它,从那以后,”Lua 在游戏开发者之间口耳相传,成为游戏行业里一项实打实有市场价值的技能”。3 这种契合是结构性的。游戏引擎恰恰是那种能从嵌入式脚本层中获益的宿主——繁重的活计(渲染、物理)留在快速的 C++ 里,而游戏逻辑、任务和行为则存活在小巧的 Lua 脚本中,设计师无需重新编译引擎就能编辑并重新加载它们。小巧、快速、可移植、可嵌入,恰是游戏所需的特质,而 Lua 从第一个版本起就是为此而生的。34

协程,以及一个小而快的实现

第三大机制是协程——和 OOP 一样,它是团队对某种政策的有意拒绝。整个 20 世纪 90 年代后期,用户都在推动多线程,而显而易见的做法是采用标准的抢占式、共享内存线程模型。Lua 团队拒绝了,理由有二:在 C 中实现抢占式线程需要”不属于 ANSI C”的原语,这会破坏 Lua 的可移植性;而更根本的是,”我们当时不相信(如今仍然不相信)标准的多线程模型”,在那种模型里,”没人能在一门 ‘a=a+1’ 都不确定的语言里写出正确的程序”。3 于是,他们没有提供线程,而是在 Lua 5.0(2003)中提供了协程:一种用于协作式、非抢占式多任务的机制,函数可以挂起自身,之后再从它离开的地方精确地恢复执行。3 协程给你并发的表达力——生成器、协作式调度器、状态机——却没有那种让共享内存线程极难写对的不确定性。再一次,是机制,而非政策。

支撑这一切的,是一个之所以快、正是因为它小的实现。Lua 的虚拟机直到 Lua 4.0 都是基于栈的;到 Lua 5.0 才变为基于寄存器,这给了代码生成器更大的优化空间,并减少了一个典型程序所要执行的 VM 指令数量。设计者们指出,”Lua 5.0 的虚拟机是第一个被广泛使用的基于寄存器的虚拟机”。3 内存由一个增量式垃圾回收器(在 Lua 5.1 中引入)管理,它把工作拆成小步进行,而不是长时间地停顿整个世界——这对游戏的实时循环至关重要。3 多项独立基准测试把 Lua 列为解释型脚本语言中最快的一批,快到用设计者的话说,”Adobe Lightroom 有超过 40% 是用 Lua 写的”,约合 10 万行 Lua 代码。3

Lua 编程语言

Lua 的触角:从《魔兽世界》到一个没有操作系统的机器人

把这一切加总起来,Lua 成了一大片软件中那道隐形的脚本层。在游戏里,《魔兽世界》把它的整个界面都暴露给 Lua,让玩家可以编写插件;《Roblox》打造了 Luau 这门 Lua 方言,作为数以百万计的年轻创作者学习编程所用的语言;《Dota 2》、《孤岛危机》和《Garry’s Mod》也都嵌入了它。1 在游戏之外,Redis 在数据库内部原子地运行 Lua 脚本;nginx 通过 OpenResty 发行版,用 Lua 来编程 Web 服务器本身;Adobe LightroomWireshark 有相当一部分构建于它之上;Neovim 把 Lua 采纳为一等的配置与插件语言。1 又因为解释器小巧且可移植,Lua 触及到几乎一无所有的硬件——设计者们讲过 Crazy Ivan 的故事,这是一个赢得过 RoboCup 的机器人,它的”大脑”运行着 Lua,”直接跑在一颗 Motorola Coldfire 5206e 处理器上,底下没有任何操作系统;换句话说,Lua 就是操作系统”。7 一门在里约一间实验室、在贸易限制之下打造出来的小语言,最终却无处不在——因为它几乎一无所求,又把搭建其余一切的操纵杆交给了你。

方法论

通览 DEL、SOL、元表、协程,以及三十年来拒绝让语言臃肿的历程,同样的招式反复出现。Ierusalimschy 的方法与其说是一句口号,不如说是一组始终如一的承诺。

交付机制,而非政策。 那个最具标志性的习惯,就是提供一根通用的操纵杆,而拒绝去规定它必须如何被使用。没有内建的类系统,没有固定的并发模型——只有表、元表和协程,你用它们去构建应用所需要的一切。这条普遍的教训远远超出语言设计的范畴:最经久耐用的工具,恰恰是那些赋予能力却不规定解决方案形态的工具。它与 Guido van Rossum 的”应当有一种显而易见的做法”恰好相反,而这种对比正是要点所在——两者都自成一体,而知道你的工具该体现哪种哲学,才是真正的决定。3

让它小到足够正确,也足够随处可带。 Lua 的参考实现约为 17,000 行干净的 C 代码,比其他脚本语言小上一个数量级,而这种小巧是一项刻意为之的特性——正是它让这门语言可嵌入、可移植、可信赖。这门功夫在于不停地删减,直到再删一样东西就会让它崩坏,这使 Lua 成了 Sophie Wilson 在 ARM 中那种冷峻极简的软件镜像——剥到承重的本质,让效率随之免费落入囊中。这就是语言运行时层面上的最小可敬产品3

抵住别人向你索要的那个特性,直到你找到它底下的机制。 当用户要对象时,Lua 给了他们可扩展的语义;当他们要线程时,它给了他们协程。每一次,团队都拒绝了那个具体的政策,转而交付更通用的机制,让用户自己去构建政策——而且关键在于,多年之后也没有改变主意。3 这就是把证据门槛应用到特性请求上:不要因为有人索要就把东西加进去;先弄清它解决的是什么问题,以及你手上已有的某个机制能否解决它。

做泛化,而非做堆砌。 元表并非一蹴而就——它从回退长成标签方法,再长成元方法,每一步都是用一个更通用的机制替换前一个机制,而不是在旁边再栓上一个新特性。3 教训在于通过统一来演进,而非通过添加来演进,这样语言变得更有能力,体量却保持不变——正是 Thompson 和 Ritchie 用小巧、可组合的零件构建 Unix 时所秉持的那种手段上的经济性。

让约束去设计工具。 Lua 之所以存在,是因为巴西的贸易壁垒迫使 Tecgraf 自建软件;它之所以可移植,是因为实验室的客户运行着”一大堆五花八门的计算机平台”。3 Ierusalimschy 没有把这些约束当作累赘,反而让它们把设计推向某种更小、更干净、也比一支资源充裕的团队多半会做出的东西更可移植的方向——这条教训告诉我们,匮乏只要被认真对待,就是一种设计工具,而不是一句辩解。3

影响链

谁塑造了他

Scheme 与 Lisp 传统。 设计者们明确表示,”Scheme 对 Lua 的影响逐渐加深”,成为”一个灵感来源,尤其是在引入匿名函数和完整的词法作用域时”。3 和 Scheme 一样,Lua 是动态类型的,把函数当作普通的一等值,并把核心保持得很小——这背后是一种信念:一门语言可以靠极简而非庞大来变得强大。(奠基性影响)

DEL 与 SOL 这两门小语言。 Lua 并非从理论中跃出;它是从为 Petrobras 构建的两门领域特定语言中生长出来的。SOL 贡献了用于描述数据的表构造器语法,而这两者的经验教会了团队:”复杂应用的大部分都可以用可嵌入的脚本语言来编写”——用他们的话说,Lua 的诞生正是建立在这一领悟之上。3(直接影响)

巴西的市场保留政策。 从 1977 年延续到 1992 年的贸易壁垒,是一个出人意料却千真万确的影响:正是它让 Tecgraf 自建了自己的工具,而其客户平台的多样性,正是可移植性成为一流设计目标的原因。是政策造就了这门语言。(奠基性影响)

他塑造了谁

游戏行业的脚本层。 从《Grim Fandango》起,Lua 成了嵌入游戏逻辑的准默认之选,而它所普及的那种模式——快速引擎用 C++、可编辑行为用嵌入式脚本——如今已是标准做法。Roblox 的 Luau 让一代孩子用一门 Lua 方言学会了编程。(定义领域的影响)

嵌入式与系统软件。 Redis、nginx/OpenResty、Wireshark、Neovim,以及数不清的设备,都把 Lua 采纳为脚本层,正是因为它索求甚少。鲜有语言能从一个数据库,触及到一个网络分析器,再触及到一个跑在裸机上的机器人。

那些珍视小巧的语言设计者。 Lua 是一个可运作的明证:一个微小、不偏袒任何范式的核心,能够在嵌入这一利基里胜过庞大而固执己见的语言——这一论点回响在此后每一个极简运行时与”机制胜过框架”的设计之中。

贯穿的主线

Ierusalimschy 处在本系列那场漫长论辩的一极,那场论辩关乎一个工具该替你决定多少Guido van Rossum 把 Python 建立在”应当有一种显而易见的做法”之上,并附带”电池内置”——语言有自己的主张,而顺从这些主张就是阻力最小的路径。Bjarne Stroustrup 把 C++ 造得足够丰富,几乎能表达任何范式,代价是它在体量和复杂度上的付出。Ierusalimschy 走了与两者都相反的路:几乎不交付任何政策,几乎不交付任何特性,只有少数几样通用机制和一个 17,000 行的运行时,然后让用户去构建其余的一切。他是 Sophie Wilson 的软件镜像,她的 ARM 靠着被剥减到不足 25,000 个晶体管而取胜——Lua 就是用 C 写就的同一种冷峻的小巧,而且和 ARM 那意外的低功耗一样,它的小巧最终成了让它征服一个无人为它设计的领域(嵌入)的那个关键。当 van Rossum 说这就是那条显而易见的路、Stroustrup 说这里有每一条路时,Ierusalimschy 说的是:这里是操纵杆——你来决定构建什么,而我会把整个东西保持得足够小,随处都能带着走。(系列桥接)

我从中得到的

我从 Ierusalimschy 那里一直记着的一课是:你能交给一个人的最强的东西,是机制,而非政策。 当你构建一个工具时,很容易禁不住把自己对它该如何被使用的看法烘焙进去——交付那个类系统、那个框架、那一条被祝福的工作流。Lua 的整段生涯都在论证:相反的做法更经得起岁月。正是因为拒绝固定一种对象模型、转而交付元表,这门语言才让用户构建出了设计者从未设想过的继承方案,用在他们从未预料过的游戏、数据库和编辑器里。如今当我构建什么东西时,我从 Lua 借来的问题是:我交付的究竟是一个决定,还是一种能力——因为决定服务于我今天能看见的那些情形,而能力服务于我看不见的那些。

第二课是:小巧不是一种你勉强容忍的约束——它是一种你要去守护的特性。 在三十年的用户压力之下,要让 Lua 长成一门带着 class 关键字、一个线程库和一套包罗万象的标准框架的庞大语言,本是再容易不过的事。团队拒绝了,而正是这种拒绝,才让 Lua 能装进一张软盘、能随处编译、能嵌入一个机器人的裸机大脑。保持小巧这门功夫——做泛化而非做堆砌,抵住那个特性直到你找到它底下的机制——比做添加那门功夫更难,也远更宝贵。这是把质量是唯一的变量当作克制来读:那件正确的小东西,被守护了数十年,便成了别的一切都能立足其上的基础设施。

常见问题

Roberto Ierusalimschy 是谁,他创造了什么?

Roberto Ierusalimschy 是一位巴西计算机科学家,1960 年生于里约热内卢,现为 PUC-Rio 的信息学正教授。他是 Lua 的首席设计者——这门小巧、快速、可嵌入的脚本语言,由他于 1993 年在 PUC-Rio 的 Tecgraf 实验室与 Luiz Henrique de Figueiredo 和 Waldemar Celes 一同创造。他也是《Programming in Lua》一书的作者、模式匹配库 LPeg 的创造者,并合著了这门语言的权威历史文献《The Evolution of Lua》。356

Lua 中的”提供机制,而非政策”是什么意思?

它意味着 Lua 给你少数几样强大而通用的机制,而不是强加固定的决定。最清晰的例子是面向对象:Lua 没有内建的类系统。相反,它提供表(既能存放数据又能存放方法)和元表(让你定制表的行为方式),而继承、类或任何其他对象模型都由你自己来构建。设计者们写道:”Lua 不会把任何对象或类模型强加给程序员”,并选择”提供灵活的机制”作为替代——这是他们自 1993 年起一直坚持的立场。3

为什么 Lua 在游戏和嵌入式系统中如此广泛地被使用?

因为它从一开始就被设计得小巧、快速、可移植且易于嵌入。参考实现约为 17,000 行干净的 ANSI C 代码,几乎在任何地方都能编译;构建出的解释器约为 143 KB;一套定义明确的 C API 让宿主程序得以完全掌控它。这种特质恰是游戏引擎或嵌入式设备所需要的——繁重的活计交给 C/C++,可编辑的逻辑放进小巧的脚本——这也是它为何能为《魔兽世界》、《Roblox》(通过 Luau)、Redis、nginx/OpenResty、Adobe Lightroom 乃至底层的裸机机器人编写脚本。137

“Lua”这个名字从何而来?

Lua 在葡萄牙语中意为”月亮”。它得名于作为更早一门 Tecgraf 语言 SOL 的继任者——SOL 即”简单对象语言”(Simple Object Language),同时在葡萄牙语里也是”太阳”的意思。Tecgraf 的一位同事 Carlos Henrique Levy 为这门新语言建议了”Lua”这个名字,完成了从太阳到月亮的递进。整个项目脱胎于 DEL 和 SOL 这两门为巴西石油公司 Petrobras 构建的小语言。3


资料来源


  1. “Lua (programming language),” Wikipedia. Lua was created in 1993 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes at the Computer Graphics Technology Group (Tecgraf) at the Pontifical Catholic University of Rio de Janeiro (PUC-Rio), Brazil; implemented in ANSI C, MIT-licensed, with a register-based virtual machine since Lua 5.0, garbage collection, coroutines, and first-class functions. Recent reference implementations remain small (the article notes Lua 5.5.0 comprises approximately 32,000 lines of C). Documented users include the games World of Warcraft, Roblox (which developed Luau, a Lua derivative), Dota 2, Crysis, and Garry’s Mod, and non-gaming software including Redis, nginx (via OpenResty), Adobe Lightroom, Wireshark, and Neovim. 

  2. “Roberto Ierusalimschy: Known for Lua Programming Language,” machaddr (biographical profile). Summarizes Ierusalimschy’s role as creator and lead architect of Lua, developed with Luiz Henrique de Figueiredo and Waldemar Celes at PUC-Rio, first released in 1993; notes Lua’s worldwide use in software including World of Warcraft and Adobe Lightroom, his authorship of Programming in Lua, and his creation of the LPeg library. 

  3. Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes, “The Evolution of Lua,” Proceedings of the Third ACM SIGPLAN Conference on the History of Programming Languages (HOPL III), 2007. Primary source. “Lua is a scripting language born in 1993 at PUC-Rio.” “From the start, Lua was designed to be simple, small, portable, fast, and easily embedded into applications.” The single data structure: “it offers a single kind of data structure, the table.” Implemented in “clean C,” “the intersection of C and C++,” and “compiles out-of-the-box on most platforms.” Small size: the Lua 5.1 source is “around 17,000 lines of C,” the tarball “fits comfortably on a floppy disk,” and “the Lua interpreter built with all standard Lua libraries takes 143K.” “over 40% of Adobe Lightroom is written in Lua (that represents around 100,000 lines of Lua code).” On Brazil’s trade policy: “From 1977 until 1992, Brazil had a policy of strong trade barriers (called a ‘market reserve’) for computer hardware and software,” and “those reasons led Tecgraf to implement from scratch the basic tools it needed”; Lua is “the only language created in a developing country to have achieved global relevance.” Predecessors DEL (“data-entry language”) and SOL (“Simple Object Language”). Naming: SOL is sun in Portuguese, and “a friend at Tecgraf (Carlos Henrique Levy) suggested the name ‘Lua’ (moon in Portuguese), and Lua was born.” First implementation finished July 1993 following “the simplest thing that could possibly work.” On “mechanisms, not policy”: “we did not want to turn Lua into an object-oriented language because we did not want to fix a programming paradigm for Lua”; “Lua does not force any object or class model onto the programmer”; “we decided to provide flexible mechanisms that would allow the programmer to build whatever model was suitable to the application”; “Extensible semantics has become a hallmark of Lua.” Mechanism evolution: fallbacks (Lua 2.1, 1995) → tag methods (Lua 3.0, 1997) → metatables and metamethods (Lua 5.0, 2003); table-indexing fallbacks supported “many forms of inheritance (through delegation)”; the term “metatable” was suggested by Rici Lake in 2001. Lua as “an extensible extension language” with a C API allowing “full communication between Lua code and external code.” Games: in January 1997, Bret Mogilefsky, lead programmer of LucasArts’ Grim Fandango, reported that “a tremendous amount of the game was written in Lua,” after which “Lua spread by word of mouth among game developers to become a definitely marketable skill in the game industry.” Concurrency: implementing preemptive threads requires primitives “not part of ANSI C,” and “we did not (and still do not) believe in the standard multithreading model… no one can write correct programs in a language where ‘a=a+1’ is not deterministic”; cooperative multitasking via coroutines was provided in Lua 5.0 (2003). VM: “Since Lua 5.0, the virtual machine is register-based,” and “the virtual machine of Lua 5.0 was the first register-based virtual machine to have wide use”; incremental garbage collection appears in Lua 5.1. 

  4. “Lua: about,” Lua.org (official site). “Lua is a powerful, efficient, lightweight, embeddable scripting language.” It “is implemented as a small library of C functions, written in clean C, the common subset of Standard C and C++,” and “runs on all kinds of Unix and Windows systems, as well as on mobile devices… embedded microprocessors… and IBM mainframes.” Describes Lua as combining “simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics,” with dynamic typing, automatic memory management with incremental garbage collection, and being “fast” and “portable.” 

  5. “Roberto Ierusalimschy,” Wikipedia, corroborated by his “faculty profile,” Department of Informatics, PUC-Rio. Born 21 May 1960 in Rio de Janeiro, Brazil; PhD in computer science from PUC-Rio (1990); full professor of informatics at PUC-Rio; post-doctoral work at the University of Waterloo and visiting professor at Stanford (2012). Creator and lead architect of the Lua programming language, author of Programming in Lua (four editions), and developer of LPeg, a Lua library for implementing parsing expression grammars. 

  6. “Programming in Lua,” by Roberto Ierusalimschy, Lua.org. The official book on Lua, written by its lead designer, describing the language’s design and use; the first edition is freely available online. Reinforces Lua’s design around tables as the sole data-structuring mechanism, metatables for extensible behavior, first-class functions, and coroutines for cooperative multitasking. 

  7. Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes, “The Evolution of Lua,” HOPL III, 2007, footnote on embedded use. “Crazy Ivan, a robot that won RoboCup in 2000 and 2001 in Denmark, had a ‘brain’ implemented in Lua. Lua ran directly on a Motorola Coldfire 5206e processor without any operating system (in other words, Lua was the operating system). Lua was stored on a system ROM and loaded programs at startup from the serial port.” Illustrates Lua’s reach into bare-metal embedded devices, a consequence of its small, portable implementation. 

相关文章

工程哲学:Guido van Rossum,可读性至关重要

Guido van Rossum把Python建立在一个判断之上:代码被阅读的次数远多于被编写的次数,因此语言本身应当为正在读它的人而优化。

1 分钟阅读

工程哲学:Grace Hopper,让计算机说人类的语言

Grace Hopper 打造了第一个编译器,让程序得以用人类语言书写;她用一段电线把延迟变得触手可及,并向陈腐的教条宣战。

3 分钟阅读

The Shader Gallery That Lied: Debugging 216 WebGL Presets

A user said the shader playground looked broken. Pixel-readback testing found 30 dead presets, 11 that never compiled, a…

11 分钟阅读