Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:64596 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 73944 invoked from network); 6 Jan 2013 03:31:54 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 6 Jan 2013 03:31:54 -0000 Authentication-Results: pb1.pair.com header.from=ircmaxell@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=ircmaxell@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.220.50 as permitted sender) X-PHP-List-Original-Sender: ircmaxell@gmail.com X-Host-Fingerprint: 209.85.220.50 mail-pa0-f50.google.com Received: from [209.85.220.50] ([209.85.220.50:54925] helo=mail-pa0-f50.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id CB/55-62408-920F8E05 for ; Sat, 05 Jan 2013 22:31:53 -0500 Received: by mail-pa0-f50.google.com with SMTP id hz10so10017332pad.37 for ; Sat, 05 Jan 2013 19:31:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=4HQGgPnQ6bMTRvIJzq7PjufdVyd0fEG9Klz32N1qFrA=; b=DScLKP/FXW1b1ej+OGnzGoqRTK0YZ++B+PUwvnKDlmKWiFo/xpjqslarAzUxsVkumM hkxn6xxVV8Qku8xoa2ZlTX6Q1uQmAn15FXKJtHmFqiimc6vTa501MpXRmYUDMeAnhuF1 OA8JX9T5dteVqrV8N6/nVRnir+GbBR2k9ZdiVEGnvc3hGrOcodGybWyLEKu4LwwYdzzc KgbzONnhrRFhSZrrQI+Y6ExzWtmegOuFmDTApDV41zXBq34bZlv1zusYORGdGHHUW2AN ntCZXoJ3PadMa5yWh1aFxGroOrPDRqAHLPSYQzkaswLtx1h9BUw1Zx9seMLzdVxyatR/ VB4Q== MIME-Version: 1.0 Received: by 10.68.137.234 with SMTP id ql10mr174560077pbb.158.1357443110647; Sat, 05 Jan 2013 19:31:50 -0800 (PST) Received: by 10.68.17.67 with HTTP; Sat, 5 Jan 2013 19:31:50 -0800 (PST) In-Reply-To: <50E8EC66.7000800@sugarcrm.com> References: <19D80B01-BE88-4119-8A15-B631A96060E5@mrclay.org> <50E8AA4D.5090207@sugarcrm.com> <50E8C2BA.9080309@sugarcrm.com> <50E8CBD4.9090000@sugarcrm.com> <50E8EC66.7000800@sugarcrm.com> Date: Sat, 5 Jan 2013 22:31:50 -0500 Message-ID: To: Stas Malyshev Cc: Nikita Popov , PHP internals Content-Type: multipart/alternative; boundary=047d7b2e440669b6a804d2965a73 Subject: Re: [PHP-DEV] [RFC] Alternative typehinting syntax for accessors From: ircmaxell@gmail.com (Anthony Ferrara) --047d7b2e440669b6a804d2965a73 Content-Type: text/plain; charset=ISO-8859-1 Stas, You can not both say "it works just like method parameters" and in the > same breath say it needs the concept of dynamic initializers which never > existed in PHP and which BTW was not introduced in the RFC either (and > which won't solve the problem you're trying to solve anyway). I never said it *needed* dynamic initializers. I said it would be cool if it had them, but the concept stands on its own without them. > > You always have the possibility of having null before the object is > > constructed. That's given. > > Not before. While initialization is running. Which can be quite a > complex process. E.g. look at SoapClient class - it parses whole WSDL in > the constructor. Imagine you implemented something like this - there > would be a bunch of things happening while object is being constructed. You miss the key point here. It's not that it can't happen, it's that nothing *outside your code* can interfere. If you set it in your constructor, it's set. If you don't, it's not. But it's on your shoulders... > > But after the constructor finishes, you can actually guarantee that the > > property is never null. For example: > > You can only guarantee it if you know ctor actually assigned the > variable, but there's no way to check it in the code. I.e. if you > manually reviewed the code, you can know it, but declaration itself in > no way guarantees it, even though you were thinking it does. > So for it to be actually useful, you need to know that ctor has already > finished working and that that ctor actually assigned value to this > property. And if you are third-party library using this class as an API, > it's not very useful for you unless you code-review all third-party > libraries you use. Declaration itself does not guarantee it, even if it > looks and is promoted as if it did. There's no way to check lots of things unless you look at the code. In fact, there's tons of more pressing issues then this. What if the code calls shell_exec("rm -rf /");... OMG!!! The point I'm trying to get at here, is this is not about trying to defend yourself from yourself. It's about trying to let you write code easily that defends yourself from others. Simple as that... And as far as revewing 3pd libraries, if they fatal, that's on them. I'm talking about preventing *my class* from fataling. That's all that I can ever hope to do anyway... > > In PHP, inside foo(), $bar will *never* be anything except an instance > > of Bar. It's not possible. Trying to pass Null would generate a > > catchable fatal: http://codepad.viper-7.com/Le3jC1 > > Again, for parameters you MUST provide parameter to call a function, > otherwise function would not be called. So there's no way the control > can enter the function and $bar not be assigned to instance of Bar, > whatever the code around it is doing, however crazy it is. On the > contrary, it is very easy to find scenario where property is declared as > "public Bar $bar;" and still contains null. Unlike parameters, again, > the declaration itself DOES NOT guarantee the property is not null. You're mincing words here. The point I was making in the email you replied to wasn't that the variable couldn't contain NULL, but that it could never be *assigned* null. A very different concept... > > This concept is just an exception of that. After construction, if the > > property is not declared with = NULL, it's never allowed to be set to > > it. Simple as that. It's the same thing as setting the setter to a > > function which type hints against Bar $bar instead of Bar $bar = NULL; > > But that's not very useful. Who cares if it can't be set to null if it > can still be null? You'll have to check it anyway. Or, even worse, > you'll rely on your own insistence that it can not be null and get fatal > error in production code. I don't need to check it if I know that it was set before I get to that point (such as in the constructor). > > As far as unset failing, we already have the ability to do that right > > now with __unset(). All this is doing is applying it to the implicit > > declaration when providing a type-hinted property variable... > > With __unset, you will have to specifically write code to do that. Here, > it is a side effect of a declaration that has nothing to do with unset > and it is completely unobvious to 99.999% of the users that this is what > will happen. It's completely unobvious because it's not documented. Simple as that... And if you have a better alternative to signify the ability to pass null or not, I'm all ears. Would public nullable Foo $foo; be better? Or public not-nullable Foo $foo be better? What we're trying to do here is make life easier for the 99% use case. Not the far edge-cases that you've presented so far... > > No. The whole point of this is to make defensive coding easier. We can > > But you don't make it easier if you're making promises you can not keep, > such as "this value will never be null". Again, nobody promised "this value will never be null". What we're talking about is the promise that it can never be assigned null. A big difference... Please, stop grasping at straws. If you can come up with a non-edge case scenario where this breaks down, by all means let's discuss this. But red herrings like you have proposed so far do no good but dilute the discussions... Anthony --047d7b2e440669b6a804d2965a73--