I see. The first thought is about extending the class definition: along with functions hashtable we would add virtual functions HT and lookup for the function will be another HT lookup.
[image: image.png] That for sure is better than trap for cpu, but enlarge memory usage at the moment. --- Moreover, it allows us to keep both static and dynamic functions. function class::func(){} // static extension class:func() function class->func(){} // dynamic function $class->func() --- this functions can be found dynamically and it seems alright: // a.php use Models\User; function User::getName(){} // new User->getName is available here // b.php use Models\User; // new User->getName is NOT available here, because a.php wasn't loaded and here User::getName isn't available // c.php namespace Stuff; include 'a.php'; // new User->getName here you can do it, because a.php was loaded and functions table was adjusted with getName function // d.php use Stuff\Smth; use Tools\Smth2; // if it's an app entrypoint // autoloader loads c.php because of Smth file is found there // c.php loads a.php // the extension function User::getName is also available here // either is this file an entrypoint or not // it stores the extension function in the class definition // so Smth2 now can use the extension function, because it was loaded "by parent" > Very much not. The `use` construct has no bearing on autoloading currently. Autoloading happens only for classes and class-like things (interfaces, traits, enums). If a function is not found, PHP just crashes. Various solutions to this have been discussed over the years, none of which ever made it as far as a vote. Is this covered by the texts above? > In fairness, I think with universal opcache, preloading, and the increasing use of persistent processes, just skipping autoloading for functions and front-loading them via composer.json's "files" block is fine for the 80% case. But it feels like I am in the minority on that position. That's what we have now. Can't see any problems. On Tue, Jun 10, 2025 at 11:11 PM Larry Garfield <la...@garfieldtech.com> wrote: > On Tue, Jun 10, 2025, at 2:45 PM, Dmitry Derepko wrote: > > Thanks for participating, Larry. > > > > On Mon, Jun 9, 2025 at 10:29 PM Larry Garfield <la...@garfieldtech.com> > wrote: > >> 2. Please link to a PR of your actual implementation. In context it > looks like your branch comparison link is to the version you said didn't > work, so it's not that helpful. > > > > Correct, I don't have another one. This is big feature, I need a lot of > > time to implement it. I don't want to waste my time if we decide that > > RFC won't pass at all. > > Understood. > > >> 3. The biggest question that has come up in the past (Ilija and I have > discussed it at length) is, naturally, autoloading. How if at all do you > address that? > > > > In the original message I mentioned `use extension` construction. This > > should be enough for solution, isn't it? > > Very much not. The `use` construct has no bearing on autoloading > currently. Autoloading happens only for classes and class-like things > (interfaces, traits, enums). If a function is not found, PHP just > crashes. Various solutions to this have been discussed over the years, > none of which ever made it as far as a vote. > > I toyed with the idea of having extension functions compile to a static > method on a class as a way around this, but of course then you end up with > a file-per-function, and the file name has to match not the function name, > but whatever mangled class name gets generated. Not at all intuitive. > > In fairness, I think with universal opcache, preloading, and the > increasing use of persistent processes, just skipping autoloading for > functions and front-loading them via composer.json's "files" block is fine > for the 80% case. But it feels like I am in the minority on that position. > > >> 4. The other big question was determining when to match a given > "method" call to an extension function, when the type of a variable is not > always known at compile time. How did you address this? > > > > Cannot understand the passage, could you explain more? > > <?php > // index.php > > function Point.area(): int { > return $this->x & $this->y; > } > > function doStuff($p) { > // At compile time, we don't know that $p is a Point. In fact, it may > not be. > // The function will allow any value here, even a non-object, so it > doesn't know > // if this should be compiled to Point__area($p) or left as is. > print $p->area(); > } > > The only way I could think of to handle that is to have a method call > "trap" similar to class autoloading, that when hit checks at runtime "hey, > this method didn't exist, but is there a `use`d function that would match > based on the runtime type of this value?" But Ilija felt that would be > prohibitively slow. It would certainly be slower than just a > function/method call since the trap takes time. > > And then we get into questions of inheritance, and, well, it gets even > messier fast. > > One possibility that we riffed on during the pipes discussion (mostly off > list, I think) was using +> for some combination of extension functions and > Elixir-style first-arg pipe passing, so that $p+>area() would signal to the > engine (compile time or runtime) that area() wasn't a method but a function > that should get $p passed to it. That would solve the "trap" problem, but > still doesn't address autoloading, the lack of compile time type knowledge, > or how to differentiate between Point.area(), ShapeInterface.area(), > Rect.area(), etc. > > --Larry Garfield > -- Best regards, Dmitrii Derepko. @xepozz