As a general point, Python went through this almost 2 years ago. Their PEP
is worth reading (I didn't see it mentioned before):
https://www.python.org/dev/peps/pep-0570/

Peter

On Fri, 24 Jul 2020 at 12:13, 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