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

Reply via email to