On Thu, Dec 7, 2023 at 11:36 PM G. P. B. <george.bany...@gmail.com> wrote:

- Objects are always casted to true, GMP(0) will equal to true.
>>
>
> This is incorrect, GMP object do _not_ support casts to bool
> See https://3v4l.org/LHpD1
>

This is weird. Any PHP user would expect that a zero number can be easily
casted to boolean false. This is also why I think we need a scalar decimal
type.



>
>> It works the same as "float" in terms of its usage and type casting
>> except
>> for one thing. Float value can be passed to a decimal argument or
>> typecasted with a warning like "Float to decimal conversion may incur
>> unexpected results".
>>
>> Decimal to float conversion is allowed and smooth:
>>
>> function f (float $value) {}
>>
>> f(0.2);
>>
>> f(0.2d); // allowed with no warnings
>>
>
> I disagree with this part, floats can not represent decimal values
> properly e.g.
> $f1 = 0.1;
> $f2 = 0.2;
> $f3 = 0.3;
> var_dump($f1 + $f2 === $f3);
>
will return false.
> As such, floats are not at all compatible with decimals.
>

Yes, I know that. I mentioned that we can not convert float to decimal
without an intermediate value where we apply rounding and get a
human-readable value in some representation (string or whatsoever).

My intention was to provide implicit conversion with warnings because I
guess that the majority of end users will expect that numeric scalar types
are interoperable. To not make them scared and point them to issues in
their code instead of slapping their hands immediately when they run
something that is not so correct.



> Moreover, the whole point of adding a warning when implicit conversions
> from int to float happen was to be able to warn before elevating the
> warning to a TypeError.
>

Sorry, I'm not aware of issues of converting ints to floats. Are there any
issues? I understand the issue of the backward conversion, but not the
forward one. Could you add details here?



> Therefore, introducing behaviour that warns instead of throwing a
> TypeError is already a no-go from my PoV.
>

I'm okay with TypeErrors for float to decimal conversions as well. This is
not a key point of my proposal. If the community prefers errors instead of
warnings - that's also fine.


Literal numbers in the code are converted to floats by default. If
>> prepended by the "(decimal)" typecast, the decimal result is produced
>> without an intermediary float.
>>
>
> This behaviour is rather suboptimal, I'd rather have literals be decimals,
> as decimals to floats should always be a reasonable implicit coercion
> considering we already do int to float.
>

Is it optimal to perform conversions on every fractional literal? This is
also not a key point for me and I'm okay with any implementation that the
internals community prefers.



>  New declare directive "default_decimal" is added. When used, literals and
>
>> math operations return decimal by default instead of float. This is to
>> simplify creating source files working with decimals only.
>>
>
> Please no, no new declare directives that affect engine behaviour.
> Strict types was already a mistake because of this IMHO.
>

I didn't know that the strict types directive was a mistake. My intention
is to be able to write clean all-decimal units of code and not break the
backward compatibility. The old code should work as it was before. At the
same time, there are use cases when the whole class/project should be
written with decimals only. As a user, I want to do that without complex
language structures and excessive typehints or explicit conversions. The
all-decimal code  should be as clean as it is now with floats. This is why
I proposed this directive. Can you suggest something better to achieve the
same?



> New language construct "as_decimal()" is added to produce decimal math
>> results for literals and math operations instead of float without
>> intermediary float:
>>
>> $var = 5 / 2; // returns float 2.5
>> $var = as_decimal(5 / 2); // returns decimal 2.5
>>
>> This is a kind of "default_decimal" for a specific operation.
>>
>
> Again, this should return a decimal instead IMHO.
>

While it will work from the logical perspective, additional conversions
from decimal to float may incur performance issues in the existing code
that relies on floats only. Again, my intention here is to not break
backward compatibility and not introduce performance issues to the existing
code.



