[RFC] Partial Function Application for instance of non-static methods ("$this")

php.internals

Tim Düsterhus

222 days ago
Hi Arnaud and I would like to start discussion on our RFC “Partial Function Application for instance of non-static methods ("$this")” which is intended to round-off the Partial Function Application RFC that was accepted recently: https://wiki.php.net/rfc/partial_function_application_this Best regards Tim Düsterhus

Derick Rethans

222 days ago
On Thu, 22 Jan 2026, Tim Düsterhus wrote:
> Arnaud and I would like to start discussion on our RFC “Partial Function > Application for instance of non-static methods ("$this")” which is intended to > round-off the Partial Function Application RFC that was accepted recently: > > https://wiki.php.net/rfc/partial_function_application_this
We propose allowing a named parameter $this: ? to be combined with the “scope resolution operator” syntax of referring to a method. I can't say I am entirely sold on the syntax here — starting with a $ makes it look like a variable. Since the $this: ? parameter does not refer to a parameter in the underlying argument list and thus there is no ambiguity with regard to positional parameters it may be placed at any position of the parameter list I think I would be keen on *requiring* this to be the **first** in the argument list. Although there is no ambiguity, I also can't see why you would want to have it anywhere else. And the RFC does acknowledge "instance methods which effectively carry an implicit $this parameter that is provided on the left side of the -> operator." With both these two above comments, I think I would like to see a better syntax — but I am unsure if that's possible. It may also not be used when partially applying an instance method with a known object. $c = $dateTime->format($this: ?, "c"); // Fatal error: Invalid use of $this placeholder Can you explain (in the RFC) what you mean by "known object" — I don't think the language on what this means is clear enough. cheers, Derick

Tim Düsterhus

222 days ago
Hi Am 2026-01-22 16:33, schrieb Derick Rethans:
>> https://wiki.php.net/rfc/partial_function_application_this > > We propose allowing a named parameter $this: ? to be combined with the > “scope resolution operator” syntax of referring to a method. > > I can't say I am entirely sold on the syntax here — starting with a $ > makes it look like a variable.
Yes, it certainly requires some getting used to it. It's the best we could come up with, but if there are any better suggestions, we're open to hearing those. I'd like to note the “Rejected Features” section, since it lists some non-workable alternatives we considered.
> Since the $this: ? parameter does not refer to a parameter in > the underlying argument list and thus there is no ambiguity with > regard to positional parameters it may be placed at any position > of the parameter list > > I think I would be keen on *requiring* this to be the **first** in the > argument list. > > Although there is no ambiguity, I also can't see why you would want to > have it anywhere else.
Being able to “reorder” parameters to (better) fit a specific callback signature is an explicit feature of PFA that we also wanted to support for `$this`. As an example, suppose objects could be used as an array key. `array_find()` first passes the value and then the key to the callback. In this case users might want to do the following: class SomeObject { public function __construct(private string $value) { } public function hasMatchingValue(string $value) { return $value === $this->value; } } $array = [ new SomeObject('foo') => 'bar', new SomeObject('baz') => 'baz', ]; array_find(SomeObject::hasMatchingValue(value: ?, $this: ?), $array); In this case `array_find()` is supposed to return `'baz'`, since this is where the values match.
> It may also not be used when partially applying an instance > method with a known object. > > $c = $dateTime->format($this: ?, "c"); // Fatal error: Invalid use of > $this placeholder > > Can you explain (in the RFC) what you mean by "known object" — I don't > think the language on what this means is clear enough.
I have rephrased that to “It may also not be used when partially applying an instance method using the -> operator, since the object is already specified:” Best regards Tim Düsterhus

Rowan Tommins [IMSoP]

