rfc:numeric_literal_separator

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:numeric_literal_separator [2019/05/01 21:35] – Revise based on feedback theodorejbrfc:numeric_literal_separator [2019/08/19 19:58] (current) – Separators in C# aren't just a proposal theodorejb
Line 1: Line 1:
 ====== PHP RFC: Numeric Literal Separator ====== ====== PHP RFC: Numeric Literal Separator ======
-  * Date: 2019-05-01+  * Date: 2019-05-15
   * Author: Theodore Brown <theodorejb@outlook.com>, Bishop Bettini <bishop@php.net>   * Author: Theodore Brown <theodorejb@outlook.com>, Bishop Bettini <bishop@php.net>
   * Based on [[https://wiki.php.net/rfc/number_format_separator|previous RFC]] by: Thomas Punt <tpunt@php.net>   * Based on [[https://wiki.php.net/rfc/number_format_separator|previous RFC]] by: Thomas Punt <tpunt@php.net>
-  * Proposed PHP version: PHP 7.4 +  * StatusImplemented (in PHP 7.4) 
-  * Discussion: https://externals.io/message/105450 +  * Discussion: https://externals.io/message/105714 
-  * StatusDraft +  * Target versionPHP 7.4 
 +  * Implementation: https://github.com/php/php-src/pull/4165
  
 ===== Introduction ===== ===== Introduction =====
  
 The human eye is not optimized for quickly parsing long sequences of The human eye is not optimized for quickly parsing long sequences of
-digits. Thus, a lack of visual separators increases the time it takes +digits. Thus, a lack of visual separators makes it take longer to 
-to read and debug code, and can lead to unintended mistakes.+read and debug code, and can lead to unintended mistakes.
  
 <code php> <code php>
Line 45: Line 45:
 299_792_458;   // decimal 299_792_458;   // decimal
 0xCAFE_F00D;   // hexadecimal 0xCAFE_F00D;   // hexadecimal
-0b0010_1101;   // binary +0b0101_1111;   // binary 
-026_73_43    // octal+0137_041     // octal
 </code> </code>
  
Line 69: Line 69:
 ===== Unaffected PHP Functionality ===== ===== Unaffected PHP Functionality =====
  
-Underscores in numeric literals will be stripped out during the +Adding an underscore between digits in numeric literal will not 
-lexing stage, so the runtime will not be affected.+change its value. The underscores are stripped out during the lexing 
 +stage, so the runtime is not affected.
  
 <code php> <code php>
Line 91: Line 92:
 [[https://en.wikipedia.org/wiki/Subitizing|subitizing]]. That is, [[https://en.wikipedia.org/wiki/Subitizing|subitizing]]. That is,
 accurately and confidently "telling at a glance" the number of digits, accurately and confidently "telling at a glance" the number of digits,
-rather than having to count them. This measurably decreases the time+rather than having to count them. This measurably lessens the time
 to correctly read numbers longer than four digits. to correctly read numbers longer than four digits.
  
Line 97: Line 98:
 constants, unit test values, and performing data conversions. constants, unit test values, and performing data conversions.
 For example: For example:
- 
-Bugsnag's maximum payload size: 
- 
-<code php> 
-const MAX_SIZE = 500000; // without separator 
- 
-const MAX_SIZE = 500_000; // with separator 
-</code> 
  
 Composer's retry delay when removing a file: Composer's retry delay when removing a file:
Line 118: Line 111:
  
 <code php> <code php>
-$time = (int) ($adTime / 10000000 - 11644473600); // without separators+$time = (int) ($adTime / 10000000 - 11644473600); // without separator
  
-$time = (int) ($adTime / 10_000_000 - 11_644_473_600); // with separators+$time = (int) ($adTime / 10_000_000 - 11_644_473_600); // with separator 
 +</code> 
 + 
 +Working with scientific constants: 
 + 
 +<code php> 
 +const ASTRONOMICAL_UNIT = 149597870700; // without separator 
 + 
 +const ASTRONOMICAL_UNIT = 149_597_870_700; // with separator 
 +</code> 
 + 
 +Separating bytes in a binary or hex literal: 
 + 
 +<code php> 
 +0b01010100011010000110010101101111; // without separator 
 + 
 +0b01010100_01101000_01100101_01101111; // with separator 
 + 
 +0x42726F776E; // without separator 
 + 
 +0x42_72_6F_77_6E; // with separator
 </code> </code>
  
Line 127: Line 140:
 It may be tempting to use integers for storing data such as phone, It may be tempting to use integers for storing data such as phone,
 credit card, and social security numbers since these values appear credit card, and social security numbers since these values appear
-numeric. However, this is almost always a bad idea, since these +numeric. However, this is almost always a bad idea, since such 
-values often have prefixes and leading digits that are significant.+numbers often have prefixes and leading digits that are significant.
  
 A good rule of thumb is that if it doesn't make sense to use A good rule of thumb is that if it doesn't make sense to use
 mathematical operators on a value (e.g. adding it, multiplying it, mathematical operators on a value (e.g. adding it, multiplying it,
-dividing it, etc.), then an integer probably isn't the best way to +etc.), then an integer probably isn't the best way to store it.
-store it.+
  
 <code php> <code php>
-// never do this:+// don'do this:
 $phoneNumber = 345_6789; $phoneNumber = 345_6789;
-$creditCard = 378_2822_4631_0005;+$creditCard = 231_6547_9081_2543;
 $socialSecurity = 111_11_1111; $socialSecurity = 111_11_1111;
 </code> </code>
Line 151: Line 163:
 binary, octal, decimal, hexadecimal, or exponential notation. In binary, octal, decimal, hexadecimal, or exponential notation. In
 practice, this isn't problematic as long as a codebase is consistent. practice, this isn't problematic as long as a codebase is consistent.
 +
 +Furthermore, separators can sometimes make it easier to find numbers.
 +To use an earlier example, 13_500 and 135_00 could be differentiated
 +in a find/replace. Another example would be separated bytes in a hex
 +literal, which allows searching for a value like "_6F_" to find only
 +the numbers containing that specific byte.
 +
 +==== Should it be the role of an IDE to group digits? ====
 +
 +It has been suggested that numeric literal separators aren't needed
 +for better readability, since IDEs could be updated to automatically
 +display large numbers in groups of three digits.
 +
 +However, it isn't always desirable to group numbers the same way.
 +For example, a programmer may write ''10050000'' differently
 +depending on whether or not it represents a financial quantity stored
 +as cents:
 +
 +<code php>
 +$total = 100_500_00; // represents $100,500.00 stored as cents
 +
 +$total = 10_050_000; // represents $10,050,000
 +</code>
 +
 +Binary and hex literals may also be grouped by a varying number of
 +digits to reflect how they are used (e.g. bits may be separated into
 +nibbles, bytes, or words). An IDE cannot do this automatically
 +without knowing the programmer's intent for each numeric literal.
  
 ==== Why resurrect this proposal? ==== ==== Why resurrect this proposal? ====
Line 172: Line 212:
 Andrea Faulds summarized the considerations [[https://externals.io/email/90673/source|as follows]]: Andrea Faulds summarized the considerations [[https://externals.io/email/90673/source|as follows]]:
  
-> This feature offers some benefit in some cases. It doesn't introduce +<blockquote> 
-much new complexity. There's no new syntax or tokens, it just modifies +This feature offers some benefit in some cases. It doesn't introduce 
-the form of the existing number tokens. It fits in well [with] what'+much new complexity. There's no new syntax or tokens, it just modifies 
-already there, consistently applying to all number literals. It follows +the form of the existing number tokens. It fits in well [with] what'
-established convention in other languages. Its appearance at least hints +already there, consistently applying to all number literals. It follows 
-that values with these separators are not constants or identifiers, but +established convention in other languages. Its appearance at least hints 
-numbers, reducing potential for confusion. It limits its own application +that values with these separators are not constants or identifiers, but 
-to prevent abuse (no leading, trailing, or repeated separators). And +numbers, reducing potential for confusion. It limits its own application 
-it's relatively intuitive.+to prevent abuse (no leading, trailing, or repeated separators). And 
 +it's relatively intuitive. 
 +</blockquote>
  
 ==== Comparison to other languages ==== ==== Comparison to other languages ====
Line 187: Line 229:
  
   * Ada: single, between digits [[http://archive.adaic.com/standards/83lrm/html/lrm-02-04.html#2.4|1]]   * Ada: single, between digits [[http://archive.adaic.com/standards/83lrm/html/lrm-02-04.html#2.4|1]]
-  * C# (proposal for 7.0): multiple, between digits [[https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.0/digit-separators.md|2]]+  * C#: multiple, between digits [[https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.0/digit-separators.md|2]]
   * C++: single, between digits (single quote used as separator) [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3781.html|3]]   * C++: single, between digits (single quote used as separator) [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3781.html|3]]
   * Java: multiple, between digits [[https://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html|4]]   * Java: multiple, between digits [[https://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html|4]]
-  * JavaScript and TypeScript: single, between digits [[http://2ality.com/2018/02/numeric-separators.html|5]]+  * JavaScript and TypeScript: single, between digits [[https://github.com/tc39/proposal-numeric-separator|5]]
   * Julia: single, between digits [[https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/|6]]   * Julia: single, between digits [[https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/|6]]
-  * Perl: single, between digits [[https://perldoc.perl.org/perldata.html#Scalar-value-constructors|7]] +  * Kotlin: multiple, between digits [[https://github.com/Kotlin/KEEP/blob/master/proposals/underscores-in-numeric-literals.md|7]] 
-  * Python: single, between digits [[https://www.python.org/dev/peps/pep-0515/|8]] +  * Perl: single, between digits [[https://perldoc.perl.org/perldata.html#Scalar-value-constructors|8]] 
-  * Ruby: single, between digits [[http://ruby-doc.org/core-2.6.3/doc/syntax/literals_rdoc.html#label-Numbers|9]] +  * Python: single, between digits [[https://www.python.org/dev/peps/pep-0515/|9]] 
-  * Rust: multiple, anywhere [[https://doc.rust-lang.org/reference/tokens.html#number-literals|10]] +  * Ruby: single, between digits [[http://ruby-doc.org/core-2.6.3/doc/syntax/literals_rdoc.html#label-Numbers|10]] 
-  * Swift: multiple, between digits [[https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID415|11]]+  * Rust: multiple, anywhere [[https://doc.rust-lang.org/reference/tokens.html#number-literals|11]] 
 +  * Swift: multiple, between digits [[https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID415|12]]
  
-===== Proposed Voting Choices =====+===== Vote =====
  
-Add numeric literal separators in PHP 7.4? Yes/No.+Voting started 2019-05-30 and ended 2019-06-13.
  
-===== Patches and Tests ===== +<doodle title="Support numeric literal separator in PHP 7.4?" auth="theodorejb" voteType="single" closed="true"> 
- +   * Yes 
-Previous implementation (needs to be rebased): https://github.com/php/php-src/pull/1699+   * No 
 +</doodle>
  
 ===== References ===== ===== References =====
 +
 +Request to revive RFC: https://externals.io/message/105450
  
 Discussion from previous RFC: https://externals.io/message/89925, https://externals.io/message/90626, https://marc.info/?l=php-internals&m=145320709922246&w=2. Discussion from previous RFC: https://externals.io/message/89925, https://externals.io/message/90626, https://marc.info/?l=php-internals&m=145320709922246&w=2.
  
-Blog post about implementation: https://phpinternals.net/articles/implementing_a_digit_separator.+Blog post about original implementation: https://phpinternals.net/articles/implementing_a_digit_separator.
rfc/numeric_literal_separator.1556746534.txt.gz · Last modified: 2019/05/01 21:35 by theodorejb