[PHP-DEV] [RFC] Partial Function Application v2

On 9. Oct 2025, at 20:54, Larry Garfield <larry@garfieldtech.com> wrote:

One outstanding question is whether to allow reordering of parameters in the PFA closure by using named arguments. With this implementation, Arnaud says it's possible to do if we decide to. I am still concerned that it would create too much complexity and confusion in practice. But we're willing to go with a broad consensus if it emerges.

Hi

I also find it confusing if I define a different parameter order in the partial function and then this order is automatically overridden to the original order rather than being used. When I consciously change the parameter order, I expect this order to be preserved in the resulting function. That's the behavior I would expect as a developer.

Cheers

Joshua Rüsweg

On Thu, Oct 9, 2025, at 1:54 PM, Larry Garfield wrote:

Hi folks. PFA is back. :slight_smile:

Since our last episode, Arnaud has greatly revised the implementation.
Rather than emulating a closure and all the associated behavior, the
new approach compiles PFAs into normal closures at runtime, leveraging
opcache. The resulting closure is then "just a closure," and will
behave like any other. That means, for instance, its behavior in
debugging, reflection, etc. is all self-evident.

There were a few small behavior changes as a result, but not
dramatically. Mainly it impacted variadic cases, where parameter names
are now auto-generated when appropriate rather than simply being
unnamed.

We have also changed the order of placeholders from "positional,
variadic, named" to "positional, named, variadic." Meaning the `...`
"and the rest" placeholder is always at the end of the call.

One outstanding question is whether to allow reordering of parameters
in the PFA closure by using named arguments. With this implementation,
Arnaud says it's possible to do if we decide to. I am still concerned
that it would create too much complexity and confusion in practice.
But we're willing to go with a broad consensus if it emerges.

PHP: rfc:partial_function_application_v2

--Larry Garfield

Another set of updates.

* Some improvements to the error handling and error messages.
* Clarified that PFA is compatible with constant expressions.
* Clarified when the resulting closure is static or not.

The main change is we revisited how extra arguments are handled. Long story short, they now forward only if the PFA has a ..., and how they forward depends on if the underlying function is variadic or not.

The RFC now includes more precise examples of how the desugaring works, including the variadic/func_get_args cases, which should make it all a lot clearer.

The one outstanding question is whether we allow reordering using named arguments or preserve the underlying order. Arnaud says either one is doable. So far, only 2 people have commented on it (favoring reordering). We still want feedback from more people to see if there really is a consensus one way or another. (2 people is too small a sample size to draw any conclusions.)

Also, if anyone not named Tim would like to weigh in, now is the time. :slight_smile:

--Larry Garfield

On 30/10/2025 19:44, Larry Garfield wrote:

The one outstanding question is whether we allow reordering using named arguments or preserve the underlying order. Arnaud says either one is doable. So far, only 2 people have commented on it (favoring reordering). We still want feedback from more people to see if there really is a consensus one way or another. (2 people is too small a sample size to draw any conclusions.)

Also, if anyone not named Tim would like to weigh in, now is the time. :slight_smile:

Hi

I'm not named Tim.

Reordering makes the most sense and is what I intuitively expect to happen.

Kind regards

On Thu, Oct 30, 2025 at 7:46 PM Larry Garfield <larry@garfieldtech.com> wrote:

On Thu, Oct 9, 2025, at 1:54 PM, Larry Garfield wrote:
The one outstanding question is whether we allow reordering using named arguments or preserve the underlying order. Arnaud says either one is doable. So far, only 2 people have commented on it (favoring reordering). We still want feedback from more people to see if there really is a consensus one way or another. (2 people is too small a sample size to draw any conclusions.)

Also, if anyone not named Tim would like to weigh in, now is the time. :slight_smile:

For what it's worth:

function f($a, $b, $c) { echo "$a-$b-$c"; }

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

I expect this to print 3-2-1, intuitively. "c" is the new first
parameter in the "function definition" for me.