222 days ago
On 22/01/2026 16:08, Tim Düsterhus wrote:
> Yes, it certainly requires some getting used to it. It's the best we > could come up with, but if there are any better suggestions, we're > open to hearing those. I'd like to note the “Rejected Features” > section, since it lists some non-workable alternatives we considered.
Looking at this:
> PHP itself already has "ALGOL-style" declarations, for "const",
"global", and "static". I'm reminded of placeholders in PostgreSQL; the type is needed to choose overloaded functions and operators, so this doesn't compile (without extra metadata): Select do_something(?) as result Instead, you can insert a dummy cast to indicate the type: Select do_something(?::int) as result The PHP equivalent would be something like this: $f = (DateTimeImmutable)?->format('c'); Or, slightly more readable but less consistent with casts: $f = (? as DateTimeImmutable)->format('c'); That doesn't solve the second part of the problem though:
> It would also not allow to reorder the parameters in the resulting
Closure, which is an explicit feature of Partial Function Application. I thought I'd throw it out there anyway in case it stimulates any other ideas.
-- Rowan Tommins [IMSoP]

Larry Garfield

222 days ago
On Thu, Jan 22, 2026, at 10:26 AM, Rowan Tommins [IMSoP] wrote:
> On 22/01/2026 16:08, Tim Düsterhus wrote: >> Yes, it certainly requires some getting used to it. It's the best we >> could come up with, but if there are any better suggestions, we're >> open to hearing those. I'd like to note the “Rejected Features” >> section, since it lists some non-workable alternatives we considered. > > > Looking at this: > > > PHP itself already has "ALGOL-style" declarations, for "const", > "global", and "static". > > I'm reminded of placeholders in PostgreSQL; the type is needed to choose > overloaded functions and operators, so this doesn't compile (without > extra metadata): > > Select do_something(?) as result > > Instead, you can insert a dummy cast to indicate the type: > > Select do_something(?::int) as result > > > The PHP equivalent would be something like this: > > $f = (DateTimeImmutable)?->format('c'); > > Or, slightly more readable but less consistent with casts: > > $f = (? as DateTimeImmutable)->format('c'); > > > That doesn't solve the second part of the problem though: > > > It would also not allow to reorder the parameters in the resulting > Closure, which is an explicit feature of Partial Function Application. > > > I thought I'd throw it out there anyway in case it stimulates any other > ideas.
More spitballing on my previous reply: class Test { public function stuff(int $a) {} } (Test)?->stuff(?); Translates to: fn(Test $__this, int $a) => $__this->stuff($a); But if there's no partialing on the method side, it could get abbreviated to: (?)->stuff(4); Translates to: fn(object $__this) => $__this->stuff(4); Because we don't need to know the type at compile time, and a method-not-found error would still happen at runtime anyway if necessary. That would then be a lot easier to write in cases where you're just dropping a $this->stuff() call into a pipe chain but want to receive $this. I'm not sure if that would also allow for reading properties with the same syntax? --Larry Garfield

Tim Düsterhus

207 days ago
Hi On 1/22/26 17:41, Larry Garfield wrote:
> More spitballing on my previous reply: > > class Test { > public function stuff(int $a) {} > } > > (Test)?->stuff(?);
As mentioned in the sibling mail, this is existing syntax and thus doesn't work.
> But if there's no partialing on the method side, it could get abbreviated to: > > (?)->stuff(4); > > Translates to: > > fn(object $__this) => $__this->stuff(4); > > Because we don't need to know the type at compile time, and a method-not-found error would still happen at runtime anyway if necessary.
By that argument you wouldn't need to type the argument as `object` either (calling methods on a non-object will throw) and the comparison would become: $c = (?)->stuff(4); $c = fn($o) => $o->stuff(4); Keeping full type information is the main benefit of PFA over “just write a Closure”. Being able to reorder parameters as part of partial application is another explicit feature that would not be supported by that syntax.
> That would then be a lot easier to write in cases where you're just dropping a $this->stuff() call into a pipe chain but want to receive $this.
The use case for partially applying `$this` is in cases where you need a “function handle”, that's why the examples are ones where the resulting Closure is passed as a parameter to another function. Within a pipe chain you would just use the regular `->` operator on the result of the previous step: $result = (trim($username) |> $repository->findBy(name: ?) )->getId(); It would also naturally support `?->` in case your repository returns `null` when the user cannot be found. Best regards Tim Düsterhus

Larry Garfield

