mailto:[email protected]
Lua 用户,维基幕后之人。(挑战:快速说十遍“lua-users”。)
我通过成功游说影响了 Lua,例如:
- [使用表格作为全局作用域](Lua 5.0)
- 词法作用域(Lua 5.0)
- 布尔类型(Lua 5.0)
- 使用标准许可证(Lua 5.0)
- 增量式垃圾回收(Lua 5.1)
- 在显示错误对象时尊重
__tostring
(Lua 5.2)
- [作用域退出钩子](Lua 5.4 待关闭变量)
演示文稿 / 出版物
我的页面(或者至少是我创建的页面)
我发布到 lua-l 的帖子 [1]
最喜欢的 lua-users 维基页面
lua-users.org 是...
我认为 Python PEP 的 [3] 是一个很棒的信息来源。 找出 Python 的缺陷以及如何修复它们。了解 Python 如何实现最新的语言潮流。
我想提一下(大多数)维基实现的一个可能并不完全明显的奇妙特性。 它们会忘记过去。虽然每个页面的编辑历史都会被保留,但它会随着时间的推移而逐渐消失。因此,删除的错误、不友好的话语和无用的内容会真正消失,除非有人明确采取行动恢复或存档它们。这与邮件列表或新闻组的概念完全不同,在公共论坛的情况下,每个词都可能被存档到文明结束。一篇与这个主题相关的有趣文章是“删除键的辩护” [4]。
以下是如何使用 unix wget
命令制作此维基的静态副本以供离线浏览。 当然,你无法在离线状态下编辑或搜索维基,所以这会让事情变得不那么有趣。
wget --mirror --html-extension --convert-links https://lua-users.lua.ac.cn/wiki/
JOHN 的 LUA 缺陷
这些问题很严重,如果最终没有得到解决(我很有耐心),我会考虑开始一个实现它们的 Lua 派生版本。
- 表构造器会丢弃序列长度信息。 当一个表由表构造器定义时(例如 { x = 10; 'foo', 5, bar() }),列表部分的长度(在核心构建表时已知)会被丢弃。长度运算符 (#) 可以在之后正确推断出它,但前提是序列中没有 nil 值。(作为一种笨拙的解决方案,Lua 5.2 中的 `table.pack` 将涵盖仅包含序列的表。)
- 没有高效且简洁的列表迭代。 "
for i=1,getn(t)
" 这种写法冗长,如果使用不当,每个项目都需要进行全局表查找。foreachi
这种写法效率不高,因为每个项目都需要额外的函数调用开销,而且也不简洁,因为需要定义一个函数对象。我实现了一个新的 `for` 结构作为解决方案,请参见 LuaPowerPatches。(从 Lua 5.1 开始,这种写法已经改变,但问题仍然存在。现在我们有 "for i=1,#t
" 或 "for _,item in ipairs(t)
"。)
这些问题虽然难看,但可以忍受。
- 从 1 开始索引和使用闭区间。 从 1 开始索引与大多数常用语言背道而驰,Dijkstra 在 [5] 中简洁地对此提出了反对意见。在 Lua 中,闭区间用于 "for" 结构和库函数,这会导致令人不舒服的 (n, n-1) 表示零长度。在普通代码中,经常需要进行 +/-1 的索引调整。(参见 CountingFromOne。)
- 列表操作不支持 nil 元素。 # 运算符和依赖它的函数(如 unpack 和 ipairs)如果列表包含 nil 元素,则行为不确定,或者干脆忽略尾部的 nil。nil 是一个有用的值,这种基本数据类型的合理行为不应该被 Lua 的表实现所阻碍。(Roberto 承认 nil 由于这个问题不是一等公民。)如果表构造器没有丢弃序列长度信息(见上文),这个限制会很容易解决。
- Lua 核心和标准库没有枚举异常。 Lua 核心和标准库可以抛出的错误集没有被枚举。如果一个应用程序想要捕获一个特定的错误,它必须采用解析异常字符串的脆弱做法。
- 顺便说一句,也许我的页面上更普遍地说是“回溯改革”。例如,Lua 使用字符串异常连接文件路径,甚至截断这些文件路径。--DavidManura
已解决的历史问题
- 全局作用域被特殊对待。虽然全局作用域在许多方面可以被视为一个普通的表,但用户定义的事件的处理方式不同。(在 Lua 5.0 中修复)。例如,以下几行调用不同的赋值事件
a = 5
globals().a = 5
- 没有词法作用域。与表一起使用的 upvalue 特性提供了一种词法作用域的形式,但仅限于访问下一个更高作用域的情况。(在 Lua 5.0 中修复。)
- 没有用户定义的迭代。缺乏对用户定义迭代的钩子,阻止了我们创建有用的代理表和列表。(在 Lua 5.0 中修复。)
- 实现中的类型控制较差。实现不提供用于(完全)控制 C 类型用法的编译选项。例如,double 和 long 类型被广泛引用,这会导致某些平台出现问题。(从 Lua 5.0 开始得到很大改进。)
- 无法覆盖表或字符串上的长度运算符 (#)。最值得注意的是,在表的情况下,这阻碍了从 Lua 代码创建自定义列表式对象。(在 Lua 5.2 中修复 - 至少对于表而言。)
-
lua_tostring
不尊重 __tostring
元表钩子。C API 中的 lua_tostring
和基本 Lua 库中的 tostring
不等效。前者不尊重 __tostring
钩子,这对于用户定义类型的调试和错误输出以及使用用户类型模拟字符串非常重要。例如,lua
命令行解释器在未捕获异常的情况下使用 lua_tostring
,因此无法将非字符串异常对象的详细信息传达给用户。(在 Lua 5.2 中,有一个单独的函数 luaL_tolstring
尊重 __tostring
,并且解释器异常处理程序似乎使用了它。)
-
string.format
%s 不调用 tostring
。(在 Lua 5.2 中修复。)
- 没有作用域钩子元机制。 许多应用程序将稀缺资源(例如锁、文件句柄、内存和数据库事务等)暴露给脚本环境。这些资源需要在使用后立即且确定性地释放,无论程序中出现任何异常情况。此外,Python 的上下文管理器(`with` 语句)展示了此类功能的无限用途。当然,这可以用现有的 Lua 实现,但生成的代码难以理解,容易出错,并且大量使用受保护的调用,限制了协程的潜在用途。如果 Lua 提供一种方法来钩入作用域退出事件,则可以解决此问题。请参阅 [Lua:改进确定性资源清理]。(Lua 5.4 中的“待关闭”变量涵盖了这一点。)
最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于 2022 年 9 月 17 日上午 6:47 GMT (差异)