# Revive Number Format Separator RFC

- Thread: https://externals.io/message/105450
- Original archive: https://news-web.php.net/php.internals/105450
- Started by Theodore Brown on 2019-04-25T22:07:26+00:00
- Messages: 19
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #105450 — Theodore Brown — 2019-04-25T22:07:26+00:00

URL: https://externals.io/message/105450#105450

Is there any chance the Number Format Separator RFC [1] could be revived for PHP 7.4? I looked at the discussion from a few years ago and it's not clear why many people originally voted against it.

JavaScript and Python have both gotten this feature recently and it's something I really miss in PHP when declaring/reading large numbers.

Maybe it would help to simplify how the restrictions are described in the RFC. As I understand it, the only restriction is that each underscore in a numeric literal must be between two digits. Perhaps the way the RFC described this syntax made it seem more complex than it is.

Best regards,

Theodore Brown

[1]: https://wiki.php.net/rfc/number_format_separator

---

## #105451 — Bishop Bettini — 2019-04-26T01:28:02+00:00

URL: https://externals.io/message/105450#105451

On Thu, Apr 25, 2019 at 6:07 PM Theodore Brown <theodorejb@outlook.com>
wrote:

> Is there any chance the Number Format Separator RFC [1] could be revived
> for PHP 7.4? I looked at the discussion from a few years ago and it's not
> clear why many people originally voted against it.
>
> JavaScript and Python have both gotten this feature recently and it's
> something I really miss in PHP when declaring/reading large numbers.
>
> Maybe it would help to simplify how the restrictions are described in the
> RFC. As I understand it, the only restriction is that each underscore in a
> numeric literal must be between two digits. Perhaps the way the RFC
> described this syntax made it seem more complex than it is.
>
> Best regards,
>
> Theodore Brown
>
> [1]: https://wiki.php.net/rfc/number_format_separator


Subsequent conversation occurred on the voting thread [1], which wasn't
included by reference in the RFP itself.

The only dissent I saw in that thread came from Pascal Martin, speaking for
AFUP, who wrote [2]:
> it would be harder to search in code, as there would be more than
> one way to write a number. Basically, it would break grep/find.
> Splitting numbers so they are more readable is kind of a presentation
> matter and, as such, could be done by an editor/IDE when displaying
> code, without having to modify the code by hand

Related: the RFC author Tom Punt also detailed the implementation, but
didn't incorporate that by reference into the RFC [3]. Worth the read.

With Tom's blessing, I'd support re-visiting this feature. It's useful, IMO.

[1]: https://marc.info/?l=php-internals&m=145271098232484&w=2
[2]: https://marc.info/?l=php-internals&m=145320709922246&w=2
[3]: https://phpinternals.net/articles/implementing_a_digit_separator

---

## #105452 — Bishop Bettini — 2019-04-26T05:15:10+00:00

URL: https://externals.io/message/105450#105452

> On Thu, Apr 25, 2019 at 6:07 PM Theodore Brown <theodorejb@outlook.com>
> wrote:
>
> > […]
>
>
> Subsequent conversation occurred on the voting thread [1], which wasn't
> included by reference in the RFP itself.
>
> The only dissent I saw in that thread came from Pascal Martin, speaking
> for AFUP, who wrote [2]:
> > […]
>
> Related: the RFC author Tom Punt also detailed the implementation, but
> didn't incorporate that by reference into the RFC [3]. Worth the read.
>
> With Tom's blessing, I'd support re-visiting this feature. It's useful,
> IMO.
>
> [1]: https://marc.info/?l=php-internals&m=145271098232484&w=2
> [2]: https://marc.info/?l=php-internals&m=145320709922246&w=2
> [3]: https://phpinternals.net/articles/implementing_a_digit_separator
>

Using a variant of Nikita's top packages visitor [1], the top 250 packages
contain about 3 million integer literals. Of those, about 800k have 5 or
more digits, while only about 3k have 10 or more digits. Nine digits is
unusually common, because of its use in giggsey/libphonenumber-for-php for
United States phone numbers.

Applying some rough heuristics to file names, 89% of those literals appear
in a data file, 8% in code, and 3% in tests.

A cursory scan of current usage suggests that number format separator might
be used in scenarios such as:

Phone numbers
919_555_1234
49_89_636_48018

Date time values
2018_04_26
20180426_183242

