On Wed, Aug 28, 2019 at 8:35 AM Zeev Suraski <z...@php.net> wrote: > On Wed, Aug 28, 2019 at 2:10 PM Nikita Popov <nikita....@gmail.com> wrote: > > > On Wed, Aug 28, 2019 at 12:41 PM Zeev Suraski <z...@php.net> wrote: > > > >> > >> > >> On Wed, Aug 28, 2019 at 12:33 PM Nikita Popov <nikita....@gmail.com> > >> wrote: > >> > >>> Hi internals, > >>> > >>> I think it's time to take a look at our existing warnings & notices in > >>> the > >>> engine, and think about whether their current classification is still > >>> appropriate. Error conditions like "undefined variable" only > generating a > >>> notice is really quite mind-boggling. > >>> > >>> I've prepared an RFC with some suggested classifications, though > there's > >>> room for bikeshedding here... > >>> > >>> https://wiki.php.net/rfc/engine_warnings > >> > >> > >> Specifically on undefined variables, the way we deal with them has > little > >> to do with register_globals. It's behavior you can find in other > >> dynamic languages (e.g. Perl), and allows for certain code patterns > (which > >> rely on the automatic creation of a variable whenever it's used in write > >> context, and on a default known-in-advance value in case it's used in a > >> read context). It's fine not to like this behavior or the code patterns > >> that commonly rely on it (e.g., @$foo++), but it's intentional and isn't > >> related to any historical reasons. > >> > > > > This argument makes sense for arrays and objects (and I don't promote > > undefined index/property to exceptions for that reason), but I don't > think > > it holds any water for simple variables. Writing @$counts[$key]++ is a > lazy > > way to count values and avoid ugly boilerplate for if > > (isset($counts[$key])) { $counts[$key]++; } else { $counts[$key] = 1; }. > > But @$foo++ is just a really bad way of writing either $foo++ or $foo = > 1. > > Outside of variable variables, the concept of a conditionally defined > > variable just doesn't make a lot of sense. > > > > This example has nothing to do with arrays. There are many code patterns > in which relying on this behavior makes perfect sense for folks who are a > lot less strictly-minded. For example: > > foreach (whatever) { > if (sth) { > @$whCount++; > } > } > > Yes, it may be painful for many eyes that $whCount is not explicitly > initialized, but the above code is perfectly legitimate, warning-free > notice-compliant code since forever. Moreover - this isn't legacy - there > are a lot of folks who appreciate this precise behavior, which is > documented and works as expected for the last 20+ years. > > Or: > > if ($bookCount>0) { > $suffix = 's'; > } > > print "$bookCount book$suffix"; > > These are just two simple cases I bumped into myself recently. There's an > infinite supply of more of those where these came from. > > > > > >> I think many (if not all) of your proposals make sense, but most of them > >> make sense as an opt-in - perhaps using something similar to Perl's > strict > >> mode (which incidentally, changes the way the language treats undefined > >> variables in exactly the same way). This would also provide a > future-proof > >> solution for additional similarly-themed proposals (such as strict ops, > >> etc.). > >> > > > > I don't think this is an appropriate use of an opt-in. It's a case where > > we can balance language cleanup with backwards compatibility concerns. > Code > > that works after this proposal will also work before it, and as such > there > > is no danger of ecosystem bifurcation that would need to be addressed by > an > > opt-in. > > > > Calling this 'cleanup' is opinionated, and avoiding bifurcation by forcing > that opinion on everyone isn't a very good solution for those who have > other opinions. While the opinion that variables must not be used before > being initialized is obviously a valid one - it is just that, one valid > opinion - and there are others. PHP never took this opinion as an > axiomatic requirement (and not because of register_globals) - instead, the > intent was to have a default value for uninitialized variables - a > consistent, documented behavior since the dawn of the language. Can this > be problematic under certain situations? Absolutely. Can it be useful in > other cases? Sure (which is why it's very common). A great deal of folks > both rely on this behavior and *like *it. Those who don't (and there's > plenty of those as well of course) - always had a reasonable solution of > enabling E_STRICT and enforcing E_STRICT-compliant code. I still think > that having a strict mode (which can encompass strict types, strict ops, > stricter error behavior, etc.) makes a lot of sense and would arguably be a > superior option for the many folks who prefer a stricter language - but > there's simply no way we can change one of the most fundamental behaviors > of the language and force it down people's throats - not only because it > breaks compatibility, but because it breaks how many people are used to > write their PHP code. Perl provided stricter-liking folks with a solution > in the form of 'use strict;' decades ago; JS did something similar much > more recently. Neither of these created any sort of bifurcation - it's a > simple, sensible solution that has virtually no downsides. > > While I like Zeev's idea of making it opt-in, I think that a deprecation path is needed at the very least. I think this has the potential to be an even bigger issue to deal with than short tags. At least short tags have been discouraged for a long time. The first short tags RFC would have probably lead to a delay in upgrading to 8.0. This RFC would pretty much guarantee never being able to upgrade to 8.0 until we've totally retired our legacy code base... which will probably be just in time for PHP 28.0 - assuming the PHP project isn't dead at that point due to this RFC.
> Zeev > -- Chase Peeler chasepee...@gmail.com