Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:109866 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 10914 invoked from network); 28 Apr 2020 09:58:57 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 28 Apr 2020 09:58:57 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 7223C1804B4 for ; Tue, 28 Apr 2020 01:32:02 -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.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_NONE 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-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) (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 ; Tue, 28 Apr 2020 01:32:00 -0700 (PDT) Received: by mail-wm1-f41.google.com with SMTP id z6so1855627wml.2 for ; Tue, 28 Apr 2020 01:32:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=beberlei-de.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=3/ljGsqBQQ6QTYAgvM8NuPlW7aK1C3WiSxuRDer+w0M=; b=G6Bnvb3B8nj6wrCTdabUAStzJktxVtFCl9ej/8Xbw2pReafJo/Tspexy53B/FOLq3B P3iBQKKyh8OyXsEr9BHlsMbgKno6IO+QdjQ52sG9fxM3mLdAZlut72TBJIOe4h7DZzXu WUwTF0RaxVopC/rCyGAhaPfC4uGVYdSpqBH7dokd4c0NVgq6ZJ1sG2fhUJkd6giQFvfs BDFresO5ZwmWnYRQF5wQtLBuDhWqXSSnUV05iy8DjuzaN3x9vxDciDdlXSwhVWNh+/ek gNvtwVg1Oxlnoj6eSdFyOCHezb48eyV/tbpb1WJGd1zzHr1Hhk3ehODxMMl6dpBBfZpH n0bw== 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=3/ljGsqBQQ6QTYAgvM8NuPlW7aK1C3WiSxuRDer+w0M=; b=EDxHKpr0Vh0xx9WrkdzuGqMmvM9mppim4u9iTteo/Ff+jbP2KCOJCVusupjRkYzR5w F+R+yMz4KIt/S2UGQ4keR+KptVYdd2MhspFh2EOyCglX8LFb2zOMiFCG/JWDdNPXnusc 2TXHjcSazK2BmDmoTEOKCGsyBWBc8caaGdp2MMK5tsOdoqYgoyeRb2XEZyPwwPLFYTRv yJBu7oAgmC/jQbzEj02nVT+DsCz1TFKVfMr0vDbPgcgSyS9PaEnyn+Ska+PskoQ3+pds n6JiEOI3zBz6QSGGYqe56KYw5opC6RyqF4hpnqbA2/zFOWp/MrVXWKgTrZoepsTdSJ9n ZN7w== X-Gm-Message-State: AGi0PuYBtVq0lPNtPw+721LFd3jgOcIpCg9S3O2iGTAs1SkijJmlvT88 voBWUDX6DoTcYMf55fZYALx2BOQLXWlIgCtcg6vVwg== X-Google-Smtp-Source: APiQypIJDk68iUHnzyVEvspOrGSXr8c02QnMBQvVfTabyYg1axyE9tR8zDiwTS9/OqsDzutjnJPy6dgz6d10f4C3z7Y= X-Received: by 2002:a1c:4946:: with SMTP id w67mr3442636wma.38.1588062718603; Tue, 28 Apr 2020 01:31:58 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 28 Apr 2020 10:31:46 +0200 Message-ID: To: Nikita Popov Cc: PHP internals Content-Type: multipart/alternative; boundary="00000000000039459405a455aa89" Subject: Re: [PHP-DEV] Resurrecting named parameters From: kontakt@beberlei.de (Benjamin Eberlei) --00000000000039459405a455aa89 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Tue, Apr 7, 2020 at 2:45 PM Nikita Popov wrote: > Hi internals, > > It's been a few years since I originally brought up the named parameters > RFC: https://wiki.php.net/rfc/named_params > > This topic has recently come up as part of > https://externals.io/message/109220 again, in particular with the > observation that the combination of constructor parameter promotion and > named parameters will give us, as a side-effect, an ergonomic object > initialization syntax that is well-integrated with the remainder of the > language. > > I've reimplemented basic named param support for master in > https://github.com/php/php-src/pull/5357, but before going any further > here, I want to restart discussion on the various open issues that the > named parameter concept in PHP has. I think there's two primary issues: > > ## LSP checks for parameter names > > Parameter names currently have no particular significance in PHP, only > their position in the signature is important. If named parameters are > introduced (in a way that does not require opt-in at the declaration-site= ), > then parameter names become significant. This means that changing a > parameter name during inheritance constitutes an LSP violation (for > non-constructor methods). There are a number of ways in which this issue > may be approached: > > 1. Silently ignore the problem. No diagnostic is issued when a parameter > name is changed during inheritance. An error exception will be thrown whe= n > trying to use the (now) unknown parameter name. > > 2. Throw a notice if a parameter name is changed. While LSP violations ar= e > normally fatal errors (in PHP 8), we could use a lower-severity diagnosti= c > 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 option 2 here makes the most sense. People haven't taken parameter names into account for now, so warning them in 8.x should help avoid subtle bugs when starting to use named parameters. and we could make it an LSP failure in 9. > > 3. Allow using parameter names from the parent method, even if they have > been renamed. This makes things "just work", but seems fairly magic, and > has edge cases like a signature foo($a, $b) being changed to foo($b, $a), > where it's not possible to implicitly support both at the same time. > 4. Make named-parameter opt-in in some fashion, so that parameter names > only need to be preserved for methods that have the opt-in marker. I'm no= t > a fan of this, as it greatly diminishes the practical usefulness of named > parameters. > > ## Internal functions > > There are two problems when it comes to named parameters and internal > functions. The first is that the internal parameter names do not always > match the parameter names in the documentation. This is nothing we can't > solve (in a hopefully mostly automated way), but is work that needs to be > done. > > 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= . > I still can see us getting 95-99% of php-src migrated to use parameters form the documentation in a short amount of time before 8, as the more detailed and complex work on the stubs has shown. > While it is possible (but rather challenging) to make things work mostly > transparently with current ZPP, some functions do need to adjusted to > support named parameters, and may cause misbehavior/crashes if they are > not. As a rule of thumb, functions that make non-trivial use of > ZEND_NUM_ARGS() are affected. This is something we can address for > functions in bundled extensions, but may also affect 3rd-party extensions= . > > I think that ideally, we'd deal with internal functions the same way we d= o > for userland functions, by relying on default values that are part of the > function declaration. As part of the PHP stub work, we now have informati= on > on default values in stub files, but this information is currently not > available to the engine. > > M=C3=A1t=C3=A9 Kocsis has been working on getting this information expose= d in > Reflection, see https://github.com/php/php-src/pull/5353. In the current > form, accessing these defaults is fairly inefficient, but maybe with some > caching, we could base named parameters on this information: > > If there are no "gaps" in the passed parameters, then named parameters wi= ll > always work. If an optional parameter is not specified, but a later > parameter is, then we will fetch the default value for that parameter, an= d > pass it instead. If the parameter is optional, but has no well-defined > default (UNKNOWN in stubs), then the call is not permitted (Error: "Canno= t > skip parameter $foo with unknown default value", or similar.) > I think this is a good approach. Even when the function has more complex "default" logic than the stub can represent, the default value in the stub (and more importantly in the docs) is what counts for users, not what the function body does when the argument is not present. > > Any thoughts on these issues, or named parameters in general would be > welcome. > > Regards, > Nikita > --00000000000039459405a455aa89--