On 07/04/2024 18:09, Tim Düsterhus wrote:
- I'm not sure if the priority for the rounding modes is sound. My gut feeling is that operations on numbers with different rounding modes should be disallowed or made explicit during the operation (much like the scale for a division), but I'm not an expert in designing numeric APIs, so I might be wrong here.


Personally, I'm not a fan of setting the rounding mode and the "max expansion scale" on each instance, for the same reason I'm not keen on having the collation on each instance in Derick's Unicode string draft.

I understand the temptation: specifying it for every operation makes code more verbose, particularly since it rules out use of $a / $b; while specifying it as a global or scoped option would make code harder to reason about.

But I think carrying it around on the instance doesn't really solve either problem, and creates several new ones:

- A program which wants all operations to use the same rounding system still has to specify the options every time it initialises a value, which is probably nearly as often as operating on them.

- A program which wants different modes at different times will end up calling $foo->withRoundingMode(RoundingMode::HALF_UP)->div(2), which is more verbose and probably slower than $foo->div(2, RoundingMode::HALF_UP)

- You can't look at a function accepting a Number as input and know what rounding mode it will operate in, unless it explicitly changes it. It would be easier to scan up to find a per-file / per-block declare() directive, than to trace the calling code to know the rounding mode of an instance.

- A complex set of rules is invented to "prioritise" the options in operations like $a + $b. Or, that operation has to be forbidden unless the mode is consistent, at which point it might as well be a global setting.


As a thought experiment for comparison, imagine if to sort an array numerically you had to write this:

$array = array_set_sorting_mode($array, SORT_NUMERIC);
$array = array_sort($array);

Or worse, if you had to set it on each string:

$array = array_map($array, fn($s) => $s->withSortingMode(SORT_NUMERIC));
$array = array_sort($array);

Rather than (assuming we replaced the current by-reference sorts):

$array = array_sort($array, SORT_NUMERIC);

Because we're designing an object, attaching extra properties to it is easy, but I don't think it actually makes it easy to use.


Regards,

--
Rowan Tommins
[IMSoP]

Reply via email to