Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:124963 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id C341B1A00B7 for ; Thu, 15 Aug 2024 22:43:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1723761898; bh=70Qh2YsubwrFkzl4Lu+6REyR+cPNaIwuXAapoxTgbaA=; h=Date:From:To:In-Reply-To:References:Subject:From; b=OcuzKiN9nLC+jLyzOAbJqjq94xEJSaoRL4dQg5cQiEZvuJPWvyjz/HIrPI9a6roJa ox6G5ep4krt7JlsbF3BZKDrXGdt1urs1b68S8xEnkuyf0FqjSOclJRm6CGizONsbQ1 QeG7lNU3bTkMmNSRuDjdnbIG4/pKY81H0kK/9F3w06hdc7/BmXeFSCZV9AW46/+/H5 NoIB/Jaff7apqaLVdggZSKNjwkr4hxf6qYfRhdC4OIftHLSPTz4yJLvZzF25eQnerE ztd3Ba4OMtfcqgkDI/fQh8I1LP8jPllpaxfxh8tf/xLw3MYGy4JIdWcO8jmizXrqsl S3nFFl9C6aKgw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 12992180077 for ; Thu, 15 Aug 2024 22:44:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from fout8-smtp.messagingengine.com (fout8-smtp.messagingengine.com [103.168.172.151]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 15 Aug 2024 22:44:56 +0000 (UTC) Received: from phl-compute-03.internal (phl-compute-03.nyi.internal [10.202.2.43]) by mailfout.nyi.internal (Postfix) with ESMTP id 85FA9138CED9 for ; Thu, 15 Aug 2024 18:43:09 -0400 (EDT) Received: from phl-imap-09 ([10.202.2.99]) by phl-compute-03.internal (MEProxy); Thu, 15 Aug 2024 18:43:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc:content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1723761789; x=1723848189; bh=QZfgxshhLq ETMBB6RHcbsjlrDlUpWdM/YpQ5vQbW0wA=; b=jYXwD9Zzni3ZoxPxDmpQQsvWCD hSDFKp53JvgFvjKVKno7qIA18jL+FKFo606Q+UZczKl+EFq45oTdj9VHUR0P3D4O 0SK4iuNqOP6XzhIikmmR0QH6eazGsqIduLTLP939DAQ6OJePoHNl2sfvYVr10mvK KuFHy7fmKcBXt5OTDtbk7qrWcgf5ax+g0Nc6W/0VV37V/dYgsAOcU80BsrNjrMEV acJdsk3SzILaGAdi9Xjgv+nrYdodd/lDn3nvsxsQMdObXitJHWEIvBprEYDDAWd0 gVhphvxsZw6bSaJ0VpxHe1N/250xpDfClg3aDLoyZA1A7ibmVOVq/uJrURdA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; t=1723761789; x=1723848189; bh=QZfgxshhLqETMBB6RHcbsjlrDlUp WdM/YpQ5vQbW0wA=; b=AAV9N61Db8FZC8BgmNStyC8pAca//+cX+UUr4EsGVa+I zsX/malrkGhENbPRLWkX91lVyCwXVDNYWbjBBaykOwOVPSg+aSAAjGo394am56Q6 0o+Am1ZkUiTouVjSl+z4fi3oNmZjz7FGBTCmrBddGHrcf6TQjnTPKYfBKgIaY1V1 uczZJKfFI9o7WX2IOSLFgXIovr2RnN4O66eIxMyNl0lgsnC5KL6KQzdiLw3V66qV x0Q5UYsLHUf46GBVA/i+OxZTgOlRyw/CCnM+MJneFT1FNv/iqA04bznWKNJ0Sqrp Wp2t8Q5BkXzT8K/YDJR1DL9oDw2OFXeaP/dsdD6YdA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeftddruddtjedgudegucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucenucfjughrpefoggffhf fvkfgjfhfutgesrgdtreerredtjeenucfhrhhomhepfdftohgsucfnrghnuggvrhhsfdcu oehrohgssegsohhtthhlvggurdgtohguvghsqeenucggtffrrghtthgvrhhnpeelkeehtd fgfefhleeilefggeeihfekvdelfeejtdfflefhheehfffgudetuddutdenucffohhmrghi nhepphhhphdrnhgvthenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrih hlfhhrohhmpehrohgssegsohhtthhlvggurdgtohguvghspdhnsggprhgtphhtthhopedu pdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehinhhtvghrnhgrlhhssehlihhsth hsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id 377DD15A005E; Thu, 15 Aug 2024 18:43:09 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Fri, 16 Aug 2024 00:41:52 +0200 To: internals@lists.php.net Message-ID: In-Reply-To: References: <2716f729-4008-4f75-8412-861d8960b746@app.fastmail.com> Subject: Re: [PHP-DEV] function autoloading v4 RFC Content-Type: multipart/alternative; boundary=e5ba7ea668a14097932f7f61f69d9e2d From: rob@bottled.codes ("Rob Landers") --e5ba7ea668a14097932f7f61f69d9e2d Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Thu, Aug 15, 2024, at 20:40, Rowan Tommins [IMSoP] wrote: > On 15/08/2024 16:22, Rob Landers wrote: >> Hello internals, >>=20 >> I've decided to attempt an RFC for function autoloading. After readin= g hundreds of ancient (and recent) emails relating to the topic along wi= th several abandoned RFCs from the past, and after much review, I've dec= ided to put forth a variation of a previous RFC, as it seemed the least = ambitious and the most likely to work: >>=20 >> https://wiki.php.net/rfc/function_autoloading4 >=20 >=20 > Hi Rob, >=20 > While brevity can sometimes be a virtue, I feel like there's a lot lef= t to the reader's interpretation here. >=20 > Specifically, one of the main issues that has come up in previous disc= ussions of the topic is the behaviour of unqualified function names, whi= ch check the current namespace first, then fall back to global scope. Yo= ur RFC implies an approach to this, but doesn't actually spell it out, n= or discuss its pros and cons. >=20 It doesn't go too much into details here on purpose, especially since th= ere was some recent discussion on changing the order. That being said, w= hile 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 behavio= r. > 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: >=20 To fill in your chart: > Defined in current namespace? | Defined in global namespace? | Propose= d behaviour > ------------------------------+------------------------------+--------= ------------------------------ > No | No | Prefixe= d name > No | Yes | Prefixe= d name > Yes | No | No chan= ge > Yes | Yes | No chan= ge >=20 > The third and fourth cases (where the function exists in the current n= amespace) are straight-forward, although it wouldn't hurt to spell them = out: presumably, the namespaced function is used as now, so no autoloadi= ng is needed. >=20 > 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.) >=20 This should have the same behavior as in the class autoloader. In my att= empt 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. Me= aning if you create a class called "Fiber" and a function called "strlen= " in the current namespace, in unloaded files, an autoloader should be g= iven the opportunity to load them. I should also probably define some vocabulary so this is all less confus= ing. and Done. > In concrete terms, what does this code output: >=20 > spl_autoload_register( function($function, $type) { echo "$function...= "; }, type:SPL_AUTOLOAD_FUNCTION); >=20 > namespace Foo { > foreach (['hello', 'goodbye'] as $word) { > echo strlen($word), ';'; > } > } >=20 > a) "Foo\strlen...5;Foo\strlen...7;" (the autoloader is called every ti= me the function is encountered) > b) "Foo\strlen...5;7;" (the autoloader is called once, then somehow ma= rked not to run again for this name > c) "5;7;" (the autoloader is never run for this code) >=20 I believe the "most correct" answer is (a) -- and is what the current cl= ass autoloader does as well. Option (b) would make it impossible to do a= ny kind of dynamic code generation or old-fashioned file-based deploymen= ts. 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 wor= ried 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 a= ccount how their codebase works. For example, I highly suspect FIG will = create a PSR for this (eventually), based on how they expect things to w= ork. I suspect a project like WordPress could make use of it and impleme= nt 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 function= s" where it just returns immediately for built-in functions and doesn't = even try autoloading (I also suspect there will be someone who code-golf= s this to death so this check is extremely efficient). Is there a perfor= mance impact there? Probably not as big as you'd think -- and there alre= ady is a performance impact by using unqualified global functions (as sh= own 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 w= hen I have an actual implementation to play with (hopefully a PoC this w= eekend). > 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. >=20 I went looking for this (I had sworn I had seen it last year), but unfor= tunately, I did not find it while searching the RFCs for prior work. I h= ad thought it abandoned so I was looking in the wrong place. This RFC do= es 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 con= stants in this RFC, unlike in some previous proposals. Is this a conscio= us decision to leave them out of scope, or an oversight? >=20 I'm leaving them out on purpose to keep the scope tight. I've got a whol= e year ahead of me. >=20 >=20 > Regards, >=20 > --=20 > Rowan Tommins > [IMSoP] =E2=80=94 Rob --e5ba7ea668a14097932f7f61f69d9e2d Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
On Thu, Aug 15, 2024, at 20:40, Rowan Tommins= [IMSoP] wrote:
=
On 15/08/2024=0A 16:22, Rob Landers wrote:=
Hello internals,

I've decided to attempt an RFC f= or=0A function autoloading. After reading hundreds of ancient (= and=0A recent) emails relating to the topic along with several=0A= abandoned RFCs from the past, and after much review, I've=0A = decided to put forth a variation of a previous RFC, as it=0A = seemed the least ambitious and the most likely to work:
=
=


Hi Rob,

While brevity can sometimes be a virtue, I=0A = feel like there's a lot left to the reader's interpretation=0A he= re.

Specifically, one of the main issues that=0A has come up in pr= evious discussions of the topic is the=0A behaviour of unqualifie= d function names, which check the current=0A namespace first, the= n fall back to global scope. Your RFC=0A implies an approach to t= his, but doesn't actually spell it out,=0A nor discuss its pros a= nd cons.


It doesn't go to= o much into details here on purpose, especially since there was some rec= ent 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=0A= straight-forward: the autoloader is called, and if still not=0A = defined, an error is thrown. But for the unqualified case, there=0A= are multiple scenarios, and you only give the behaviour for one=0A= of them:


To fill = in your chart:

D= efined in current namespace? | Defined in=0A global namespace? | = Proposed behaviour
------------------------------+------------------= ------------+--------------------------------------
No  &n= bsp;           &n= bsp;           &n= bsp; | No          &nb= sp;           &nb= sp;    |=0A Prefixed name
No   =             =             = | Yes           =             =    | Prefixed name
Yes        &nbs= p;           &nbs= p;      | No=0A     =             =           | No change
<= /span>Yes  &n= bsp;           &n= bsp;            |= =0A Yes         &nbs= p;           &nbs= p;    | No change

The third and fourth cases (where the=0A = function exists in the current namespace) are straight-forward,=0A = although it wouldn't hurt to spell them out: presumably, the=0A = namespaced function is used as now, so no autoloading is needed.

The= complex case has always been the=0A second one: the function doe= sn't exist in the current namespace,=0A but *does* exist in the g= lobal namespace. (Or, an autoloader=0A *defines* it in the global= namespace.)


This should = have the same behavior as in the class autoloader. In my attempt to be v= ague (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 cur= rent namespace, in unloaded files, an autoloader should be given the opp= ortunity to load them.

I should also probab= ly define some vocabulary so this is all less confusing. and Done.


In con= crete terms, what does this code=0A output:

spl_autoload_register(= function($function,=0A $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=0A = autoloader is called every time the function is encountered)
b) "Foo= \strlen...5;7;" (the autoloader is called once, then=0A somehow m= arked not to run again for this name
c) "5;7;" (the autoloader is ne= ver run for this code)


I beli= eve the "most correct" answer is (a) -- and is what the current class au= toloader does as well. Option (b) would make it impossible to do any kin= d of dynamic code generation or old-fashioned file-based deployments.


namespace global {
spl_autoload_register(function ($function) {
echo "$function...";
});
}
<= span style=3D"color:rgb(232, 186, 54);">
namespace Foo {

foreach (['hello', 'goodbye'] as $word) {
= if (!class_exists= (Fiber::class)
) {
echo "Test...";
}
= }
}

=
Since I foresee (based on previous conversations) about people bein= g worried about performance:

I think this i= s best left to autoloader authors to manage. If there isn't a function a= utoloader, then there won't be any performance impact (or at least, mini= mal). However, if there is one, the author can take into account how the= ir codebase works. For example, I highly suspect FIG will create a PSR f= or 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 ca= se where you have a file full of unqualified `strlen()`'s, the autoloade= r author could create an option "do not shadow global functions" where i= t just returns immediately for built-in functions and doesn't even try a= utoloading (I also suspect there will be someone who code-golfs this to = death so this check is extremely efficient). Is there a performance impa= ct there? Probably not as big as you'd think -- and there already is a p= erformance impact by using unqualified global functions (as shown in a r= ecent 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 t= his weekend).

Note t= hat there is an open RFC=0A implementing option (b) by Gina and D= an here: https://wiki.php.net/rfc/core-autoloading = Last I heard, Gina was=0A still hoping to get back to it.<= br>


I went looking for this (I had s= worn I had seen it last year), but unfortunately, I did not find it whil= e 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, i= f Gina/Dan were to pick it back up again. I may borrow the `function_exi= sts()` change, which I just updated the RFC to do.

<= blockquote type=3D"cite" id=3D"qt" style=3D"">

On a different note, there is no mention=0A= of autoloading namespaced constants in this RFC, unlike in some=0A= previous proposals. Is this a conscious decision to leave them=0A= out of scope, or an oversight?

<= br>
I'm leaving them out on purpose to keep the scope tight. I= 've got a whole year ahead of me.


Regards,

--=20=0ARowan Tommins=0A[IMSoP]
=
=E2=80=94 Rob
--e5ba7ea668a14097932f7f61f69d9e2d--