Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129237 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 lists.php.net (Postfix) with ESMTPS id 868091A00BC for ; Sat, 15 Nov 2025 20:30:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1763238614; bh=XP2KwwfgwU555cLMIGlVEt/HBc7DgNN1nqYaJtSxTMY=; h=Date:From:To:Cc:In-Reply-To:References:Subject:From; b=Nqhl8O2DYTdrVoW6GPispTW0S+ki0/uQhmt+xLEavX0vw2QQSx8ilkm1jnyrN7jQ2 fMe9ykmzK8BlEzlyjIBtplkHmgRuKnlS5eL30MZeFOgiLgxOYza/LRSbOmD9VCjaTk gNTN8OZ2QaO1WRfTTR5vIEt8pxzz2Y56JxxRQNOskLBmSpfOXkrEe3NyLIhPamqYSG lnIz7qWDCKgzESG0TtHWsYWbIr4ggHstPX6ntfpvg1ZNlFaS6qtEB4f+llKKSrhRII JWCsGd/jM53Oky4U2qRuQOQP1zTZ6UqToGJ2Zh4XW+x28/A7VVyZj+d7Qtt9Y1ee4W 8ifo5NlgwRmgA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2AE0B1801E1 for ; Sat, 15 Nov 2025 20:30:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) 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.1 X-Spam-Virus: No X-Envelope-From: Received: from fout-b1-smtp.messagingengine.com (fout-b1-smtp.messagingengine.com [202.12.124.144]) (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, 15 Nov 2025 20:30:13 +0000 (UTC) Received: from phl-compute-12.internal (phl-compute-12.internal [10.202.2.52]) by mailfout.stl.internal (Postfix) with ESMTP id 9E5C21D0016A; Sat, 15 Nov 2025 15:30:02 -0500 (EST) Received: from phl-imap-05 ([10.202.2.95]) by phl-compute-12.internal (MEProxy); Sat, 15 Nov 2025 15:30:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc: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=1763238602; x= 1763325002; bh=XP2KwwfgwU555cLMIGlVEt/HBc7DgNN1nqYaJtSxTMY=; b=S OrGzocuRiShlXrKjNaV5Fp0QSMCAtbe9PsK+unHLJtGydcQRC33kh03tljPQji95 vWtv4I6EMthM78Gwnya3jNsE46w+nrz83UZg98bGRUWzRmwnK8LxfEXWQheGEXnk vmiFkuuUzbJjmkVe+QGCoCWPKA08N1BZhgX3ru0ekvi6+J9htBZi8wXbkhvwTm5N wwylrHJzZTnU3ou0rDirCiq2RhDdMxkgNkXeERE44dXwK0BmsDNmF8fQWVuWYWYA FAWjd5+iNYeNB15yZ72TfjV//F4lYCk/i6bsIGtw98CzU//FdiNm3qh09fHN1ljm uTrVetDVhM4qitiW2BqDA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc: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=fm3; t= 1763238602; x=1763325002; bh=XP2KwwfgwU555cLMIGlVEt/HBc7DgNN1nqY aJtSxTMY=; b=paLDs/v/+iVp1Eb/aiwAlwu5Xdy/L+36CC7C0pLwqlqK8GDVK/C vvYtvUPIAk99Ac0F38d8+suyV3y/8cy4KSrgi4axOWTdpzPRZKdBcTfvzkVxbG0m Lf9qWM9Lt7QayV+hTf9Pa5ykz4gNSMLfhjO/l7NG49i8atrL1eRV5k6as/SKcID9 RytlrwhFxks5scrp6f7usOec+xRD2QIJ9d0GspK/ozL+HEN6MmMFnEHYTLHLDylO a83DhV/XH3TQwfUPk0SjGZd/wSjGfl3JJhgJ5Sdq4U67EO2SraSJPNxudttOJhCQ 2K0Nq+s6L50XebEdrtO6vIjDMpCbrj4Hw7g== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdeggddvudefieeiucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepofggfffhvfevkfgjfhfutgesrgdtreerredtjeenucfhrhhomhepfdftohgsucfn rghnuggvrhhsfdcuoehrohgssegsohhtthhlvggurdgtohguvghsqeenucggtffrrghtth gvrhhnpeeiueethedvvdefjefhgfeiheelheehtdfhfeekjefflefgvedvkeduteejjedt tdenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehroh gssegsohhtthhlvggurdgtohguvghspdhnsggprhgtphhtthhopeehpdhmohguvgepshhm thhpohhuthdprhgtphhtthhopehlrghrrhihsehgrghrfhhivghlughtvggthhdrtghomh dprhgtphhtthhopegvughmohhnugdrhhhtsehgmhgrihhlrdgtohhmpdhrtghpthhtohep ihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvthdprhgtphhtthhopegsuhhkkh grsehphhhprdhnvghtpdhrtghpthhtohepjhgsrghffhhorhguseiiohhrthdrnhgvth X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id CB0E61820054; Sat, 15 Nov 2025 15:30:01 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: A2k3WxiDp57Z Date: Sat, 15 Nov 2025 21:29:40 +0100 To: "Edmond Dantes" , "John Bafford" Cc: "php internals" , "Jakub Zelenka" , "Larry Garfield" Message-ID: In-Reply-To: References: <6618a91c-5393-4f40-88b5-b5041ee09deb@app.fastmail.com> <12D52EE4-62F4-42AC-A17D-A8F3A19D2433@zort.net> Subject: Re: [PHP-DEV] PHP True Async RFC Stage 5 Content-Type: multipart/alternative; boundary=6fe1390be4484fd5b26c6bd1741cdbb2 From: rob@bottled.codes ("Rob Landers") --6fe1390be4484fd5b26c6bd1741cdbb2 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sat, Nov 15, 2025, at 18:22, Edmond Dantes wrote: > > To provide an explicit example for this, code that fits this pattern= is going to be problematic >=20 > Why is this considered a problem if this behavior is part of the > language=E2=80=99s contract? > Exactly the same way as in Go for example, this is also part of the > contract between the language and the programmer. One of the stated goals of the RFC: *Code that was originally written and intended to run outside of a Corou= tine must work EXACTLY THE SAME inside a Coroutine without modifications= .* The examples you give here seem to contradict that. You are now saying t= hat developers *must* refactor shared state, must avoid passing objects = to multiple coroutines, and must adopt a certain programming style to av= oid breaking existing code. That=E2=80=99s the opposite of "works exactl= y the same without modification". > > $this->data can be changed out from under writeData(), which leads t= o unexpected behavior. >=20 > So the developer must intentionally create two different coroutines. > Intentionally pass them the same object. > Intentionally write this code. > And the behavior is called =E2=80=9Cunexpected=E2=80=9D? :) The original claim of the RFC is that code *not written with coroutines = in mind* should still behave the same inside them. If any function can s= uspend at arbitrary points, the ordinary synchronous assumptions, includ= ing read/modify/write patterns on properties, no longer hold. Whether th= at pattern is good style or not doesn=E2=80=99t change the fact that the= behaviour is different once asynchrony is introduced. > A developer must understand that potentially any function can > interrupt execution. This is a consequence of transparent asynchrony. This is also a direct tension with another major goal: *A PHP developer should not have to think about how Coroutine switch and= should not need to manage their switching=E2=80=94except in special cas= es where they consciously choose to intervene in this logic.* If any function can suspend, then developers MUST reason about all the u= sual concurrency hazards: torn writes, interleaving, race conditions, an= d the entire class of bugs that coloured function models prevent. That a= bsolutely counts as "thinking about coroutine switching". > It is both its strength and its weakness. I will repeat it again: not > some specific function, but almost ANY function. Because under > transparent asynchrony you can use suspend() inside any function. This > does not negate the fact that documentation should list all functions > that switch context, but a certain coding style encourages this way of > thinking. These statements also seem to go against another goal of the RFC: *A PHP developer should not have to think about how Coroutine switch and= should not need to manage their switching=E2=80=94except in special cas= es where they consciously choose to intervene in this logic.* > How did we refactor old code for coroutines? >=20 > 1. We took the modules that had global state. There were not many of t= hem. > 2. We used a Context, which is essential, and moved the global state > into the context. > [snip] > But why anyone would intentionally pass the same object to different > coroutines and then complain that the code broke. I have no idea who > would need that. :) Existing PHP codes does this today without issue. Many libraries, parser= s, database clients, stream decorators, in-memory caches, DTOs, middlewa= re chains ... are built around shared mutable objects. That style is ext= remely common in PHP, and today it=E2=80=99s perfectly fine to share the= se things. Saying "just refactor all your shared-state-code" seems to contradict th= e goals given in the RFC. > A developer should strive to minimize asynchronous code in a project. > The less of it there is, the better. Asynchronous code is evil. An > anti-pattern. A high-complexity zone. But if a developer chooses to > use asynchronous code, they shouldn=E2=80=99t act like they=E2=80=99re= three years old > and seeing a computer for the first time. Definitely not. This > technology requires steady, capable hands :) >=20 > Best Regards, Ed. Right now, today, PHP has almost zero async code in the ecosystem. If th= e position of the RFC is that transparent asynchrony is inherently dange= rous, requires careful discipline, breaks common patterns, and requires = refactoring shared state, then it isn=E2=80=99t clear how the central va= lue proposition "existing code works unchanged" is meant to hold. This is why the semantics need to be written down explicitly, not left t= o implication or the experience of those who already work with coroutine= s. =E2=80=94 Rob --6fe1390be4484fd5b26c6bd1741cdbb2 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable


On Sat, Nov 15, 2025, at 18:22, Edmond Dantes wrote:
> To provide = an explicit example for this, code that fits this pattern is going to be= problematic

Why is this considered a problem i= f this behavior is part of the
language=E2=80=99s contract?
Exactly the same way as in Go for example, this is also part of = the
contract between the language and the programmer.

One of the stated goals of the RFC:
<= div>
Code that was originally written and intended to r= un outside of a Coroutine must work EXACTLY THE SAME inside a Coroutine = without modifications.

The examples you= give here seem to contradict that. You are now saying that developers&n= bsp;must refactor shared state, must avoid passing objects to mul= tiple coroutines, and must adopt a certain programming style to avoid br= eaking existing code. That=E2=80=99s the opposite of "works exactly the = same without modification".

> $this->data can be changed out from = under writeData(), which leads to unexpected behavior.

So the developer must intentionally create two different corouti= nes.
Intentionally pass them the same object.
Intent= ionally write this code.
And the behavior is called =E2=80=9Cu= nexpected=E2=80=9D? :)