Range end points (using any locale's grouping strategy)
2_147_483_647
1_67_77_215

Nibble groups
0b0011_1111_0100_1110

For those first few, Kotlin has similar examples [2], but Javascript
discourages use of number separator in "number-ish" values (eg phone
numbers) [3].

https://gist.github.com/bishopb/157d403dc1c190957a558c93e120a07d


[1]: https://gist.github.com/nikic/a2bfa3e2f604f66115c3e4b8963a6c72
[2]:
https://kotlinlang.org/docs/reference/basic-types.html#underscores-in-numeric-literals-since-11
[3]: http://2ality.com/2018/02/numeric-separators.html

---

## #105456 — Rowan Collins — 2019-04-26T11:10:00+00:00

URL: https://externals.io/message/105450#105456

> > […]
> not
> > […]
>


Hi,

I'm not particularly against this proposal, but I'm not sure how often I'd
use it.




A cursory scan of current usage suggests that number format separator might
> be used in scenarios such as:
>
> Phone numbers
> 919_555_1234
> 49_89_636_48018
>


This is a poor example, because phone numbers shouldn't be stored as
integers; there's nothing you can do with them mathematically, and outside
of North America it's extremely common for them to have significant leading
zeroes.



> Date time values
> 2018_04_26
> 20180426_183242
>


Again, I can't see why you'd ever use an integer for that, rather than a
string. Were there really integer literals of this form in the packages you
searched?



> For those first few, Kotlin has similar examples [2], but Javascript
> discourages use of number separator in "number-ish" values (eg phone
> numbers) [3].
>


The second article you link to isn't official documentation, just someone's
blog post about the feature. I agree with the comment, though - the Kotlin
example of a credit card number wouldn't pass code review with me, because
they're not really "numbers", they're identifiers which happen to only use
digits (the only mathematical operation on a card number would be checking
the Luhn checksum, which is a digit-by-digit operation anyway).


The only example that I can see myself using is the one of money-as-cents
(or, in my case, pence):

$pricePence = 1000_00; // GBP 1000.00

Although some kind of struct with separate fields and overloaded operators
would probably be better still:

$price = Money{ 'GBP', 1000, 00 };


The main use I've had for large number literals is for things like cache
lifetimes, where the extra syntax wouldn't help, but constant expressions
do:

$lifetimeSecs = 604800; // 7 days

const SECONDS_IN_MINUTE = 60;
const SECONDS_IN_HOUR = SECONDS_IN_MINUTE * 60;
const SECONDS_IN_DAY = SECONDS_IN_HOUR * 24;
$lifetimeSecs = 7 * SECONDS_IN_DAY;


Similar approaches work for other contexts, for instance:

const GIBIBYTE = 1024 ** 3;
const GIBIBYTE = 2 ** 30;

both read more clearly than anything you could do with underscores:

const GIBIBYTE = 1_073_741_824;
const GIBIBYTE = 0x40_000_000;
const GIBIBYTE = 0b1_00000_00000_00000_00000_00000_00000;

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #105457 — Lester Caine — 2019-04-26T11:29:54+00:00

URL: https://externals.io/message/105450#105457

> This is a poor example, because phone numbers shouldn't be stored as
> integers; there's nothing you can do with them mathematically, and outside
> of North America it's extremely common for them to have significant leading
> zeroes.

Along with flagging the country code with a '+' ...

-- 
Lester Caine - G8HFL
-----------------------------
Contact - https://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - https://lsces.co.uk
EnquirySolve - https://enquirysolve.com/
Model Engineers Digital Workshop - https://medw.co.uk
Rainbow Digital Media - https://rainbowdigitalmedia.co.uk

---

## #105464 — Theodore Brown — 2019-04-26T15:30:59+00:00

URL: https://externals.io/message/105450#105464

> 
>
> > […]
>
>
> I'm not particularly against this proposal, but I'm not sure how often I'd
> use it.

How often you use numeric separators depends on what you are doing.
I definitely agree that phone numbers and dates are not good use cases,
and that there are usually better ways to write things like the number
of seconds in a day or number of bytes in a gigabyte.

However, there are many other appropriate uses of large integers
where numeric separators can make the code more readable and
prevent mistakes. Here's an example from code I maintain:

```php
function getActiveDirectoryTimestamp(DateTime $date): int
{
    // Active Directory stores dates as the number of 100-nanosecond
    // intervals since January 1, 1601.
    $epochDiff = 11_644_473_600;
    $secondsAfterADEpoch = $date->getTimestamp() + $epochDiff;
    return $secondsAfterADEpoch * 10_000_000;
}
```

Another common use case is constants used in scientific calculations:

```php
const ASTRONOMICAL_UNIT = 149_597_870_700;
const SPEED_OF_LIGHT = 299_792_458;

echo 'Time for light to travel from sun to earth: ';
echo (ASTRONOMICAL_UNIT / SPEED_OF_LIGHT) . ' sec.';
```

For me personally the most frequent use case is actually in tests,
where various values (e.g. large dollar amounts) are passed to
functions in order to validate business logic. Numeric separators
would help make such unit tests a lot more readable.

Best regards,

Theodore Brown

---

## #105466 — Thomas Punt — 2019-04-27T11:18:45+00:00

URL: https://externals.io/message/105450#105466

Hi!

> 
>
> > […]
>
> How often you use numeric separators depends on what you are doing.
> I definitely agree that phone numbers and dates are not good use cases,
> and that there are usually better ways to write things like the number
> of seconds in a day or number of bytes in a gigabyte.

Storing dates in an integer format can be a valid use case if performance is a
concern. It is far faster and more compact to store and compare integer-based
dates than using objects for everything.

Anyway, if anyone would like to revive this RFC, then feel free to!

Thanks,
Tom

---

## #105467 — Rowan Collins — 2019-04-27T12:37:41+00:00

URL: https://externals.io/message/105450#105467

> Storing dates in an integer format can be a valid use case if 
> performance is a
> concern. It is far faster and more compact to store and compare 
> integer-based
> dates than using objects for everything.


The only way I've seen dates stored as integers is as a number of 
seconds / milliseconds / whatever since some epoch, most commonly 
seconds since 1970-01-01 00:00:00 UTC


The format Bishop seemed to be suggesting would be absolutely useless 
for anything other than the simplest comparisons: how do you add a day 
to the date-as-number 20190430?


I'm sure there are use cases for this syntax, but the examples in that 
e-mail were poorly chosen.


Regards,

-- 
Rowan Collins
[IMSoP]

---

## #105468 — Lester Caine — 2019-04-27T12:51:11+00:00

URL: https://externals.io/message/105450#105468

> The only way I've seen dates stored as integers is as a number of 
> seconds / milliseconds / whatever since some epoch, most commonly 
> seconds since 1970-01-01 00:00:00 UTC

Use of a days count rather than a seconds count makes dates a lot easier 
to work with. 2 32bit numbers give a substantial day count along with 
either fractional time of day or alternatively a second count for the 
day. Genealogical data is substantially easier to manage as a day count 
which can be expanded in accuracy with a time count either viewed as 
integers or as floating point numbers ... leap seconds just get hidden 
in the processing.

-- 
Lester Caine - G8HFL
-----------------------------
Contact - https://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - https://lsces.co.uk
EnquirySolve - https://enquirysolve.com/
Model Engineers Digital Workshop - https://medw.co.uk
Rainbow Digital Media - https://rainbowdigitalmedia.co.uk

---

## #105469 — Rowan Collins — 2019-04-27T18:17:25+00:00

URL: https://externals.io/message/105450#105469

>
> > […]
>
>Use of a days count rather than a seconds count makes dates a lot
>easier 
>to work with. 2 32bit numbers give a substantial day count along with 
>either fractional time of day or alternatively a second count for the 
>day.


That makes sense, but it's still a variant on the epoch + count concept, not year-month-day as in Bishop's example. As such, it still wouldn't particularly benefit from separators; you'd probably write constants in string form and convert them on the fly, or have durations which were multiples of 7 or 365 rather than powers of 10 or 16.

Regards,

-- 
Rowan Collins
[IMSoP]

---

## #105477 — Stanislav Malyshev — 2019-04-28T03:25:14+00:00

URL: https://externals.io/message/105450#105477

Hi!

> A cursory scan of current usage suggests that number format separator might
> be used in scenarios such as:
> 
> Phone numbers
> 919_555_1234
> 49_89_636_48018

Just noting here that using integers as phone numbers is not something
we want to support, enable or promote.

> Date time values
> 2018_04_26
> 20180426_183242

Same here, these are not integers (or numbers).

> Range end points (using any locale's grouping strategy)
> 2_147_483_647
> 1_67_77_215

These are numbers, but should be only ever used in constants (with
appropriate comment).

I am not exactly against this feature, but the potential for abuse -
like enabling people using integers for things that are not integers and
should not be stored as integers - worries me now.
-- 
Stas Malyshev
smalyshev@gmail.com

---

## #105485 — Theodore Brown — 2019-04-28T17:47:33+00:00

URL: https://externals.io/message/105450#105485

> I am not exactly against this feature, but the potential for abuse
> \- like enabling people using integers for things that are not
> integers and should not be stored as integers - worries me now.

Based on the usage analysis Bishop did, people already use integers
for number-like values (e.g. phone and social security numbers) that
can be better represented in other ways.

Perhaps adding the numeric separator feature can actually be an
opportunity to discourage such misuse. We can add a paragraph to the
RFC (and the documentation if it is accepted) that lists examples of
usage that should be avoided.

Ultimately there remains many legitimate uses of large numbers in
code (e.g. scientific constants, unit test values, business logic
thresholds, etc.), and this feature is a simple way to improve their
readability.

I've lost count of the number of times I've been debugging a failing
test and struggling to count the number and position of digits to
make sure I have the right value. This feature would save time when
reading code and indeed prevent a lot of mistakes in the first place.

---

## #105497 — Bishop Bettini — 2019-04-29T07:33:03+00:00

URL: https://externals.io/message/105450#105497

On Sun, Apr 28, 2019 at 1:47 PM Theodore Brown <theodorejb@outlook.com>
wrote:

> On Sat, Apr 27, 2019 at 10:25 PM Stanislav Malyshev <smalyshev@gmail.com>
> wrote:
>
> > […]
>
> Based on the usage analysis Bishop did, people already use integers
> for number-like values (e.g. phone and social security numbers) that
> can be better represented in other ways.
>
> Perhaps adding the numeric separator feature can actually be an
> opportunity to discourage such misuse. We can add a paragraph to the
> RFC (and the documentation if it is accepted) that lists examples of
> usage that should be avoided.
>
> Ultimately there remains many legitimate uses of large numbers in
> code (e.g. scientific constants, unit test values, business logic
> thresholds, etc.), and this feature is a simple way to improve their
> readability.
>
> I've lost count of the number of times I've been debugging a failing
> test and struggling to count the number and position of digits to
> make sure I have the right value. This feature would save time when
> reading code and indeed prevent a lot of mistakes in the first place.
>

Well said.

One need not agree with an implementation to appreciate the improved
readability.

If you'd like to re-open this for voting, I'm able to assist with the RFC
process and any code changes.

---

## #105530 — Theodore Brown — 2019-04-30T20:41:55+00:00

URL: https://externals.io/message/105450#105530

> Well said.
>
> One need not agree with an implementation to appreciate the improved
> readability.
>
> If you'd like to re-open this for voting, I'm able to assist with
> the RFC process and any code changes.

Thanks! I drafted a preliminary RFC, but I'll need assistance with
the implementation and publishing the RFC on wiki.php.net.

https://gist.github.com/theodorejb/653221e3221b2b4d2ad8fa94d3a963ff

---

## #105531 — Bishop Bettini — 2019-04-30T20:59:45+00:00

URL: https://externals.io/message/105450#105531

On Tue, Apr 30, 2019 at 4:41 PM Theodore Brown <theodorejb@outlook.com>
wrote:

> 
>
> > […]
>
> Thanks! I drafted a preliminary RFC, but I'll need assistance with
> the implementation and publishing the RFC on wiki.php.net.
>
> https://gist.github.com/theodorejb/653221e3221b2b4d2ad8fa94d3a963ff


Excellent. I hope we can make the case this time. Please request Wiki karma
[1], and we'll iterate on it there.

[1]: https://wiki.php.net/rfc/howto

---

## #105536 — Bishop Bettini — 2019-05-01T00:13:15+00:00

URL: https://externals.io/message/105450#105536

> 
>
> > […]
>
> I was granted karma, and published an initial RFC draft:
> https://wiki.php.net/rfc/numeric_literal_separator.
>
> I would greatly appreciate help with the implementation, since I
> don't have much experience with C and haven't contributed to PHP before.
>
> Also let me know if you have any ideas for improving the RFC.
>

I am happy to help with these. Let us take the RFC refinement and
implementation details conversation off-list. Then come back when prepared
to present for discussion.

---

## #105543 — Thomas Punt — 2019-05-01T09:42:39+00:00

URL: https://externals.io/message/105450#105543

Hi!

> 
> > […]
>
> I am happy to help with these. Let us take the RFC refinement and
> implementation details conversation off-list. Then come back when prepared
> to present for discussion.

I would think that pretty much the whole of the original implementation[1] should
be reusable (maybe some merge conflicts to fix only). But anyway, I can offer some
support with the implementation, if needed.

Thanks,
Tom

[1]: https://github.com/php/php-src/pull/1699

---

## #105552 — Bishop Bettini — 2019-05-02T02:00:53+00:00

URL: https://externals.io/message/105450#105552

> Hi!
>
> > […]
> wrote:
> > […]
> before.
> > […]
> prepared
> > […]
>
> I would think that pretty much the whole of the original implementation[1]
> should
> be reusable (maybe some merge conflicts to fix only). But anyway, I can
> offer some
> support with the implementation, if needed.
>

Great, thanks Tom. Theodore and I are polishing the RFC, then will tackle
the implementation. Besides the necessary merge fixes, are there any
changes/improvements you specifically want to make in the new proposed
implementation?

---

## #105556 — Thomas Punt — 2019-05-02T10:03:16+00:00

URL: https://externals.io/message/105450#105556

> 
>
> Great, thanks Tom. Theodore and I are polishing the RFC, then will tackle the implementation. Besides the necessary merge fixes, are there any changes/improvements you specifically want to make in the new proposed implementation?

None that I can see/think of. Good luck with the RFC!

-Tom
