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

Reply via email to