206 days ago
On Fri, Feb 6, 2026, at 10:43 AM, Tim Düsterhus wrote:
> Hi > > On 1/22/26 17:41, Larry Garfield wrote: >> More spitballing on my previous reply: >> >> class Test { >> public function stuff(int $a) {} >> } >> >> (Test)?->stuff(?); > > As mentioned in the sibling mail, this is existing syntax and thus > doesn't work.
Sure, but we can fiddle with the details to find something that works. I also suggested something like these to Arnaud off-list: (?: Test)->stuff(?); (Test ?)->stuff(?); ((Test)?)->stuff(?);
> Keeping full type information is the main benefit of PFA over “just > write a Closure”. Being able to reorder parameters as part of partial > application is another explicit feature that would not be supported by > that syntax.
Honestly, I don't much care about the reordering. And with this approach you'd still be able to reorder the method params, just keep the object as first arg.
>> That would then be a lot easier to write in cases where you're just dropping a $this->stuff() call into a pipe chain but want to receive $this. > > The use case for partially applying `$this` is in cases where you need a > “function handle”, that's why the examples are ones where the resulting > Closure is passed as a parameter to another function. > > Within a pipe chain you would just use the regular `->` operator on the > result of the previous step: > > $result = (trim($username) > |> $repository->findBy(name: ?) > )->getId(); > > It would also naturally support `?->` in case your repository returns > `null` when the user cannot be found.
Directly in a pipe chain, sure. However, I would see this as most useful as a callback to array_map et al (or future equivalents). Eg: import_stuff() |> array_filter(?, (?)->hasField('comment') |> array_map((?)->save(), $records) ; In this case, the only thing being partialed is the object on which to invoke. So there's no need to think about reordering the params in the first place: There's just one. Needing to specify the type in this case: import_stuff() |> array_filter(?, Record::hasField('comment', ...) |> array_map(Record::save(...), $records) ; Just adds more noise, and IMO creates confusion between static and non-static methods. --Larry Garfield

Bob Weinand

206 days ago
I'd like to search for appropriate words... On 6.2.2026 21:30:11, Larry Garfield wrote:
> Sure, but we can fiddle with the details to find something that works. I also suggested something like these to Arnaud off-list: > > (?: Test)->stuff(?); > (Test ?)->stuff(?); > ((Test)?)->stuff(?); > > --Larry Garfield
Could you please not push this garbage. It's ugly, and just because we have a question mark, we don't have to universally use it. I know, PHP is the double clawed hammer and everything the nail. That doesn't have to apply to every aspect the language though. No thank you, Bob

Larry Garfield

203 days ago
On Fri, Feb 6, 2026, at 4:05 PM, Bob Weinand wrote:
> I'd like to search for appropriate words...
You were apparently unsuccessful.
> On 6.2.2026 21:30:11, Larry Garfield wrote: >> Sure, but we can fiddle with the details to find something that works. I also suggested something like these to Arnaud off-list: >> >> (?: Test)->stuff(?); >> (Test ?)->stuff(?); >> ((Test)?)->stuff(?); >> >> --Larry Garfield > > > Could you please not push this garbage.
As stated repeatedly, this is just idiating on possible syntaxes that allow for an abbreviated form when the object is the only thing being partialed. If you don't like the ideas thrown out so far, please share your own rather than getting insulting. My original plan was to use `$$->foo(3, 4)`, which would always produce a single-parameter closure that would invoke `foo(3, 4)` on whatever object was passed to it. I was not involved in this RFC from Arnaud and Tim, but I'm trying to look for ways to improve it so that it can cover the most common use case better. I very much support the idea, but I don't think I would vote Yes on the current syntax. It's far too cumbersome for the most common case. Assistance finding a syntax that would satisfy all presented situations would be more welcome than calling brainstorming "garbage." --Larry Garfield

Mathieu Rochette

206 days ago
On Friday, February 6th, 2026 at 21:32, Larry Garfield <larry@garfieldtech.com> wrote:
> On Fri, Feb 6, 2026, at 10:43 AM, Tim Düsterhus wrote: > > Hi > > > > On 1/22/26 17:41, Larry Garfield wrote: > >> More spitballing on my previous reply: > >> > >> class Test { > >> public function stuff(int $a) {} > >> } > >> > >> (Test)?->stuff(?); > > > > As mentioned in the sibling mail, this is existing syntax and thus > > doesn't work. >
> Sure, but we can fiddle with the details to find something that works. I also suggested something like these to Arnaud off-list: >
> (?: Test)->stuff(?); > (Test ?)->stuff(?); > ((Test)?)->stuff(?); >
>
> > Keeping full type information is the main benefit of PFA over “just > > write a Closure”. Being able to reorder parameters as part of partial > > application is another explicit feature that would not be supported by > > that syntax. >
> Honestly, I don't much care about the reordering. And with this approach you'd still be able to reorder the method params, just keep the object as first arg. >
> >> That would then be a lot easier to write in cases where you're just dropping a $this->stuff() call into a pipe chain but want to receive $this. > > > > The use case for partially applying `$this` is in cases where you need a > > “function handle”, that's why the examples are ones where the resulting > > Closure is passed as a parameter to another function. > > > > Within a pipe chain you would just use the regular `->` operator on the > > result of the previous step: > > > > $result = (trim($username) > > |> $repository->findBy(name: ?) > > )->getId(); > > > > It would also naturally support `?->` in case your repository returns > > `null` when the user cannot be found. >
> Directly in a pipe chain, sure. However, I would see this as most useful as a callback to array_map et al (or future equivalents). >
> Eg: >
> import_stuff() > |> array_filter(?, (?)->hasField('comment') > |> array_map((?)->save(), $records) > ; >
> In this case, the only thing being partialed is the object on which to invoke. So there's no need to think about reordering the params in the first place: There's just one. >
> Needing to specify the type in this case: >
> import_stuff() > |> array_filter(?, Record::hasField('comment', ...) > |> array_map(Record::save(...), $records) > ; >
> Just adds more noise, and IMO creates confusion between static and non-static methods. >
> --Larry Garfield >
I find the `(Test ?)->method()` suggestion quite nice. For 2 reasons, it looks similar to a function argument ("Type $arg"), and following that, given that the type is optional for function arguments, it could also be optional here to have `(?)->method()` or even `?->method()` as a shortcut. I understand it means some optimization cannot be done, but in a lot of case it doesn't matter, and if I have to write `DateTimeImmutable::format($this: ?, 'c')` vs `fn ($dt) => $dt->format('c')`. The only benefit would be the optimization. so if I don't care about that I'm still going to go for the shorter one unless this a performance critical situation Having `(DateTimeImmutable ?)->format('c')` and `?->format('c')` as a non-optimized shortcut seems more interesting to me. I'm not too bothered by the reordering, I think this still covers 99% of the use cases --- That said, regarding your 2 suggestions, Tim, and after reading your explanations, my preference goes for `$this: ?` And yet more suggestions: `DateTimeImmutable::methodName($: ?, ...)` and whatever is between `$` and `:` could be used as the arg name of the generated function (with something like "__this" being the default if omitted) the `$` prefix could also be replaced by any symbol not authorized at the start of an argument name, eg: * `DateTimeImmutable::methodName(*it: ?, ...)` * `DateTimeImmutable::methodName(~it: ?, ...)` * `DateTimeImmutable::methodName(.it: ?, ...)` (it's getting worse and worse, ain't it?) or, even more drastic changes: * `DateTimeImmutable::methodName(*it, ...)` * `DateTimeImmutable::methodName(?this, ...)` (feel free to silently ignore them; I'm not putting that much thought into those suggestions) regards, Mathieu Rochette

Tim Düsterhus

221 days ago
Hi Am 2026-01-22 17:26, schrieb Rowan Tommins [IMSoP]:
> The PHP equivalent would be something like this: > > $f = (DateTimeImmutable)?->format('c');
See my reply to Mathieu on why this specific one wouldn't work.
> Or, slightly more readable but less consistent with casts: > > $f = (? as DateTimeImmutable)->format('c');
That would work, but indeed would not solve the reordering case. I also feel it is inventing more new syntax than the current “scope-resolution-operator” syntax the RFC uses (which is not just used for static method calls). Best regards Tim Düsterhus

Larry Garfield

222 days ago
On Thu, Jan 22, 2026, at 10:08 AM, Tim Düsterhus wrote:
> Hi > > Am 2026-01-22 16:33, schrieb Derick Rethans: >>> https://wiki.php.net/rfc/partial_function_application_this >> >> We propose allowing a named parameter $this: ? to be combined with the >> “scope resolution operator” syntax of referring to a method. >> >> I can't say I am entirely sold on the syntax here — starting with a $ >> makes it look like a variable. > > Yes, it certainly requires some getting used to it. It's the best we > could come up with, but if there are any better suggestions, we're open > to hearing those. I'd like to note the “Rejected Features” section, > since it lists some non-workable alternatives we considered.
I too am very much in favor of this functionality, though not a fan of the syntax either. My previous, un-finished thinking was for `$$->foo('blah')`, which would translate to a mixed fn that just forwards the call. I... hadn't actually thought about also partially applying the method, since the use cases I can think of would all be "call this method on the value piped from the previous pipe step." (Or, read this property.) That would allow it to be embedded within an array_map() call or similar, since it's technically independent of both PFA and pipes. If it's being partially applied, then I don't see a way around the redundant typing, which is annoying. At least not without vastly better type inference than we have today. So, I think I am mainly interested in the degenerate case where $this is the only thing being partially applied, which seems like a common enough case that it could have a nicer version? I'm just spitballing at this point, I think. But I do like the direction. --Larry Garfield

Mathieu Rochette

222 days ago
On Thursday, January 22nd, 2026 at 10:52, Tim Düsterhus <tim@bastelstu.be> wrote:
> Hi >
> Arnaud and I would like to start discussion on our RFC “Partial Function > Application for instance of non-static methods ("$this")” which is > intended to round-off the Partial Function Application RFC that was > accepted recently: >
> https://wiki.php.net/rfc/partial_function_application_this >
Hi! I often whished something like this existed :) Didn't get trough to suggest it because I wasn't sure of the syntax either (and lazyness) still, my syntax suggestions: array_map(DateTimeImmutable->format("c"), $dates); I understand this doesn't allow reordeing though, but it feels so much better and I expect would be what's needed for most cases that I hope something like this could work. and an opt-in mechanic to reorder could be introduced for that use case. the previous suggestion could be a shortcut for: array_map(?::DateTimeImmutable->format("c"), $dates); and a separate improvement to PFA could add support for picking arguments by name or position: array_find(?key::SomeObject->hasMatchingValue(?), $array); array_find(?2::SomeObject->hasMatchingValue(?), $array); I noticed `?->method(?)` was considered; evne if it was possible, I would prefer if the type was explict, as you may want to use an interface name (or a union type, etc.) too regards, Mathieu Rochette

Tim Düsterhus

221 days ago
Hi Am 2026-01-22 18:30, schrieb Mathieu Rochette:
> I often whished something like this existed :) Didn't get trough to > suggest it because I wasn't sure of the syntax either (and lazyness)
Thank you for participating in the discussion of *this* RFC then. Having more voices available helps building things that suit the community best :-)
> still, my syntax suggestions: > > array_map(DateTimeImmutable->format("c"), $dates);
Unfortunately this doesn't work, because it is a already-legal method call on a method stored in the constant called `DateTimeImmutable`. See: https://3v4l.org/3khkT#veol
> I noticed `?->method(?)` was considered; evne if it was possible, I > would prefer if the type was explict, as you may want to use an > interface name (or a union type, etc.) too
Union types would likely be unsupported either way, since multiple members of the union could have incompatible signatures for the same method. Interfaces are fully supported with the currently proposed syntax (it's explicitly mentioned in the RFC). Best regards Tim Düsterhus

Mathieu Rochette

221 days ago
Mathieu Rochette On Friday, January 23rd, 2026 at 09:37, Tim Düsterhus <tim@bastelstu.be> wrote:
> Hi >
> Am 2026-01-22 18:30, schrieb >
> Mathieu Rochette >
> : >
> > I often whished something like this existed :) Didn't get trough to > > suggest it because I wasn't sure of the syntax either (and lazyness) >
>
> Thank you for participating in the discussion of this RFC then. Having > more voices available helps building things that suit the community best > :-) >
> > still, my syntax suggestions: > >
> > array_map(DateTimeImmutable->format("c"), $dates); >
>
> Unfortunately this doesn't work, because it is a already-legal method > call on a method stored in the constant called `DateTimeImmutable`. See: > https://3v4l.org/3khkT#veol
ohhh then, continuing on bikeshedding, I think I still prefer `?::DateTimeImmutable->format("c")` or `(? as DateTimeImmutable)->format("c")` as Larry mentioned. `(DateTimeImmutable)?->format("c")` feels a bit weird. Reminds me too much of the null-safe operator.
>
> > I noticed `?->method(?)` was considered; evne if it was possible, I > > would prefer if the type was explict, as you may want to use an > > interface name (or a union type, etc.) too >
>
> Union types would likely be unsupported either way, since multiple > members of the union could have incompatible signatures for the same >
They could have incompatible signatures, yes, but they also could have compatible ones too. It's not a deal breaker. I don't imagine needing this in practice. But I don't see why the language would prevent that; I can already make that mistake with short closures or any methods. For me, it's the role of the static analyzer to tell me if I made such a mistake (or runtime errors ^^).

Tim Düsterhus

221 days ago
Hi Am 2026-01-23 14:06, schrieb Mathieu Rochette:
> `(DateTimeImmutable)?->format("c")` feels a bit weird. Reminds me too > much of the null-safe operator.
That's because it is. It's literally the same case of a `DateTimeImmutable` constant with useless parentheses and the null-safe object member access: https://3v4l.org/NebOR#veol
> They could have incompatible signatures, yes, but they also could have > compatible ones too. It's not a deal breaker. I don't imagine needing > this in practice. But I don't see why the language would prevent that; > I can already make that mistake with short closures or any methods. For > me, it's the role of the static analyzer to tell me if I made such a > mistake (or runtime errors ^^).
The signature would need to be “unique” to properly generate the signature of the resulting Closure. Best regards Tim Düsterhus

Theodore Brown

221 days ago
On Thu, January 22, 2026 at 03:50 Tim Düsterhus wrote: > Arnaud and I would like to start discussion on our RFC “Partial Function > Application for instance of non-static methods ("$this")” which is > intended to round-off the Partial Function Application RFC that was > accepted recently: > > https://wiki.php.net/rfc/partial_function_application_this Hi Tim and Arnaud, Thank you for your work on this. However, I'm struggling to see the benefit of this syntax over short closures given the examples in the RFC: $dates = [ new DateTimeImmutable('now'), ]; $formattedDates = array_map(DateTimeImmutable::format($this: ?, "c"), $dates); This saves only three characters compared to a short closure: $formattedDates = array_map(fn(DateTimeImmutable $d) => $d->format("c"), $dates); Furthermore, duplicating the array's type isn't necessary when IDEs and static analysis can infer it, so short closures can usually be even more concise: $formattedDates = array_map(fn($d) => $d->format("c"), $dates); I also find the use of `$this` as a named argument confusing. It makes it appear as though the current class instance is somehow being passed to the method, when this isn't the case. The other example with Symfony Form's `ChoiceType` doesn't sell the syntax for me, either: 'choice_label' => Category::getName($this: ?), A short closure is barely any longer, and makes it easier to add additional logic when needed: 'choice_label' => fn(Category $c) => $c->getName(), 'choice_label' => fn(Category $c) => strtoupper($c->getName()), Ultimately I'm not convinced it's worth it to make the partial function syntax and semantics more complicated to support this scenario, given that short closures already provide similar conciseness and greater flexibility. Kind regards, Theodore

Tim Düsterhus

221 days ago
Hi Am 2026-01-23 00:25, schrieb Theodore Brown:
> Thank you for your work on this. However, I'm struggling to see the > benefit > of this syntax over short closures given the examples in the RFC: > > $dates = [ > new DateTimeImmutable('now'), > ]; > > $formattedDates = array_map(DateTimeImmutable::format($this: ?, > "c"), $dates);
To provide some background on how this RFC came about: Arnaud and I were discussing my recent `array_map()` optimization (https://github.com/php/php-src/pull/20934) that compiles `array_map()` calls that either use FCC or PFA as the callback into the equivalent `foreach()` loop. The optimization skipped when an actual Closure is passed, since full-blown Closures come with all kinds of scope-related (edge) cases to consider, making it much more complicated. I noted that I believed that with PFA many `array_map()` cases could be handled without a full Closure and that it was unfortunate that it didn't work for “filling in the object itself”. I then came up with the basic idea for the proposed syntax half-a-minute later and we figured it would at least be worth proposing it, since it mapped onto the existing PFA semantics in a fairly straight-forward fashion.
> This saves only three characters compared to a short closure: > > $formattedDates = array_map(fn(DateTimeImmutable $d) => > $d->format("c"), $dates);
The return type would be missing in that snippet. And depending on your codebase's policy you might also need `static` in front of the short Closure. This might become less relevant with https://news-web.php.net/php.internals/129825, but personally I would still consider it a best-practice to be explicit. Personally I also feel that short Closures have some “visual overhead” in that they don't feel like a simple “method reference”. It's quite similar to how PFA itself is technically redundant with short Closures, but allows to be more explicit with the intention (which enabled the optimization mentioned above).
> Furthermore, duplicating the array's type isn't necessary when IDEs and > static > analysis can infer it, so short closures can usually be even more > concise: > > $formattedDates = array_map(fn($d) => $d->format("c"), $dates);
This is true when the Closure is immediately consumed, but not when it's intended to be reused at a later point, e.g. with the Symfony Form example where the IDE / Static Analyzer needs some deeper knowledge about how the 2nd and 3rd parameter of `->add()` interact.
> I also find the use of `$this` as a named argument confusing. It makes > it > appear as though the current class instance is somehow being passed to > the > method, when this isn't the case.
That's fair. I would've hoped to just use `this:` without the `$`, but that comes with the breaking change for variadics mentioned at the bottom of the RFC.
> A short closure is barely any longer, and makes it easier to add > additional > logic when needed: > > 'choice_label' => fn(Category $c) => $c->getName(), > > 'choice_label' => fn(Category $c) => strtoupper($c->getName()),
Note: Return type + Static also missing here. And of course if more parameters would be passed, it would scale differently (since more types are required for proper autocompletion). Best regards Tim Düsterhus

Pierre Joye

219 days ago
Hi Tim, On Thu, Jan 22, 2026 at 4:53 PM Tim Düsterhus <tim@bastelstu.be> wrote:
> > Hi > > Arnaud and I would like to start discussion on our RFC “Partial Function > Application for instance of non-static methods ("$this")” which is > intended to round-off the Partial Function Application RFC that was > accepted recently: > > https://wiki.php.net/rfc/partial_function_application_this
I really like that feature. The syntax however, including some proposed in this thread, makes little sense to me. It is also challenging as it targets 8.6. I am not sure it is a good idea to rush and make bad compromises with the syntax because of BC or other issues due to the engine current state/behaviors. I would rather wait for the next major and have a proper, self explained syntax. Even if I doubt that "_" as function name will ever be deprecated as well, that would be my favorite. The next would be "it", as new keyword, $formattedDates = array_map(DateTimeImmutable::format(it, "c"), $dates); That could give some time to send some deprecation warning for "it", as an example. Or whatever other symbols may be chosen. Or whatever else would be needed to have a better approach that could last for the next decade :). best,
-- Pierre

Bob Weinand

213 days ago
Hey Tim, On 22.1.2026 10:50:26, Tim Düsterhus wrote:
> Hi > > Arnaud and I would like to start discussion on our RFC “Partial > Function Application for instance of non-static methods ("$this")” > which is intended to round-off the Partial Function Application RFC > that was accepted recently: > > https://wiki.php.net/rfc/partial_function_application_this > > Best regards > Tim Düsterhus
I've been thinking about this RFC and I think it's a good addition. I just have one question: Why "$this: $obj" and not "this: $obj"? The variable in the function is "$this". Just like "$arg", which gets passed as "arg: $value", without the extra leading dollar-sign. (There's also no conflict, as you may not redeclare $this yourself in a non-static method.) When I see $<varname> before the colon, I sort of expect a dynamic parameter name, but it's not. Thanks, Bob