On Wed, 18 Jan 2023 at 15:06, Derick Rethans <der...@php.net> wrote:

> On Tue, 17 Jan 2023, G. P. B. wrote:
>
> > I would like to start the discussion about the Saner
> > array_(sum|product)() RFC:
> > https://wiki.php.net/rfc/saner-array-sum-product
> >
> > Currently, the array_sum() and array_product() behave differently than
> > their userland implementation as they ignore arrays and objects, and
> > cast the remaining types to int/float. This is in contrast with the
> > behaviour of arithmetic operators that throw TypeErrors on types and
> > values that are not interpretable as int/float.
> >
> > This RFC aims to resolve this discrepancy.
>
> I think I agree with the premise of this RFC, but I do think a few
> details are wrongly addressed.
>
> First of all, a clarification why this produces int(4) would be useful:
>
>         $input = [true, STDERR, new stdClass(), [], gmp_init(6)];
>         $output = array_sum($input);
>
> I had to look up that STDERR would cast to int(3) :-)
>

ACK will clarify this.


> I don't understand why this would result in a warning and a return of
> int(50):
>
>         $a = [10, 15.6, gmp_init(25)];
>         var_dump(array_sum($a));
>
> Why doesn't this return float(50.6) instead? I realise that the
> array_reduce variant (below) does the same, but it's not what I would
> expect:
>
>         <?php
>         $input = [10, 15.6, gmp_init(25)];
>         $output = array_reduce($input, fn($carry, $value) => $carry +
> $value, 0);
>

The issue is that now when encountering an object, if it defines a
do_operation handler, it will use that and not cast the value to a numeric
type.
I suppose it's possible to first check if the entry is an object and do a
manual cast, which might also negate the next issue you mentioned.


> I think the phrase "If traversing the array transforms the return value
> into an object, if that object is not numerically castable an E_WARNING
> is emitted and the initial return value is returned instead, which may
> change the return value if scalar values were present in the array. "
> should come with an example :-)
>

Within php-src we don't really have any "practical" examples, FFI\CData can
possibly satisfy this condition by doing something like:
$x = FFI::new("int[2]");
$x[0] = 10;
$x[1] = 25;
var_dump($x + 1);
/* dumps:
object(FFI\CData:int32_t*)#2 (1) {
  [0]=>
  int(25)
}
*/

I constructed a special class and added it to zend_test to be able to test
this behaviour, but will see if I can wrangle FFI to also show this case.

Best regards,

George P. Banyard

Reply via email to