Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:93508 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 89169 invoked from network); 25 May 2016 15:34:52 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 25 May 2016 15:34:52 -0000 Authentication-Results: pb1.pair.com header.from=fsb@thefsb.org; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=fsb@thefsb.org; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain thefsb.org designates 173.203.187.99 as permitted sender) X-PHP-List-Original-Sender: fsb@thefsb.org X-Host-Fingerprint: 173.203.187.99 smtp99.iad3a.emailsrvr.com Linux 2.6 Received: from [173.203.187.99] ([173.203.187.99:36260] helo=smtp99.iad3a.emailsrvr.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 97/B1-14311-A16C5475 for ; Wed, 25 May 2016 11:34:52 -0400 Received: from smtp13.relay.iad3a.emailsrvr.com (localhost.localdomain [127.0.0.1]) by smtp13.relay.iad3a.emailsrvr.com (SMTP Server) with ESMTP id E1194100146; Wed, 25 May 2016 11:34:47 -0400 (EDT) X-Auth-ID: fsb@thefsb.org Received: by smtp13.relay.iad3a.emailsrvr.com (Authenticated sender: fsb-AT-thefsb.org) with ESMTPSA id B11AB10025D; Wed, 25 May 2016 11:34:47 -0400 (EDT) X-Sender-Id: fsb@thefsb.org Received: from yossy.local (c-66-30-62-12.hsd1.ma.comcast.net [66.30.62.12]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA) by 0.0.0.0:587 (trex/5.5.4); Wed, 25 May 2016 11:34:47 -0400 To: Nikita Popov , Joe Watkins References: Cc: Dmitry Stogov , PHP internals Message-ID: <5b256581-5a41-5e78-fd11-76c69af3383e@thefsb.org> Date: Wed, 25 May 2016 11:34:42 -0400 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0) Gecko/20100101 Thunderbird/45.1.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] [RFC][Vote] Typed Properties From: fsb@thefsb.org (Tom Worster) On 5/25/16 9:03 AM, Nikita Popov wrote: > On Wed, May 25, 2016 at 10:30 AM, Joe Watkins wrote: > >> Morning Dmitry, >> >> > I made this check(s) to be invariant. You may like to do this >> differently... >> >> I think this is what everyone expects, isn't it ? >> >> I did omit to mention that part ... >> >> > RFC doesn't define how uninitialized nullable typed properties should >> behave. >> >> It does: >> >> > *Nullable typed properties will not raise an exception when accessed >> before initialization.* >> > > I don't agree with this choice, for three reasons: > > a) This unnecessarily restricts what can be expressed in the type system. > With these semantics it will no longer be possible to express that a > property should be nullable, but have no default value. This situation is > not uncommon in practice, in particular anytime you have a nullable > constructor argument, you will want the corresponding property to be > nullable without a default, to ensure that it is explicitly initialized. > > b) This directly contradicts the meaning of ?Type for parameters. For > parameters ?Type means that it's a nullable parameter **without a default > value**. That's the very thing that distinguishes it from the Type $prop = > null syntax. And now ?Type for properties should mean the exact opposite? > > c) If you view this in a larger scope of union types, this *special case* > becomes even more weird. Why does the particular union Type|null get > special treatment, while all other unions don't? Or is it actually not > specific to "null", but to single value types? E.g. if we also allowed > Type|false, would that also receive an implicit false default value? What > about the type null|false? Does that get an implicit default, and if so, > which? I realize this is not quite in scope for type properties, but the > further evolution of the type system should be kept in mind. > > Please keep things consistent: If there is not default, there is no default. Object properties being in a uninitialized state is unfamiliar in current PHP practice. We are accustomed to not worrying about an "uninitialized error" when we read a property. We are assured to get either null or whatever was last written to the property. I suspect this unfamiliarity lies behind some people's preference for an implicit initial null value of a nullable typed property. But I'm inclined to agree with Nikita that the following should be different: public ?Client $mark; public ?Client $mark = null; ... and that the difference should be coherent with that between: function con(?Client $mark) {} function con(?Client $mark = null) {} ... which is that you *must* give $mark value in the first and you don't need to in the second because it has an explicit default. We are more-or-less accustomed already to the difference between: function con(Client $mark) {} function con(Client $mark = null) {} ... so I think your consistency argument is good. Moreover, the "good old" implicit initial null for untyped properties (i.e. that `public $foo;` means `public $foo = null;`) is just a lazy shortcut that I wouldn't defend except for BC, which isn't an issue here. Tom