On Tue, Mar 19, 2024 at 5:35 AM Rowan Tommins [IMSoP]
<imsop....@rwec.co.uk> wrote:

> I think a reasonable number of people do share the sentiment that having two 
> separate modes was a mistake; and neither mode is actually perfect. It's not 
> about "making it on by default", it's about coming up with a unified 
> behaviour that makes the setting redundant.

This is off-topic, but just to conclude: as a user, I personally would
love to see strict_types to be always enabled eventually.


> I don't think choice is really what you want: if you were designing a 
> language from scratch, I doubt you would say "let's give the user a choice of 
> what type 1 / 10 returns". What it's actually about is *backwards 
> compatibility*: what will happen to code that expects 1/10 to give a float, 
> if it suddenly starts giving a decimal.

> In short, the best way of avoiding declare() directives is not to replace 
> them with something else, but to choose a design where nobody feels the need 
> for them.

I understand your point and it is completely valid. But I'm speaking
from a different angle. There are obviously two opposite areas of
calculations, two "modes": "I don't care much about the performance,
give me precise results" and "I don't care about rounding errors, give
me the fastest results". I can't imagine a way of joining them and
unifying the work with them until a completely new CPU architecture is
invented. It makes me think "how can we make both types of users
happy"? I would like to see native and intuitive support for both of
the "modes". So "declare(default_decimal)" seems to be a good option.
Users already know what is "declare" so it will be not a problem to
start using another option. Again, I'm not trying to replace float
calculations with decimals due to performance and backward
compatibility. My goal is to invent a way to make two "modes"
convenient without bandaids.


> For most cases, I think the rule can be as simple as "decimal in means 
> decimal out". What's maybe not as obvious at first sight is that that can 
> apply to operators as functions, and already does: 100 / 10 gives int(10), 
> but 100.0 / 10  gives float(10.0), as do 100 / 10.0  and 100.0 / 10.0

I agree that if one of the operands is decimal then the result should
be decimal. The "declare(default_decimal)" is suggested specifically
for the cases when it is unclear what result we should return and to
not introduce monstrous syntax with a lot of typecast or special
syntax.


> By the same logic, decimal(1) / 10 can produce decimal(0.1) instead of 
> float(0.1), and we don't need any fancy directives. Even better if we can 
> introduce a shorter syntax for decimal literals, so that it becomes 1_d / 10

With "declare(default_decimal)" there's no need to introduce new
syntax for numbers. I personally would prefer to work with "normal"
number literals and let PHP decide (under my guidance) how to
represent them internally - as floats or as decimals.


> Where things get more complicated is with *fixed-precision* decimals, which 
> is what is generally wanted for something like money. What is the correct 
> result of decimal(1.03, precision: 2) / 2 - decimal(0.515, 3)? decimal(0.51, 
> 2)? decimal (0.52, 2)? an error? And what about decimal(10) / 3?

As a user, I see it as we store a decimal number internally with the
maximum number of fractional digits and let the user choose how to
represent it only when converting it from decimal to something else.
Only at this moment, some rounding will happen and we may give users
the proper tools for this. When it comes to 1/3, we may hardcode some
specific rounding mode when it exceeds the internal limit of
fractional digits. In my view, this limit will be more than enough for
99.9% of so they will be able to apply their own rounding mode to 0 or
2 or 10 fractional digits with no issues.


> If you stick to functions / methods, this is slightly less of an issue, 
> because you can have decimal(1.03, 2)->dividedBy(2, RoundingMode::DOWN) == 
> decimal(0.51, 2); or decimal(1.03, 2)->split(2) == [ decimal(0.52, 2), 
> decimal(0.51, 2) ] Example names taken directly from the brick/money package.

Yes, but the whole point of my suggestion is to go away from the
object syntax :) My goal is not to make the future implementation
simpler but to lift the PHP language to the next level even if will
cost much more effort in total.

And just to clarify. I'm not a big expert in decimal calculations, my
proposal is still not so specific and I may have a lack of knowledge
in some terms or details and may need help from more experienced
people. I'm discussing possible ways of the implementation and I would
like to help the community to develop some design that will make
future development aligned with some principles and eventually achieve
the final goal. I understand the complexity of the proposal so I'm not
standing on the implementation as a whole by some PHP version. But I
would be more than happy to know that the language is evolving in the
defined direction.

--
Best, Alexander

Reply via email to