Hi
Apologies for the late response. An unexpected high priority task came
up at work on Thursday and I wanted to make sure to provide a proper reply.
On 11/4/25 19:19, Rowan Tommins [IMSoP] wrote:
I agree with Ed and with Arnaud: this feels like it's trying to squeeze two
different features into one syntax and ends up with an awkward version of both.
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.
For this reason the RFC very intentionally relies on the existing
semantics of PHP and leaves anything more complicated to future scope,
as Seifeddine also mentioned in response to Edmond.
For block scoping of "normal" variables it feels clunky to add an extra block, rather than
declaring the variable with a keyword like "let" or "var". This is particularly obvious
in the foreach example, where the variable has to be named twice on one line:
use ($value) foreach ($array as &$value) {
Languages with a keyword for declaring variable scope instead let you write the
equivalent of this:
foreach ($array as let &$value) {
Requiring to declare all block scoped variables at the start of the
block is an intentional decision to keep the scope easy to reason about.
Consider this example:
function foo() {
$a = 1;
var_dump($a);
{
var_dump($a);
let $a = 2;
var_dump($a);
}
var_dump($a);
}
What would you expect the output of each of the `var_dump()`s to be?
With regard to the foreach, I agree there is no ambiguity. I can imagine
a follow-up that desugars:
foreach ($array as let &$value);
to
use ($value) foreach ($array as &$value);
Or if you feel that this is important to have right away, I can look
into how complicated the implementation would be?
I think splitting the two use cases (context managers and scoped variables)
would allow us to have much better solutions for both.
As mentioned above, this RFC explicitly is not a context manager
proposal. It's scoping - but it would make the existing lifetime
semantics easier accessible for what you call context managers.
Given the opinions disliking overloading the `use()` keyword, I have
discussed the keyword choice with Seifeddine. Personally I prefer
`let()` over all alternatives for this reason.
Best regards
Tim Düsterhus