Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123041 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id A6CC11A009C for ; Mon, 8 Apr 2024 12:01:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1712577692; bh=HkdZqgKIQZTkg/Erx7d9oJDK0tRdqI0l8MHIx8f0MdI=; h=Date:Subject:To:References:From:In-Reply-To:From; b=bARl/9oTB7HncxWov+DMje8aXSr3ymSh1rkxVKdyPjtAAaLmSGnh3/HS9tYM4Sxhd rBR3vXH2dNZP7nQV+10anK5HPC4FUMyObKEpabKC5IcEyQYZbxKPJiGtuclMtjfWtw DrdkEGT6WyIt44Smt7aLahN+arXwQD5R/0tGzDZSgyDy7tS33V4DZDirb8fl4ofA/8 boFxGXigzh+9p4zhb0c9KJRDSF3r8+nd1fvw/fzyAjGZJcTdkbn+T3yN/Pb5G+ItrQ ZnVtnouIMUUDwaLE7/ycf098Duq1727r70mLncmA/rG+eC3Jcl9VrgkfeReDNIn7VJ x2gLeK+7ehdUA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 78E381806B7 for ; Mon, 8 Apr 2024 12:01:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.2 required=5.0 tests=BAYES_40,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,SPF_HELO_PASS,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from smtp-bc0c.mail.infomaniak.ch (smtp-bc0c.mail.infomaniak.ch [45.157.188.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 8 Apr 2024 12:01:28 +0000 (UTC) Received: from smtp-3-0001.mail.infomaniak.ch (smtp-3-0001.mail.infomaniak.ch [10.4.36.108]) by smtp-3-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4VCnjg6N37zpGj for ; Mon, 8 Apr 2024 14:00:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=uzy.me; s=20230717; t=1712577655; bh=HkdZqgKIQZTkg/Erx7d9oJDK0tRdqI0l8MHIx8f0MdI=; h=Date:Subject:To:References:From:In-Reply-To:From; b=j8xPmmCf/ySR5MJpkdEJ7x8p3t9Dp5riJ6zcyrRNSMg0cRSAqnj4Sw960PKS/614A CjbzPUjmjqE5cLVdILDxXrIK41Rz1+CWN6OpC+9yyHfJs5L+oeS12SEGFBhoOFFKR1 e6cMKtew3/aXe7bp3piUPLoTzpya09yQWiRspkSQBv2okADd+oSPR2oaPazDcvsP29 MiBGRNPIMq9GDF4JcRfCYsq1QisTnghbCy5txJ2R90hdBDnLwnZU/8ycpVCug0Cx3p KNG8Z4SmTvhREKELas2NSpchQ/J6anpKhQz4Zk08kaTaePlHoTw1kGEMZHTuzrKwYI IyXIEw/2W5z/A== Received: from unknown by smtp-3-0001.mail.infomaniak.ch (Postfix) with ESMTPA id 4VCnjg2442zf4P for ; Mon, 8 Apr 2024 14:00:55 +0200 (CEST) Content-Type: multipart/alternative; boundary="------------f0Ug0uvRwN48TKd55jomaspv" Message-ID: Date: Mon, 8 Apr 2024 14:00:57 +0200 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PHP-DEV] RFC idea: using the void type to control maximum arity of user-defined functions To: internals@lists.php.net References: <6299b649-c19b-4172-9632-2ef0a55d256d@uzy.me> <7B32AF65-CA40-40F5-BA59-CB5180EC4D7F@gmail.com> <8f71d807-78e6-49f6-acc7-b1fc09d815ba@uzy.me> <989e3e13-48ee-4970-8485-f79bb70ad37c@bastelstu.be> Content-Language: fr In-Reply-To: X-Infomaniak-Routing: alpha From: r@uzy.me (Pablo Rauzy) This is a multi-part message in MIME format. --------------f0Ug0uvRwN48TKd55jomaspv Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hello all, Le 05/04/2024 à 15:53, Larry Garfield a écrit : > On Thu, Apr 4, 2024, at 9:27 PM, Ilija Tovilo wrote: >> On Thu, Apr 4, 2024 at 5:58 PM Tim Düsterhus 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 So what should be done to move forward with this? Should the old RFC on strict argument count be revived? Or should a new RFC proposal be written? If so, should it contain an approval voting (where voters can select any number of candidates), prior to the RFC proposal vote itself, to decide if the change should be: strict argument count, using the void keyword to explicitely stop the argument list, or using a #[Nonvariadic] attribute? Best regards, -- Pablo --------------f0Ug0uvRwN48TKd55jomaspv Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit

Hello all,

Le 05/04/2024 à 15:53, Larry Garfield a écrit :
On Thu, Apr 4, 2024, at 9:27 PM, Ilija Tovilo wrote:
On Thu, Apr 4, 2024 at 5:58 PM Tim Düsterhus <tim@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

So what should be done to move forward with this?

Should the old RFC on strict argument count be revived?

Or should a new RFC proposal be written? If so, should it contain an approval voting (where voters can select any number of candidates), prior to the RFC proposal vote itself, to decide if the change should be: strict argument count, using the void keyword to explicitely stop the argument list, or using a #[Nonvariadic] attribute?

Best regards,

-- 
Pablo
--------------f0Ug0uvRwN48TKd55jomaspv--