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 <andr...@dqxtech.net> 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 <poll...@php.net> wrote: > >> On Fri, Jul 24, 2020 at 10:10 AM Nikita Popov <nikita....@gmail.com> >> 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 >> >