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

Reply via email to