Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:111196 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 66044 invoked from network); 27 Jul 2020 00:46:30 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 27 Jul 2020 00:46:30 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 9B4761804DA for ; Sun, 26 Jul 2020 16:42:01 -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-Virus: No X-Envelope-From: Received: from mail-oi1-f176.google.com (mail-oi1-f176.google.com [209.85.167.176]) (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 ; Sun, 26 Jul 2020 16:42:00 -0700 (PDT) Received: by mail-oi1-f176.google.com with SMTP id u24so3011605oiv.7 for ; Sun, 26 Jul 2020 16:42:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dqxtech-net.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=SOZSU//4cbWc4im4BtfE7Z+szKH1Bwa4q1SUSn+56R4=; b=OKGyp4jVnkiz+mdhReeF+sb2G8yllKiX7c1OxO5TDbdshTHwi1rtT2ee3YOzb5gmyQ qiGSxdEapvkqWutB7E0Mq6MXCcf3/JG0xD/qjCPZ5dopleNJnDi4itMJmhvsJUiZ/6h+ ZIVVjcL3w6NA2AuN06pT4mgjrlva6P1kXJFDiCRffLQxsRiHqlPW2NuetkmSf5aadNRh ULSU4bep3NPkuvcNJvb8Rkx3sxm15ftoOh9CUY9sJ7Q4FOqfahuegar983VxJ1m5KwGI 4VHIxHYikfmJAQ5nGzuadYRNTFCOoasjL0yOhY/hyci4u3iRMqbAB5MlDIVifEXWJ1aL O7ZQ== 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=SOZSU//4cbWc4im4BtfE7Z+szKH1Bwa4q1SUSn+56R4=; b=GZBibynFWzMvRKB4WM674YB3MYNMeXdhDBQrXM54JUvRZ1VdVBa9JX3TtuEiC+4xsT siOEYp+OSjU4nsgvLRrGlwTAIyOpGjdPbo9N+K664ounjONYal4la7vvPgceFmUuB3Eb dJ+XfAQh9Kxpff0B3K4t76z2ybMSwlxZ8lcYRfsstB++f1cp072lLsGx/u1S4IkQ8yPn gU2P846IoAlDV/b0dadHzwK87GpQ+SH9QpoGP/NO7ET6IFd4BhgqtXs15VFUfkoBab+u 6nNKjlaY0b7JReltld0Ytwgez4ySRFcFfK4UkP2lXhR6b9GGIsr9s6k0a8cOxbpc0ktI 7c+w== X-Gm-Message-State: AOAM531oc+jvw4/T4vFrWd7h+sFfpNpbwN0QjdhBxmfXxbAAV1cRsE5K G2ZYjYztVYcFiIBJ3gFxtb8CsfiuR4Dn0IS7Kwlhxg== X-Google-Smtp-Source: ABdhPJy7iML1K+LivnCdyidq+MTzOHX6xIzL8WLpQLmTZbtX+2VrV8NPHWj+kBWdxTSyqQai0AoblUXFwncXu3AVF+s= X-Received: by 2002:aca:e0d6:: with SMTP id x205mr16508171oig.176.1595806920054; Sun, 26 Jul 2020 16:42:00 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Mon, 27 Jul 2020 01:41:49 +0200 Message-ID: To: Sara Golemon Cc: Nikita Popov , Bob Weinand , Benjamin Eberlei , Chris Riley , PHP internals Content-Type: multipart/alternative; boundary="00000000000099ab1b05ab60c0f4" Subject: Re: [PHP-DEV] [RFC][Proposal] Renamed parameters From: andreas@dqxtech.net (Andreas Hennings) --00000000000099ab1b05ab60c0f4 Content-Type: text/plain; charset="UTF-8" Hello all, I would like to make my own alternative proposal from my previous message more concrete. I am going to describe a version that is not compatible with the existing RFC at https://wiki.php.net/rfc/named_params. It _could_ be modified to be an extension to the existing, accepted RFC for named parameters. But I think it is useful to discuss this version first. 1. Calls with named arguments can only happen on: - explicitly named functions (e.g. no call_user_func()). - constructor calls with an explicitly named class. - object methods, if the object variable is type-hinted or a type is known at compile time. 2. Named arguments in calls are converted to number-indexed arguments at compile time. 3. Parameter name lookup is done based on the type-hinted class or interface. Parameter names on the actual object are ignored. Example: interface I { function setBackgroundColor($bgcolor); } interface J { function setBackgroundColor($background_color); } class C implements I, J { function setBackgroundColor($color) {} } class X { private J $colorable; function foo(I $colorable) { // Good: Parameter names from "I::setBackgroundColor()" are used. $colorable->setBackgroundColor(bgcolor: 'green'); // Error: Unknown parameter name for I::setBackgroundColor(). $colorable->setBackgroundColor(color: 'green'); // Error: Unknown parameter name for I::setBackgroundColor(). $colorable->setBackgroundColor(background_color: 'green'); // Good: Parameter names from "J::setBackgroundColor()" are used. $this->colorable->setBackgroundColor(background_color: 'green'); } } // Parameter names from C::setBackgroundColor() will be ignored within ->foo(). (new X())->foo(new C()); ---------- Future extensions: Allow to define "descriptive pseudo-interfaces" to provide reliable parameter names, if the original package cannot be trusted to keep parameter names stable. interface K describes I { function setBackgroundColor($color); } function foo(K $colorable) { // Parameter names from K::setBackgroundColor() are used. $colorable->setBackgroundColor(color: 'green'); } // Parameter names from C::setBackgroundColor() will be ignored within foo(). foo(new C()); ----------- Why? This version of named parameters can be used with any existing old interface. It is compatible with any 3rd party library that may implement an interface with renamed parameters. It also allows inheritance from multiple "equivalent" interfaces which use different parameter names. Only the package that defines the interface needs to keep the parameter names stable between versions. ----------- How to make this compatible with the existing RFC? We could introduce an alternative method call syntax for calls that should take parameter names from a specific interface, instead of the actual class instance. Eg. $obj->{J::setBackgroundColor}(background_color: 'green'); This would be undesirably verbose for long interface names.. ----- Best Andreas On Fri, 24 Jul 2020 at 18:14, Andreas Hennings wrote: > TLDR > Only consider parameter names from a type-hinted interface, ignore > parameter names from the actual class. > > ----- > > I had a look at > https://wiki.php.net/rfc/named_params#to_parameter_name_changes_during_inheritance > Indeed I have concerns about this, because a call with named arguments > would make your code incompatible with 3rd party implementations of the > interface that do not keep the parameter names. > I would see this as a flaw in a newly added feature, which should be fixed > during the feature freeze. > I might even say the current version as described in the RFC is broken. > > I have no objection to the OP's proposal, but would like to add some > alternative ideas to the discussion. > > My first idea would be to only consider the parameter names in the > original interface, and ignore all renamed parameters in sub-classes. > This would cause problems if a class implements multiple interfaces that > declare the same method, but with different parameter names. > > So, a better idea would be like this: > - The variable must be type-hinted with an interface. E.g. as a parameter > or as object properties. > - named arguments always use the parameter names from the type-hinted > interface. > > This would need some static analysis at compile time, and we need to be > able to type-hint regular local variables. > > An alternative would be to somehow "import" the parameter names at the top > of the file, somehow like so: > > use Acme\Animal::bar; // Parameter names from this method will be used. > > (this syntax probably needs more thought). > > Yet another option would be to somehow specify the interface in the method > call.. > > ((\Acme\Animal) $instance)->foo(a: 'A', b: 'B'); > > Regards > Andreas > > > > On Fri, 24 Jul 2020 at 17:41, Sara Golemon wrote: > >> On Fri, Jul 24, 2020 at 10:10 AM Nikita Popov >> wrote: >> > > > You added PHP 8.0 as a proposed version, but that will not be >> possible >> > > > anymore 2 weeks of discussion + 2 weeks of voting are not possible >> to >> fit >> > > > in before the feature freeze, which is in 11 days. >> > > >> > > While you are technically correct, the primary point of a feature >> freeze >> > > is not allowing in completely new features. >> > > It will always happen that there are changes and extensions to RFCs >> > > introduced for the next version which may need to be addressed first, >> > > because there is massive benefit to the new feature in that case. >> (from >> a >> > > backwards/forwards compatibility standpoint for example) >> > > >> > We should of course be open to making minor adjustments due to >> > unanticipated issues after feature freeze -- after all, that's where we >> > gain experience with new features. The emphasis here is very much on >> > *minor* and *unanticipated* though. >> > >> >> Endorsing this. Anything post FF needs to be held to a high standard. >> Minor and Unanticipated changes. >> * The option to set alt-names on parameters is substantial. >> * Making named params explicitly opt-in is less substantial (though >> certainly not trivial), especially if it were hung off an attribute which >> would mean no actual new syntax, but Niki's point that it wasn't an >> unknown >> or unanticipated issue stands. >> >> I share OP's worry that this pushes workload onto library and framework >> maintainers, and I wouldn't look forward to the review of all APIs to make >> sure their names are correct, but the vote has spoken. We should >> absolutely continue pursuing this topic with an eye to 8.1 so that library >> updates are less painful moving forward. >> >> -Sara >> > --00000000000099ab1b05ab60c0f4--