Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:109693 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 62348 invoked from network); 17 Apr 2020 10:33:51 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 17 Apr 2020 10:33:51 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 1E2071801FD for ; Fri, 17 Apr 2020 02:04:11 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,FREEMAIL_FROM,HTML_MESSAGE,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-lj1-f182.google.com (mail-lj1-f182.google.com [209.85.208.182]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Fri, 17 Apr 2020 02:04:10 -0700 (PDT) Received: by mail-lj1-f182.google.com with SMTP id q19so1222032ljp.9 for ; Fri, 17 Apr 2020 02:04:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=4E07yO12zen8CZcaCDteJAoVEkH5dapXb970sx/cukk=; b=ZSB8kc8fLAuF37gQoXAI2Q4eeQFLSvRH4RpBS9qdd5OHgaJaEH7Xnt/5axHeOdelO6 r+3K8VPvn6hnGeruzTYBauFeQ91K3cxKVNqiG4/ecF5llB4puKFyovPkMv1uNaDT+dTD bUm6VphR/bspqXrfp7Au9WcYDje/FXR5D+MCJ7n+HelkXziFQq8PT79sTXTziX9PhqLd 6p4TKRlOUcNcubqOmnPb4lMZbrhJDa2B9DCwZCwopKfuYg+nD5hwjnV1Gr/tIPZtN6cd t4/xZCpGASlrLITkZzTLgVV+smxjUdh78qz7Z+CR7Q6dIyveW3CJM/d02e30iG/6gCan GdZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=4E07yO12zen8CZcaCDteJAoVEkH5dapXb970sx/cukk=; b=Kmobm1+YMQwGZt1VgZYeX3BJLyOXPymYCzQ6G4JQyCFcSI6sqml2vARIKuPVByayrt 3N3er6yYnvfg3drT+ZaVFfq6jch9M4DJVXkg7pfOs90jF8HGVZHE/WVjea7q2UkyoAg/ E/LJm8/C8xmUBOrGDyLmCmwwEkGBSFJ6SS1HiwUcfv+FWxKAn7XYpter3wOL5B+j4nN9 MoImWARKxVsIvdmg9isxkIqzjvytZOG5xgLLyuHoDydYxw17rbYHsYfjNrAzvsb3FzuP UxSt3TL+woKBpIVOfAVU24P+0CuTbhR8Qzc19GfgmKq31gm8K7A5j5u8m2QCgwlfI84x NA+w== X-Gm-Message-State: AGi0PuaxCsXNe9S7R4LM52pdS5/hqqUdf/nXsIgKTt0f3vUFbP6d2V9Y s9BXzxp/nVUgKBwnC+m7t4l3ufnIMS37SyYoggk= X-Google-Smtp-Source: APiQypKl8Wi7o3bV94KsgJipEKP+Fbfn5lXUWehwT+3CN0NxlM2+l3h2SforTgZCXY6SoAfqEc0PW+9QfVRwksRa/3g= X-Received: by 2002:a2e:8884:: with SMTP id k4mr1499320lji.267.1587114245392; Fri, 17 Apr 2020 02:04:05 -0700 (PDT) MIME-Version: 1.0 References: <663d3596-824c-f98e-2ddd-6d912f6a94d8@gmail.com> In-Reply-To: <663d3596-824c-f98e-2ddd-6d912f6a94d8@gmail.com> Date: Fri, 17 Apr 2020 11:03:48 +0200 Message-ID: To: Stanislav Malyshev Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000d08edf05a378d411" Subject: Re: [PHP-DEV] Resurrecting named parameters From: nikita.ppv@gmail.com (Nikita Popov) --000000000000d08edf05a378d411 Content-Type: text/plain; charset="UTF-8" On Thu, Apr 9, 2020 at 7:21 AM Stanislav Malyshev wrote: > Hi! > > > 2. Throw a notice if a parameter name is changed. While LSP violations > are > > normally fatal errors (in PHP 8), we could use a lower-severity > diagnostic > > for this case, that allows code to still run, but makes developers aware > of > > the problem. (It should be noted that automatic fixup of parameter names > > using tooling should be fairly easy to implement.) > > I think we should have a notice for now, and eventually when people are > used to it upgrade it to an error. > > > The larger problem is that internal functions don't have a well-defined > > concept of parameter default value. Parameter defaults are implicit in C > > code, and sometimes based on argument count checks. When named parameters > > are involved, one generally cannot assume that if a later (optional) > > parameter is passed, all earlier (optional) parameters are passed as > well. > > IIRC I did some work on that when making the skipped parameter RFC, but > I think we have no choice but to make all internal functions we control > have proper default implementation. Older modules may be lagging though, > so another option would be to add some kind of flag to internal > functions that would block named parameters if not set, and make > extension writers fix their functions and then set this flag explicitly. > Of course we'll set this flag for all functions in core, after fixing > those of them that need fixing. Maybe not a flag but using different > macro/API function, etc. - the idea is that some explicit change would > be needed. Yes, that means additional work... Yeah, I'm aware of the work you did in this area, and used this as part of my previous named parameters implementation. However, I'm not sure that this is the right way forward anymore, for a couple of reasons: 1. Safety: 3rd party extension functions that don't get updated may end up crashing if it has ZEND_NUM_ARGS() based assumptions. Not just stop working or misbehave, but segfault. I think we should try to avoid that. 2. Implementation: This approach still requires ZPP support, in that we need to skip over arguments that have not been passed and leave them at their default values. This is pretty easy to do for classic ZPP, but somewhat problematic for FastZPP. This will require an extra UNDEF check for all arguments, which (I think) is not much of a concern for performance, but is a concern for code size, which is a limiting factor of this API. 3. Behavior: Even if there are no safety issues because no arg num assumptions are made, we might still be left with behavior that does not make a lot of sense. For example, the array_keys() function does not do arg count checks, but writing something like array_keys($array, strict => true); would still not make any sense, because the "strict" parameter is only meaningful if the "search_value" parameter is specified. We specify this function as follows in stubs: function array_keys(array $arg, $search_value = UNKNOWN, bool $strict = false): array {} If we simply allow the call and fall back to ZPP defaults, that means the call works, and will have the same behavior as array_keys($array), with the "strict" parameter simply going ignored. On the other hand, if we handle internal functions like userland functions, and replace missing arguments with specified default values, then this case would yield an exception: array_keys(): Argument #2 ($search_value) must be passed explicitly, because the default value is not known I think that this gives us a more sensible behavior. We have (unfortunately) quite a lot of internal functions that are "magic" in some way, and where certain parameters do not have well-defined defaults and cannot reasonably be skipped when named parameters are used. I think that this approach gives us a pretty clean handling of such cases. Of course, the big disadvantage is that it does require default value information in stubs. We have this information for nearly all bundled extensions at this point, but not for 3rd party extensions. The ZPP based approach does make most code "just work", even if it will some of the code "just crash" instead... Regards, Nikita --000000000000d08edf05a378d411--