I have the following code (for partial application):
function partial(Closure $func, mixed ...$args): Closure
{
return static fn() => $func(...$args, ...func_get_args());
}
function add(int $a, int $b): int
{
return $a + $b;
}
$increment = partial(add(...), 1);
echo $increment(2); // Output: 3
I wanted to replace func_get_args with an explicitly built array, but I had no success in using it as an argument to a function:
function partial(Closure $func, mixed ...$args): Closure
{
return static fn() => $func(...$args, ...[ $func, ...$args ]);
}
function add(int $a, int $b): int
{
return $a + $b;
}
$increment = partial(add(...), 1);
echo $increment(2); // Fatal error: Uncaught TypeError: add(): Argument #2 ($b) must be of type int, Closure given
I added debugging lines to partial to see if the explicitly built array was equal to the array given buy func_get_args, and it is so:
function partial(Closure $func, mixed ...$args): Closure
{
echo func_get_args() === [ $func, ...$args ]; // Output: 1
// or for the whole argument list handed over to $func:
echo [ ...$args, ...func_get_args() ] === [ ...$args, ...[ $func, ...$args ] ]; // Output: 1
return static fn() => $func(...$args, ...[ $func, ...$args ]); // Crashes anyway
}
Both test lines show they are equal. Therefore I do not understand why it works with the arguments built with func_get_args and crashes when using the explicitly built array.
>Solution :
In your 1st example, you call func_get_args in the scope of the static arrow function, but in the 3rd example, it is called in the scope of the partial function. The argument 2 is passed to the static arrow function:
function partial(Closure $func, mixed ...$args): Closure
{
return static fn(...$args_i) => $func(...$args, ...$args_i);
}