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