[RFC] Paren-less access to scalar extension methods ('a,b'->arr as sugar for 'a,b'->arr())

From: 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. -&gt;name becomes sugar for -&gt;name(). extension string $s { &nbsp; &nbsp; public function arr(string $separator = ','): array { &nbsp; &nbsp; &nbsp; &nbsp; return explode($separator, $s); &nbsp; &nbsp; } } 'a,b'-&gt;arr; // ['a', 'b'] <- new 'a,b'-&gt;arr(); // ['a', 'b'] <- already works 'a|b'-&gt;arr('|'); // ['a', 'b'] <- already works Only methods callable with zero arguments would be eligible. 'abc'-&gt;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-&gt;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; -&gt;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'-&gt;length; // Warning: Attempt to read property "length" on string -&gt; NULL 'a,b'-&gt;arr; // Warning: Attempt to read property "arr" on string -&gt; 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-&gt;upper works, $obj-&gt;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

« previous php.internals (#132913) next »