允许在列表或元组末尾添加额外的逗号。Darren New 提出了这个更改;Richard O’Keefe 不太喜欢它,但把它写成了 EEP。
对于某个项 X,原本以 “,X]” 结尾的列表可以改为以 “,X,]” 结尾。对于某个项 X,原本以 “,X}” 结尾的元组可以改为以 “,X,}” 结尾。元组的规则也适用于记录和 -record 声明。
Erlang/OTP 源代码中大约有 5000 行以右方括号或右花括号开头。例如,-record 声明通常布局如下:
-record(foo, {
field_1 = default_1,
...
field_n = default_n
}).
例如,
-record(hostent, {
h_name,
h_aliases = [],
h_addrtype,
h_length,
h_addr_list = []
}).
记录创建表达式通常也类似布局,例如:
make_hostent(Name, Addrs, Aliases, ?S_A) ->
#hostent {
h_name = Name,
h_addrtype = inet,
h_length = 4,
h_addr_list = Addrs,
h_aliases = Aliases
};
如果它们都以相同的方式标点,则向这些列表(在非正式意义上的“列表”)添加条目、删除条目和重新排序条目会更简单。选项列表(在 Erlang 意义上的“列表”)也经常这样布局。
C、C++、Java 和 Javascript 允许在初始值列表中使用尾随逗号。Python 允许在列表和字典中使用尾随逗号。特别是 Python,证明了一种编程语言可以支持此功能,而不会被指责为“羡慕 C”或极端丑陋。
我实际上并不觉得需要这个提议;我认为更好的解决方案是工具支持。然而,许多人迷恋于他们的工具,甚至超过了他们的编程语言。Darren New 不是唯一一个要求这样做的人,并且 Erlang/OTP 源代码中大约有 1/110 的 SLOC 反映了可以使用此功能的列表或元组,这是一个低成本高公众赞赏的功能。
在我修改解析器以使其接受此“功能”之前,我写了最后一句。有 115 行简单的差异。我可以在 10 分钟内对 Prolog 解析器进行此更改,但 Prolog 解析器有一个巨大的优势,它不是使用像 Yecc 这样的 LR 解析器生成器编写的。尽管如此,既然我已经修改了解析器,那么对其他人的成本就很低了。
该规范措辞谨慎。逗号不允许出现在空列表或元组中,也不允许出现在列表或元组推导式中。它们仅允许出现在最后一个元素之后,因此也不允许使用 [1|L,]
。尾随逗号也不允许在参数列表中使用,只能在 []
和 {}
中使用。但是,允许在元组和记录类型中使用。
这与“可选分号”EEP 非常相似(实现起来要简单得多)。该 EEP 的核心是希望使分号和逗号看起来不同;因此,重要的是不允许使用可选的尾随分号。如果分号可以尾随,则逗号不能。如果逗号可以尾随,则分号不能。同样重要的是不要通过允许可选的前导逗号来解决“列表元素的一致标点符号”问题。如果分号可以前导,则逗号不能。如果逗号可以前导,则分号不能。由于尾随逗号是 C、C++、Java、ECMAScript、Python 等的既定做法,因此逗号尾随,分号前导。
我重申这不是我的想法。我只是写了 EEP 并弄清楚了如何实现它。由于 Erlang/OTP 系统中几乎有 1% 的 SLOC 是人们很可能有理由添加尾随逗号的情况(如果它是合法的),因此找出它是否可行似乎是值得的。
所有现有的 Erlang 代码仍然可以接受,且语义不变。逗号完全在解析器中处理;其他语言操作工具永远不知道它们的存在,因此可以与使用它们的代码完美配合。
辅助文件 eep-0021-1.diff 是一个应用于 erl_parse.yrl
的补丁文件。
你可能会认为我们只需要更改
... ']' ... '}'
为
... ',' ']' ... ',' '}'
在几个地方。你会错的。对于不同的语法,也许可以。对于当前的语法,这是一个非常棘手的更改,需要对各种地方进行修改。结果通过 Yecc,除了预期的两个移位/规约冲突(与此更改无关)之外,没有其他抱怨。
本文档已置于公共领域。