4  未来潜在的不兼容性

4 未来潜在的不兼容性

本文档列出了 Erlang/OTP 中计划的未来潜在不兼容性。

从 OTP 27 开始,函数 erlang:fun_info/1,2 将始终表示本地 init 进程创建了所有 fun,无论 fun 最初是在哪个进程或节点上创建的。

在 OTP 28 中,{pid,_} 元素将完全移除。

从 OTP 27 开始,maybe_expr 功能将被批准并默认启用。这意味着使用未引用的原子 maybe 的代码将无法编译。所有将 maybe 用作原子的用法都需要用引号引起来。或者,作为短期解决方案,可以禁用 maybe_expr 功能。

建议尽快将所有使用原子 maybe 的地方用引号引起来。编译器选项 warn_keywords 可用于发出关于所有未加引号的 maybe 出现的警告。

模块 re 的功能目前由 PCRE 库提供,该库不再积极维护。因此,在 OTP 27 中,我们将切换到不同的正则表达式库。

re 模块使用的 PCRE 源代码已由 OTP 团队修改,以确保正则表达式匹配在匹配大型输入二进制文件或使用要求苛刻(回溯)的正则表达式时会产生结果。由于这些修改,迁移到 PCRE 的新版本一直是一个耗时的过程,因为所有修改都必须手动应用到更新的 PCRE 源代码中。

最有可能的是,新的正则表达式库将是 RE2。RE2 保证匹配时间与输入字符串的长度呈线性关系,并且它还避免递归以防止堆栈溢出。这应该可以使在不修改其源代码的情况下使用 RE2 成为可能。有关为什么 RE2 是一个好选择的信息,请参阅 WhyRE2

此更改的一些影响是

  • 我们预计 re 模块中的函数将继续得到支持,尽管某些选项可能会被停止。

  • 只有对 UTF8 编码的二进制文件的模式匹配可能会得到支持(而不是 Latin1 编码的二进制文件)。

  • 为了保证线性时间性能,RE2 不支持 PCRE 中正则表达式模式的所有结构。例如,不支持反向引用和环视断言。请参阅 Syntax,了解 RE2 支持的内容的描述。

  • 编译正则表达式可能会变慢,因此通过在与正则表达式匹配之前显式地编译正则表达式,可以获得更多收益。

目前,浮点数 0.0-0.0 具有不同的内部表示。如果将其转换为二进制文件,则可以看出这一点

1> <<0.0/float>>.
<<0,0,0,0,0,0,0,0>>
2> <<-0.0/float>>.
<<128,0,0,0,0,0,0,0>>

但是,当它们相互匹配或使用 =:= 运算符进行比较时,它们被认为是相等的。因此,0.0 =:= -0.0 目前返回 true

在 Erlang/OTP 27 中,0.0 =:= -0.0 将返回 false,而将 0.0-0.0 匹配将失败。当用作映射键时,0.0-0.0 将被视为不同的。

== 运算符将继续对 0.0 == -0.0 返回 true

为了帮助查找可能需要修改的代码,在 OTP 27 中,当与 0.0 匹配或使用 =:= 运算符与该值进行比较时,将出现一个新的编译器警告。可以通过与 +0.0 而不是 0.0 匹配来抑制警告。

我们计划在 OTP 26.1 中引入相同的警告,但默认情况下它将被禁用。

在 Erlang/OTP 26 之前,编译器会静默地接受以下规范

-spec f(Opts) -> term() when
    Opts :: {ok, Unknown} | {error, Unknown}.
f(_) -> error.

在 OTP 26 中,编译器会发出警告,指出类型变量 Unknown 未绑定

t.erl:6:18: Warning: type variable 'Unknown' is only used once (is unbound)
%    6|     Opts :: {ok, Unknown} | {error, Unknown}.
%     |                  ^

在 OTP 27 中,该警告将成为错误。

Escripts 将默认编译而不是解释。这意味着 compiler 应用程序必须可用。

可以通过在脚本文件中添加以下行来恢复解释 escripts 的旧行为

-mode(interpret).

在 OTP 28 中,对解释 escript 的支持将被移除。

此命令行选项控制在命令行、启动脚本和代码服务器中给出的路径应该是严格解释还是宽松解释。

OTP 26 及更早版本默认设置为 relaxed,这意味着 -pa myapp/ebin 将尝试加载 -pa myapp/ebin-pa myapp/myapp/ebin。该选项将在 OTP 27 中默认设置为 strict。

OTP 26 及更早版本允许应用程序将其部分目录作为普通文件夹,而其他目录作为存档。此功能以前由 reltool 使用,但从 OTP 26 开始不再是这种情况。在 OTP 27 中,将从代码服务器中移除对存档回退的支持。

在 Erlang/OTP 27 之前,3 个或更多个双引号字符的序列将成对分组,每个对表示空字符串,如果数量为奇数,则最后一个字符是字符串的开头。然后,这些空字符串被连接起来,并有效地消失了。

在 Erlang/OTP 27 中;3 个或更多个双引号字符被解释为“三引号字符串”的开头。请参阅 EEP 64

以下是一些代码示例,这些代码的含义将发生改变。请注意,在 Erlang/OTP 27.0 之前,所有这些示例都有些奇怪,因为没有充分的理由以这种方式编写代码。

"""String Content"""
%% Was interpreted as
"" "String Content" ""
%% Which becomes
"String Content"
%%
%% In OTP 27 it is instead a syntax error since no text is allowed
%% on the line after an opening triple-quote
      
"""
String Content
"""
%% Was interpreted as
"" "
String Content
" ""
%% Which becomes
"
String Content
"
%%
%% In OTP 27 it is instead interpreted as a
%% Triple-Quoted String equivalent to
"String Content"
      
""""
++ foo() ++
""""
%% Became
"" ++ foo() ++ ""
%%
%% In OTP 27 it is instead interpreted as a
%% Triple-Quoted String (triple-or-more) equivalent to
"++ foo() ++"
      

从 Erlang/OTP 26.1 到 26.2,编译器会对 3 个或更多个双引号字符的序列发出警告,因为这几乎肯定是一个错误,或者类似于错误的自动代码生成的结果。如果用户收到该警告,应更正代码,例如,在空字符串之间插入适当的空格,或完全删除多余的空格,这在 Erlang/OTP 27 之前和之后将具有相同的含义。

从 Erlang/OTP 26.2 到 27.0,这种情况得到改进,因此编译器改为对没有空格间隔的相邻字符串字面量发出警告,这在字符串开头实际上是相同的,但也涵盖了字符串结尾处的相同情况。

从 OTP 28 开始,函数 erlang:fun_info/1 将不包括 {pid,_} 元素,函数 erlang:fun_info/2 将不再接受 pid 作为第二个参数。

Escripts 将被编译,并且将不再可以通过使用指令 -mode(interpret) 来强制 escript 被解释。

从 OTP 29 开始,maybe_expr 功能将成为永久功能,并且将不再能够禁用。所有将 maybe 用作原子的用法都需要用引号引起来。

建议尽快将所有使用原子 maybe 的地方用引号引起来。编译器选项 warn_keywords 可用于发出关于所有未加引号的 maybe 出现的警告。