What I don't understand is what the issue with that is?

You can already build up a named array and splat it into a function call to 
pass by name.  It's a really neat trick.  It doesn't need a dedicated function.

About a month ago, I went through all of TYPO3 and removed all remaining 
call_user_func_array() calls in favor of just $function(...$args), because it 
does the same thing and is faster, and easier to read.  Named arguments already 
work exactly that way, too.

I don't see an advantage to adding a function that does what you can already do 
with less syntax:

$args['foo'] = 5;
$args['beep'] = get_value_from_db();
$args['narf'] = 'poink';

$callable(...$args);

That works today in 8.0.  We're good.

The proposal focuses on the onus put on the author of the closure/function, not the caller.

If your $callable is only interested in $foo enforced as an int and $narf enforced as a string, what does the signature and body of the subscribing $callable look like in this case?

I am proposing that if a system is providing all of this for any registered callables:

  $args['foo'] = 5;
  $args['beep'] = get_value_from_db();
  $args['narf'] = 'poink';
  $args['boop'] = $boopObject;
  $args['isNoomable'] = false;

But are only interested in value for 'foo' and 'narf', they can still get type hinting/checking/enforcement and the benefits of named mapping.


Let's assume the following which has a little bit of context:

  // developer/consumer code
  $library = (new SomeLibrary)
  $library->registerCallback(function ($foo, $narf) {});
  $library->call();

  // some 3rd party library with a callback system in place
  class SomeLibrary {
    public function registerCallback(callable $callback) {
      $this->callback = $callback;
    }
    public function call() {
      if (!$this->callback) {
        return;
      }

      $args = [];
      $args['foo'] = 5;
      $args['beep'] = 'value from db';
      $args['narf'] = 'poink';
      $args['boop'] = new StdClass;
      $args['isNoomable'] = false;

      ($this->callback)(...$args);
    }
  }


This will fail with message:

  PHP Fatal error:  Uncaught Error: Unknown named parameter $beep in ...


Currently, the consumer/developer would have to write:

  $library->registerCallback(function (...$args) {
    $foo = $args['foo'];
    $narf = $args['narf'];
    // ...
  });

  // or
$library->registerCallback(function ($foo, $beep, $narf, $boop, $isNoomable) {
    // do something with foo or narf
  });


Additionally, the library/framework is now precluded from adding new parameters since any consuming callables would also have to introduce these new parameters as it could be considered a BC break.

The more I think about it though, the more sensible this would be as it allows the callback provider to opt into named parameter mapping destructuring:


  $library->registerCallback(function (...[string $foo, string $narf]) {
    // do something with $foo and $narf
  });


-ralph

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

Reply via email to