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'-&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
[email protected]

Reply via email to