The origina= l claim of the RFC is that code not written with coroutines in m= ind should still behave the same inside them. If any function can su= spend at arbitrary points, the ordinary synchronous assumptions, includi= ng read/modify/write patterns on properties, no longer hold. Whether tha= t pattern is good style or not doesn=E2=80=99t change the fact that the = behaviour is different once asynchrony is introduced.

A developer must u= nderstand that potentially any function can
interrupt executio= n. This is a consequence of transparent asynchrony.

This is also a direct tension with another major goal:=

A PHP developer should not have to think ab= out how Coroutine switch and should not need to manage their switching=E2= =80=94except in special cases where they consciously choose to intervene= in this logic.

If any function can suspend= , then developers MUST reason about all the usual concurrency hazards: t= orn writes, interleaving, race conditions, and the entire class of bugs = that coloured function models prevent. That absolutely counts as "thinki= ng about coroutine switching".

It is both its strength and its weaknes= s. I will repeat it again: not
some specific function, but alm= ost ANY function. Because under
transparent asynchrony you can= use suspend() inside any function. This
does not negate the f= act that documentation should list all functions
that switch c= ontext, but a certain coding style encourages this way of
thin= king.

These statements also seem t= o go against another goal of the RFC:

A PHP = developer should not have to think about how Coroutine switch and should= not need to manage their switching=E2=80=94except in special cases wher= e they consciously choose to intervene in this logic.
=
How did we= refactor old code for coroutines?