So count me as "reordering".

Kind Regards,
Volker

On 30.10.25 19:44, Larry Garfield wrote:

The one outstanding question is whether we allow reordering using named arguments or preserve the underlying order. Arnaud says either one is doable. So far, only 2 people have commented on it (favoring reordering). We still want feedback from more people to see if there really is a consensus one way or another. (2 people is too small a sample size to draw any conclusions.)

To me reordering according to the named arguments seems more intuitive, because that is what you see when the PFA is created. The original order would seem surprising to me.

Hi

Am 2025-10-30 19:44, schrieb Larry Garfield:

The one outstanding question is whether we allow reordering using named arguments or preserve the underlying order. Arnaud says either one is doable. So far, only 2 people have commented on it (favoring reordering). We still want feedback from more people to see if there really is a consensus one way or another. (2 people is too small a sample size to draw any conclusions.)

It appears there is a larger (and unanimous) agreement. This should be adjusted in the RFC then. Other than that, I've read through the RFC once more and have the following comments:

1. In the //// Regular functions //// examples:

I believe the `static` is missing from every example. Given that the examples in the Overview at the start already have it, this might be a mistake?

2. // Placeholders may be named, too. Their order doesn't matter.

This example will likely change given the reordering decision, but I'd like to note a typo: The 's' and 'i' parameters in the PFAs are missing their number.

3. (four(c: ?, d: 4, b: ?, a: 1))(2, 3);

This is also a reordering example. Just listing it to make it easier for you to find.

4. Constant expressions

I assume that “nested” PFA will just work? A little more complex example would be good, just to showcase what's possible. How about:

     public const BASE = 10;

     private \Closure $arrayToInt = \array_map(\intval(?, self::BASE), ?),

My understanding is that this should be valid.

5. Implementation notes and optimizations

// Transpiles into:

The `static` should definitely be added here, since you are specifically talking about internal details.

6. Scoping

Seeing the scoping section: Is it possible to partial a `parent::` call? I never tried with FCC.

--------------------

All minor clarification bits. I'm super happy with the proposed semantics once the “reordering” question is resolved.

Best regards
Tim Düsterhus

Hi

Am 30.10.25 um 8:53 PM schrieb Volker Dusch:

function f($a, $b, $c) { echo "$a-$b-$c"; }

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

I expect this to print 3-2-1, intuitively.

That is what I would expect, too.

Kind regards
Dennis

On Fri, Oct 31, 2025, at 4:22 AM, Tim Düsterhus wrote:

Hi

Am 2025-10-30 19:44, schrieb Larry Garfield:

The one outstanding question is whether we allow reordering using named
arguments or preserve the underlying order. Arnaud says either one is
doable. So far, only 2 people have commented on it (favoring
reordering). We still want feedback from more people to see if there
really is a consensus one way or another. (2 people is too small a
sample size to draw any conclusions.)

It appears there is a larger (and unanimous) agreement. This should be
adjusted in the RFC then. Other than that, I've read through the RFC
once more and have the following comments:

Mm, yeah, it would appear I have been outvoted. :slight_smile: So be it. The RFC has been updated to include reordering, and Arnaud will update the implementation shortly.

I expect this to be the last major change, so we'll likely call the vote in a little over 2 weeks, baring any additional feedback.

1. In the //// Regular functions //// examples:

I believe the `static` is missing from every example. Given that the
examples in the Overview at the start already have it, this might be a
mistake?

Artifact of how many times this RFC has been edited. :slight_smile: I think I got them all now.

2. // Placeholders may be named, too. Their order doesn't matter.

This example will likely change given the reordering decision, but I'd
like to note a typo: The 's' and 'i' parameters in the PFAs are missing
their number.

I ended up removing this example and replacing it with another anyway.

3. (four(c: ?, d: 4, b: ?, a: 1))(2, 3);

This is also a reordering example. Just listing it to make it easier for
you to find.

thumbs-up.gif

4. Constant expressions

