Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:62781 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 26016 invoked from network); 4 Sep 2012 07:40:38 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 4 Sep 2012 07:40:38 -0000 Authentication-Results: pb1.pair.com smtp.mail=glopes@nebm.ist.utl.pt; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=glopes@nebm.ist.utl.pt; sender-id=unknown Received-SPF: error (pb1.pair.com: domain nebm.ist.utl.pt from 193.136.128.22 cause and error) X-PHP-List-Original-Sender: glopes@nebm.ist.utl.pt X-Host-Fingerprint: 193.136.128.22 smtp2.ist.utl.pt Linux 2.6 Received: from [193.136.128.22] ([193.136.128.22:50829] helo=smtp2.ist.utl.pt) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id BB/C7-17715-370B5405 for ; Tue, 04 Sep 2012 03:40:37 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp2.ist.utl.pt (Postfix) with ESMTP id 281B370003D6; Tue, 4 Sep 2012 08:40:33 +0100 (WEST) X-Virus-Scanned: by amavisd-new-2.6.4 (20090625) (Debian) at ist.utl.pt Received: from smtp2.ist.utl.pt ([127.0.0.1]) by localhost (smtp2.ist.utl.pt [127.0.0.1]) (amavisd-new, port 10025) with LMTP id rGz3lLEqwnVk; Tue, 4 Sep 2012 08:40:32 +0100 (WEST) Received: from mail2.ist.utl.pt (mail.ist.utl.pt [IPv6:2001:690:2100:1::8]) by smtp2.ist.utl.pt (Postfix) with ESMTP id 224F07000449; Tue, 4 Sep 2012 08:40:32 +0100 (WEST) Received: from damnation.nl.lo.geleia.net (unknown [IPv6:2001:470:94a2:4:21d:baff:feee:cc0b]) (Authenticated sender: ist155741) by mail2.ist.utl.pt (Postfix) with ESMTPSA id DA08F200738F; Tue, 4 Sep 2012 08:40:30 +0100 (WEST) Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes To: "Stas Malyshev" Cc: "internals@lists.php.net" References: <5040DC47.8000305@ajf.me> <5040F4D9.80206@sugarcrm.com> <5042946A.80204@sugarcrm.com> <5042A7D6.7050001@lerdorf.com> <5045266F.7000303@sugarcrm.com> <47ddfb3c6842ca1fa92f6502e8d3504f@nebm.ist.utl.pt> <50453CD0.5080301@sugarcrm.com> Date: Tue, 04 Sep 2012 09:40:47 +0200 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Organization: =?utf-8?Q?N=C3=BAcleo_de_Eng=2E_Biom=C3=A9di?= =?utf-8?Q?ca_do_I=2ES=2ET=2E?= Message-ID: In-Reply-To: <50453CD0.5080301@sugarcrm.com> User-Agent: Opera Mail/12.01 (Linux) Subject: Re: [PHP-DEV] Re: Are exceptions allowed in php core? From: glopes@nebm.ist.utl.pt ("Gustavo Lopes") On Tue, 04 Sep 2012 01:27:12 +0200, Stas Malyshev wrote: >> to be gained vs. the additional risk. And there is little to no benefit >> in a model where rewinding a closed iterator is allowed, so the >> threshold for acceptable risk is very low. This is not a difficult case >> at all, IMHO. > > We are discussing whether it should lead to the fatal error. I see no > reason for that and declaring "it's not difficult" does not make a > reason a bit clearer. There should be a reason for generating fatal > error, and "this may be a bug" is not a reason enough, at least not in > PHP, as long established practice in PHP clearly shows. Yes, we are. I am saying that "reason" is a balancing of factors: (1) whether the non-exception error behavior makes sense and (2) the extent it has legitimate uses on one hand and, on the other hand (3) the risk it introduces. Of course different languages balance these factors differently and PHP puts less emphasis on (3) -- I'm not trying to change that. >> There is no strict technical reason for most fatals in PHP too. Except >> maybe parser errors, you usually can abstain from doing whatever action >> would cause the fatal instead of raising the fatal. Calling function >> that does not exist or abstract method? Return NULL (like an invalid >> call btw). > > Returning null is a legitimate function return, and there's no value > that can not be legitimately returned from an existing function. > Moreover, since unlike empty iterator, not calling a function is not > normal (iterators can be legitimately empty, but function can not be > legitimately non-existing) fatal error is a proper response to it. Of > course, if we used exceptions, there could be an exception thrown > instead, which is the same thing more or less. Your distinctions here make no sense to me. I cannot understand how the first sentence is even an argument, but in any case you can also say, "Returning an empty set is a legitimate iterator return, and there's no set that cannot be legitimately returned from an existing iterator". There's also no meaningful distinction after. It boils down to what you consider "normal" and "legitimate", and for some reason you equate not traversing an iterator and replacing it with an empty one as "normal" and "legitimate", but not executing a function and replacing it with a null returning one abnormal and illegitimate. But I'm glad you think this way. It means that you accept that the criterion for raising a fatal is not simply "will we segfault if we do this?" or "can we continue parsing if we do this?", but it is instead more nuanced, requiring us to evaluate the "normality" and "legitimacy" of non-fatal behavior, as you put it. > >> IMO, this is perhaps your strongest argument. But 1) that was a bad >> idea, 2) we're not really talking about the behavior of foreach(), we're >> talking about the behavior of specific methods that may or may not be >> called in the context of a foreach, in a hierarchy where exception >> throwing is well established. So it's not really analogous. > > Sorry, but again I have a feeling that you are not satisfied in general > with how PHP handles errors and want much more strictness there. Which > is completely fine, but I must again emphasize that doing it by sneaking > exceptions here and there into the core is not the right way to do it. > If you want to change how PHP behaves, it should be done as a > language-level principle change, and not being done by altering bits of > random patches to behave how the "strict" people like and inconsistently > with how the rest of PHP behaves. I would be happy to discuss it, I have > a lot of issues with current error handling too, but we can not just > ignore the established principles. I think you're misrepresenting my position. I want strictness only in the cases where the alternative behavior fails the balancing test I mention above, a test you (at least to some extent) also support. In the other e-mail you say: > So it basically comes to "it doesn't follow but E_NOTICE in fact should > be fatal for those who prefer a stricter model because I had some code > where it indicated a bug". That's exactly what I was talking about. > [...] > If however we want to keep the current nature of PHP, introducing fatal > errors where it can be avoided only because it _may be_ a bug makes > little sense - we have tons of situations where it may be a bug - just > as you described with E_NOTICE and no fatal error there. My test is not whether it *may* be a bug, as I explained. Yes, E_NOTICEs *may* indicate a bug. But many times they will not (esp. on templates). Now, we may disagree on this, but I content that the situation we're discussing is *almost certainly* a bug. > > If we have a behavior that can be used in two contexts and it is not > consistent with one of them, it is not good to point out it may be > consistent with another. Not throwing exception in this case is > consistent with all other PHP - nothing requires that generator or > iterator would throw exceptions on every problem. In fact, I do not > believe any of the existing iterators throw on trying to iterate past > the end. So not throwing will be consistent with everything. Nor are they supposed to to throw an exception in that case. Even though we don't document in the manual, iterators return null when they have no more elements. But let's look at rewind: > Rewinds back to the first element of the Iterator. Making a no-op is a violation of the post-conditions rewind() is supposed to offer. And yes, I know about NoRewindIterator, which is an aberration -- classical circle is-an ellipse bad design. In fact, I would have preferred that rewind() was not a part of Iterator, but it's too late for that. > However, throwing will be inconsistent with foreach() usage pattern and > only marginally consistent with other iterators - while they indeed > throw exceptions, as far as I can see they don't do it in normal > iteration scenarios, only when trying to pull something weird like > accessing keys of invalid iterator or when using underlying > functionality that fails. But as far as I can see you can not make any > of existing SPL iterators to throw by repeatedly iterating over them. > Even NoRewindIterator - which states "no rewind" in its name - does not > throw when you try to repeatedly iterate over it. I disagree that this is a normal iteration scenario. And AFAIK all SPL iterators are rewindable, so it's normal we can't find examples on point. -- Gustavo Lopes