1. We took t= he modules that had global state. There were not many of them.
2. We used a Context, which is essential, and moved the global state
into the context.
[snip]
But why anyone woul= d intentionally pass the same object to different
coroutines a= nd then complain that the code broke. I have no idea who
would= need that. :)

Existing PHP codes = does this today without issue. Many libraries, parsers, database clients= , stream decorators, in-memory caches, DTOs, middleware chains ... are b= uilt around shared mutable objects. That style is extremely common in PH= P, and today it=E2=80=99s perfectly fine to share these things.

Saying "just refactor all your shared-state-code" seems= to contradict the goals given in the RFC.

A developer should strive= to minimize asynchronous code in a project.
The less of it th= ere is, the better. Asynchronous code is evil. An
anti-pattern= . A high-complexity zone. But if a developer chooses to
use as= ynchronous code, they shouldn=E2=80=99t act like they=E2=80=99re three y= ears old
and seeing a computer for the first time. Definitely = not. This
technology requires steady, capable hands :)

Best Regards, Ed.

Right now, today, PHP has almost zero async code in the ecosystem. If = the position of the RFC is that transparent asynchrony is inherently dan= gerous, requires careful discipline, breaks common patterns, and require= s refactoring shared state, then it isn=E2=80=99t clear how the central = value proposition "existing code works unchanged" is meant to hold.

This is why the semantics need to be written down e= xplicitly, not left to implication or the experience of those who alread= y work with coroutines.

=E2= =80=94 Rob
--6fe1390be4484fd5b26c6bd1741cdbb2--