作者
Richard A. O'Keefe <ok(at)cs(dot)otago(dot)ac(dot)nz>
状态
最终版/R12B-5 已在 OTP 版本 R12B-5 中实现
类型
标准跟踪
创建于
2008-09-22
Erlang 版本
OTP_R12B-4

EEP 24:可以在所有模块属性中使用 F/N 来命名函数 #

摘要 #

允许程序员在任何模块属性中使用 F/N 形式(目前仅限于 -export-import)来命名函数。解析器会将此形式转换为现有的 {F,N} 形式,以便下游工具不受影响。

规范 #

在任何模块属性中,形式为 F/N(其中 F 是一个原子,N 是一个非负整数)的项应被转换为 {F,N},前提是它不是在会被计算的表达式中。

本 EEP 不涉及 X/Y 的其他出现情况。特别是,-record-enum 声明中出现的 X/Y 将被评估,因此不受影响。

动机 #

比较

-compile({inline,
    [{ukeymerge3_12,13}, {ukeymerge3_21,13},
     {rukeymerge3_12a,11}, {rukeymerge3_21a,13},
     {rukeymerge3_12b,12}, {rukeymerge3_21b,12}]}).

-deprecated(
    [{new_set,0},{set_to_list,1},{list_to_set,1},{subset,2}]).

-compile({inline, [
    rukeymerge3_12a/11,
    rukeymerge3_12b/12,
    rukeymerge3_21a/13,
    rukeymerge3_21b/12,
    ukeymerge3_12/13,
    ukeymerge3_21/13]}).

-deprecated([
    list_to_set/1,
    new_set/0,
    set_to_list/1,
    subset/2]).

可读性的提高是值得注意的,特别是如果作者在这样的列表中遵循 Prolog 的做法,每行放置一个按字母顺序排列的 F/N 形式时。

一致性的提高是值得拥有的:不再是 -export-import 模块属性中的 new_set/0,而是 -deprecated 模块属性中的 {new_set,0},它在所有模块属性中都是相同的,从而更容易找到那些提到特定函数的属性。

原理 #

包含实际表达式的模块属性,例如 -record(以及如果被接受的 -enum),需要一定的注意。我考虑过允许在所有地方使用 F/N 表示法;毕竟,一个原子不能除以一个整数。然而,有了 fun F/N 形式,现在在表达式中将函数表示为 {F,N} 的场合非常少。

此外,-export-import 属性中出现的 F/N 目前会被转换为元组(通过 farity_list),所以这只是一个在其他地方扩展这个概念的小问题。我无法想象为什么这没有在几年前就完成。

向后兼容性 #

目前没有属性接受 F/N,它不是要计算的表达式的一部分,并且不表示函数,而那些表示函数的属性已经将其视为 {F,N} 元组。

没有任何现有的源代码会受到影响。

使用自制前端而不是 Erlang 语法工具的程序,例如那些想要保留空格、注释等的程序,必须由它们的维护者进行扩展以识别新形式。{fred,3} 已经在 Erlang 源代码中可以用两种不同的方式编写:也允许使用 {fred,+3}。因此,这样的程序已经必须处理具有相同抽象形式的多个源形式,而这只是添加了一个变体。

生成 Erlang 源代码的程序应该在某一天被修改为生成新形式,但由于旧形式不会被删除,甚至(为了保留最近书籍的价值)也不会被弃用,所以没有必要。

参考实现 #

需要在 parse.yrl 文件中的 normalise/1 函数的

%% Name/Arity case
normalise({op,_,'/',{atom,_,F},{integer,_,I}}) when I >= 0 ->
   {F,I};

最后一个子句(它会引发异常)之前添加一个子句。提供了一个上下文差异 eep-0024-1.diff

版权 #

本文档已置于公共领域。