I assume that “nested” PFA will just work? A little more complex example
would be good, just to showcase what's possible. How about:

     public const BASE = 10;

     private \Closure $arrayToInt = \array_map(\intval(?, self::BASE),
?),

My understanding is that this should be valid.

Mine as well. I'll add that example, and if Arnaud corrects me we can deal with it then. :slight_smile:

5. Implementation notes and optimizations

// Transpiles into:

The `static` should definitely be added here, since you are specifically
talking about internal details.

6. Scoping

Seeing the scoping section: Is it possible to partial a `parent::` call?
I never tried with FCC.

I... have no idea. Presumably? I'll add it and wait for Arnuad to yell at me if not. :slight_smile:

All minor clarification bits. I'm super happy with the proposed
semantics once the “reordering” question is resolved.

Huzzah!

--Larry Garfield

Hi

I have just went through the RFC again (the 2025/11/01 17:54 version).

On 11/1/25 18:54, Larry Garfield wrote:

4. Constant expressions

I assume that “nested” PFA will just work? A little more complex example
would be good, just to showcase what's possible. How about:

      public const BASE = 10;

      private \Closure $arrayToInt = \array_map(\intval(?, self::BASE),
?),

My understanding is that this should be valid.

Mine as well. I'll add that example, and if Arnaud corrects me we can deal with it then. :slight_smile:

Small note: The example is missing the closing brace for the class.

Other than that, I have no further notes, am happy with the RFC and plan to vote in favor.

Best regards
Tim Düsterhus

On Nov 1, 2025, at 12:56, Larry Garfield <larry@garfieldtech.com> wrote:

On Fri, Oct 31, 2025, at 4:22 AM, Tim Düsterhus wrote:

Hi

Am 2025-10-30 19:44, schrieb Larry Garfield:

The one outstanding question is whether we allow reordering using named
arguments or preserve the underlying order. Arnaud says either one is
doable. So far, only 2 people have commented on it (favoring
reordering). We still want feedback from more people to see if there
really is a consensus one way or another. (2 people is too small a
sample size to draw any conclusions.)

It appears there is a larger (and unanimous) agreement. This should be
adjusted in the RFC then. Other than that, I've read through the RFC
once more and have the following comments:

Mm, yeah, it would appear I have been outvoted. :slight_smile: So be it. The RFC has been updated to include reordering, and Arnaud will update the implementation shortly.

Just another data point—I prefer reordering, too. It seems like the more intuitive experience.

Cheers,
Ben

On Sat, Jun 28, 2025, at 12:06 AM, Larry Garfield wrote:

Hi folks. Arnaud and I would like to present take-2 at Partial
Function Application.

PHP: rfc:partial_function_application_v2

It is largely similar to the previous PFA proposal from 2021, though
there are a number of changes. Most notably:

* The implementation is simpler, because FCC already did part of the
work. This RFC can build on it.
* Constructors are not supported.
* But optional arguments and named placeholders are supported.
* It includes pipe-based optimizations.

Note: We realize that this is a non-trivial RFC coming late in the
cycle. We are proposing it now because, well, it's ready now. If the
discussion goes smoothly, we're OK calling a vote on it for 8.5,
especially as it would complement pipes so well. If the discussion
runs longer, we're also OK with targeting 8.6 instead. We'll see how
that goes.

<floor opens for discussion, Larry falls through the trap door>

It's been just over 2 weeks since the last comment in the thread, and the last change was made (allowing for parameter reordering). Please consider this the Intent to Vote post; I'll be calling the vote sometime probably late Tuesday or on Wednesday, baring any new issues before then.

--Larry Garfield

Hey Larry,

On 16.11.2025 21:51:59, Larry Garfield wrote:

On Sat, Jun 28, 2025, at 12:06 AM, Larry Garfield wrote:

Hi folks. Arnaud and I would like to present take-2 at Partial
Function Application.

PHP: rfc:partial_function_application_v2

