On 10/12/2025 16:23, Tim Düsterhus wrote:

That sentence you quoted was specifically in the context of the initial paragraph of that section, contrasting PHP - where block scoping is expected to be used comparatively sparingly - against languages where variable declarations are a more “bread and butter” part of the development process, because formally / explicitly declaring variables is a necessity for one reason or another.


I don't think that changes anything I said in my previous reply: as soon as you declare a variable half-way through a block, there is an ambiguity about its range of visibility. Having more variable declarations makes that *more* likely to come up, not *less*, so I'm not sure why you think it "avoids" the problem.

There's also an assumption that if PHP added block scoping, it would only rarely be used. We have no way to know, but I'm not sure that's true. I can easily imagine code styles adding a rule that all local variables be declared at an appropriate level. I can also imagine new users coming from other languages - particularly JS - adding "let" out of habit, even if seasoned PHP coders wouldn't.


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;
    }

Probably the simplest solution is to re-use our existing definition of "constant expression". In fact, we already have variable declarations using that rule:

function foo() {
    static $a = 1; // OK
    static $b = $a; // Fatal error: Constant expression contains invalid operations
}



As an example, is a goto jump label a statement?

    {
        let $foo = 1;
 label:
        let $bar = $foo++;
        goto label;
    }

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".

Or, we could just bite the bullet and answer the "which way does it resolve" question, as loads of other languages have already done.


Being able to declare variables with “if” lifetime that I can also check is a big part of the benefits of the proposed syntax and something I'm missing in other languages.

    if (let $user = $repository->find(1); $user !== null) { }

I find this more readable than the proposed version:


    let ($user = $repository->find(1)) if ($user !== null) { }


Skimming down a piece of code, I can spot where code is being run conditionally without reading the condition itself:

if ............ {

With the proposed syntax, that first glance is:

let ........... {

On closer inspection, it's actually:

let ..... if ..... {


Maybe it's also because I've dabbled in Perl, which has post-fix conditions, so a very similar line would have a very different meaning:

my $foo=do_bar() if ($baz != 0);

is equivalent to:

my $foo;
if ($baz != 0) { $foo=do_bar(); }

Which is also a word order we can use in English, e.g. "hang the wet clothes inside if it is raining".


In terms of making it less of a special case, some languages have a "," operator which lets you glue any two expressions together and get the right-hand result.

In Perl, you can write this:

```
my $a = 'outer', $b = 'whatever';
if ( my $a='inner', $b == 'whatever' ) {
    say $a; // 'inner'
}
say $a; // 'outer'
```

This gives the desired scope for $a, but the if statement is still just accepting a single expression.

JavaScript has the same operator, but apparently doesn't allow "let" in an expression, so you can write:

if ( a="inner", b=="whatever" ) { }

but can't use it to declare a local version of "a".


I haven't thought through exactly how to apply that to PHP, but it might give us an option for "both and": a concise and reusable syntax for the if use case, and a separate syntax for cases like the closure example I gave earlier: https://externals.io/message/129059#129075


--
Rowan Tommins
[IMSoP]

Reply via email to