Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129798 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 2EA651A00BC for ; Tue, 20 Jan 2026 21:41:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1768945292; bh=R6MJ3v/KaybE7+XJ3Hm3bkz2yrBiHfBmb3wuDw5Yv80=; h=Date:Subject:To:References:From:In-Reply-To:From; b=KFgsA3vdtYzfPCwqYFDAg+Af5Ur0LBdTaXQDrpUJeGdxPMuj8mfzm3XopqW7utIPV 6w0LcIVH+ZSfVhQfqN5s6/T805SyqfbFM/z1iOMfachc5cDVBU8EMtkiNoMgAoEeL6 /k7tkJtpGZimfbJpUNUR1WVEcCzLnF5I2uEczm1Nk/QTh0MoGGYlklt41lqVocK3d4 KJRnAz0v0NipRJblIVDlHduMWXBKG7SVJJMWKfPIz0zhb4QMOeJ9YhzkocDR17jTcE Hdbp4fKYq6mIJk/Ec/DqoWm8cOR/jQVFpTPus9Uw/kDTvTn9Iyt6dH2Z+sFIt5YspX KvCJPyuQW/Kpg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id B0AB21801D8 for ; Tue, 20 Jan 2026 21:41:31 +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_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from fout-b7-smtp.messagingengine.com (fout-b7-smtp.messagingengine.com [202.12.124.150]) (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, 20 Jan 2026 21:41:31 +0000 (UTC) Received: from phl-compute-04.internal (phl-compute-04.internal [10.202.2.44]) by mailfout.stl.internal (Postfix) with ESMTP id 8B40D1D00089 for ; Tue, 20 Jan 2026 16:41:25 -0500 (EST) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-04.internal (MEProxy); Tue, 20 Jan 2026 16:41:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rwec.co.uk; 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=fm2; t=1768945285; x=1769031685; bh=tdNQ9NmKYxl76oxzXG9TOvzyvpmJBMlB2xo8iv30sWo=; b= L9zW5nGCIps7SCZKh9nJSnMWRfmE2V9YV/4l88iAe6Eqs75qYbJuancBJ+QluvnA O2T0gVZVA/7Ql9Xec54iJwh1hpSQpWBFMVfnPRnFI/Z5r+MhXzWUBvITMe2cLTXS OLhUgxaUOnF/RpWb/32oINvGyKHtbh8841DbCygfBDPlVb1WcWkgdKJ7YMX64In1 poPn0JvTrExriuJipAhOtxs9k2VCBsErdNgwxizhZGGyhtSd2UXftpDeH0hSXkN3 fvETprvFjn/3XsPahu0M4mRjMOijxg4im+/fQfmfFznAGgKSDAJe3fiep8rEpulg A6L6xPNrKzsLC2eITpV7Qw== 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=fm2; t=1768945285; x=1769031685; bh=t dNQ9NmKYxl76oxzXG9TOvzyvpmJBMlB2xo8iv30sWo=; b=THF+bvJi5HMJCiXBl HNOtyj0APjGBPYVE67yuV060O1/qGM5oKashc1xUAwa+cfOd/z/pNWhVbaCOEdVF wMRFWOOcRP5W1s/B0bPOThjdYVsggRMpIcOLkPhEkwtC+Q0Wf0+XBCI1ygZC155Z Ij/bOzVlCJurvYz+X3mxg/NQtDr1gp9MmCqs1nEfPl3awhgyM0jq0Cvrc+WRMHA0 pjYhOOxOChM7si4TS9P7rbOnxgJXtG1O26FK+WnIc8H/OAWU9coKNww8OlaXOl1C J3FD9+BawKMXpKmwo5FLpCeETLX058q1NFqaZ4r1SZVrbP3uzXgp0i70XDzCn3Zj Z5S1w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddugeduhedvucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucenucfjughrpefkffggfgfuvfhfhfgjtgfgsehtkeertd dtvdejnecuhfhrohhmpedftfhofigrnhcuvfhomhhmihhnshculgfkoffuohfrngdfuceo ihhmshhophdrphhhphesrhifvggtrdgtohdruhhkqeenucggtffrrghtthgvrhhnpeffke evudffuddvheejvdefkeelfedtudegfeehjeduheegieduffeggeegveefheenucevlhhu shhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehimhhsohhprdhphh hpsehrfigvtgdrtghordhukhdpnhgspghrtghpthhtohepuddpmhhouggvpehsmhhtphho uhhtpdhrtghpthhtohepihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: id5114917:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Tue, 20 Jan 2026 16:41:24 -0500 (EST) Message-ID: <7bbff1ee-ada2-4ef9-a9cd-4ea3f18bc243@rwec.co.uk> Date: Tue, 20 Jan 2026 21:41:23 +0000 Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PHP-DEV] Examples comparing Block Scoped RAII and Context Managers To: internals@lists.php.net References: <26a2f13c-f318-4d6c-9595-bfaaebcbabcb@rwec.co.uk> <78bfa50ad7c5111a1c6caaff3a525255@bastelstu.be> <52165B35-D495-40C8-97B3-9684ED30F220@rwec.co.uk> <954a2c05-af46-4df0-bc42-fc14a80dae51@bastelstu.be> <437656ab-8113-43de-b68d-11d2083320d0@bastelstu.be> Content-Language: en-GB In-Reply-To: <437656ab-8113-43de-b68d-11d2083320d0@bastelstu.be> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit From: imsop.php@rwec.co.uk ("Rowan Tommins [IMSoP]") On 15/01/2026 09:03, Tim Düsterhus wrote: > Existing constructs in PHP that take a list of multiple “items” behave > equivalent to consecutive single-item entries. Or in less abstract terms: > >     const FOO = 1, BAR = 2; > > is equivalent to: > >     const FOO = 1; >     const BAR = 2; > > So to me it is only natural to extend that logic to the `let()` > construct, which only leaves the let($a) let ($b) desugaring which > then implies (3). There's a jump here. In a grouped "const", "global", or "static" statement, the expansion is to a *series of statements* with a common prefix. In your proposed syntax, the expansion is to a *nested set of blocks*. That makes the semantics more complicated, and in my opinion more surprising... Rather than "const", a better example is probably "static", where this is legal: ``` $bar = 42; static $foo=$bar + 1, $bar = 1; echo "$foo,$bar"; ``` It desugars to a series of separate statements: ``` $bar = 42; static $foo=$bar + 1; static $bar = 1; echo "$foo,$bar"; ``` The static $bar silently shadows the local one, and you get an output of 43,1 Interestingly, this is *not* legal PHP: ``` static $foo=$bar + 1, $bar = 1, $foo = -1; ``` "Fatal error: Duplicate declaration of static variable $foo" Note that these are two largely arbitrary design decisions: - A static variable with the same name as a local one shadows the previous variable, with no hoisting or dead zone - A static variable with the same name as an existing static variable is forbidden > This is exactly matching the proposed semantics of `let()`. Not quite. It works for this: ``` $bar = 42; let($foo=$bar + 1, $bar = 1) {     echo "$foo,$bar"; } ``` The block-scoped $bar shadows the function-local $bar, and the output is 43,1 just like with "static". But what if we declare the same variable twice: ``` $bar = 42; let($foo=$bar + 1, $bar = 1, $foo=-1) {     echo "$foo,$bar"; } ``` My intuition from "static", and from every other language I've used, is that this would be an Error: there's a single block, and you're trying to declare two different local variables called "$foo" inside that block. Instead, what happens is that the second declaration of $foo shadows the first. The justification is that this is not actually one block at all, it's secretly a whole set of nested blocks: ``` $bar = 42; {     let($foo=$bar + 1) {         let($bar = 1) {             let($foo=-1) {                 echo "$foo,$bar";            }        }    } } ``` > Yes, but the “more traditional syntax” would also leave the > possibility of (1) or (2) - unless restricted to the start of the > block as in C90. I suspect this is where we've been talking past each other a bit: looking at the syntax, I interpreted the comma-separated list as defining a set of variables in the same scope. That leaves all the same options as the "traditional" syntax: $bar = 42; let($foo=$bar+1, $bar=1) {     echo $foo; } - You could treat $bar as "hoisted" within the let() construct, giving $foo==2 - You could treat $bar as creating a Dead Zone within the let() construct, giving an Error - You could treat the declarations as sequential, and shadow the value, giving $foo==43 What I completely missed, and seemed obvious to you, is that there are actually two separate scopes being declared, nested inside each other. (Even so, there is another possibility: variable shadowing could be forbidden, as in C#, making the "$bar=1" declaration an error). So I guess it all comes down to the same thing: the syntax just doesn't seem intuitive to me, because I keep expecting it to behave like JS, C, Java, Perl, etc. I can't get past the fact that copying from one of those languages would be so much more obvious. -- Rowan Tommins [IMSoP]