On Wed, Jul 23, 2025, at 3:56 AM, Tim Düsterhus wrote:
> Hi
>
> Am 2025-06-28 07:06, schrieb Larry Garfield:
>> https://wiki.php.net/rfc/partial_function_application_v2
>
> I've now given the RFC an in-depth read. I have the following remarks:
>
> 1.
>
>> If the function is variadic, there are two additional rules:
>>
>> - Any positional placeholders that run into the variadic portion become
>> required.
>> - If any positional placeholders run into the variadic portion, all
>> prior remaining placeholders become required. However, those parameters
>> may not be called with named arguments, as there is no name to use.
>
> I do not understand what “running into the variadic portion” means. An
> example would probably be helpful. The first bullet point is probably
> intended to mean the following:
>
> function foo($a, ...$b) { }
> $pfa = foo(?, ?, ?, ?);
>
> Now `$pfa` has 4 required parameters, despite `foo()` only having 1?
>
> But I don't understand what the second bullet point is intended to say.
I have added the following example:
function foo(int $a = 5, int $b = 1, string ...$c) { }
$pfa = foo(?, ?, ?, ?);
// Equivalent to this:
// Note that $a and $b become required, because there must be at least 4
arguments.
$pfa = fn(int $a, int $b, string $c1, string $c2) => foo($a, $b, $c1, $c2);
> 2.
>
> In the placeholder semantics section:
>
>> While in theory that means a call like this would be legal:
>
> From what I see this specific case is not part of the examples section
> either. Including the desugaring of this extreme case would certainly
> help understanding.
I have added the following equivalent:
$c = fn(string $s, Point $p, int $m = 0) => stuff(1, $s, 3.14, $m);
> 3.
>
> In the “Examples” section:
>
> The choice of parameters names makes it hard to understand the examples,
> particularly when named parameters are used to provide arguments out of
> order. Including the “position” in the name of the parameter would make
> it easier to follow the example, since it is not necessary to look up
> the signature of `stuff()` all the time. (it becomes manageable if you
> read it as a sentence "is FPM")
LOL. That was completely unintentional. :-)
However, I have gone through and added numbers to the variable names to clarify
their original ordering.
> 4.
>
> In the “Examples” section:
>
> Is the “thunk” example accurate? It's the only example where the
> resulting “PFA” includes a variadic picking up the remaining arguments.
Hm. I think you're right, with the Extraneous Args section's clarification,
the others should likely have a trailing ...$args as well. I will clarify with
Arnaud when he returns and update accordingly.
> 5.
>
> In the “Examples” section:
>
>> $c = stuff(?, p: $point, f: ?, s: ?, m: 4);
>
> It is unexpected to me that this definition will take `$s` before `$f`
> in the resulting Closure. The explanation says that the “order does not
> matter”, but it is certainly unexpected that the order *changes* during
> desugaring.
>
> In fact, the "(four(c: ?, d: 4, b: ?, a: 1))(2, 3);" example further
> down below seems to contradict this.
The order is determined by the original function. The same is true for a
normal function call.
function foo(int $a, int $b, int $c) {}
// All of these are equivalent.
foo(a: 1, b: 2, c: 3);
foo(b: 2, a: 1, c: 3);
foo(c: 3, b: 2, a: 1);
foo(1, 2, 3);
So the same is true of a PFA:
foo(a: ?, b: 2, c: ?);
foo(b: 2, a: ?, c: ?);
foo(c: ?, b: 2, a: ?);
foo(?, 2, ?);
All of those produce the same result.
> 6.
>
> In the “Extraneous arguments” section:
>
> I disagree with silently ignoring trailing arguments, because it *adds*
> to the existing inconsistency between userland and internal functions.
> In fact there was a recent-ish discussion (I would provide a link, but
> can't find it right now) about allowing userland functions to define
> that they want to be called with a strict arity.
>
> While it would add to the symbol soup, having an explicit “ignore the
> argument at this position” indicator would be useful. For example:
> `$firstNonZero = array_find($arr, intval(?, _));` (I understand this
> specific one doesn't work, because `_` is a valid constant).
>
> 7.
>
> It is not clear to me from the RFC, why the `...` placeholder to
> indicate “all remaining arguments” must come between positional and
> named parameters. It would make more sense to me for it to become last,
> because it would also make it clearer that named parameters take
> priority over `...`. Is there some technical limitation that caused this
> choice to be made?
I can't find an answer to that in my notes, so I'll have to defer to Arnuad
when he returns. (Ilija tells me he's back Monday.) I think so, but I'm not
certain.
--Larry Garfield