On Thu, Apr 4, 2024, at 9:27 PM, Ilija Tovilo wrote:
> On Thu, Apr 4, 2024 at 5:58 PM Tim Düsterhus <t...@bastelstu.be> wrote:
>>
>> On 4/4/24 16:36, Pablo Rauzy wrote:
>> > I strongly agree in theory, but this could break existing code, and
>> > moreover such a proposal was already rejected:
>> > https://wiki.php.net/rfc/strict_argcount
>>
>> The RFC is 9 years old by now. My gut feeling is be that using an actual
>> variadic parameter for functions that are variadic is what people do,
>> because it makes the function signature much clearer. Actually variadic
>> parameters are available since PHP 5.6, which at the time of the
>> previous RFC was the newest version. Since then we had two major
>> releases, one of which (7.x) is already out of support.
>>
>> I think it would be reasonable to consider deprecating passing extra
>> arguments to a non-variadic function.
>
> IIRC one of the bigger downsides of this change are closure calls that
> may provide arguments that the callee does not care about.
>
> https://3v4l.org/0QdoS
>
> ```
> function filter($array, callable $c) {
>     $result = [];
>     foreach ($array as $key => $value) {
>         if ($c($value, $key)) {
>             $result[$key] = $value;
>         }
>     }
>     return $result;
> }
>
> var_dump(filter(['foo', '', 'bar'], function ($value) {
>     return strlen($value);
> }));
>
> // Internal functions already throw on superfluous args
> var_dump(filter(['foo', '', 'bar'], 'strlen'));
> ```
>
> The user may currently choose to omit the $key parameter of the
> closure, as it is never used. In the future, this would throw. We may
> decide to create an exemption for such calls, but I'm not sure
> replacing one inconsistency with another is a good choice.
>
> Ilija

This is unfortunately not reliable today, because of the difference between how 
internal functions and user-defined ones are handled.  The code above will 
fatal if you use a callable that is defined in stdlib rather than in 
user-space.  I have been bitten by this many times, and is why I ended up with 
double the functions in my FP library:

cf: https://github.com/Crell/fp/blob/master/src/array.php#L34

It's also been argued to me rather effectively that ignoring trailing values 
and optional arguments creates a whole bunch of exciting landmines, as you may 
pass an "extra" parameter to a function expecting it to be ignored, but it's 
actually part of the optional arguments so gets used.  The standard example 
here is intval($value, $base=10).  Basically no one uses the $base parameter, 
and most people forget it exists, but if you allow an optional value to get 
passed to that, especially if in weak typing mode, you could get hilariously 
wrong results.  (For sufficiently buggy definitions of hilarious.)

The behavior difference between internal and user-defined functions is the root 
issue.  One way or another it should be addressed, because the current behavior 
is a landmine I have stepped on many times.

--Larry Garfield

Reply via email to