Re: function autoloading v4 RFC

From: Date: Thu, 15 Aug 2024 22:41:52 +0000
Subject: Re: function autoloading v4 RFC
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-124963@lists.php.net to get a copy of this message
On Thu, Aug 15, 2024, at 20:40, Rowan Tommins [IMSoP] wrote: > On 15/08/2024 16:22, Rob Landers wrote: >> Hello internals, >> >> I've decided to attempt an RFC for function autoloading. After reading hundreds of >> ancient (and recent) emails relating to the topic along with several abandoned RFCs from the past, >> and after much review, I've decided to put forth a variation of a previous RFC, as it seemed >> the least ambitious and the most likely to work: >> >> https://wiki.php.net/rfc/function_autoloading4 > > > Hi Rob, > > While brevity can sometimes be a virtue, I feel like there's a lot left to the > reader's interpretation here. > > Specifically, one of the main issues that has come up in previous discussions of the topic is > the behaviour of unqualified function names, which check the current namespace first, then fall back > to global scope. Your RFC implies an approach to this, but doesn't actually spell it out, nor > discuss its pros and cons. > It doesn't go too much into details here on purpose, especially since there was some recent discussion on changing the order. That being said, while writing the reply below, I realized it simply wasn't clear enough. I've updated the RFC to be more clear, in regards to the current behavior. > The fully qualified case is straight-forward: the autoloader is called, and if still not > defined, an error is thrown. But for the unqualified case, there are multiple scenarios, and you > only give the behaviour for one of them: > To fill in your chart: > Defined in current namespace? | Defined in global namespace? | Proposed behaviour > > ------------------------------+------------------------------+-------------------------------------- > No | No | Prefixed name > No | Yes | Prefixed name > Yes | No | No change > Yes | Yes | No change > > The third and fourth cases (where the function exists in the current namespace) are > straight-forward, although it wouldn't hurt to spell them out: presumably, the namespaced > function is used as now, so no autoloading is needed. > > The complex case has always been the second one: the function doesn't exist in the current > namespace, but *does* exist in the global namespace.. (Or, an autoloader *defines* it in the global > namespace.) > This should have the same behavior as in the class autoloader. In my attempt to be vague (in case the loading order is changed, which I assumed would affect class autoloading as well), I wasn't very clear on this. Meaning if you create a class called "Fiber" and a function called "strlen" in the current namespace, in unloaded files, an autoloader should be given the opportunity to load them. I should also probably define some vocabulary so this is all less confusing. and Done. > In concrete terms, what does this code output: > > spl_autoload_register( function($function, $type) { echo "$function..."; }, > type:SPL_AUTOLOAD_FUNCTION); > > namespace Foo { > foreach (['hello', 'goodbye'] as $word) { > echo strlen($word), ';'; > } > } > > a) "Foo\strlen...5;Foo\strlen...7;" (the autoloader is called every time the function > is encountered) > b) "Foo\strlen...5;7;" (the autoloader is called once, then somehow marked not to run > again for this name > c) "5;7;" (the autoloader is never run for this code) > I believe the "most correct" answer is (a) -- and is what the current class autoloader does as well. Option (b) would make it impossible to do any kind of dynamic code generation or old-fashioned file-based deployments. namespace global { spl_autoload_register(function ($function) { echo "$function..."; }); } namespace Foo { foreach (['hello', 'goodbye'] as $word) { if (!class_exists(Fiber::class)) { echo "Test..."; } } } Since I foresee (based on previous conversations) about people being worried about performance: I think this is best left to autoloader authors to manage. If there isn't a function autoloader, then there won't be any performance impact (or at least, minimal). However, if there is one, the author can take into account how their codebase works. For example, I highly suspect FIG will create a PSR for this (eventually), based on how they expect things to work. I suspect a project like WordPress could make use of it and implement things how they expect things to work, etc. For the case where you have a file full of unqualified strlen()'s, the autoloader author could create an option "do not shadow global functions" where it just returns immediately for built-in functions and doesn't even try autoloading (I also suspect there will be someone who code-golfs this to death so this check is extremely efficient). Is there a performance impact there? Probably not as big as you'd think -- and there already is a performance impact by using unqualified global functions (as shown in a recent proposal to change the order). So, if you are doing that already; you likely don't care about performance anyway. But I'm going to reserve any serious discussions about performance for when I have an actual implementation to play with (hopefully a PoC this weekend). > Note that there is an open RFC implementing option (b) by Gina and Dan here: > https://wiki.php.net/rfc/core-autoloading Last I heard, Gina was > still hoping to get back to it. > I went looking for this (I had sworn I had seen it last year), but unfortunately, I did not find it while searching the RFCs for prior work. I had thought it abandoned so I was looking in the wrong place. This RFC does not conflict with that RFC, if Gina/Dan were to pick it back up again.. I may borrow the function_exists() change, which I just updated the RFC to do. > On a different note, there is no mention of autoloading namespaced constants in this RFC, > unlike in some previous proposals. Is this a conscious decision to leave them out of scope, or an > oversight? > I'm leaving them out on purpose to keep the scope tight. I've got a whole year ahead of me. > > > Regards, > > -- > Rowan Tommins > [IMSoP] — Rob

« previous php.internals (#124963) next »