>
>
>> If mixed float and decimal operands are used in a math operation, decimal
>> is converted to float by default. If "default_decimal" directive or
>> "as_decimal()" construct is used, float is converted to decimal (with a
>> warning):
>>
>> $f = (float) 0.2;
>> $d = (decimal) 0.2;
>>
>> $r = $f + $d; // returns float result by default
>> $r = as_decimal($f + $d); // returns decimal result with a warning about
>> implicit float to decimal conversion
>>
>> All builtin functions that currently accept float also accept decimal. So
>> users don't need to care about separate function sets, and PHP developers
>> don't need to maintain separate sets of functions. If such functions get
>> the decimal parameter, they return decimal. If they have more than one
>> float parameter and mixed float and decimal passed, decimals converted to
>> float by default. If "default_decimal" or "as_decimal" used, float is
>> converted to decimal with the warning.
>>
>
> Messing with the return value type has already proved controversial.
> And as I said previously, I am dead against having implicit float to
> decimal conversions.
> Making the functions type generic is something that I am fine, however.
>

I'm fine with generic functions as well. I'm most probably not aware of all
the ongoing discussions. If the internals community prefers generic
functions, I'm absolutely fine with it.




>
>
>> The new type uses libmpdec internally to perform decimal calculations
>> (same
>> as Python).
>>
>
> I really don't think we need arbitrary precision decimals.
>
I'm also not convinced using a floating point spec is the most sensible,
> due to the rounding errors this is going to introduce.
> The non-arbitrary IEEE 754-2008 specification cannot describe the decimal
> 123457.1467 exactly, which is frankly pointless.
>
> Decimals, or more broadly rational numbers that, outside numerical
> computations, that are going to be used are not going to need huge
> denominators.
>
> I've been thinking about this for a while, and I personally think that
> rational numbers are just better than trying to support only decimals.
> And considering we have 64 bits to play with for a new zval type splitting
> the bits into a 32-bit unsigned integer for the numerator and an 32-bit
> signed integer for the denominator should provide us with enough reasonable
> rational numbers.
> As any number that do not fit in this structure seems to be something
> relegated to the world of numerical computation where floats are what are
> mostly used anyway.
>

If you can suggest a better way of working with fractional numbers - please
do :) But IMO limiting the language by 64 bits is not a good way. It is
more easy to go over the limit than you may think :) Especially in some
intermediary values while performing complex calculations. I could be
wrong, but fractional numbers limited to 64 bits sound like a bandaid. The
language will tell users "hey, you can do something general, but if you
want something else please don't use me at all or involve bandaids with
extensions". My key point is not only to allow working with decimals, but
also to make all the alternatives useless, cover their functionality by
builtin tools, to free users from thinking about workarounds and bandaids.
>From my POV, introducing a new decimal type that does not cover the
GMP/bcmath/ext-decimal functionality is pointless and a waste of time.



>
>
>> All of the points above are subject to discussions, it is not an RFC
>> candidate right now. So please share your opinions.
>>
>> I know that the implementation of this will require a lot of work. But I
>> don't think this is a stopper from formulating the requirements.
>> Sometimes,
>> any project requires big changes to move forward. I'm pretty sure this
>> functionality will move PHP to the next level and expand its area of
>> applications. My thoughts here are mostly from the user's perspective,
>> I'm
>> not so familiar with PHP internal implementation. But I think this
>> feature
>> can be a good goal for PHP 9.
>>
>
> Yes, this is a major project, and as said above I have also thought about
> adding a rational number type.
> But the main hurdle for this is changing the zval structure and applying
> the change everywhere to the engine and extensions.
>

I understand that changing something that is at the core of the whole
project is a huge butthurt. But let's focus on end benefits :) I love PHP
but it is also well-known that it is perceived as a language NOT for
"serious and mature" projects. Partly because if you try working with
financial data for a bank app, for example, you immediately have troubles
choosing a workaround to work with fractional numbers and the code you
write will look weird. How quickly you would be able to read something like
this: gmp_add(gmp_mul(gmp_div(gmp_sub($value, $add), $value2, $factor,
gmp_sin($value3), gmp_intval($value))) ? This absence of intuitive
readability makes the development and support difficult and it's better to
choose another language. This is what I want to change and make PHP
powerful enough for this kind of applications.


Best regards,
Alex.

Reply via email to