On Fri, Jul 24, 2020 at 4:00 PM Chris Riley <t.carn...@gmail.com> wrote:

> Hi all,
>
> Following up from this I've created a draft RFC:
> https://wiki.php.net/rfc/renamed_parameters will move to in discussion
> once
> I've ensured everything important has been captured.
>
> Regards,
> Chris
>

You added PHP 8.0 as a propsoed 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.

>
> On Fri, 24 Jul 2020 at 12:12, Chris Riley <t.carn...@gmail.com> wrote:
>
> > 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
> >
>

Reply via email to