Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126631 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 B18901A00BC for ; Sat, 8 Mar 2025 07:39:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1741419392; bh=U98frfA+bOZz77i6uFhZSf86E28a5Ei9G6/mvzBA9gs=; h=Date:From:To:In-Reply-To:References:Subject:From; b=dh0CuEFA66b6vnQrrePytEzcCEAYCcu9iJwrKO6X+F24QCBxqvyWLOwL8sC+0Ze0H M1hsZh4UWKqtfaRnJn+ZOcKT8+h/QWnIiYmr3+2Ngp+ZnULwrVf/TYde4xRpomo2t3 fKUcTNhAMJH34rv6ABzy7Y/96KsGQls9aVZ/k8GfuSkE+MxQd/Pg/LOsLuQ6Od55ny eB+7ITtePXHLvcaebcVZwRqOLcdo8iInvtIoOQHjjWhvb5BuaAqBRk3SNvqn5vtHR0 9fPArEv3p14FDpOwPWt54jvfedF5Zf1MiOUse9lY2+SJHaP2orZ0h3WZpJ4l1GKQXx G8dNMkeRO0vvg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2712B180034 for ; Sat, 8 Mar 2025 07:36:31 +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=-2.8 required=5.0 tests=BAYES_00,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 fout-b5-smtp.messagingengine.com (fout-b5-smtp.messagingengine.com [202.12.124.148]) (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 ; Sat, 8 Mar 2025 07:36:30 +0000 (UTC) Received: from phl-compute-11.internal (phl-compute-11.phl.internal [10.202.2.51]) by mailfout.stl.internal (Postfix) with ESMTP id 506541140089 for ; Sat, 8 Mar 2025 02:39:05 -0500 (EST) Received: from phl-imap-09 ([10.202.2.99]) by phl-compute-11.internal (MEProxy); Sat, 08 Mar 2025 02:39:05 -0500 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=fm2; t=1741419545; x=1741505945; bh=7/UDirV9me UKijsmcSS1WJmF2qMc+gxaCNn4Md521uU=; b=CUc8TEPvJZFyPIRn0FDE1PWBzz HzhpLHBb/S05RH3Wm5/qHvbdV07fR/kM8k6MLSMaHxtjg8TeS3J2JIXfamii63Rc bdzo2z52ejCow7fHXHn9LEThzrb8YRSlYfH9A3IOw4wgal/fChX9RHao+p8NoaHf 4q0062EoshJ9gU82RZBWpOy5M75InFH3xcKMxOGP/CxP4ausjxmq7vMCsOhwLBGC fzS/bo/Y2Cp2u/R5NarYtN2wBWHdqW6n2GBLYnKpxfN7/N+QXe/2Z3GBPBl8Q0lW jfAyi20ALnFmH+cyLysj3NQ088pt/g5Zcl2ch7xD0zWyCqCe09BsqP4LPkqQ== 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-sender:x-me-sender:x-sasl-enc; s=fm1; t= 1741419545; x=1741505945; bh=7/UDirV9meUKijsmcSS1WJmF2qMc+gxaCNn 4Md521uU=; b=c7W+UakNtDuz8WY6vEr2zdFtKTGhxlScjGul3mFVkGigSfKEtNH DWEWs4507vB54qq7wUrjVJpMP4EZo9ITJ1FqcUbn5ea+RqC1CclfMnVOZgGVZQoR lHy1vzCzvGJFJtSRMHKq+HbNHoOunJ4svYv5g8/mdTjsCvXRB6JtRJd/ZkmIFZSA S+K6/umm8IRnMMHZU4iqBJaDvDyFmnB1UCBTfi98OO9YreXcvNIJmL4xyXm8eYf4 jH6breqwmVIPxtbDhB+ldhC1i4mFHvqXSpGcn4rTRNuhlw6/EztJhj847FEHz3v+ AWZfk+UF9+JXn6e6Y1spCW51EcZWR++5lAw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdduuddvleekucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggv pdfurfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucenucfjughrpefogg ffhffvkfgjfhfutgesrgdtreerredtjeenucfhrhhomhepfdftohgsucfnrghnuggvrhhs fdcuoehrohgssegsohhtthhlvggurdgtohguvghsqeenucggtffrrghtthgvrhhnpedtue ejtdethfeulefhtdelieduteelffdtudelheffgedtieehhfelieejgfevgeenucevlhhu shhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehrohgssegsohhtth hlvggurdgtohguvghspdhnsggprhgtphhtthhopedupdhmohguvgepshhmthhpohhuthdp rhgtphhtthhopehinhhtvghrnhgrlhhssehlihhsthhsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id BFD4A780068; Sat, 8 Mar 2025 02:39:04 -0500 (EST) 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: Sat, 08 Mar 2025 08:38:44 +0100 To: internals@lists.php.net Message-ID: In-Reply-To: References: <9964db8c-0ffe-43d5-8246-47fc76b07180@app.fastmail.com> <78a03dd0-fd4a-4f4a-ad8a-37e5704f06fc@app.fastmail.com> <08c8ad0b-e8f4-46e3-99f0-b80748d40b89@app.fastmail.com> <07973EAE-2D83-47A8-8FA0-84286C77C02B@rwec.co.uk> <48d66433-3ae9-4895-8361-7c81a0a3670d@app.fastmail.com> Subject: Re: [PHP-DEV] PHP True Async RFC Content-Type: multipart/alternative; boundary=67b9960310a2415289787b3f6c8cf949 From: rob@bottled.codes ("Rob Landers") --67b9960310a2415289787b3f6c8cf949 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sat, Mar 8, 2025, at 00:21, Rowan Tommins [IMSoP] wrote: > On 07/03/2025 22:01, Larry Garfield wrote: > > Is that what you're suggesting? If so, I'd have to think it through= a bit more to see what guarantees that does[n't] provide. It might wor= k. (I deliberately used spawn instead of "await" to avoid the mental as= sociation with JS async/await.) My biggest issue is that this is starti= ng to feel like colored functions, even if partially transparent. >=20 >=20 > Yes, that's pretty much what was in my head. I freely admit I haven't=20 > thought through the implications either. >=20 >=20 > > My biggest issue is that this is starting to feel like colored funct= ions, even if partially transparent. >=20 >=20 > I think it's significantly *less* like coloured functions than passing=20 > around a nursery object. You could almost take this: >=20 > async function foo($bar int, $baz string) { > spawn something_else(); > } > spawn foo(42, 'hello'); >=20 > As sugar for this: >=20 > function foo($bar int, $baz string, AsyncNursery $__nursery) { > $__nursery->spawn( something_else(...) ); > } > $__nursery->spawn( fn($n) =3D> foo(42, 'hello', $n) ); >=20 > However you spell it, you've had to change the function's *signature* = in=20 > order to use async facilities in its *body*. >=20 >=20 > If the body can say "get current nursery", it can be called even if it= s=20 > *immediate* caller has no knowledge of async code, as long as we have=20 > some reasonable definition of "current". >=20 >=20 > --=20 > Rowan Tommins > [IMSoP] >=20 The uncoloring of functions in PHP is probably one of the most annoying = aspects of fibers, IMHO. It's hard to explain unless you've been using t= hem awhile. But, with colored functions, the caller has control over whe= n the result is waiting on -- it could be now, it could be in a totally = different part of the program, or not at all. With fibers, the author of= the function you are calling has control over when the result is waited= on (and they don't have control over anything they call). This can crea= te unpredictable issues when writing code where a specific part wrote so= me code thinking it had exclusive access to a property/variable. However= , someone else changed one of the functions being called into an async f= unction, making that assumption no longer true. With colored functions, the person making changes also has to update all= the places where it is called and can validate any assumptions are stil= l going to be true; uncolored functions means they almost never do this.= This results in more work for people implementing async, but more corre= ct programs overall. But back to the awaiting on results. Say I want to read 10 files: for ($i =3D 0; $i < 10; $i++) $results[] =3D file_get_contents($file[$i]= ); Right now, we have to read each file, one at a time, because this is syn= chronous. Even with this RFC and being in a fiber, the overall execution= might be non-blocking, but the code still reads one file after another = sequentially. Fibers do not change this. With this RFC (in its original form), we will be able to change it so th= at we can run it asynchronously though and choose when to wait: for($i =3D 0; $i < 10; $i++) $results[] =3D async\async(fn($f) =3D> file= _get_contents($f), $file[$i]); // convert $results into futures somehow -- though actually doesn't look= like it is possible. $results =3D async\awaitAll($results); In that example, we are deliberately starting to read all 10 files at th= e same time. If we had colored functions (aka, async/await) then changin= g file_get_contents to async would mean you have to change everywhere it= is called too. That means I would see that file_get_contents is synchro= nous and be able to optimize it without having to even understand the re= asoning (in most cases). I was a user of C# when this happened to C#, an= d it was a pain... So, at least with PHP fibers, this won't be AS painfu= l, but you still have to do some work to take full advantage of them. I kind of like the idea of a nursery for async, as we could then update = file_get_content's return type to something like string|false|future. In non-async, you have everything behave as normal, but insi= de a nursery, it returns a future that can be awaited however you want a= nd is fully non-blocking. In other words, simply returning a future is e= nough for the engine to realize it should spawn a fiber (similar to how = using yield works with generators).=20 In any case, I believe that a nursery requires the use of colored functi= ons. That may be good or bad, but IMHO makes it much more useful and eas= ier to write correct and fast code. =E2=80=94 Rob --67b9960310a2415289787b3f6c8cf949 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable

=
On Sat, Mar 8, 2025, at 00:21, Rowan Tommins [IMSoP] wrot= e:
On 07/03= /2025 22:01, Larry Garfield wrote:
> Is that what you'r= e suggesting?  If so, I'd have to think it through a bit more to se= e what guarantees that does[n't] provide.  It might work.  (I = deliberately used spawn instead of "await" to avoid the mental associati= on with JS async/await.)  My biggest issue is that this is starting= to feel like colored functions, even if partially transparent.


Yes, that's pretty much what was in = my head. I freely admit I haven't 
thought through th= e implications either.


> = My biggest issue is that this is starting to feel like colored functions= , even if partially transparent.


=
I think it's significantly *less* like coloured functions than pass= ing 
around a nursery object. You could almost take t= his:

async function foo($bar int, $baz stri= ng) {
    spawn something_else();
=
}
spawn foo(42, 'hello');

As sugar for this:

function foo($bar int,= $baz string, AsyncNursery $__nursery) {
   = ; $__nursery->spawn( something_else(...) );
}
=
$__nursery->spawn( fn($n) =3D> foo(42, 'hello', $n) );

However you spell it, you've had to change the fu= nction's *signature* in 
order to use async facilitie= s in its *body*.


If the body= can say "get current nursery", it can be called even if its 
*immediate* caller has no knowledge of async code, as long as w= e have 
some reasonable definition of "current".
<= /div>


-- 
Rowan Tom= mins
[IMSoP]

The uncoloring of functions in PHP is probably one of the mo= st annoying aspects of fibers, IMHO. It's hard to explain unless you've = been using them awhile. But, with colored functions, the caller has cont= rol over when the result is waiting on -- it could be now, it could be i= n a totally different part of the program, or not at all. With fibers, t= he author of the function you are calling has control over when the resu= lt is waited on (and they don't have control over anything they call). T= his can create unpredictable issues when writing code where a specific p= art wrote some code thinking it had exclusive access to a property/varia= ble. However, someone else changed one of the functions being called int= o an async function, making that assumption no longer true.

With colored functions, the person making changes also = has to update all the places where it is called and can validate any ass= umptions are still going to be true; uncolored functions means they almo= st never do this. This results in more work for people implementing asyn= c, but more correct programs overall.

But b= ack to the awaiting on results. Say I want to read 10 files:

for ($i =3D 0; $i < 10; $i++) $results[] =3D file_g= et_contents($file[$i]);

Right now, we have = to read each file, one at a time, because this is synchronous. Even with= this RFC and being in a fiber, the overall execution might be non-block= ing, but the code still reads one file after another sequentially. Fiber= s do not change this.

With this RFC (in its= original form), we will be able to change it so that we can run it asyn= chronously though and choose when to wait:

= for($i =3D 0; $i < 10; $i++) $results[] =3D async\async(fn($f) =3D>= ; file_get_contents($f), $file[$i]);
// convert $results i= nto futures somehow -- though actually doesn't look like it is possible.=
$results =3D async\awaitAll($results);

=
In that example, we are deliberately starting to read all 10 = files at the same time. If we had colored functions (aka, async/await) t= hen changing file_get_contents to async would mean you have to change ev= erywhere it is called too. That means I would see that file_get_contents= is synchronous and be able to optimize it without having to even unders= tand the reasoning (in most cases). I was a user of C# when this happene= d to C#, and it was a pain... So, at least with PHP fibers, this won't b= e AS painful, but you still have to do some work to take full advantage = of them.

I kind of like the idea of a nurse= ry for async, as we could then update file_get_content's return type to = something like string|false|future<string|false>. In non-async, yo= u have everything behave as normal, but inside a nursery, it returns a f= uture that can be awaited however you want and is fully non-blocking. In= other words, simply returning a future is enough for the engine to real= ize it should spawn a fiber (similar to how using yield works with gener= ators). 

In any case, I believe that a= nursery requires the use of colored functions. That may be good or bad,= but IMHO makes it much more useful and easier to write correct and fast= code.

=E2=80=94 Rob
--67b9960310a2415289787b3f6c8cf949--