[RFC] Paren-less access to scalar extension methods ('a,b'->arr as sugar for 'a,b'->arr())
| From: | 497161114 | Date: | Sat, 24 Oct 2026 09:33:53 +0000 |
| Subject: | [RFC] Paren-less access to scalar extension methods ('a,b'->arr as sugar for 'a,b'->arr()) | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-132913@lists.php.net to get a copy of this message | ||
Hi,
This follows up on the Extension Methods / Scalar Extension Methods RFCs (currently in draft).
I'd like to propose allowing extension methods on scalar values to be invoked through
property-fetch syntax, with the parentheses omitted.
Proposal: when a property read on a scalar fails, fall back to the extension method registry and
invoke the method with its default arguments. ->name becomes sugar for ->name().
extension string $s {
public function arr(string $separator = ','): array {
return explode($separator, $s);
}
}
'a,b'->arr; // ['a', 'b'] <- new
'a,b'->arr(); // ['a', 'b'] <- already works
'a|b'->arr('|'); // ['a', 'b'] <- already
works
Only methods callable with zero arguments would be eligible. 'abc'->needsArg would
throw ArgumentCountError. Unknown names keep today's behavior.
Why this is cheap here: the main use case for scalar extension methods is derived values (length,
upper, slug, toArray), which read like properties. And first-class callables are already disabled
for scalar receivers (a by-value receiver cannot be bound into a Closure), so $s->arr cannot
be interpreted as "return a Closure" - the only remaining meaning is "call it and
return the value". That removes the usual ambiguity that makes this expensive in C#.
Scope: scalar receivers only (string, int, float, bool, array). Object receivers are excluded on
purpose: a missing property on an object is usually a typo, and turning that warning into a
successful call would weaken a useful diagnostic. Scalars have no property table today, so nothing
is shadowed.
Backward compatibility: no parser change; ->name already compiles to ZEND_FETCH_OBJ_R. Today
the affected expressions always emit "Warning: Attempt to read property "x" on
string" and evaluate to null, which no correct code can rely on. Verified against a local build
of hollyschilling/php-src@extension-methods-scalars (5e5112f):
'aaa'->length; // Warning: Attempt to read property "length" on string
-> NULL
'a,b'->arr; // Warning: Attempt to read property "arr" on string
-> NULL
These two lines are exactly what the proposal would change.
Open questions I'd like the list's input on:
A. When a method has a required parameter, throw ArgumentCountError (my preference; a silent null
would be indistinguishable from a typo), or fall back to the existing warning?
B. Should isset() / ?? consult the registry, or stay untouched for v1?
C. Is excluding object receivers the right call, or is the resulting inconsistency
($str->upper works, $obj->upper does not) worse than losing the typo diagnostic on
objects?
Happy to prototype against the extension-methods-scalars branch once (A) is settled.
Thanks,
h4acda
497161114
h4acda@qq.com