Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129799 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 2DDA51A00BC for ; Tue, 20 Jan 2026 22:26:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1768948012; bh=+3O7vJDWAa5vZx2hr5JcnPv48a7loPYEUF4ANdTqVRc=; h=Date:Subject:To:References:From:In-Reply-To:From; b=jpFujty8y5r1MdrYxUlenQskO6pCNdJYWkCB7TROweyqgMu6wrnM6BpmD4V0jrJt0 Fx1nViUWE+6SBQ1Q6RPokMkH6wXMmP5hXP8myxQrg9uzA4NCyVnFSFDxgG4jtG6FjX I3tviBtrUogMEgt+vUMw1VgHbTdLeBE84f/2yQrey9cIR/I/t8xJXFkN1q3ihG53wb OvzGx3GoN+rbsx2jXaUCwCk3VD2fLdR4GQfoKRFI6sP4kMit8ZlZYBgmKVmj9PR/MP +tr8/8NHygbIlraV6/449qeqfCcS0syb+qOU79zA2ruh1zhlFIDyB+h53X2CsumlLo 7EWsFuaV9rsJg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id DCAD0180088 for ; Tue, 20 Jan 2026 22:26:51 +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)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 20 Jan 2026 22:26:51 +0000 (UTC) Received: from phl-compute-03.internal (phl-compute-03.internal [10.202.2.43]) by mailfout.stl.internal (Postfix) with ESMTP id F04911D000E2 for ; Tue, 20 Jan 2026 17:26:45 -0500 (EST) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-03.internal (MEProxy); Tue, 20 Jan 2026 17:26:46 -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=1768948005; x=1769034405; bh=wCaP+sVnkv9Q8DvnbvUY1I/EV203yZpgYDR8a9nUMoo=; b= CpSvl6z7W1J+jbtP6R8oW5DaXf0h1QszsVFSP6duDpGQerV9uDa2nnVVHEuc5fKR voV1JRdsXFsg18Lch0twMYggdhyKVu0VZ4Y0I2jom6AgQ6OG11GJGlp+AYgKe316 ELI2dZ3/0TKp1qNy2xFWMJ3y5yBlrwh23QZLykm9vLzICB2p6aueXmMBAW4ruZ8e cZzUo0gCuxcyzfoaOHQUug3Kqb93P4/Gd3tvjt3ebrfeACRpljEM37lFGGaOZxz2 QH1Snjuq4/O72mhnG8QmKZTOqp+ELTKNud3FqznvO7pNU9MIvoo4YBzJyWDgRaxI 6BqNEWnDhXTqHpcB/LDNmg== 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=1768948005; x=1769034405; bh=w CaP+sVnkv9Q8DvnbvUY1I/EV203yZpgYDR8a9nUMoo=; b=A64DG+8/4RDhn1c8A AYwTx4wKV21FfzeRSFUs9rsD9AsMJWJOUJUxTmECB95lY78gbQqiWFp2dVN7kM4d XnyWwHkEptkfMdpkMfbiyoQ1Z696zN0LU6qh0WDdVP8QMNU17fg6fDaKjJ1ka+Af N7ogiS254JfIA41uPtZ4Lq1D32XQm+GtzudrCPKxlBoee2HVCZbCDrt0gZmu3GRc qCZCl+uSA130mRP+e2p6ouZKIOTqqe82RUurf5tB0L2y83BZhibYlxPfrrmn0Nej qRyRJUXCTBwF9y98JhIjV0mn/k9AKaUV6grGMTSaxVesLbUbO1g393pL9rstcxC+ uiFxg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddugeduiedtucetufdoteggodetrf 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 17:26:45 -0500 (EST) Message-ID: <323651a4-f4c5-4a93-bddb-0986bf01eef8@rwec.co.uk> Date: Tue, 20 Jan 2026 22:26:44 +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] [RFC][Discussion] use construct (Block Scoping) To: internals@lists.php.net References: <1F3473C7-5D83-48D3-964E-A63D6F44D21E@rwec.co.uk> <4998b4c6-0474-4f0c-b63a-9909b8acfa96@bastelstu.be> <018421f64342a0d960589b4c8eea5cc5@bastelstu.be> <84b9dc16-3eb3-4283-b015-3af29fc0e55d@rwec.co.uk> <590fa655-d170-43f2-984c-d0a5ff6c30e4@bastelstu.be> <7c623161-cde3-4fc0-944c-ddfc2785c845@rwec.co.uk> <21f12343-b212-456f-93b3-079810d3d76d@rwec.co.uk> <7da06511e359f73410032a03757dfbe4@bastelstu.be> Content-Language: en-GB In-Reply-To: <7da06511e359f73410032a03757dfbe4@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 17/12/2025 19:09, Tim Düsterhus wrote: > The difference I'm seeing is that for languages where variable > declarations (and block scoping) are a core part of the language, the > scoping rules are “moulding” (if that word makes sense here) how code > in that language is written and how folks reason about the code. This > is different for a language where block scoping is added > after-the-fact and remains an optional part of the language. I can sort of see where you're coming from, but counter-examples include Perl and JS, both of which treat declarations as optional, and innovated new variants of them, but stuck to the "ALGOL-style" syntax. >>> I feel that the C99 requirements and syntax would still have more >>> ambiguity compared to the proposed `let()` syntax in cases like this: >>> >>>     { >>>         let $foo = bar($baz); // What is $baz referring to? >>> Particularly if it is a by-reference out parameter. >>> >>>         let $baz = 1; >>>     } As discussed on the other thread, this part of the discussion turns out be moot, because exactly the same ambiguity exists in the proposed syntax: let($foo = bar($baz), $baz=1) { ... } The syntax alone doesn't tell you what that will do, only knowing the choices made in the RFC. >>> PHP already limits where "goto" can jump to; I don't know how that's >>> implemented, but I don't think we need to get into philosophical >>> definitions to say "you can't jump into the middle of a declaration >>> list". > > Another, perhaps better, example that is not handled well by any > C-derived language that we are aware of is block scoping in > combination with `switch()` Compile Error: 'let' declarations whose closest block is a 'switch' are forbidden. Problem solved. > Other languages have other ecosystems and other user expectations. PHP > has extensive “scope introspection” functionality by means of > `extract()`, `compact()`, `get_defined_vars()` and variable variables. > Folks are used to being able to access arbitrary variables (it's just > a Warning, not an Error to access undefined variables) and there's > also constructs like `isset()` that can act on plain old local-scope > variables. Adding semantics like the “temporal dead zone” from > JavaScript that you suggested in the other thread would mean that we > would need to have entirely new semantics and interactions with > various existing language features that folks already know, adding to > the complexity of the language. I don't think most of these would need special semantics at all. If it's an error to read from $foo, it follows that it's an error to read from $$x when $x is 'foo', and an error to run compact('foo'). It seems equally obvious to me that get_defined_vars() would omit the variable, and isset() would return false. There might be some nuances to the implementation, but I imagine it would be similar to uninitialized object properties: a sentinel value in the zval, and checks for that sentinel in suitable places. I don't know JS well enough to name them, but I bet the ECMA committee had to consider similar features, and most users simply never encounter them. > For me this works, because the `let()` is preparing me that “this code > is doing user processing” and the `if()` is just an “implementation > detail” / “means to an end” of that. By the block scoping semantics I > know that when I read the closing brace, the user processing is > finished. The function is a

, the user processing is a

and > the `if()` is a

if that analogy makes sense. If I just want to > get an overview over the function, I only care about the

headings. I can't think of any situation where "this block of code contains a scoped variable" is more important information than "this block of code might not run at all". In the analogy, I would always class an if() as an h2; it's one of the most fundamental pieces of control flow. > I understand that some languages have postfix conditions, but being > able to place an `if()` after another control structure is not a new > thing. The same would apply to: > >     foreach ($users as $user) if ($user->isAdmin()) { >         echo "User is admin"; >     } > > which is already valid PHP. That syntax would never occur to me, and if I saw it, I'd immediately add the "missing" braces. > The comma would leave ambiguity in cases like `if (let $repository = > $container->getRepository(), $user = $repository->find(1))`. I think you missed the context: in Perl, the comma isn't part of the "if" or "let", it's just a general purpose operator, so this ambiguity is just the precedence of "," vs "my". > That's probably why C++ uses the `;` as a delimiter there. But sure, that works too. I was just exploring possibilities. I think, in a nutshell, this is where we have opposing opinions: > we believe the “top of the block” semantics are important for block > scoping to work well in PHP due to its unique semantics and 30y history. I believe using familiar declaration syntax is important for block scoping to work well in PHP due to its strong similarity to other languages in the ALGOL-C-Java family, and the 65 year history of that family. -- Rowan Tommins [IMSoP]