Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129621 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 2259A1A00BC for ; Tue, 16 Dec 2025 15:59:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1765900774; bh=VINmN6iBjSHn9qR1YWZYqKt4RfRf5tiSD/bUpZH6VFc=; h=Date:From:To:In-Reply-To:References:Subject:From; b=MK0x6QQIxGkhxjismZHB6T+ZIdg357OXDILTxPZVKpnphp7gkdo6ICpqDAp8avhAg T4HLjfqQpeZBAvTXA6lkC98XkHcbXbmJoYUPC8r2b2Zf8jkIcxka1XbOmN0Um8tLF9 qPlZrOFoTcpvad0tO9BgeDL0HJ1dbkjHfChcqzxVAFQ8tBTNOj22+0IgHRaT9dqIkb jyAE+veiO5NCniaU4882fhepi9TiJH+J3LnjBU24Stx84pTg8Q9meD5m9FLF6xttTy CVFdBMCsVgCH9rPKh/7TL52kXdA7Fv1yLMeAC+QOUwC4bvK6OZSefseUSSQetvVYsz 4GIIN5l2O1Iag== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 8A3211801EC for ; Tue, 16 Dec 2025 15:59:33 +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,RCVD_IN_DNSWL_LOW, SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from fhigh-b7-smtp.messagingengine.com (fhigh-b7-smtp.messagingengine.com [202.12.124.158]) (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 ; Tue, 16 Dec 2025 15:59:33 +0000 (UTC) Received: from phl-compute-04.internal (phl-compute-04.internal [10.202.2.44]) by mailfhigh.stl.internal (Postfix) with ESMTP id 9CC7E7A0079 for ; Tue, 16 Dec 2025 10:59:27 -0500 (EST) Received: from phl-imap-01 ([10.202.2.91]) by phl-compute-04.internal (MEProxy); Tue, 16 Dec 2025 10:59:27 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-transfer-encoding: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=1765900767; x=1765987167; bh=C4Mu2pIZgtK/JaU/MeQxG 3cV6ozORarBD6g4iduU02E=; b=TYBxEWzpc3yJrifZ84PHS1GkvLup4nEawdMJP /dUmxLYABFRGc6cnxSxEv8Y0AiFFdBzma85JGePGWi+vkJ8lCAbl1kTdAr9HCaxz xyytqVd+vEwYLp004HjcLi1elK8/eD7l+DkPimUpr7kgcfqANdV3ndC/jntnEuZF 6YAS2bIiJW0IdnMqkEOwE/Ujoh+To17Y4O5UYCbj55/2mqkQDrGjbhlfMF2BHlAv hy7I4efVXV1U4PXBhRkOwEraDsoj7r162Jn1yk8G56m+YqwMo+4Yo44n3VB6qCS1 jCZTnc+dK6fS868yZRx4Zgi2k207AlH0vo4sZry6ABpy1Zyrw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding: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=1765900767; x=1765987167; bh=C 4Mu2pIZgtK/JaU/MeQxG3cV6ozORarBD6g4iduU02E=; b=GCExcYLqVLSBm//xW UgI3RAWWmLTT3LOB4wGrhgDHA+uHNQ2KwoXC07iyW4ne8oaDf0YNg7/c+nFTIpn4 HD2LM+Cz9oFMZD/p72waxcSrEN7IE+f0AvcY6fP9m+3PpcEaD03lEE4AyU5dS0Zn Vkp/HQ12e7fRMauo7bfsoUS44eARAFE/z3fIF+PCTVEBO4XIrxYDJar4OnNKMhZZ zSFp99sOOfMR8f1nYQ3Sn9sg6ZPSN44tl8eK/f7D+HLAwnfq1vpvZBnx3ocSJkNU 1vXFiGen96xAf6lPUfvOrAQN3RvKNqB6rUGhaf1wonAuVz4ljUr9bYSzyIcg2+jV tK4aQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgdegtddutdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjug hrpefoggffhffvkfgjfhfutgfgsehtqhertdertdejnecuhfhrohhmpedfnfgrrhhrhicu ifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtghomheqne cuggftrfgrthhtvghrnhepffeiiedvhfdvgedutddtgeetieeugeevhfetheeffeeftedu iedthedtgeejueeinecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilh hfrhhomheplhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhmpdhnsggprhgtphht thhopedupdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehinhhtvghrnhgrlhhsse hlihhsthhsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 3E82418C004E; Tue, 16 Dec 2025 10:59:27 -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: ALvh3TDXSVwZ Date: Tue, 16 Dec 2025 09:59:06 -0600 To: "php internals" Message-ID: In-Reply-To: References: <70A79513-5503-467E-BC6F-2B0494A3EBB9@benramsey.com> Subject: Re: [PHP-DEV] [RFC] Context Managers Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable From: larry@garfieldtech.com ("Larry Garfield") On Tue, Dec 16, 2025, at 5:25 AM, Deleu wrote: > On Tue, Dec 16, 2025 at 5:10=E2=80=AFAM Rowan Tommins [IMSoP]=20 > wrote: >> (Replying to a few of you in one go, I hope the formatting is clear)=20 >>=20 >> >>> we have changed the RFC to use =3D> instead. So the new syntax is >> >>> >> >>> using (new CM() =3D> $cVar) { >> >>> // Do stuff here. >> >>> } >> >>> >> >> >> >> Going to be controversial here, but this is confusing, because it = operates >> >> in the exact opposite of every other usage of =3D> we have.=20 >> > >> > I agree with Matthew. >> > >> > I think it makes more sense to reverse them, like this: >> > >> > using ($cVar =3D> new CM()) { >> > // Do stuff here. >> > } >>=20 >>=20 >> It took me a long time to figure out what you were both saying here, = because to me the direction of the arrow seems to consistently indicate = data flow: you call the function, and data comes out; you enter the cont= ext, and a variable comes out. >>=20 >> But I think I see it now: you're treating the context variable like a= n array key, that is somehow "bound to" the result. Except that's not wh= at's happening, otherwise we could just use "=3D". >>=20 >>=20 >> >I also agree with Matthew but the reversed proposed here looks very = very >> >awkward to me. I think the most natural thing is the =E2=80=9Cas=E2=80= =9D but I may have >> >missed the discussion on why it had to be changed. >> > >> >Thinking of foreach ($array as $value), an item from the array (left= ) is >> >assigned to $value (right). >>=20 >>=20 >> This is the way to read the "as" syntax, yes; as I've said in a few p= laces, a Context Manager is like an iterator that goes around once. >>=20 >>=20 >> > That seems symmetrical to using (new Manager as >> >$manager) where the instance (left) is assigned to the variable (rig= ht). >>=20 >>=20 >> This, however, is why it was changed: that is *not* what is happening= . The Context Manager is not assigned to the variable, it *produces a va= lue* which is assigned to the variable.=20 >>=20 >> Again, look at the foreach equivalence: you wouldn't write "foreach(n= ew MyIterator as $iterator)", because it's not the iterator that ends up= in the variable, it's the *items produced by* the iterator.=20 >>=20 >> So you have "foreach(new MyIterator as $item)" and "using(new MyConte= xtManager as $contextVar)".=20 >>=20 >> But evidently that is not obvious to readers. > > My conclusion here is exactly the opposite of yours because this=20 > explanation makes `as` even more symmetrical now. As you've mentioned=20 > `foreach(new MyIterator as $iterator)` is not how it works. An iterato= r=20 > *produces a value* that is assigned to the variable after `as`.=20 > Symmetrically, `using(new ContextManager as $context)` the=20 > ContextManager is also producing a value that is assigned to the=20 > variable after `as`. The only difference is in the keyword: foreach=20 > will loop, but using will not loop since ContextManager is not an=20 > iterator. > > I'm assuming this would also be a valid syntax: `using ($manager =3D n= ew=20 > ContextManager as $context)` which gives us a shot at capturing the=20 > context manager. > > I wrote a little snippet to try and see (using GitHub Gist Syntax=20 > Highlighter) how some of the options would look like once IDE support = /=20 > syntax highlighting is baked in: > > image.png > > Ultimately, people will take a quick reading in a Context Manager=20 > documentation and the parallels to explain how it works seems to be=20 > very well in place for `as`, imo. > > In the image above I tried adding `for using` because I was trying=20 > really hard to come up with a word that could replace `each` in=20 > `foreach` to make it even more symmetrical, but I could not find=20 > anything decent. > > - `for context(new ContextManager as $context)`=20 > This one reads well, but the fact its two words (and a long word for=20 > that matter) doesn't sit well. > > - `for with(new ContextManager as $context)` > I'm not a native English speaker, but I think this doesn't read at all > > - `for one(new ContextManager as $context)` > Kind of implies it works with iterators (similar to each), which is no= t=20 > exactly the case and the language has very little motivation to create=20 > an iterator that loops only once just to make this work. > > - `for using(new ContextManager as $context)` > Similar thoughts as `for context`, the only difference that makes me=20 > like this one more is because `for context` doesn't sit well with `try=20 > context` while `for using` could go well with `try using`. > > In any case, the longer I sit with this the more I dislike `=3D>` for = this.=20 > > In an array, `=3D>` is an assignment of key/value pairs.=20 > For foreach ($iterator as $key =3D> $value), the =3D> is a destructing=20 > instruction that aligns with how the array was originally assigned. > For the arrow function, it's kind of implied in the name ARROW functio= n=20 > that we would need a syntax in the lines of `fn () =3D>`. I don't thin= k=20 > this relates well with arrays, but it works well to me because of how=20 > universal arrow functions are in Javascript.=20 > For match ($value), it reads as `WHEN ($value) MATCH '' THEN. The arro= w=20 > here `=3D>` is the THEN. > > My conclusion is that `=3D>` is either a value placement (for arrays) = or=20 > an instruction execution (for arrow function and match). As such, If =3D= >=20 > were to be incorporated into Context Managers, I think it would make=20 > much more sense like this: > > `using (new ContextManager as $context) =3D> [single line expression]`=20 > where the arrow creates a symmetry with how arrow functions work. > > > --=20 > Marco Deleu First, yeesh, where were y'all 2 weeks ago? :-P Second, I find it fascinating that there's so many different mutually-in= compatible spins on what =3D> means. As argued in the short-functions a= nd auto-capture-closure RFCs from a few years ago, =3D> in nearly all ca= ses currently means "evaluates to." $arr =3D [ 'a' =3D> 'A", 'b' =3D> 'B', ]; $arr['a'] // This "evaluates to" A match ($foo) { 'a' =3D> 'A', 'b' =3D> 'B', // The 'b' case "evaluates to" B }; fn($foo) =3D> 'bar'; // This function "evaluates to" bar foreach ($arr as $k =3D> $v) {} The last is a little bit inconsistent, but can still be read as "$k, and= the thing that $k evaluates to." So given that, and as Rowan noted the context manager is *NOT* the conte= xt variable: using ($cm evaluates to $cv) {} That's the meaning we're going for. If there's some better word than =3D>, we're still open to it, but I am = going to insist on left-to-right reading. $cm is created first, then it= produces $cv. 'as' is what we had originally, since that's what Python used. However,= it was pointed out that it was confusing as it implied the CM and CV we= re the same thing, or rather the expression on the left gets assigned to= $cv, which is not the case. Hence the change. A symbol does have the (dis?)advantage of a somewhat squishier meaning t= han a keyword. --Larry Garfield