(Jump to bottom for alternative suggestion that achieves same goals)



Just to make sure I got this right: call_user_func_map() is the same as call_user_func_array(), but a) only accepts named params

Yes, only accepts named parameters (associative array),

and b) silently ignores unknown named params?
I would characterize this as "explicitly doesn't pass unrequested parameters"

I'm not really convinced by your use-case here. This seems like a rather odd way to design an API, which goes against commonplace assumptions. If

I didn't invest a lot of thought in the use case to make the argument, ha.

That said, I disagree with "odd way to design an API" sentiment...

This is a common idiom in a few different places found inside frameworks. Laravel and Symfony both do named argument mapping when dispatching controller actions. Additionally, both containers do a significant amount of work with Reflection to map named arguments with potential parameters.

I am not discrediting the fact that they don't also do more complex stuff, but I think this supports the argument that this method of parameters mapping does not go against commonplace assumptions.

Eg:
https://github.com/symfony/http-kernel/blob/5.3/HttpKernel.php#L149-L157
https://github.com/symfony/dependency-injection/search?q=reflectionMethod
https://github.com/laravel/framework/blob/8.x/src/Illuminate/Container/Container.php#L649


you pass a closure somewhere, the general expectation is that the parameter names you use are irrelevant and only the order matters. This creates a very unusual API contract, and while I can't prevent you from doing that, I'm pretty sure this is not something we want to endorse with additional library support.

(The same question for named parameters in general is answered by https://wiki.php.net/rfc/named_params#what_are_the_benefits_of_named_arguments <https://wiki.php.net/rfc/named_params#what_are_the_benefits_of_named_arguments> -- notably none of the arguments made there are relevant in this context, the only benefit I see is saving a few keystrokes.)

Named mapping is arguably better than forced ordered mapping for all the reasons laid out in the above link. One of the primary benefits being you get type checking and better language supported analysis from tooling (like your IDE knowing the type of the parameter).

This is the effective way of accomplishing what you suggested today, you can skip parameters here but get no type checking:

  $f = function ($params) {
    [$foo, $baz] = null;
    extract($params, EXTR_IF_EXISTS);

    var_dump($foo, $baz); //
  };

  $f(['foo' => 'a', 'bar' => 'b', 'baz' => 'c']);
  // string(1) "a"
  // string(1) "c"



What's wrong with good old fn($params) => $params['a'] + $params['b']?


...Maybe nothing, perhaps if instead of adding parameters or new functions to call_user_func_* (language construct functions) we instead can add some type checking and destructuring to it ;)


# Alternative Suggestion

An alternative suggestion would be to follow Javascript's lead to accomplish something similar and allow parameter destructuring, but in a more PHP way:

  $f = function (...[string $foo, string $baz]) {
    var_dump($foo, $baz);
  };

  $f(['foo' => 'a', 'bar' => 'b', 'baz' => 'c']);
  // string(1) "a"
  // string(1) "c"


-ralph

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to