It is largely similar to the previous PFA proposal from 2021, though
there are a number of changes. Most notably:

* The implementation is simpler, because FCC already did part of the
work. This RFC can build on it.
* Constructors are not supported.
* But optional arguments and named placeholders are supported.
* It includes pipe-based optimizations.

Note: We realize that this is a non-trivial RFC coming late in the
cycle. We are proposing it now because, well, it's ready now. If the
discussion goes smoothly, we're OK calling a vote on it for 8.5,
especially as it would complement pipes so well. If the discussion
runs longer, we're also OK with targeting 8.6 instead. We'll see how
that goes.

<floor opens for discussion, Larry falls through the trap door>

It's been just over 2 weeks since the last comment in the thread, and the last change was made (allowing for parameter reordering). Please consider this the Intent to Vote post; I'll be calling the vote sometime probably late Tuesday or on Wednesday, baring any new issues before then.

--Larry Garfield

I've just gave the RFC another deep read, and found only mentions of pass-by-ref. But not return-by-ref, and neither does the implementation handle this case:

# ./sapi/cli/php -r 'function &r(&$a) { return $a; } $a = 1; $b = &r($a); ++$b; var_dump($a);'
int(2)
# ./sapi/cli/php -r 'function &r(&$a) { return $a; } $a = 1; $b = &r(?)($a); ++$b; var_dump($a);'

Notice: Only variables should be assigned by reference in Command line code on line 1
int(1)

Was this an oversight or intentionally omitted in the RFC? If it was, I'd like to hear the reasoning on this.

Thank you,

Bob

On Mon, Nov 17, 2025, at 10:26 AM, Bob Weinand wrote:

Hey Larry,

On 16.11.2025 21:51:59, Larry Garfield wrote:

On Sat, Jun 28, 2025, at 12:06 AM, Larry Garfield wrote:

Hi folks. Arnaud and I would like to present take-2 at Partial
Function Application.

PHP: rfc:partial_function_application_v2

It is largely similar to the previous PFA proposal from 2021, though
there are a number of changes. Most notably:

* The implementation is simpler, because FCC already did part of the
work. This RFC can build on it.
* Constructors are not supported.
* But optional arguments and named placeholders are supported.
* It includes pipe-based optimizations.

Note: We realize that this is a non-trivial RFC coming late in the
cycle. We are proposing it now because, well, it's ready now. If the
discussion goes smoothly, we're OK calling a vote on it for 8.5,
especially as it would complement pipes so well. If the discussion
runs longer, we're also OK with targeting 8.6 instead. We'll see how
that goes.

<floor opens for discussion, Larry falls through the trap door>

It's been just over 2 weeks since the last comment in the thread, and the last change was made (allowing for parameter reordering). Please consider this the Intent to Vote post; I'll be calling the vote sometime probably late Tuesday or on Wednesday, baring any new issues before then.

--Larry Garfield

I've just gave the RFC another deep read, and found only mentions of
pass-by-ref. But not return-by-ref, and neither does the implementation
handle this case:

# ./sapi/cli/php -r 'function &r(&$a) { return $a; } $a = 1; $b =
&r($a); ++$b; var_dump($a);'
int(2)
# ./sapi/cli/php -r 'function &r(&$a) { return $a; } $a = 1; $b =
&r(?)($a); ++$b; var_dump($a);'

Notice: Only variables should be assigned by reference in Command line
code on line 1
int(1)

Was this an oversight or intentionally omitted in the RFC? If it was,
I'd like to hear the reasoning on this.

Just an oversight. We both use return-by-ref so rarely we forgot it's even a thing. :slight_smile: I've updated the RFC to include it, and Arnaud said it's easy to update the implementation so will do so shortly. Thanks for the catch.

As this is largely just a forgotten case (I just added a "/return-by-ref" to the text), I'm not sure if it needs a cooldown reset. For the moment I will plan to continue opening the vote in the next few days, but if someone requests it I'll mark it a minor change and delay a week.

--Larry Garfield