Re: [PHP-DEV] [RFC][Proposal] Renamed parameters

This is only part of a thread. view whole thread
  111201
July 27, 2020 18:40 rowan.collins@gmail.com (Rowan Tommins)
Hi Andreas,


On 27/07/2020 00:41, Andreas Hennings wrote:
> 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.
While this is an interesting concept in general, it introduces a much larger change to the semantics of the language than seems justified for this particular problem - it would effectively require introducing an element of "static typing" into the language. By "static typing", I mean this: > variables have an intrinsic type, and the same value can behave differently depending on the type of variable that holds it Which could be contrasted with "dynamic typing" like this: > values have an intrinsic type, and operations will be selected based on those values, regardless of which variables hold them Although we have various type annotations in the language now, they are all just restrictions on the types of value a variable can hold; they don't change the behaviour of that value. With this proposal, these two function would potentially do different things when given the exact same argument: function a(FooInterface $arg) { $arg->doSomething(namedparam: 42); } function b(BarInterface $arg) { $arg->doSomething(namedparam: 42); } Static typing of that sort is a useful feature of other languages, and there are people who'd love to see PHP go that way, but it's not something we should bolt on in a hurry just to solve an issue with named parameters. Regards, -- Rowan Tommins (né Collins) [IMSoP]
  111204
July 27, 2020 23:21 andreas@dqxtech.net (Andreas Hennings)
Good point about the static typing!

On Mon, 27 Jul 2020 at 20:40, Rowan Tommins collins@gmail.com> wrote:

> Hi Andreas, > > > On 27/07/2020 00:41, Andreas Hennings wrote: > > 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. > > > While this is an interesting concept in general, it introduces a much > larger change to the semantics of the language than seems justified for > this particular problem - it would effectively require introducing an > element of "static typing" into the language. > > By "static typing", I mean this: > > > variables have an intrinsic type, and the same value can behave > differently depending on the type of variable that holds it > > Which could be contrasted with "dynamic typing" like this: > > > values have an intrinsic type, and operations will be selected based > on those values, regardless of which variables hold them > > Although we have various type annotations in the language now, they are > all just restrictions on the types of value a variable can hold; they > don't change the behaviour of that value. With this proposal, these two > function would potentially do different things when given the exact same > argument: > > function a(FooInterface $arg) { $arg->doSomething(namedparam: 42); } > function b(BarInterface $arg) { $arg->doSomething(namedparam: 42); } >
It would be an edge case, if both of them are valid but with swapped parameter names. In the more common cases, one of them would simply be broken. But your point is still correct. I would argue that this is still better than the behavior with the current RFC: The developer who implements the function a or b only knows the parameter names as in FooInterface or BarInterface. They know nothing about the actual class of the object passed in as $arg. A name lookup based on the known interface is closer to what the developer wants, and is guaranteed to work for all implementations of the interface. The main inheritance contract for methods is still based on parameter order: E.g. interface I { function foo(A $x, B $y); } interface J extends I { function foo(A $y, B $x); } The parameter names can be swapped, but the types have to remain in order.
> > > Static typing of that sort is a useful feature of other languages, and > there are people who'd love to see PHP go that way,
Count me in :)
> but it's not > something we should bolt on in a hurry just to solve an issue with named > parameters. >
You have a point. It would not be a full-blown static typing, but at least it has the smell of it. The parameter name lookup would be based on the variable itself, instead of the value. As mentioned, there could be other ways to determine the version of the method that should be used for parameter name lookup. The options I can come up with atm would make the code more verbose, and/or look awkward, and probably already clash with existing language features. But perhaps there are better ways. Either in the call itself: $x->{FooInterface::doSomething}(namedparam: 42); FooInterface::doSomething::invoke($x, namedparam: 42); Or through a declaration in the file: use \Acme\FooInterface::*(); $x->doSomething()
> just to solve an issue with named > parameters.
I still think the current RFC is deeply flawed and should not have been accepted in its current form. It adds uncertainty and fragility to the language. The Liskov substitution principle was something we could rely on, guaranteed natively by the language. But with named parameters it is not. I saw the explanations in the RFC about inheritance, but I don't find them convincing. But I am not a voting member and also I did not pay attention when this discussion was happening. And I am just one person, I don't want to make more than one person's worth of drama. Perhaps we will see people mostly use this for constructor or static calls, and avoid it for polymorphic method calls. For these cases it seems like a useful feature.
> > > Regards, > > -- > Rowan Tommins (né Collins) > [IMSoP] > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >