Hi

Am 2026-01-31 05:25, schrieb Bob Weinand:
I see the rejected features section, but this is a non-argument to me, like x(...['$this' => $obj]) is just allowed the same currently.

I don't think that argument weighs strong enough.

Thank you. We didn't consider unpacking and after checking with Arnaud, it would indeed be an option to use `x(this: ?)` within the call and still allow `x(...["this" => $x])` as an escape hatch to preserve compatibility.

With regard to your comment on the PR and the “Open Issue” listed in the RFC about the name for the `$this` parameter in the resulting Closure we have two options to offer:

1. `ClassName::methodName(this: ?)` with the parameter being called `$__this`.

2. `ClassName::methodName($this: ?)` with the parameter being called `$this`.

Notably `ClassName::methodName(this: ?)` with the parameter being called `$this` is not an option, because it would result in inconsistent behavior:

`ClassName::methodName(this: ?)` semantically relies on `$this` never being a valid parameter name, such that `this: ?` can unambiguously refer to the “implicit `$this` value” for a method call. However when the parameter in the generated Closure would be called `$this`, there is some ambiguity for cases like:

     $c = DateTime::format(this: ?, format: ?);
     $c2 = $c(this: ?, format: 'c');

Is `this: ?` in the definition of `$c2` referring to the `$this` parameter of the generated Closure or is it an attempt to partially apply the `Closure` object for the `Closure::__invoke()` method that is referenced by `$c`?

Similarly allowing `this: $object` with a concrete value is explicitly disallowed, because of possible ambiguity with regard to inheritance:

     class P { public function m() { echo "P"; } }
     class C extends P { public function m() { echo "C"; } }

     // is this calling P::m() or is this calling C::m()?
     P::m(this: new C());

This would however prevent calling a partially applied instance method with named arguments:

     $c = DateTime::format(this: ?, format: ?);
     // Disallowed, because this: must be partially applied.
     $c(this: new DateTime(), format: 'c');

If the syntax to define the PFA was using `C::m($this: ?)`, `$this` in the resulting Closure would just work like any other parameter.

So this leaves `this: ?` + `$__this` and `$this: ?` + `$this`, for which Arnaud an I didn't come to a clear agreement and thus want to hold an informal poll. For you to make an educated decision, we prepared a comparison table: ($this: ?) (this: ?)
     (1) `this: $value` remains legal (with variadics):   Yes        No
     (2) Unpack ambiguity:                                Yes        Yes
     (3) Uses existing syntax / no weird name:            No         Yes
     (4) PFA param name is $this, not $__this:            Yes        No

To explain each of the points:

(1) Is referring to:

     function dump(...$args) { var_dump($args); }
     dump(this: "foo");

remaining legal without using dump(...['this' => 'test']); as a workaround.

(2) Is referring to:

     dump(...['this' => 'foo']);
     dump(...['$this' => 'foo']);

behaving differently from:

     dump(this: "foo");
     dump($this: "foo");

(3) Is referring to:

     dump($this: ?)

introducing new syntax (the leading `$`) instead of just new semantics (a special parameter referring to an object instance).

(4) Is referring to:

     $c = DateTime::format(this: ?, "c");
     $c("foo");

emitting:

Uncaught TypeError: DateTime::{closure:pfa:test.php:3}(): Argument #1 ($__this) must be of type DateTime, string given

with the error message referring to `$__this` rather than `$this` and similarly:

     $c(__this: new DateTime());

being required when using named parameters to call the Closure is desired.

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

Long story short: Which of the two alternatives of

1. `ClassName::methodName(this: ?)` with the parameter being called `$__this`.

2. `ClassName::methodName($this: ?)` with the parameter being called `$this`.

Do you prefer?

Best regards
Tim Düsterhus

Reply via email to