On 18/03/2024 04:39, Alexander Pravdin wrote:
I'm not in the context of the core team plans regarding "strict types". Could you share some details here? What is the current plan regarding it? To make strict types on by default eventually? Or something else?
PHP doesn't really have a defined "core team". There are contributors who are particularly active at a given time (sometimes, but far from always, because someone is paying them), contributors who are particularly long-standing and respected, contributors who throw themselves into a pet project and make it happen, and so on.
Partly as a consequence of this, it's often hard to pin down any long-term plan about anything, outside of what particular people would like to see. So Gina's opinion (it was suffixed "IMHO") that strict types was a mistake shouldn't be read as "we have a solid plan for what is going to replace strict_types which everyone is on board with".
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.
All of which is something of a diversion from the topic at hand, which is this:
How can we introduce the ability to write user code in default decimals and at the same time keep the old way of working as it was before, to not introduce any troubles into the existing code and not introduce performance issues? As a user, I would like to have a choice.
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.
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
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
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?
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.
At that point, backwards compatibility is less of an issue as well: make the new functions convenient to use, but distinct from the existing ones.
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.
Regards, -- Rowan Tommins [IMSoP]