On Fri, Sep 6, 2013 at 6:39 PM, Nikita Popov <nikita....@gmail.com> wrote:
> Hi internals! > > I created an RFC and preliminary implementation for named parameters: > > https://wiki.php.net/rfc/named_params > Thanks for the feedback everyone! I will not answer every mail individually (as many share a common topic) and will try to group things reasonably. Dynamic named parameters syntax ----- I'm strongly against making the parameter names in named-args calls dynamic. If you need dynamic parameter names you can always use unpacking notation: foo(...[$paramName => $paramValue]); If we allow dynamic named params virtually any syntax we choose will seem somewhat ambiguous, e.g.: foo(paramName => $paramValue); // is paramName a parameter name or a constant with the parameter name? foo($paramName => $paramValue); // is $paramName a parameter name or a variable with the parameter name? By clearly saying that the parameter names in the named-args syntax (whichever we choose) are static much confusion can be avoided. Furthermore allow non-constant parameter names will complicate the implementation for very little practical gain. Let only special functions accept named params ----- There has been the suggestion that only functions that are specifically marked (a "named" keyword) can accept named parameters and another suggestion that only parameters that have been specifically marked can be passed as named parameters. In such a setting named parameters would loose all value for me. Implementing the good old $options array isn't *that* hard after all. The value named parameters offer to me is being able to use them everywhere I consider them beneficial without requiring special support from the API. In particular I think it's critical that they also work with existing internal functions (we have quite a lot of internal functions with many independent optional parameters) and also in cases where $options are not worth it (just a single optional parameter). Concerns about readability and APIs ----- There have been some concerns regarding readability and API design relating to named args: By Matthew: > I feel like this will just encourage more core PHP functions with an > unmanageable number of parameters. Will there be any proposed > guidelines to how future functions will make use of named parameters? > e.g., Will we see native functions with 20 arguments You need to shift your viewpoint. Named parameters change what "an unmanageable number of parameters" is. Right now I would consider a function with just two independent(!) optional parameters to already have "an unmanageable number of parameters". Right now I would not willingly include such a function in an API design. Named args change this. With them there is nothing bad to a function with multiple independent optional parameters. So: Will there be more functions that have more parameters? Maybe. Is that a problem? No. By Matthew: > The OCD in me shudders to think about now having to parse through > people's code like: > > substr('length' => 1, 'string' => 'Hello World'); > > Now I see the function, and I have to see how they ordered their > parameters. Why was 'start' omitted... is this a warning due to using > NULL as an int.. did the person mean 'start', etc? It's just one > example, but I know that this sort of code will start cropping up > everywhere. You will not have to parse through that code, because it's not valid. If you fail to pass a required argument, you'll get a warning just like you already do now. Your example is no different from the nonsensicality of doing a substr("Foo") call. Furthermore I think your concerns of overuse of named parameters in contexts where they make no sense (like a substr call) are unfounded. Looking at other languages that already support named parameters (like Python or C#) I never noticed such patterns. Of course, every feature has a potential for misuse, but I tend to think that most programmers *do* have enough common sense to use features where reasonable and not at every possible occurrence just because they can. Renaming of parameters in signatures ----- Until now three options were discussed: 1. Throw an E_STRICT (or similar) error during signature validation if a parameter is renamed 2. Don't validate parameter renames in signature and just let people hit the runtime error when they do the call. 3. Create an ini-setting chooses either behavior 1 or 2. Both options 1 and 2 are not ideal, the former because it "breaks" old code, the latter because we allow LSP violations that lead to runtime errors. Option 3 is not really an option, we already decided a while ago not to introduce ini-settings controlling runtime behavior. I have another suggestion at how this could be approached: When the used named parameter is not found we go through the inheritance hierarchy and try to find the parameter name there. So if we have class A { public function foo($oldBar) { ... } } and class B extends A { public function foo($newBar) { ... } } and write a call $b->foo(oldBar => $xyz); then we'd first try the $oldBar parameter of B::foo (doesn't exist) and then the $oldBar parameter of A::foo (exists). This could be combined with throwing an warning/notice/whatever saying that a parameter was renamed (or not). So the call would still work, but you'd get a notification that your names are off (but only if you actually use named args). Of course this does not save us in some pathological cases: class A: public function fn($foo, $bar) class B: public function fn($bar, $foo) In cases where the parameter order was swapped the above approach wouldn't work correctly. That's it for now :) Nikita