Long numerical literals can be a source of poor readability in code. Take the following examples:
// what number is this? 197823459; // which number is greater? 97802345932 > 97802349532; // are these numbers equal? 9803458239 === 9803457239;
These are difficult to read and difficult reason about. To ameliorate this issue, this RFC proposes the introduction of a digit separator in numerical literals. This will enable the examples above to be rewritten as:
// what number is this? 197_823_459; // which number is greater? 97_802_345_932 > 97_802_349_532; // are these numbers equal? 9_803_458_239 === 9_803_457_239;
This RFC will add support for using the underscore character as a separator in PHP's numerical literals. The separator will be supported by all numerical types and notations in PHP.
Example:
1_000_000; // versus 1000000 3.141_592; // versus 3.141592 0x02_56_12; // versus 0x025612 0b0010_1101; // versus 0b00101101 0267_3432; // versus 02673432 1_123.456_7e2 // versus 1123.4567e2
The underscores will be stripped out during the lexing stage, and so the runtime will not be affected in any way. For example:
var_dump(1_000_000); // int(1000000)
The digit separator is used to mark boundaries between digits - it is not used to separate digits from other characters. The following syntax choices are therefore based on this.
Leading underscores will not enhance readability and will conflict with constant naming conventions.
_100; // a valid constant in PHP
Trailing underscores will not enhance readability - if anything, they will decrease it.
100_<=>1_000_+_CONST_NAME; // Parse error: syntax error, unexpected '_' (T_STRING)...
Allowing for two or more underscores to be placed together will provide no further readability benefits.
1__000___000_000; // Parse error: syntax error, unexpected '__000___000_000' (T_STRING)...
Underscores are not allowed around the period for floats, around the 0x for hexadecimal notation, around the 0b for binary notation, or around the e for scientific notation. This is because readability will be negatively impacted, and it doesn't really serve the purpose of a “digit separator.”
100_.0; // Parse error: syntax error, unexpected '_' (T_STRING) in... 100._01; // Parse error: syntax error, unexpected '_01' (T_STRING) in... 0x_0123; // Parse error: syntax error, unexpected 'x_0123' (T_STRING) in... 0b_0101; // Parse error: syntax error, unexpected 'b_0101' (T_STRING) in... 1_e2; // Parse error: syntax error, unexpected '_e2' (T_STRING)... 1e_2; // Parse error: syntax error, unexpected 'e_2' (T_STRING)...
Underscores may be freely interspersed between arbitrary groups of digits, enabling for developers to group the digits as they see fit. One such argument for relaxing the interspersing of underscores is that not all countries group digits in sets of three [1].
1_234_567; // grouped in sets of 3 123_4567; // grouped in sets of 4 (Japan, China) 1_00_00_00_000; // grouped according to India's numbering system 0x11_22_33_44_55_66; // a number to be used as bytes, grouped by bytes 0x1122_3344_5566; // a number to be used as 16-bit data, grouped by word
The underscore:
It has also been widely adopted as a digit separator in a number of other languages, including:
Few other languages have deviated from using the underscore to separate digits. One notable exception is C++, where it could not use an underscore because of conflicts with user-defined literals (specifically in a hexadecimal context). Because PHP does not have such user-defined literals, there are no technical problems with using the underscore as a digit separator. This proposal therefore seeks to follow suite with the other languages.
This RFC does not include stringy numerics because of the BC breakage involved. It would mean changing the coercion rules for strings to integers, which may potentially have wide-ranging impacts for PHP programs. Also, support for stringy numerics can be quite easily emulated in userland code.
If formatting stringy numerical literals is desired, then support for these can be added in the next major version of PHP.
There are no BC breaks with this feature.
PHP 7.1
No impact.
No impact.
No impact.
No impact.
No impact.
None so far.
Support for stringy numerics could be added in the next major version.
A simple yes/no voting option on whether to support a digit separator in PHP. A 2/3 majority is required.
Voting starts on January 13th and ends on January 20th.
After the project is implemented, this section should contain
Current discussion: https://marc.info/?l=php-internals&m=145149644624888&w=2
Previous discussion on separators for numerical literals: https://marc.info/?l=php-internals&m=142431171323037&w=2
[1]: http://www.statisticalconsultants.co.nz/blog/how-the-world-separates-its-digits.html
Keep this updated with features that were discussed on the mail lists.