作者
Sergey Prokhorov <seriy(点)pr(在)gmail(点)com>
状态
已接受/23.0 在 OTP 版本 23 中实现
类型
标准跟踪
创建于
2019-10-07
Erlang 版本
OTP-23.0

EEP 51: 数字字面量中的下划线分隔符 #

摘要 #

此 EEP 扩展了数字字面量的语法,允许使用下划线 _ 作为数字分隔符。它扩展了整数、浮点数和基于进制的整数的字面量语法。

版权 #

本文档已置于公共领域。

规范 #

当前数字字面量的语法可以用以下方案描述

DIGIT = [0-9]
BASE_DIGIT = [0-9a-zA-Z]
SIGN = [+-]

INTEGER = SIGN? DIGIT+

FLOAT = SIGN? DIGIT+ '.' DIGIT+ ('e' SIGN? DIGIT+)?

BASED_INTEGER = SIGN? DIGIT+ '#' BASE_DIGIT+

EEP 通过允许单个下划线 _ 字符作为两个 DIGITBASE_DIGIT 字符之间的分隔符来扩展此语法。即,_ 的左右两侧的字符都应该是数字。不允许前导、尾随或重复的下划线,以及与 - . # e 相邻的下划线。分隔符仅用于直观地分隔字符组。它不改变字面量的语义,并由词法分析器删除。

以下是有效数字字面量的示例

123_456
1_2_3_4_5
123_456.789_123
1.0e1_23
16#DEAD_BEEF
2#1100_1010_0011

以下是不允许的字面量的示例

_123  % will be interpreted as variable name
123_
123__456  % only single underscore allowed
123_.456  % underscore can only separate digits, not other symbols
123._456
16#_1234
16#1234_

当将抽象形式或术语表示为字符串时(erl_pp, io_lib),下划线将丢失。

动机 #

数字分隔符对于相对较长的字面量(如十进制的千位分隔符 Million = 1_000_000, SecondsInDay = 86_400)和十六进制的字节分隔符 16#DEAD_BEEF_CAFE)特别有用。组分隔符使此类字面量更具可读性(在明智使用时),并使更容易直观地发现诸如 MicroSecond = Second * 100000 之类的错别字。数字分隔符功能已被多种编程语言采用,至少从 Ada83 开始。

基本原理 #

选择下划线字符作为分隔符是因为它被许多其他语言使用,例如 “Ada 83”、“C#”、“Java 7”、“Perl 2.0”、“Python 3.6”、“Ruby”、“Rust”、“Swift” 和 “Go”。而且它不与当前的 Erlang 语法冲突(例如,与 , 不同)。唯一有歧义的决定是关于应该允许数字分隔符的确切位置。最终决定下划线应该只允许在数字之间,意为作为“数字分隔符”。

向后兼容性 #

所有现有的 Erlang 代码仍然可以接受。该实现完全在 Erlang 词法分析器中完成,因此,解析器中不需要任何更改,甚至检查 AST 的工具也不会受到影响。诸如代码编辑器和语法高亮器之类的外部工具可能需要更新才能识别新的数字字面量语法。

参考实现 #

参考实现以 GitHub 上的拉取请求的形式提供

https://github.com/erlang/otp/pull/2324