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

Reply via email to