Re: Examples comparing Block Scoped RAII and Context Managers
| From: | Tim Düsterhus | Date: | Thu, 15 Jan 2026 09:03:36 +0000 |
| Subject: | Re: Examples comparing Block Scoped RAII and Context Managers | ||
| References: | 1 2 3 4 5 6 7 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-129758@lists.php.net to get a copy of this message | ||
Hi
On 12/18/25 10:16, Rowan Tommins [IMSoP] wrote:
The point though is that any answer you give is just a design decision you've made; and the exact same decision could be made with more traditional syntax, and apply to the original example.That is true from a purely technical perspective, since syntax is independent from semantics. But the choice of syntax influences users' expectations with regard to semantics and as I've outlined, we believe that the semantics we've chosen fits PHP best and that the syntax we've chosen hints at the semantics best.
Part of it probably is probably a subconscious feeling, but I'll try with an explanation that you may or may not be able to agree with. Existing constructs in PHP that take a list of multiple “items” behave equivalent to consecutive single-item entries. Or in less abstract terms:To me the syntax of theI don't really see why. As I said above, the comma-separated list made me think of "simultaneous" action, which I think would imply (1), because accessing a variable "while it's being declared" would make no sense.let()construct very strongly suggests (3)
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).
In fact, the following works:
const FOO = 1, BAR = FOO + 1;
var_dump(FOO, BAR);
and defines BAR = 2 and
const FOO = BAR + 1, BAR = 1;throws, because
BAR is undefined when defining FOO. This is exactly matching the proposed semantics of let().
Option 3 is not necessarily a "wrong" choice, but it's a choice you have made, and you could equally use more traditional syntax and make that same choice.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. However it would compose less well with the existing control structures, e.g. by requiring the dedicated syntax for declarations that should live for a single
if() construct.
The only thing that using commas automatically does is forbids jump targets (goto labels or switch cases) in between the declarations.It also forbids nested blocks and any other “arbitrarily complex code” in-between declarations. Yes, I understand that folks can use arbitrary expressions on the right side of the declaration (including assignments), but that is more unlikely compared to a more “free-form” syntax that allows arbitrary statements, including arbitrary control flow. I also believe that the explicit separation of declaration and usage provides for a nice visual barrier of "before declaration, definitely old variable", "after declaration, definitely new variable" and "declaration phase, a small chance of ambiguity when declaring a variable that is used in the declaration of an earlier one". Best regards Tim Düsterhus