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