Hi internals,

In PHP, variables are currently scoped to the function scope, and can't be 
scoped to a block scope. This makes it difficult to reason about how a variable 
will actually be used at a glance, especially in long functions, or top-level 
statement lists of a file.
(or how the variable was originally intended to be used)

The function scope lifetime of variables in PHP is similar to how JavaScript 
treated variables with `var`, before the introduction of the `let` statement in 
JS:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

Would there be any interest in adding something similar to this in PHP?
(Or have similar ideas been proposed in the past? I didn't see any.)
Correctness would be enforced as a best-effort at compile-time - the variables 
would continue to only be freed at the end of the function call.
(e.g. __destruct() only gets called when the variable gets reassigned or the 
function call ends)

- Freeing it immediately would likely require the equivalent of a try{} 
finally{} to handle exceptions.
   try statements prevent opcache from optimizing a function, the last time I 
checked.

```
{
   let $myObject = new MyClass(), $flag = true;
   $myObject->process($flag);
}
// Accessing or setting $myObject or $flag outside a different let is an 
E_COMPILE_ERROR
// because it was declared anywhere else in the function body
// as a let statement
$myObject->doSomething();

// E_COMPILE_ERROR to access $key or $value after, outside of a separate `let` 
scope
foreach ($arr as let $key => let $value) {
    // It would be a compile error to declare a gotoLabel: inside of a scope of 
a let statement.
}
// E_COMPILE_ERROR to access $key or $value after

echo $$var;  // E_COMPILE_ERROR to use variable variables in the same scope, to 
enforce this as much as possible.

{
   let $outer = 1;
   {
       let $outer = 2;  // E_COMPILE_ERROR to declare in a different scope, can 
only reassign
       $outer = 3;   // this is allowed
    }
}

{
    let $myRef =&$other;
}

{
    let $myRef = true;  // This removes myRef from the reference group before 
assigning a new value to myRef - $other is unmodified.
}
```

I say "best-effort" because require() and $GLOBALS and get_defined_variables() 
can still read or modify or make references to variables outside of a `let`,
depending on what's in the function body or top-level statements.

- Tyson
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to