Hi

Am 2025-11-10 11:04, schrieb Rowan Tommins [IMSoP]:
On 09/11/2025 16:52, Tim Düsterhus wrote:
We don't think so. Our goal with this proposal is - as the title of the RFC suggests - making block scoping / limiting lifetimes of variables more convenient to use. The goal is to make it easier for developers and static analysis tools to reason about the code, for example because variables are less likely to implicitly change their type.


Perhaps part of the problem is the comparisons the RFC calls on. It mentions features from three existing languages, none of which is about block scoping; and doesn't mention the ways other languages *do* indicate block scoping.

I can see how this is a possible source of confusion. The motivation of this RFC was to improve handling of lifetimes (both regular variables and resource objects) and for that we looked into the listed references, since we were familiar with them to varying degrees. Afterwards we looked at how these languages differ from PHP and adapted the concepts into something that we believe fits the existing semantics of PHP best. From my experience, taking another programming language's feature as-is and putting it into PHP is almost never the right choice.

I also wouldn't say that the RFC is drawing an explicit comparison to the other languages. It just lists them as references / source of ideas, but I can see how we could spell out more explicitly why we made the changes compared to those other languages or that those are just a rough inspiration.

Syntax-wise the solution ended up similarly to those three languages, but when we were looking at the semantics, PHP's destructor semantics are quite different than those of the other languages. That's why the semantics differ from the three references and became “block scoping it is” for RFC we are proposing, since that implicitly handles resource objects.

If what you're interested in is a general-purpose block scope, none of these are relevant examples. The most relevant that comes to my mind is JavaScript's "let", which is an opt-in block scope added to an exsting dynamic language. A comparison of that approach to what you propose here would be interesting.

That's fair. I'll look into adding more explicit comparisons to the RFC together with Seifeddine. My short answer here would be that JavaScript already had explicit scoping by means of `var` and thus folks are already used to needing to declare variables. Moving to `let` is just a smaller incremental change. This is different from PHP where all variables exist implicitly, which also means that semantics from other languages need to be adapted.

Yes, this is a problem that any language with block-scoping has to tackle. Since there are many languages which have that feature, I'm sure plenty has been written on the pros and cons of different approaches.

 I'm not aware of any language that requires a specific kind of block in order to introduce a new scope, but that doesn't mean it's a bad idea. The approaches I am aware of are:

The closest comparison to “specific kind of block” might perhaps be older versions of C which require all variables to be declared - and for them to be declared at the top of the scope without any logic running in-between.

- Shadowing: At the point of declaration, any other variable with the same name becomes inaccessible, but not over-written. Result: 1, 1, 2, 1

- Forbidden shadowing: At the point of declaration, if there is another variable of the same name in scope, an error occurs. Result: 1, 1, Error (let statement must not shadow $a from outer scope)

- Hoisting: The variable declaration can occur anywhere in the scope, and affects the whole scope even lines above it. Used by JavaScript's "var" keyword, and very confusing. Result: 1, 2, 2, 1

- Forbidden hoisting: The variable declaration can occur anywhere in the scope, but lines above that point are forbidden from accessing it. Used by JavaScript's "let" keyword, with the dramatic name "Temporal Dead Zone". Result: 1, Error (must not access block variable $a before declaration)

As mentioned before, many other languages already require explicit variable declarations for everything. For those it's fairly clear that variables do not exist before their declaration. With PHP variables implicitly coming to life on the first usage, we don't believe that any of those existing semantics are fitting a PHP developer's intuition and therefore opted to require all “block scoped” variables to be declared right at the start of the block to avoid the ambiguity of when the block scoping actually starts for a given variable. The semantics of the block are then equivalent to shadowing after we made the changes to restore the original value afterwards.

Best regards
Tim Düsterhus

Reply via email to