Hi, internals!
I would like to start an RFC discussion regarding rounding modes.
https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enum
As mentioned previously by Gina on the mailing list [1], there are some issues with PHP's current rounding mode.
[1] - https://externals.io/message/123126
• First, the value is just an int, so we need to verify that the value passed is a valid rounding mode.
• The second problem is that the behavior of the “up” and “down” modes does not match the mathematical definition. Especially for non-native speakers, the different rounding modes might also be more easily confused, compared to a naming that uses less abstract terms.
To resolve these issues, change the naming to something appropriate and use Enums instead of int constants.
Please see the RFC for details.
Regards,
Saki
To resolve these issues, change the naming to something appropriate and
use Enums instead of int constants.
Hi!
I like the idea. But I don't know
From the RFC text:
To summarize, existing features will be changed to a union type of int|
\RoundingMode, and unreleased features will only accept \RoundingMode as
the rounding mode argument.
I have mixed feelings about the unreleased features using a different
typing for the same parameters that already exist in the existing features.
On one side, the user would be forced to use the new approach and get used
to it when they start to use the unreleased features, but on the other
side, the code would be strange with 2 different approaches for similar
features of the same "feature set".
I think that I would use union types for everything and plan the
deprecation and further removal of the Int version for the next releases
for everything.
Anyway, I'm in favor of starting the movement of changing these Ints to
Enums.
Thanks for working to make PHP better!
Best regards,
Erick
Hi.
I like the idea. But I don't know
Please ignore this.
Some copy-past leftovers.
Sorry!
Thank you for the clarification Erick
Sent from IPhone
On Fri, May 31, 2024 at 12:59 PM Erick de Azevedo Lima <
ericklima.comp@gmail.com> wrote:
Hi.
I like the idea. But I don't know
Please ignore this.
Some copy-past leftovers.Sorry!
Hey Saki,
I like this change. When I was implementing additional rounding modes for
the next PHP version I was initially struggling with the naming and this
change will be helpful.
I have only one concern about the names NegativeInfinity
and
PositiveInfinity
. They may be too formal from the user's perspective. As
we already have functions ceil
and floor
it's more intuitive for
developers to understand the logic of ceiling and floor rounding.
But if voters will prefer those terms then it makes sense to change the
constants implemented in PHP 8.4 (and thus not released yet) from
PHP_ROUND_(CEILING|FLOOR)
to
PHP_ROUND_(POSITIVE_INFINITY|NEGATIVE_INFINITY)
for the sake of
consistency.
Kind regards,
Jorg
Hey Saki,
I like this change. When I was implementing additional rounding modes
for the next PHP version I was initially struggling with the naming and
this change will be helpful.I have only one concern about the names
NegativeInfinity
and
PositiveInfinity
. They may be too formal from the user's perspective.
As we already have functionsceil
andfloor
it's more intuitive for
developers to understand the logic of ceiling and floor rounding.But if voters will prefer those terms then it makes sense to change the
constants implemented in PHP 8.4 (and thus not released yet) from
PHP_ROUND_(CEILING|FLOOR)
to
PHP_ROUND_(POSITIVE_INFINITY|NEGATIVE_INFINITY)
for the sake of
consistency.Kind regards,
Jorg
I was confused by those as well. It's not obvious to me what those even do. Do they mean "away from 0"? If not, then I have no clue what they are. :-)
--Larry Garfield
Hey Saki,
I like this change. When I was implementing additional rounding modes
for the next PHP version I was initially struggling with the naming and
this change will be helpful.I have only one concern about the names
NegativeInfinity
and
PositiveInfinity
. They may be too formal from the user's perspective.
As we already have functionsceil
andfloor
it's more intuitive for
developers to understand the logic of ceiling and floor rounding.But if voters will prefer those terms then it makes sense to change the
constants implemented in PHP 8.4 (and thus not released yet) from
PHP_ROUND_(CEILING|FLOOR)
to
PHP_ROUND_(POSITIVE_INFINITY|NEGATIVE_INFINITY)
for the sake of
consistency.Kind regards,
JorgI was confused by those as well. It's not obvious to me what those even do. Do they mean "away from 0"? If not, then I have no clue what they are. :-)
--Larry Garfield
Considering that there are already "Away from 0" and "Towards 0" enum cases, the Towards Positive Infinity/Towards Negative Infinity cases "obviously" don't mean this.
Towards positive infinity means that for positive numbers you round to the integer part plus 1, and for negative numbers you "just" take the negative integer part.
Similarly, for rounding towards negative infinity positive numbers round to "just" the integer part of it, and negative numbers round to the negative integer part minus 1.
It should also be noted that ceil/floor is very English specific terminology that may not be immediately obvious to non-English speakers, thus my preference for using some variation of towards positive/negative infinity.
Best regards,
Gina P. Banyard
It should also be noted that ceil/floor is very English specific
terminology that may not be immediately obvious to non-English speakers,
thus my preference for using some variation of towards positive/negative
infinity.
This statement is subjective in my opinion. For me, it's the contrary,
that's why I'm opposing introducing new terms to the PHP replacing ones
that already exist (ceil()/floor()). I don't have the data on such modes in
other programming languages, but I checked the data in Google Trends:
https://trends.google.com/trends/explore?q=round%20toward%20positive%20infinity,ceiling%20math,round%20positive%20infinity,towards%20positive%20infinity&hl=en
Far more people search for ceiling
than round toward positive infinity
or round positive infinity
. Of course, I may be wrong by choosing
incorrect search phrases, but it's also good to see some data/examples that
changing this in PHP is for the better.
by removing the newly introduced constant and instead exposing the
functionality only via the new Enum.
It brings inconsistency that some modes are accessible by ints and enums
and others only by enums. If there is no deprecation plan yet I am not sure
this is the right approach.
Kind regards,
Jorg
It should also be noted that ceil/floor is very English specific
terminology that may not be immediately obvious to non-English speakers,
thus my preference for using some variation of towards positive/negative
infinity.This statement is subjective in my opinion. For me, it's the contrary,
that's why I'm opposing introducing new terms to the PHP replacing ones
that already exist (ceil()/floor()). I don't have the data on such modes in
other programming languages, but I checked the data in Google Trends:Far more people search for
ceiling
thanround toward positive infinity
orround positive infinity
. Of course, I may be wrong by choosing
incorrect search phrases, but it's also good to see some data/examples that
changing this in PHP is for the better.
Well, probably plenty of people searching for "ceiling" who are remodeling
their house so that statistic is probably completely useless.
In terms of rounding, towards negative/positive infinity and "up" or "down"
are almost always synonyms. There IS a difference (in general) between the
terms "round towards positive infinity" and "ceil" however. They are
rounding in the same direction, however "ceil" usually means "round towards
positive infinity regardless of the value" and "round towards positive
infinity" usually means "round towards positive infinity when it is unclear
which direction is closer".
For instance (typical behavior meaning):
Ceil: 2.1 -> 3
Positive Infinity: 2.1 -> 2
Ceil: 2.5 -> 3
Positive Infinity: 2.5 -> 3
Ceil: -2.1 -> -2
Positive Infinity: -2.1 -> -2
Ceil: -2.5 -> -2
Positive Infinity: -2.5 -> -2
Ceil: -2.8 -> -2
Positive Infinity: -2.8 -> -3
If the behavior of that mode is to ALWAYS round regardless of the value of
the remainder, then it should remain ceil IMO. It's a pretty well
understood behavior in many programming languages. However,
"HALF_TOWARDS_POSITIVE_INFINITY" is a different behavior, and should not be
called ceil.
The bigger issue is that "HALF_UP" and "HALF_DOWN" are utterly and
completely incorrectly named. Those absolutely should be changed to
something sensible, and is FAR more important IMO than this discussion
about ceil.
Jordan
Hi
If the behavior of that mode is to ALWAYS round regardless of the value of
the remainder, then it should remain ceil IMO. It's a pretty well
understood behavior in many programming languages. However,
"HALF_TOWARDS_POSITIVE_INFINITY" is a different behavior, and should not be
called ceil.
There's already HalfAwayFromZero
+ AwayFromZero
as companion modes.
It would make sense to me to also make it PositiveInfinity
+
HalfPositiveInfinity
[1] instead of Ceil
+ HalfPositiveInfinity
,
which are appear to be unrelated based on their naming.
That would make it clear that those two are closely related and also
that all the modes starting with 'Half' would be the ones that are only
relevant if the last digit is 5, whereas the others act unconditionally.
Best regards
Tim Düsterhus
[1] Possibly with an 'Towards' inserted before the Negative/Positive.
Hi
Far more people search for
ceiling
thanround toward positive infinity
orround positive infinity
. Of course, I may be wrong by choosing
Could it be the case that folks do not need to search as much for
“towards positive infinity”, because in contrast to “ceiling” there is
no room for misunderstanding about what that would mean?
My native language (German) has no equivalent of “Ceiling” and “Floor”.
We only have “aufrunden” (rounding up) and “abrunden” (rounding down),
which we have determined to be too easy to misunderstand with regard to
how they interact with negative numbers. I find “Ceiling” and “Floor”
equally unclear and would likely need to look up their behavior when
facing negative numbers in the documentation.
Best regards
Tim Düsterhus
by removing the newly introduced constant and instead exposing the functionality only via the new Enum.
It brings inconsistency that some modes are accessible by ints and enums and others only by enums. If there is no deprecation plan yet I am not sure this is the right approach.
We cannot formally deprecate the constants in the same version as introducing the enums as there would be no transition period.
We can however soft deprecate the usage of the constants in the documentation by recommending to use the enumeration instead.
However, I don't see any point in having both constants and enum cases for the new modes as there is no incentive what so ever to use the enum.
It is by design to have an inconsistency, you want the new feature, use the new and better way.
Let's imagine we do introduce those new constants alongside the enum, from a user PoV there is no clear reason why one should use constants above enums or enums above constants, except if you care about type safety.
Now, let's fast forward in this imaginary world and we decide to formally deprecate the constants and tell people to use the enum.
For every single user that decided to use the constants, especially for the new rounding modes, they now need to go and fix their code because we didn't clearly incentivise people to use, what I deem, to be the recommended way forward.
Moreover, this equivalence will be an argument against deprecating the constants.
And finally, if we decide to add actual support for half up/down rounding, there is no way to establish an equivalence with a sanely named constant because the name is already taken for an incorrect mode.
So once again, if this RFC does not remove the constants for the new rounding mode I see less of a point, because it is "just" improving the naming (which is really needs considering how bonkers wrong it currently is).
This RFC must be passed for 8.4 to ammend your RFC, because I frankly don't want to be doing clean-up on yet another bad decision the project did that will haunt us for decades if the current state gets released.
Best regards,
Gina P. Banyard
Hi,
On Sunday, 2 June 2024 at 22:26, Jorg Sowa jorg.sowa@gmail.com wrote:
by removing the newly introduced constant and instead exposing the functionality only via the new Enum.
It brings inconsistency that some modes are accessible by ints and enums and others only by enums. If there is no deprecation plan yet I am not sure this is the right approach.
We cannot formally deprecate the constants in the same version as introducing the enums as there would be no transition period.
We can however soft deprecate the usage of the constants in the documentation by recommending to use the enumeration instead.However, I don't see any point in having both constants and enum cases for the new modes as there is no incentive what so ever to use the enum.
It is by design to have an inconsistency, you want the new feature, use the new and better way.Let's imagine we do introduce those new constants alongside the enum, from a user PoV there is no clear reason why one should use constants above enums or enums above constants, except if you care about type safety.
Now, let's fast forward in this imaginary world and we decide to formally deprecate the constants and tell people to use the enum.
For every single user that decided to use the constants, especially for the new rounding modes, they now need to go and fix their code because we didn't clearly incentivise people to use, what I deem, to be the recommended way forward.Moreover, this equivalence will be an argument against deprecating the constants.
And finally, if we decide to add actual support for half up/down rounding, there is no way to establish an equivalence with a sanely named constant because the name is already taken for an incorrect mode.So once again, if this RFC does not remove the constants for the new rounding mode I see less of a point, because it is "just" improving the naming (which is really needs considering how bonkers wrong it currently is).
This RFC must be passed for 8.4 to ammend your RFC, because I frankly don't want to be doing clean-up on yet another bad decision the project did that will haunt us for decades if the current state gets released.Best regards,
Gina P. Banyard
To summarize the discussion so far, it seems that there is a lot of support for the concept of this RFC itself.
The current points of discussion are the following two points:
- Whether or not to provide the new rounding modes added in 8.4 as constants.
- Naming of modes equivalent to floor/ceiling
Regarding 1, personally, I support Gina's opinion of only providing the new rounding modes as an Enum.
This can be interpreted as changing the rounding mode to Enum, with the existing constants being kept simply for backward compatibility.
Regarding 2, I like the PositiveInfinity/NegativeInfinity expression. As far as I know, there doesn't seem to be a clear distinction between these and ceil/floor.
There are several other expressions, such as upward and plus inf, but they all seem to refer to the same concept.
Regards,
Saki
Hi
Am 2024-06-08 02:29, schrieb Saki Takamachi:
Regarding 1, personally, I support Gina's opinion of only providing
the new rounding modes as an Enum.
This can be interpreted as changing the rounding mode to Enum, with
the existing constants being kept simply for backward compatibility.
I've talked about this with Saki in private. We both agree that
providing the 4 new rounding modes only by means of the proposed
RoundingMode
enum is the right choice. I have made the necessary
adjustments to the RFC text. There is a new "Rounding Modes introduced
in PHP 8.4" section that explains that the 4 constants will be removed
as part of the RoundingMode
enum RFC.
Best regards
Tim Düsterhus
Hi
Am 2024-06-08 02:29, schrieb Saki Takamachi:
Regarding 1, personally, I support Gina's opinion of only providing
the new rounding modes as an Enum.
This can be interpreted as changing the rounding mode to Enum, with
the existing constants being kept simply for backward compatibility.I've talked about this with Saki in private. We both agree that
providing the 4 new rounding modes only by means of the proposed
RoundingMode
enum is the right choice. I have made the necessary
adjustments to the RFC text. There is a new "Rounding Modes introduced
in PHP 8.4" section that explains that the 4 constants will be removed
as part of theRoundingMode
enum RFC.Best regards
Tim Düsterhus
Thank you, I think other than possibly prefixing the NegativeInfinity
and PositiveInfinity cases with "Towards" I am happy with the content
of the RFC.
Best regards,
Gina P. Banyard
Hi
Thank you, I think other than possibly prefixing the NegativeInfinity
and PositiveInfinity cases with "Towards" I am happy with the content
of the RFC.
I've discussed this with Saki. In that case the HalfEven
and HalfOdd
modes would also need to be renamed to HalfTowardsEven
and
HalfTowardsOdd
, resulting in this:
enum RoundingMode
{
case HalfAwayFromZero; // `PHP_ROUND_HALF_UP`
case HalfTowardsZero; // `PHP_ROUND_HALF_DOWN`
case HalfTowardsEven; // `PHP_ROUND_HALF_EVEN`
case HalfTowardsOdd; // `PHP_ROUND_HALF_ODD`
case TowardsZero; // PHP_ROUND_TOWARD_ZERO
case AwayFromZero; // PHP_ROUND_AWAY_FROM_ZERO
case TowardsNegativeInfinity; // PHP_ROUND_FLOOR
case TowardsPositiveInfinity; // PHP_ROUND_CEILING
}
Except for the AwayFromZero
modes, every mode contains Towards
and
especially the HalfTowardsX
modes are too similar to easily
distinguish them visually.
Thus we prefer the current state of the RFC where the different modes
have plenty of hamming distance, while still being sufficiently descriptive.
Best regards
Tim Düsterhus
Hi,
Naming is hard, for sure. Here is my review. I find the names mostly reasonable, except Round::PositiveInfinity and Round::NegativeInfinity. I will discuss Round::PositiveInfinity.
First:
I've discussed this with Saki. In that case the
HalfEven
andHalfOdd
modes would also need to be renamed toHalfTowardsEven
andHalfTowardsOdd
For me, the implied preposition in HalfEven
is “to”, not “towards”. In other words, in the HalfEven mode, a half-number is replaced with the nearest even integer; it is not replaced with a integer in the direction of (or: towards) an even integer. So, Round::HalfEven
is fine; but Round::PositiveInfinity
does not make much sense to me, as the number is not rounded to +∞, but towards +∞.
Second, “TowardsPositiveInfinity” is just a mouthful synonym for “Up”. You could just name it:
Round::Up
At this point, you may invoke either Hamming or Levenshtein and compare it negatively with Round::HalfUp
. Yes there is a risk a confusion (and I do think that such a name is suboptimal for this reason), but the confusion is not just caused by the short Levenshtein distance. That brings to the most important part of my review.
In my opinion, the most important criterion for a good name is:
The name must be clear for itself, not just when comparing it with other ones.
The problem with Round::Up
(or Round::[Towards]PositiveInfinity
), when you first encounter it, is that it is relatively easy to mistakingly assume that it is a “half-*” mode, and to erroneously interpret it as Round::HalfUp
(or, its synonym Round::HalfTowardsPositiveInfinity
).
But that the converse is false: it is impossible to interpret Round::HalfUp
as if it were Round::Up
(or Round::TowardsPositiveInfinity
), because of the distinctive “Half” token that immediately indicate the right interpretation.
So, the best way to disambiguate Round::Up
from Round::HalfUp
, is not to replace “Up” with some creative synonym, but to add a distinctive token that plays the role of — and contrasts with — “Half”. I don’t know if the following suggestion makes sense for you, but it is the one I have found:
Round::FullUp
That said, I think that there is an even better option. I know you will not like it, but bear with me. I sincerely think that the best name is just:
Round::Ceiling
It is short, distinctive, and standard across the computing industry.
Yes, this name is idiosyncratic to English and not used in several other (natural) languages, and if you don’t know English, you will not grasp the metaphor and have to just learn it. However, whatever other name you invent, you have to learn “ceil” anyway, because you will encounter it sooner or later. Many common (programming) languages, including JavaScript, C++, Java, Python, have a ceil
function. Even if you manage not to learn any of those and to code in PHP only, you are at risk to stumble on its built-in ceil(...)
function, or its newly-introduced bcceil(...)
variant.
Therefore, unless we find a name that is really good, I suggest to not fall into the NIH syndrome, and not to force users to learn another name in addition to “ceiling”.
For the same reason, Round::TowardsZero
(suboptimal, because confusable with Round::HalfTowardsZero
) could be replaced with: Round::Truncate
.
—Claude
Hi,
Naming is hard, for sure. Here is my review. I find the names mostly reasonable, except Round::PositiveInfinity and Round::NegativeInfinity. I will discuss Round::PositiveInfinity.
First:
I've discussed this with Saki. In that case the
HalfEven
andHalfOdd
modes would also need to be renamed toHalfTowardsEven
andHalfTowardsOdd
For me, the implied preposition in
HalfEven
is “to”, not “towards”. In other words, in the HalfEven mode, a half-number is replaced with the nearest even integer; it is not replaced with a integer in the direction of (or: towards) an even integer. So,Round::HalfEven
is fine; butRound::PositiveInfinity
does not make much sense to me, as the number is not rounded to +∞, but towards +∞.
I agree with this part.
Second, “TowardsPositiveInfinity” is just a mouthful synonym for “Up”. You could just name it:
Round::Up
At this point, you may invoke either Hamming or Levenshtein and compare it negatively with
Round::HalfUp
. Yes there is a risk a confusion (and I do think that such a name is suboptimal for this reason), but the confusion is not just caused by the short Levenshtein distance. That brings to the most important part of my review.
I disagree there, the main motivation of the RFC is to fix the naming of PHP_ROUND_HALF_UP
because it does not match the mathematical behaviour of rounding half toward positive infinity.
And considering multiple other programming languages also have made that mistake I do not think that “TowardsPositiveInfinity” is a synonym for "Up".
Moreover, I'm not sure something being a mouthful is a good reason to name it something else.
In my opinion, the most important criterion for a good name is:
The name must be clear for itself, not just when comparing it with other ones.
The problem with
Round::Up
(orRound::[Towards]PositiveInfinity
), when you first encounter it, is that it is relatively easy to mistakingly assume that it is a “half-*” mode, and to erroneously interpret it asRound::HalfUp
(or, its synonymRound::HalfTowardsPositiveInfinity
).But that the converse is false: it is impossible to interpret
Round::HalfUp
as if it wereRound::Up
(orRound::TowardsPositiveInfinity
), because of the distinctive “Half” token that immediately indicate the right interpretation.So, the best way to disambiguate
Round::Up
fromRound::HalfUp
, is not to replace “Up” with some creative synonym, but to add a distinctive token that plays the role of — and contrasts with — “Half”. I don’t know if the following suggestion makes sense for you, but it is the one I have found:Round::FullUp
This is an interesting point of view, but what this tell me is not an issue with Up or Down on its own, but that seemingly for you and others the focus of rounding is how to break ties, not about the rounding itself.
Moreover, and this is the part where I think the naming of “TowardsPositiveInfinity” is better, is because you said yourself that:
the implied preposition in
HalfEven
is “to”, not “towards”
Which, at least to me, also implies that if you see something that includes "Towards" you stop thinking about the tie breaking behaviour and thus just think about the total/complete rounding behaviour.
That said, I think that there is an even better option. I know you will not like it, but bear with me. I sincerely think that the best name is just:
Round::Ceiling
It is short, distinctive, and standard across the computing industry.
Yes, this name is idiosyncratic to English and not used in several other (natural) languages, and if you don’t know English, you will not grasp the metaphor and have to just learn it. However, whatever other name you invent, you have to learn “ceil” anyway, because you will encounter it sooner or later. Many common (programming) languages, including JavaScript, C++, Java, Python, have a
ceil
function. Even if you manage not to learn any of those and to code in PHP only, you are at risk to stumble on its built-inceil(...)
function, or its newly-introducedbcceil(...)
variant.Therefore, unless we find a name that is really good, I suggest to not fall into the NIH syndrome, and not to force users to learn another name in addition to “ceiling”.
I don't see how this falls into the NIH syndrome, because it has not been invented here.
The terminology chosen is standard in mathematics, and even more so in mathematical speech in other languages.
Best regards,
Gina P. Banyard
On Wed, Jun 19, 2024 at 12:16 PM Claude Pache claude.pache@gmail.com
wrote:
Second, “TowardsPositiveInfinity” is just a mouthful synonym for “Up”. You
could just name it:Round::Up
At this point, you may invoke either Hamming or Levenshtein and compare it
negatively withRound::HalfUp
. Yes there is a risk a confusion (and I do
think that such a name is suboptimal for this reason), but the confusion is
not just caused by the short Levenshtein distance. That brings to the most
important part of my review.
This is completely incorrect. "Up" is needlessly ambiguous. As evidence, I
will quote from the CURRENT documentation for PHP:
"PHP_ROUND_HALF_UP Rounds num away from zero when it is half way there,
making 1.5 into 2 and -1.5 into -2"
https://www.php.net/manual/en/function.round.php
Clearly it is not "just a synonym", as the current PHP (incorrectly)
equates "up" with "away from zero". It's the difference between rounding
"up" in magnitude, and rounding "up" in value.
Any discussion about "Hamming distance" utterly pales in the face of the
reality that developers will be confused because we have trained them for
20 years to expect something else. People wanting to tab-complete faster is
not a good argument in my opinion for doing something that will actively
cause bugs and confusion about semantical meaning.
"Up" and "Down" do not belong in a mathematical description of rounding
where negative numbers exist, unless that term is consistent and WIDELY
agreed on. However, to cause even FURTHER confusion, OTHER languages (such
as the python function round_up
) use "Up" to mean exactly what you are
saying here: towards positive infinity.
The fact that this is not a consistent terminology across languages that
support rounding, AND the fact that PHP has for decades used "Up" to mean
"Away from zero" makes this a complete non-started in my eyes.
If there is ONE improvement to be made with this RFC, it is to completely
remove "up" and "down" from the rounding terminology.
Jordan
Hi
If there is ONE improvement to be made with this RFC, it is to completely
remove "up" and "down" from the rounding terminology.
Please note that the RFC does not include the “Up” and “Down”
terminology in its proposal. It only uses it to describe which of the
”legacy” rounding mode constants are equivalent to the proposed enum cases.
Best regards
Tim Düsterhus
Hi
please apologize the delay in getting back to you. I was absolutely
swamped with mailing list mails, other work and I didn't want to give a
reply that I did not give any thought.
Second, “TowardsPositiveInfinity” is just a mouthful synonym for “Up”. You could just name it:
Round::Up
Except that it isn't and both the RFC and the two fine folks who already
replied explained why.
At this point, you may invoke either Hamming or Levenshtein and compare it negatively with
Round::HalfUp
. Yes there is a risk a confusion (and I do think that such a name is suboptimal for this reason), but the confusion is not just caused by the short Levenshtein distance. That brings to the most important part of my review.
Please note that the comparison was not made against the corresponding
“Half” mode, but rather that the term “Up” is needlessly ambiguous. As
I've also replied to Jordan: The RFC intentionally does not use the Up
terminology (except to refer to the existing constants, which
unfortunately use that terminology).
In my opinion, the most important criterion for a good name is:
The name must be clear for itself, not just when comparing it with other ones.
The problem with
Round::Up
(orRound::[Towards]PositiveInfinity
), when you first encounter it, is that it is relatively easy to mistakingly assume that it is a “half-*” mode, and to erroneously interpret it asRound::HalfUp
(or, its synonymRound::HalfTowardsPositiveInfinity
).
That is a fair concern. We shortly discussed splitting the enum into one
"MidpointRoundingMode" and one other enum for the directed rounding
modes, but we felt that it did not reliably solve this problem either.
At least with a single enum all the 'Half' modes would appear in
autocompletion.
But that the converse is false: it is impossible to interpret
Round::HalfUp
as if it wereRound::Up
(orRound::TowardsPositiveInfinity
), because of the distinctive “Half” token that immediately indicate the right interpretation.
Right.
So, the best way to disambiguate
Round::Up
fromRound::HalfUp
, is not to replace “Up” with some creative synonym, but to add a distinctive token that plays the role of — and contrasts with — “Half”. I don’t know if the following suggestion makes sense for you, but it is the one I have found:Round::FullUp
You might have misunderstood my email. The concerns were not that
HalfTowardsZero is too similar to TowardsZero, but rather that
HalfTowardsZero is too similar to HalfTowardsEven, because they share
the same 11-character prefix.
That said, I think that there is an even better option. I know you will not like it, but bear with me. I sincerely think that the best name is just:
Round::Ceiling
It is short, distinctive, and standard across the computing industry.
Yes, this name is idiosyncratic to English and not used in several other (natural) languages, and if you don’t know English, you will not grasp the metaphor and have to just learn it. However, whatever other name you invent, you have to learn “ceil” anyway, because you will encounter it sooner or later. Many common (programming) languages, including JavaScript, C++, Java, Python, have a
ceil
function. Even if you manage not to learn any of those and to code in PHP only, you are at risk to stumble on its built-inceil(...)
function, or its newly-introducedbcceil(...)
variant.Therefore, unless we find a name that is really good, I suggest to not fall into the NIH syndrome, and not to force users to learn another name in addition to “ceiling”.
There is precedent for an "infinity-based" naming in other programming
languages. The most mainstream one is probably C#:
https://learn.microsoft.com/en-us/dotnet/api/system.midpointrounding?view=net-8.0
But there is also MATLAB:
https://de.mathworks.com/help/matlab/ref/round.html#mw_e51282fd-7461-4bab-9f38-6106551bb8b2
We can even find precedent in PHP itself. The GMP extension already has
rounding mode constants GMP_ROUND_PLUSINF and GMP_ROUND_MINUSINF:
https://www.php.net/manual/en/gmp.constants.php
And to add some anecdata: Just a few days ago I fixed a bug where the
floor()
function was incorrectly used where rounding towards zero was
desired, resulting in incorrect results for negative numbers.
The Ceiling / Floor / Up / Down naming is needlessly ambiguous,
especially for non-native speakers.
For the same reason,
Round::TowardsZero
(suboptimal, because confusable withRound::HalfTowardsZero
) could be replaced with:Round::Truncate
.
While I think that Truncate is reasonably clear, breaking the mapping
between the midpoint modes and the directed rounding modes just for this
case does not appear useful.
Best regards
Tim Düsterhus
Hey Saki, I like this change. When I was implementing additional
rounding modes for the next PHP version I was initially struggling
with the naming and this change will be helpful.I have only one concern about the names
NegativeInfinity
and
PositiveInfinity
. They may be too formal from the user's
perspective. As we already have functionsceil
andfloor
it's
more intuitive for developers to understand the logic of ceiling
and floor rounding.But if voters will prefer those terms then it makes sense to
change the constants implemented in PHP 8.4 (and thus not released
yet) fromPHP_ROUND_(CEILING|FLOOR)
to
PHP_ROUND_(POSITIVE_INFINITY|NEGATIVE_INFINITY)
for the sake of
consistency.I was confused by those as well. It's not obvious to me what those
even do. Do they mean "away from 0"? If not, then I have no clue
what they are. :-)Considering that there are already "Away from 0" and "Towards 0" enum
cases, the Towards Positive Infinity/Towards Negative Infinity cases
"obviously" don't mean this.Towards positive infinity means that for positive numbers you round to
the integer part plus 1, and for negative numbers you "just" take the
negative integer part. Similarly, for rounding towards negative
infinity positive numbers round to "just" the integer part of it, and
negative numbers round to the negative integer part minus 1.It should also be noted that ceil/floor is very English specific
terminology that may not be immediately obvious to non-English
speakers, thus my preference for using some variation of towards
positive/negative infinity.
But they're well established in existing PHP features.
cheers,
Derick
--
https://derickrethans.nl | https://xdebug.org | https://dram.io
Author of Xdebug. Like it? Consider supporting me: https://xdebug.org/support
mastodon: @derickr@phpc.social @xdebug@phpc.social
Hi
But they're well established in existing PHP features.
That does not mean that we shouldn't attempt to do better for newly
introduced APIs. Over time there will be more developers that will newly
learn PHP than there are developers that already know PHP’s standard
library in detail.
Of course that does not mean that we should break consistency with
existing functionality without good justification, but in the case of
the RoundingMode
enum, the enum is self-contained and with the
addition of the new rounding modes in PHP 8.4 [1], the existing ceil()
and floor()
functions are redundant with the capabilities of
round()
. Anyone who newly learns PHP would get all the functionality
by just using round()
together with one of the self-explanatory
rounding modes provided by the proposed RoundingMode
enum.
Best regards
Tim Düsterhus
[1] https://wiki.php.net/rfc/new_rounding_modes_to_round_function
Hi, internals!
I would like to start an RFC discussion regarding rounding modes.
https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enumAs mentioned previously by Gina on the mailing list [1], there are some issues with PHP's current rounding mode.
[1] - https://externals.io/message/123126• First, the value is just an int, so we need to verify that the value passed is a valid rounding mode.
• The second problem is that the behavior of the “up” and “down” modes does not match the mathematical definition. Especially for non-native speakers, the different rounding modes might also be more easily confused, compared to a naming that uses less abstract terms.To resolve these issues, change the naming to something appropriate and use Enums instead of int constants.
Please see the RFC for details.
Regards,
Saki
IMHO, part of the RFC should be to amend the "Add 4 new rounding modes to round()
function" RFC [1] by removing the newly introduced constant and instead exposing the functionality only via the new Enum.
Especially as those constant have not yet been in a stable release of PHP.
Other than that, and seeing the confusing of some other people, maybe using the names "TowardsPositiveInfinity" and "TowardsNegativeInfinity" is better.
Best regards,
Gina P. Banyard
I would like to start an RFC discussion regarding rounding modes.
https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enum
I think it would be really helpful to have a description (and examples)
for each of the rounding modes in the Enum
(https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enum#proposal)
— that'd also be great for creating documentation later on.
cheers,
Derick
Hi
I would like to start an RFC discussion regarding rounding modes.
https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enumI think it would be really helpful to have a description (and examples)
for each of the rounding modes in the Enum
(https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enum#proposal)
— that'd also be great for creating documentation later on.
The RoundingMode
enum will not provide any new rounding modes, thus
the existing documentation of rounding modes applies. The corresponding
constant names have been mentioned.
Nevertheless I've just added a PHPDoc with a brief definition and
examples to each of the enum cases.
Please note: The definition is a little simplified to make it easier to
understand the differences on a conceptual level.
It assumes arbitrary precision (which floats do not provide) and it
assumes that rounding always rounds to integer values. In reality the
round()
function supports a specified number of decimal digits, with
integer rounding being rounding to 0 decimal digits. An integer rounding
function can emulate rounding to a specific number of decimal digits by
multiplying the input value by 10**$digits, performing integer rounding,
and then dividing by 10**$digits (assuming arbitrary precision).
There's also a helpful table on Wikipedia:
https://en.wikipedia.org/wiki/Rounding#Comparison_of_approaches_for_rounding_to_an_integer
Hope this helps.
Best regards
Tim Düsterhus
Hi
I would like to start an RFC discussion regarding rounding modes.
https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enum
We already wanted to announce the RFC vote, but then I forgot to do so
and then Claude's email came in. Oh well.
Saki and I are happy with the RFC as it is and we also checked with some
folks with a background in maths to see if they would make any further
changes, which they answered they would not.
We plan to to open the vote on Wednesday, July 3rd.
Best regards
Tim Düsterhus