Re: [RFC][Vote] Typed Properties

From: Date: Wed, 25 May 2016 15:34:42 +0000
Subject: Re: [RFC][Vote] Typed Properties
References: 1 2 3 4 5 6  Groups: php.internals 
Request: Send a blank email to internals+get-93508@lists.php.net to get a copy of this message
On 5/25/16 9:03 AM, Nikita Popov wrote:
On Wed, May 25, 2016 at 10:30 AM, Joe Watkins <pthreads@pthreads.org> 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

« previous php.internals (#93508) next »