On 11/11/2025 21:12, Tim Düsterhus wrote:
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.
Technically, JavaScript variables don't have to be declared either; the
difference is that they are global by default, and since function-scope
is generally more useful, people are indeed very familiar with "var".
PHP does have optional keywords that declare a variable with specific
scope, just much less frequently used: "global" and "static". Regarding
the discussion on shadowing vs hoisting:
- Both "global" and "static" can shadow local variables, and indeed each
other: https://3v4l.org/vPr2A
- Since the shadowing lasts until the end of the function, a shadowed
local variable is never re-instated, and will be de-allocated if it was
the only reference: https://3v4l.org/VBVkX
- Somewhat unusually, they do this as run-time statements, so you can
*conditionally* shadow variables: https://3v4l.org/fK9VJ
Whether these are *good* semantics to copy for a block-scoped variable,
I'm not sure; but they are existing PHP semantics for a very similar
situation.
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.
The big difference is the need for an extra level of indent (or, at
least, an extra pair of braces, which most people will probably assume
needs an extra level of indent). More often than not, there is an
existing block you want to scope to - a particular loop, or a
conditional branch, etc.
I do see the advantage of forcing them to the start, though. Languages
in the Pascal family might be another comparison to explore - variables
are all declared in a separate block at the top of a function. Off-hand,
I'm not sure if any allow an arbitrary nested block just to introduce
additional variables.
Regards,
--
Rowan Tommins
[IMSoP]