# [RFC] Saner array_(sum|product)()

- Thread: https://externals.io/message/119291
- Original archive: https://news-web.php.net/php.internals/119291
- Started by G. P. B. on 2023-01-17T14:33:23+00:00
- Messages: 7
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #119291 — G. P. B. — 2023-01-17T14:33:23+00:00

URL: https://externals.io/message/119291#119291

Hello internals,

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.

Best regards,

George P. Banyard

---

## #119310 — Derick Rethans — 2023-01-18T15:06:42+00:00

URL: https://externals.io/message/119291#119310 · In reply to: #119291

> 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) :-)

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);

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 :-)


cheers,
Derick

---

## #119331 — G. P. B. — 2023-01-18T19:52:43+00:00

URL: https://externals.io/message/119291#119331 · In reply to: #119310

> 
>
> > […]
>
> 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

---

## #119424 — G. P. B. — 2023-01-26T16:32:08+00:00

URL: https://externals.io/message/119291#119424 · In reply to: #119331

Hello internals,

I've slightly updated the RFC:
https://wiki.php.net/rfc/saner-array-sum-product

I've added an FFI example which overloads addition but cannot be cast to a
numeric type.
And changed the behaviours around objects. An object needs to implement a
numeric cast for it to be added/multiplied, this solves the issue around
having the return value being cast to an object as this cannot happen
anymore.

Best regards,

George P. Banyard

---

## #119533 — G. P. B. — 2023-02-13T01:47:49+00:00

URL: https://externals.io/message/119291#119533 · In reply to: #119424

Hello internals,

If there are no further feedback I intend on opening the vote for this
tomorrow.

Best regards,

George P. Banyard

---

## #119581 — Andreas Hennings — 2023-02-20T14:38:19+00:00

URL: https://externals.io/message/119291#119581 · In reply to: #119533

Hello,
the RFC seems like a good idea to me.
However, I do not see any mention of plus operator on arrays, e.g. ['a' =>
'A'] + ['b' => 'B']. The `array_reduce()` would support this, but I think
 `array_sum()` would not, because of the return type. I just think this should
be made more explicit.
-- Andreas



> Hello internals,
>
> If there are no further feedback I intend on opening the vote for this
> tomorrow.
>
> Best regards,
>
> George P. Banyard

---

## #119582 — G. P. B. — 2023-02-20T14:46:00+00:00

URL: https://externals.io/message/119291#119582 · In reply to: #119581

> Hello,
> the RFC seems like a good idea to me.
> However, I do not see any mention of plus operator on arrays, e.g. ['a' =>
> 'A'] + ['b' => 'B']. The `array_reduce()` would support this, but I think
> `array_sum()` would not, because of the return type. I just think this should
> be made more explicit.
> -- Andreas
>

Arrays are mentioned in the RFC, and they are already not supported in the
array_(sum|product) functions and remain unsupported.

Best,

George P. Banyard
