Hi

On 7/24/25 16:04, Larry Garfield wrote:
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.

The point is that PFA defines not just a function *call*, but also a function *definition* at the same time. This is what I meant by “you are dealing with two parameter lists”. What you correctly describe is the behavior of named arguments in a function *call*. What we do not have yet is the behavior for a function *definition* and I'm arguing that the proposed behavior in the RFC is wrong.

Using the existing example of:

    function foo(int $a, int $b, int $c) {}

For the first case of:

    $f = foo(a: ?, b: 2, c: ?);

My mental model desugars that to:

    $f = fn ($a, $c) => foo(a: $a, b: 2, c: $c);

And for the second case:

    $f = foo(c: ?, b: 2, a: ?);

it desugars to:

    $f = fn ($c, $a) => foo(c: $c, b: 2, a: $a);

The order of the named parameters in the inner function call to `foo()` changed, but as you said, the engine will make sure to place them into the appropriate parameters, resulting in a successful call to `foo()`.

But it does not follow that the parameters of the PFA Closure also need to be reordered, they can (and should) be completely independent, because PFA allows to “call named parameters using positional arguments”. Basically when I'm reading the signature:

    $f = foo(c: ?, b: 2, a: ?);
    $f(1, 3);

I'm reading the question-marks from “left to right” in positional order and then when I call `$f` using positional arguments, I'm expecting the question-marks to be filled in in positional order.

------

I've also asked a friend of mine, who had only skimmed the RFC a while ago, without explaining anything:

    function foo($a, $b, $c) {
      var_dump($a, $b, $c);
    }

    $f = foo(c: ?, b: 2, a: ?);
    $f(1, 3);

What would your intuitive expectation what this would output? They answered "3 2 1" and after I clarified that the RFC specifies this as "1 2 3", their first reaction was "What?", followed by "there are two placeholders, they are filled in left-to-right".


$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.

I believe this should be a compiler error, because `$a` is specified twice.

At least it would be for a normal function call: https://3v4l.org/oVMLC

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.

Likewise `b` is specified twice.

Best regards
Tim Düsterhus

Reply via email to