作者
James Hague <james(dot)hague(at)gmail(dot)com>
状态
草案
类型
标准跟踪
创建
2009年2月18日

EEP 27: 多参数类型检查 BIF #

摘要 #

类型检查 guard(例如,is_float/1)在很多情况下都很有用,但是它们很冗长。我建议允许 is_ 系列函数接受多个参数,这将在常见情况下显著减少源代码的体积。

规范 #

其中 is_type 代表任何 is_ 系列函数,例如 is_float

is_type(A, B, C, ...) 等价于 (is_type(A) andalso is_type(B) andalso is_type(C)...)

is_type 函数现在可以接受 1 到 N 个参数,其中 N 是函数元数的实现定义限制。

旧式的 guard(例如,float/1)不会改变,因为其中一些兼具类型转换的功能。

在 erlang 模块中直接引用这些函数仅针对单参数版本(例如,fun erlang:is_float/1)。

动机 #

我发现添加类型检查 guard 不仅是为了安全,而且是为了提高代码生成质量,尤其是在使用浮点数时。用 Erlang 编写具有 is_float guard 的三元素或四元素向量数学函数非常冗长。is_float 检查使得原本只需一行的函数,由于添加了多行 guard 而显得臃肿。

理由 #

以下是 Wings3D 项目中的一个示例

cross({V10,V11,V12}, {V20,V21,V22})
  when is_float(V10), is_float(V11), is_float(V12),
       is_float(V20), is_float(V21), is_float(V22) ->
    {V11*V22-V12*V21,V12*V20-V10*V22,V10*V21-V11*V20}.

is_float 检查显著提高了生成的代码质量,允许浮点数保存在虚拟机寄存器中,而不是分配在堆上。如果允许 is_float 接受多个参数,则可以将此代码重写为

cross({V10,V11,V12}, {V20,V21,V22})
  when is_float(V10,V11,V12,V20,V21,V22) ->
    {V11*V22-V12*V21,V12*V20-V10*V22,V10*V21-V11*V20}.

在第二个版本中,意图一目了然,并且添加类型检查的源代码级别开销不会使函数显得臃肿。

多年来,Erlang 系统越来越依赖于类型检查。有 dialyzer 和 typer 工具。编译器可以静态地推断类型并因此生成更好的代码。在源代码级别使类型检查 guard 更轻量级,鼓励了它们的使用,并且更符合该语言的整体语法密度。

向后兼容性 #

如果实现此提案,所有使用 is_type/1 函数的地方仍然可以正常工作。直接引用 erlang:is_floaterlang:is_atom 等作为 fun 的方式仍然可以按照最初的意图工作。

参考实现 #

无。

版权 #

本文档已置于公共领域。