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

Reply via email to