Hi all, As briefly mentioned, I think the approach to non-nullable types in the typed properties proposal needs more discussion, to make sure we're not repeating Tony Hoare's "billion-dollar mistake".
For parameter hints, nullability is naturally optional, particularly in PHP where "nullable Foo" is equivalent to a union type "null or Foo". For properties, this isn't the case, because every property must have some initial state. The simplest solution, which I think would be a sensible starting point if we're not ready for more complex changes, is to say that all typed properties must have a default value, and if that default value is null, the type hint must naturally be nullable. In other words, make "public Foo $foo" illegal, but allow "public ?Foo $foo=null". The current RFC proposes the next simplest solution, which is to allow non-nullable types, and trust the user to initialise them before use. My first objection to this is that it creates an entirely new state for object properties to be in, which behaves differently from everything else in the language. There will then be three or four different ways for an object property to be "unset": - not declared at all; access gives a notice and the implicit value null - declared with no default, uninitialised, implicitly null - declared with a default of null, or explicitly assigned as null - declared with a non-nullable type, never initialised; rather than an implicit null, access generates an Error The bigger problem is that the properties are non-nullable in name only, and the declaration can't be trusted. Consider the following class: class Validity { public \DateTimeInterface $validFrom; public ?\DateTimeInterface $validTo = null; } If I have an instance $v of that class, I would expect to be able to safely call $v->validFrom->getTimestamp(), but need to check for nulls before doing the same with validTo. Under the current proposal, doing so will risk errors, so I will have to check both properties before access anyway. Worse, using is_null() or ?: will attempt to retrieve the value, so I actually have to be *more* careful, and use isset() or ?? instead. Alternatively, I can trust the author of the class, but at that point they might as well just use a docblock - the type hint documents their intent, but is not enforced. Swift is often cited as a language which gets nullability right, and a lot of attention is given to Options, and the compiler ensuring that the None / null case is handled; but at least as important is how it handles initialisation of non-nullable properties, using "two-phase initialisation": https://docs.swift.org/swift-book/LanguageGuide/Initialization.html In short, Swift defines a specific point after which all properties must have a valid value; before this point, the entire object is invalid for read operations, so there is no need for a specific error when accessing uninitialised properties. Swift marks this point by the call to the parent initialiser, ultimately going up the chain to the root object. PHP has no root object, and no mandatory parent constructor calls, so would need a different way to mark this stage. Constructors can already violate the rules the first phase should impose, so we can't just use the end of the constructor as the validation point. One possibility would be to add a new keyword like "initialize" which must be added to constructors in the presence of non-nullable properties. Above that keyword, use of $this other than to write to its properties would be an error; afterwards, the constructor could carry on as normal. As I say, this is complex, and it may be best to add nullable typed properties first, and give more time to try out approaches to initialisation. Regards, -- Rowan Collins [IMSoP]