On Thu, Jul 24, 2025, at 6:52 AM, Tim Düsterhus wrote:
> Hi
>
> Am 2025-07-24 12:03, schrieb Tim Düsterhus:
>> I don't think they should. Specifically the (1) and (3) should not. My 
>> expectation is that:
>> 
>>     $f = foo(a: ?, b: 2, c: ?);
>>     $f(1, 3); // calls foo(1, 2, 3);
>> 
>> and
>> 
>>     $f = foo(c: ?, b: 2, a: ?);
>>     $f(1, 3); // calls foo(3, 2, 1);
>> 
>> The order of the question marks should match the order of the 
>> parameters in the resulting Closure, which is not necessarily the order 
>> of the order parameters of the original function.

That would be inconsistent with how named arguments work anywhere else.  With a 
regular function call, you can list named args in any order you feel like and 
the engine will reorder them for you back to the original defined order.  (My 
IDE keeps yelling at me to put them in order, but that's an IDE problem, not a 
language problem.)  Having PFA behave differently feels needlessly confusing, 
especially since positional placeholders are supported, too.

$f = foo(?, a: ?, b: ?)

It's not obvious to me what should happen there.  Does that implicitly mean $c 
is now the first argument?  That's not at all apparent from the syntax.

Similarly, in a longer example: 

foo ($a, $b, $c, $d, $e, $f);

$f = foo(?, 3, b: ?, e: ?, ...);

That already takes a moment of thought to know what's going on, despite being 
legal.  (A value is provided for $c, but nothing else.)  Having that also 
change the order to... I think it would be f($a, $b, $e, $d, $f) ?  Just raises 
the effort to grok it even further.

The only value to breaking existing convention and reordering parameters I can 
see would be:

> To add to that: By respecting the order of question marks as written, it 
> would also make PFA easier to understand and also more powerful. After 
> sending the email earlier, I came across this doctrine/collections PR, 
> while reviewing some dependency upgrades: 
> https://github.com/doctrine/collections/pull/424
>
> When migrating the `findFirst()` method from a custom foreach loop to 
> `array_find()`, they couldn't pass along the given callable directly, 
> since Doctrine opted for a different parameter order. Thus they needed 
> an intermediate Closure to swap the arguments. If the argument names for 
> the function are known (which they are not in the Doctrine example, as 
> it's an arbitrary Closure that is given), this would allow to swap 
> arguments as necessary:
>
>      function cb($key, $val) { … }
>
>      array_find($array, cb(val: ?, key: ?)); // array_find expects 
> $value, $key.


Which is valid, but on balance I think it's OK for that case to still be a 
manual short-closure in exchange for less confusing behavior of PFA.  In 
practice, I expect most PFA uses to be creating unary function anyway, followed 
by thunks, so it won't greatly matter.

Does anyone else agree/disagree?

--Larry Garfield

Reply via email to