Re: Non-nullable properties

From: Date: Mon, 16 Jul 2018 16:09:52 +0000
Subject: Re: Non-nullable properties
References: 1 2 3  Groups: php.internals 
Request: Send a blank email to internals+get-102856@lists.php.net to get a copy of this message
On Monday, July 16, 2018 9:55:31 AM CDT Rowan Collins wrote: > On 16 July 2018 at 14:28, Marco Pivetta <ocramius@gmail.com> wrote: > > These don't really need explicit tests in most cases, but rather static > > analysis (currently happening via docblocks). Static analysis tools like > > vimeo/psalm already pick this up. > > Then why do we need the type hints at all? > > > I'd even be happy to get type hints that only have effect on > > ReflectionProperty#getType() as a massive improvement over > > the current > > situation we've monkey-patched us into, but the patch is indeed consistent > > with PHP's current state. > > I disagree that it's consistent. It introduces an entirely new kind of null > reference ("declared but uninitialised"), which will require *more* careful > checks than forcing the value to be initially null, and will undoubtedly > further annoy those who already claim that isset() is broken (the RFC > doesn't even mention it, but I presume uninitialised properties will return > false from isset(), but throw an error from is_null()). > > If all typed properties require a valid default value, the patch is > simpler, errors are raised at a line where you can fix them, and the > language remains consistent - if you're promised a Foo, you get a Foo, not > a "whoops, why isn't there a Foo here?" error. > > > Regards, This is a possibly highly stupid idea, but I'll throw it out anyway so that it can at least be explicitly rejected in that case... Since Swift was mentioned before as a good example, what about borrowing from Swift? Viz: class Foo { protected Bar $b; // This runs before __construct, is not inherited, and cannot // ever be skipped. If this method exits and any property is still // value-less, TypeError immediately. protected function __init() { $this->b = new Bar(); } public function __construct() { Behaves as it always has. } } That's similar to the "initialize" flag inside the constructor, but splits it off to a separate method that is devoted to just that purpose; it therefore has no parameters, ever, and if you want to initialize an object property based on a constructor argument then you must either make it explicitly nullable or initialize it to a dummy value first. Which... I realize may not work well for service dependencies as the dependency chain could get deep. Of course, that use case is generally a protected property not publicly accessible, so making it nullable and trusting yourself to populate it in the constructor is likely "safe enough". Thoughts? --Larry Garfield

Attachment: [application/pgp-signature] This is a digitally signed message part. signature.asc
« previous php.internals (#102856) next »