Hi Tyson,
Normally I would be one to advocate for new features, but in the case I am against the proposed feature. I know it is a feature from Javascript, but I think it is maybe the nature of Javascript prototypes makes it more useful though I am not sure as I do not specialize in JS. OTOH the nature of PHP coding minimizes the need. More specifically regarding PHP, the purpose of your proposed feature appears to be to allow longer and more complex functions and methods and more deep nesting. However, I think we should not be encouraging people to write longer and more functions and methods and nest more deeply. And I have unfortunately have had to refactor too many long and complex functions and methods and deep nesting written by others that I actively want try to discourage such approaches to coding, in PHP at least. What I would rather see are new features in PHP that encourage developer to break functionality into shorter and simpler functions and methods, and to minimize nesting. The Software Engineering StackExchange seems to share my view: https://softwareengineering.stackexchange.com/a/200712/9114 There is also an issue with block scoping that is reasonably well-known among the GoLang community called variable shadowning and that is a developer seeming a variable in block scoping and thinking they are accessing or assigning the function-scoped variable. In GoLang it is more of a problem because of lack of explicit declaration required for variable shadowing — and the language designers have lamented that they wish they never included block scoping — but even though the original PHP developer might not get confused as they would be writing the `let's declaration another developer trying to maintain the code could easily introduce errors in the code if they don't notice the block declaration. https://rpeshkov.net/blog/golang-variable-shadowing/ (https://rpeshkov.net/blog/golang-variable-shadowing/) For these reasons I would definitely not want to see block-scoping of variables in PHP. #jmtcw #fwiw -Mike P.S. If you really need block scope within a long function or method you can already create a closure and call it in the same expression: function Foo(){ > $var = "I am a function scoped var!\n"; > > (function(){ > > > > > > $var = "I am a block-scoped var!\n"; > > > > echo $var; > > > > > })(); > > echo $var; > } // Prints: // I am a block-scoped var! // I am a function scoped var! Foo(); > > On Mar 15, 2020 at 12:47 PM, <tyson andre > (mailto:tysonandre...@hotmail.com)> wrote: > > > > 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 > >