Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:106723 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 60285 invoked from network); 28 Aug 2019 15:03:01 -0000 Received: from unknown (HELO tbjjbihbhebb.turbo-smtp.net) (199.187.174.11) by pb1.pair.com with SMTP; 28 Aug 2019 15:03:01 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=php.net; s=turbo-smtp; x=1567600510; h=DomainKey-Signature:Received: Received:MIME-Version:References:In-Reply-To:From:Date: Message-ID:Subject:To:Cc:Content-Type; bh=xQ++doNIHw9qi6rYMtVBnH utTUaF7CaWK6Yml7tuo+s=; b=uD14ZmKsuRnJDF0QM1Ji2pAMxMUfnEig4saKKy kT96MJnrzTvfF/x9IDPT7vYnzs4EVNuCG8if0OtqHG6Vf8Uo/0UpQLr7RSaSpsiv yfbFKTtRulOJk5leccxogghLMcwbnr6PRzbdR4nFoa/HGgpv2tjPQ9uKCDPzADR2 rpLm0= DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=turbo-smtp; d=php.net; h=Received:Received:X-TurboSMTP-Tracking:X-Gm-Message-State:X-Google-Smtp-Source:X-Received:MIME-Version:References:In-Reply-To:From:Date:X-Gmail-Original-Message-Id:Message-ID:Subject:To:Cc:Content-Type; b=GimbPf02mwUHouDeQK2RuxhgwqStIIHxGqDLic46m9tdsQqzPaPtBjUGPSBUXO xofctDS5ns+gTQrxO3QKfJ2xJUChqyJtogBB8DgqOgWRgZRh783hGLfSYqOvr/s0 RNiZYEHXMh6X4iN/Q3DVfckXm5hCA17TdrwnIIMxJfzUQ=; Received: (qmail 8016 invoked from network); 28 Aug 2019 12:35:10 -0000 Received: X-TurboSMTP-Tracking: 5244788672 X-Gm-Message-State: APjAAAXKPUcrYp318OGKXzFWHq0C2C1pHymBz8RbXizaZjtzeninIfy+ hso/xerOGsOG22YTB0NuIO5OhaM853/t6yNUcjk= X-Google-Smtp-Source: APXvYqzP/edK1z4N/PokY8HMk0P4aRYBsK9O55hH+l932Pb420CvR2P5HyQ+ldxFQJcnQrKZr3Ah222B8vM5iCXHEaY= X-Received: by 2002:ac8:5048:: with SMTP id h8mr3913441qtm.190.1566995709677; Wed, 28 Aug 2019 05:35:09 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 28 Aug 2019 15:34:54 +0300 X-Gmail-Original-Message-Id: Message-ID: To: Nikita Popov Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000a3d53805912c9e93" Subject: Re: [PHP-DEV] [RFC] Reclassifying engine warnings From: zeev@php.net (Zeev Suraski) --000000000000a3d53805912c9e93 Content-Type: text/plain; charset="UTF-8" On Wed, Aug 28, 2019 at 2:10 PM Nikita Popov wrote: > On Wed, Aug 28, 2019 at 12:41 PM Zeev Suraski wrote: > >> >> >> On Wed, Aug 28, 2019 at 12:33 PM Nikita Popov >> 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. Zeev --000000000000a3d53805912c9e93--