I believe disallowing multiple extensions on one type defeats one of the purposes of the feature - extending from outside. Let's say you have a vendor package for manipulating strings which defines an extension on `string` type. It works, but then you need one more custom extensions - some kind of `replaceLastRegex` method. You define it in your own extension, but then you're either missing the vendor package methods or your own extensions. This might even make people avoid extensions, because there would be no way to use both extensions, hence making them extract those into functions.
I think that if the goal is to avoid the confusion and/or mess, we could force specifying the when using the extension. It would then be crystal clear where the method is coming from and also it'd be trivial to check whether method names are conflicting between extensions. The syntax is just a demonstration: `use extension App\Whatever\CollectionExtension as Illuminate\Collection::map;` On Wed, Aug 10, 2022 at 6:28 PM Deleu <deleu...@gmail.com> wrote: > > > On Wed, Aug 10, 2022 at 5:16 PM Levi Morrison via internals < > internals@lists.php.net> wrote: > >> > What are your thoughts? >> >> It's a fantastic feature that I've used in Rust, although there are >> some differences. First, it doesn't work for regular methods -- they >> have to be part of a trait. Secondly, in general a trait can only be >> implemented for a given type if it is in the package which defines >> that type, or in the package which defines the trait. Third, the trait >> must be in scope. These rules help people understand where the methods >> are coming from, which is particularly helpful for large code bases or >> teams. >> >> PHP doesn't really have tools for these kinds of restrictions, but I >> think it's necessary. You'd need some way to manage where extension >> methods are loaded, how they are found, and without pessimizing >> performance of method calls in general just because this feature >> exists. >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: https://www.php.net/unsub.php >> >> > As I was thinking about how this feature would be cool, I was also worried > about how big of a mess it could become, given the lack of restrictions you > pointed out here. However, knowing how PHP works, I wonder if the following > could be made possible: > > ``` > // Vendor File > namespace Illuminate\Support; > > class Collection {} > > // Extension File > namespace App\Whatever; > > extension LaravelCollection on Collection {} > > // Usage File > namespace App\Business; > > use App\Whatever\Laravelcollection; > > $collection = (new Collection())->extensionMethodAvailableHere(); > ``` > > The goal here is to > 1- Disallow `use Class; use ExtensionClass` simultaneously (conflicting > symbols on compile-time?) > 2- Bind the Base-class Symbol through the ExtensionClass symbol > 3- Disallow two extensions to compete with each other > 4- The user would always know that a symbol has a method either via > 1-level extension or from the original class directly - it doesn't come > from unknown places > > I feel like this would be powerful enough to solve a lot of usability on > PHP OOP while not being crazy enough to create a nightmare on codebases and > the internals of the PHP Engine. Does this make sense? > > -- > Marco Deleu >