rfc:saner-array-sum-product
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
rfc:saner-array-sum-product [2023/01/14 21:06] – Created girgias | rfc:saner-array-sum-product [2023/03/07 15:43] (current) – girgias | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PHP RFC: Saner array_(sum|product)() | ====== PHP RFC: Saner array_(sum|product)() | ||
- | * Version: 0.1 | + | * Version: 0.2 |
* Date: 2023-01-14 | * Date: 2023-01-14 | ||
* Author: George Peter Banyard, < | * Author: George Peter Banyard, < | ||
- | * Status: | + | * Status: |
* Target Version: PHP 8.3 | * Target Version: PHP 8.3 | ||
* Implementation: | * Implementation: | ||
Line 25: | Line 25: | ||
If the entries in the input array are exclusively comprised of int and float values, then the behaviour between the built-in functions and their userland implementation is identical. However, if other types are part of the entries, the behaviour diverges. | If the entries in the input array are exclusively comprised of int and float values, then the behaviour between the built-in functions and their userland implementation is identical. However, if other types are part of the entries, the behaviour diverges. | ||
- | We believe that the behaviour between the two variants should be as close as possible, | + | We believe that the behaviour between the two variants should be as close as possible, |
Therefore, we will first look at the behaviour of the < | Therefore, we will first look at the behaviour of the < | ||
Line 31: | Line 31: | ||
==== Behaviour of the array_reduce() variants === | ==== Behaviour of the array_reduce() variants === | ||
- | As the < | + | As the < |
< | < | ||
Line 47: | Line 47: | ||
All other cases throw a '' | All other cases throw a '' | ||
+ | === Examples === | ||
+ | |||
+ | Example with < | ||
+ | <PHP> | ||
+ | $input = [gmp_init(6), | ||
+ | |||
+ | // Userland implementation of array_sum($input) | ||
+ | $output = array_reduce($input, | ||
+ | var_dump($output); | ||
+ | /* | ||
+ | object(GMP)# | ||
+ | [" | ||
+ | string(2) " | ||
+ | } | ||
+ | */ | ||
+ | |||
+ | // Userland implementation of array_product($input) | ||
+ | $output = array_reduce($input, | ||
+ | var_dump($output); | ||
+ | /* | ||
+ | object(GMP)# | ||
+ | [" | ||
+ | string(2) " | ||
+ | } | ||
+ | */ | ||
+ | </ | ||
+ | |||
+ | Pathological example: | ||
+ | <PHP> | ||
+ | /* STDERR gets cast to 3 */ | ||
+ | $input = [true, STDERR, new stdClass(), [], gmp_init(6)]; | ||
+ | |||
+ | // Userland implementation of array_sum($input) | ||
+ | $output = array_reduce($input, | ||
+ | var_dump($output); | ||
+ | |||
+ | // Userland implementation of array_product($input) | ||
+ | $output = array_reduce($input, | ||
+ | var_dump($output); | ||
+ | </ | ||
+ | |||
+ | Certain FFI\CData types implements a '' | ||
+ | <PHP> | ||
+ | $x = FFI:: | ||
+ | $x[0] = 10; | ||
+ | $x[1] = 25; | ||
+ | |||
+ | $input = [$x, 1]; | ||
+ | |||
+ | $output = array_reduce($input, | ||
+ | var_dump($output); | ||
+ | /* | ||
+ | object(FFI\CData: | ||
+ | [0]=> | ||
+ | int(25) | ||
+ | } | ||
+ | */ | ||
+ | </ | ||
==== Current behaviour of the array_sum() and array_product() functions ==== | ==== Current behaviour of the array_sum() and array_product() functions ==== | ||
Line 58: | Line 116: | ||
* Otherwise, the entry is cast to a number (int|float), | * Otherwise, the entry is cast to a number (int|float), | ||
- | As such resource, array, non-numeric strings, and non-addable/ | + | As such resource, array, non-numeric strings, and non-addable/ |
+ | |||
+ | === Examples === | ||
+ | |||
+ | Example with < | ||
+ | < | ||
+ | $input = [gmp_init(6), | ||
+ | |||
+ | $output = array_sum($input); | ||
+ | var_dump($output); | ||
+ | |||
+ | $output = array_product($input); | ||
+ | var_dump($output); | ||
+ | </ | ||
+ | |||
+ | Pathological example: | ||
+ | < | ||
+ | /* STDERR gets cast to 3 */ | ||
+ | $input = [true, STDERR, new stdClass(), [], gmp_init(6)]; | ||
+ | |||
+ | $output = array_sum($input); | ||
+ | var_dump($output); | ||
+ | |||
+ | $output = array_product($input); | ||
+ | var_dump($output); | ||
+ | </ | ||
+ | |||
+ | |||
+ | FFI example: | ||
+ | < | ||
+ | $x = FFI:: | ||
+ | $x[0] = 10; | ||
+ | $x[1] = 25; | ||
+ | |||
+ | $input = [$x, 1]; | ||
+ | |||
+ | $output = array_sum($input); | ||
+ | var_dump($output); | ||
+ | </ | ||
===== Proposal ===== | ===== Proposal ===== | ||
- | The proposal is to use the same behaviour for < | + | The proposal is to use the same behaviour for < |
+ | |||
+ | The one caveat is that objects must implement a numeric cast for them to be added/ | ||
+ | |||
+ | Therefore, the previous three examples would result in the following behaviour: | ||
+ | |||
+ | Example with < | ||
+ | < | ||
+ | $input = [gmp_init(6), | ||
+ | |||
+ | $output = array_sum($input); | ||
+ | var_dump($output); | ||
+ | |||
+ | $output = array_product($input); | ||
+ | var_dump($output); | ||
+ | </ | ||
+ | |||
+ | Pathological example: | ||
+ | < | ||
+ | $input = [true, STDERR, new stdClass(), [], gmp_init(6)]; | ||
+ | |||
+ | $output = array_sum($input); | ||
+ | var_dump($output); | ||
+ | /* | ||
+ | |||
+ | Warning: array_sum(): | ||
+ | |||
+ | Warning: array_sum(): | ||
+ | |||
+ | Warning: array_sum(): | ||
+ | int(10) | ||
+ | */ | ||
+ | |||
+ | $output = array_product($input); | ||
+ | var_dump($output); | ||
+ | /* | ||
+ | |||
+ | Warning: array_product(): | ||
+ | |||
+ | Warning: array_product(): | ||
+ | |||
+ | Warning: array_product(): | ||
+ | int(18) | ||
+ | */ | ||
+ | |||
+ | </ | ||
+ | FFI example: | ||
+ | < | ||
+ | $x = FFI:: | ||
+ | $x[0] = 10; | ||
+ | $x[1] = 25; | ||
+ | |||
+ | $input = [$x, 1]; | ||
+ | |||
+ | $output = array_sum($input); | ||
+ | var_dump($output); | ||
+ | /* | ||
+ | |||
+ | Warning: array_sum(): | ||
+ | int(1) | ||
+ | */ | ||
+ | </ | ||
- | The new implementation reuses the engine functions that perform the arithmetic operations while still accepting, but emitting an < | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
Line 70: | Line 226: | ||
< | < | ||
- | If traversing the array transforms the return value into an object, if that object is not numerically castable an < | + | Arrays that contain |
- | + | ||
- | Arrays that mix scalar values and objects may now produce different results, for example: | + | |
<PHP> | <PHP> | ||
$a = [10, 15.6, gmp_init(25)]; | $a = [10, 15.6, gmp_init(25)]; | ||
Line 79: | Line 233: | ||
Currently, results in: '' | Currently, results in: '' | ||
<PHP> | <PHP> | ||
- | Deprecated: Implicit conversion from float 25.6 to int loses precision in %s on line %d | + | int(50.6) |
- | int(50) | + | |
</ | </ | ||
Line 92: | Line 245: | ||
As per the voting RFC a yes/no vote with a 2/3 majority is needed for this proposal to be accepted. | As per the voting RFC a yes/no vote with a 2/3 majority is needed for this proposal to be accepted. | ||
- | Voting started on 2023-XX-XX and will end on 2023-XX-XX. | + | Voting started on 2023-02-20 and will end on 2023-03-06. |
<doodle title=" | <doodle title=" | ||
* Yes | * Yes | ||
Line 101: | Line 254: | ||
GitHub pull request: https:// | GitHub pull request: https:// | ||
+ | |||
+ | Landed in PHP 8.3: | ||
+ | Implemented via commit: https:// | ||
After the project is implemented, | After the project is implemented, |
rfc/saner-array-sum-product.1673730399.txt.gz · Last modified: 2023/01/14 21:06 by girgias