Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:111161 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 88888 invoked from network); 24 Jul 2020 12:17:58 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 24 Jul 2020 12:17:58 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 562191804E6 for ; Fri, 24 Jul 2020 04:12:53 -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=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) (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, 24 Jul 2020 04:12:49 -0700 (PDT) Received: by mail-pl1-f170.google.com with SMTP id k4so4257579pld.12 for ; Fri, 24 Jul 2020 04:12:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=3O40mFSYGMbaoUICxZSgCWjM6Vv7P2dHGarutnoDsmk=; b=VD92eqhxtjl+hKQvaQCAQKloszEnjxWiu6Azm+CyevK0U7INxmgcyUr9Oe/yfYWpIY pdSFDnoYs9O+f59MUsWw7YAutmBmQYnb71P89NdjrfwkW2ESUJ9xB6ZGMGAulgOoxB4s 32S7yOqJnS19GTGSKn9wMOhVBYJsnSwoDhaZM6Wu6pBcU4uazcNU9WmMjqedW2T1wiQt OXgSivs7f8+wozMVwIrwivrZ7hEsW4QH3rvu0eAUqKBE09PQot/S1VNRWRF1Z0MEzbe4 Vn5OhvX8ZHPLBsF05xpCezm85oYSHoE5GpQRNnxT9YVEaW4se+vNjjBWFBVPybSDh+Ae SnMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=3O40mFSYGMbaoUICxZSgCWjM6Vv7P2dHGarutnoDsmk=; b=H1jPjT3NrW+u7p6JaLzFNEXMW3nJtvLHGgIBOTEkeMwoQVbh85tYRDa9iKVA531XYX 2I5uZPR1WoFDG7Z9UgkzlZrPZSsmfmJ/kF+jEecu3DegvoiFcEok5O9VqcTe4Sny5cvq 3Jcj/OXY49EnVJvTbBlgDGDf3a3c3txCO4tyZW1Tmkc9mIaA1RbKByOJOq/TLr8HhbDS kFSoi0SUawZYPpGZcC5EkPeQS2YbB4VE85Whqnefhr3de38wQeovC2wKM1q4m713qtMq AY+4wJJ2HirVejCaRAPL1GkVxF4/oAMuXAE6NSPGfsBuvCrJ5mg4T7ySLxAapHDZ8VP0 vcbg== X-Gm-Message-State: AOAM530NZ7/8+/OW0DyF4u8GtYKVKtcvMq6uHbaLBQK5OsEco/DcGGX8 7eFGRbkj5Wi1SWdg6PqzeJH7lNLW1skr8AmmUKFiGMTU9Lk= X-Google-Smtp-Source: ABdhPJxVOLyhv6rLVq6sc1dnl3QaO29wWlKv1NmHfISFhefnZOxBXOhj0+cgGu/rUEQc7ab+gKhZE2dGKPYrTjjlRl8= X-Received: by 2002:a17:90a:a783:: with SMTP id f3mr3152703pjq.142.1595589165508; Fri, 24 Jul 2020 04:12:45 -0700 (PDT) MIME-Version: 1.0 Date: Fri, 24 Jul 2020 12:12:34 +0100 Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary="0000000000006aebcf05ab2e0d1f" Subject: [RFC][Proposal] Renamed parameters From: t.carnage@gmail.com (Chris Riley) --0000000000006aebcf05ab2e0d1f Content-Type: text/plain; charset="UTF-8" Hi all, The named parameters RFC has been accepted, despite significant objections from maintainers of larger OSS projects due to the overhead it adds to maintaining backwards compatibility as it has now made method/function parameter names part of the API; a change to them would cause a BC break for any library users who decide to use the new feature. It is likely that the way this will shake out is that some maintainers will accept the additional overhead of including parameter names in their BC guidelines and others will not, this leaves users unsure if they can use the new feature without storing up issues in potentially minor/security releases of the libraries they use. This is not really an ideal situation. More pressing a point is that the current implementation breaks object polymorphism. Consider this example (simplified from one of my codebases) interface Handler { public function handle($message); } class RegistrationHandler implements Handler { public function handle($registraionCommand); } class ForgottenPasswordHandler implements Handler { public function handle($forgottenPasswordCommand); } class MessageBus { //... public function addHandler(string $message, Handler $handler) { //... } public function getHandler(string $messageType): Handler { //... } public function dispatch($message) { $this->getHandler(get_class($message))->handle(message: $message); } } This code breaks at run time. Proposals were made for resolutions to this issue however all of them require trade offs and could potentially break existing code. My proposal to resolve these two issues is to add the ability to rename parameters with a new syntax as follows. function callBar(Foo $internalName:externalName) { $internalName->bar(); } $x = new Foo(); callBar(externalName: $x); This allows both the above problems to be resolved, by renaming the internal parameter and keeping the external signature the same. I propose that the RFC would have two voting options. The first would be to implement it as proposed above, this would allow any parameter to be called by name regardless of the intentions of the author of the method/function and is closest to the current behaviour. The second option would be to use this syntax to make named parameters in userland code explicitly opt in. As such an additional shortcut syntax would be implemented: $: to designate a named parameter. eg function callBar($:externalName) { $externalName->bar(); } $x = new Foo(); callBar(externalName: $x); If a parameter is not opted in, a compile time error is raised: function callBar($externalName) { $externalName->bar(); } $x = new Foo(); callBar(externalName: $x); // Error: cannot call parameter $externalName by name. There are pros and cons to this second approach, on the one hand it reduces the usefulness of the named parameter syntax by requiring changes to old code to enable it (although this could probably be automated fairly easily) however it does provide a neater solution to the second problem in that, to prevent the runtime errors in the second issue example, every child class would need to use the rename syntax on it's parameter to prevent errors, whereas if we went down this route, the parent class could just not opt into the named parameter syntax and the code would function as expected. Another advantage is that with the ability to rename parameters using the opt in, we gain some flexibility to tighten up the LSP rules relating to named parameter inheritance. class Foo { public function bar($:param) { //... } public function baz($internal:external) { //... } } // OK class Bar { public function bar($renamed:param) { //... } public function baz($renamed:external) { //... } } // Compile time error cannot rename named parameter $:param (renamed to $:renamedParam) class Baz { public function bar($:renamedParam) { //... } } // Compile time error cannot rename named parameter $:external (renamed to $:renamed) class Baz { public function baz($internal:renamed) { //... } } While this would be technically possible with the first option (no opt in) it would break any existing code which renames a parameter as every parameter would be subject to these rules. I don't have Wiki karma so can't post this yet; but I want to get the ball rolling on discussion as feature freeze is coming up fast and if we want to go for the second option, that must hit before the named parameter syntax is in a tagged version of PHP. Regards, Chris --0000000000006aebcf05ab2e0d1f--