Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:103187 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 77639 invoked from network); 19 Sep 2018 23:57:55 -0000 Received: from unknown (HELO mail-lj1-f172.google.com) (209.85.208.172) by pb1.pair.com with SMTP; 19 Sep 2018 23:57:55 -0000 Received: by mail-lj1-f172.google.com with SMTP id v9-v6so6229936ljk.4 for ; Wed, 19 Sep 2018 13:04:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=ChXCD5gALKnXzTFMwDe04El6ZKW9wxQimhkf0gVle0s=; b=iK4Z7Yid2YyMOSbuTvjvwe2BNxg8iwbD0MLnSLfb8zaLSsr8IHYyooGEiztiOtlyQS 55IhkYz4de9TnTz5ym+jYiolNLFabkzCju0sdIt1cS5gS2fJ3IAybiQWakxoEBQR7oxp IIAry5MzciMwFVOZL4pOgGORmS94LlBIPxQ+TuqikmAhp9vrA2octea+Z6N9577ZMUO6 UNPAy/xVJjK3zifnM0gdBoYevkEXEn3S0zTuq6kMJBrfpvab8L8YnbDt2JRhVHaTzZPR rdOJqtb8H1bfQOQSvLMDYy2ZW1qdbTXxGXoeg+oE5OwgoNuFULDDwaePWIFGYDwTZnTP TipQ== X-Gm-Message-State: APzg51B3UDNJ1NZcZF3o5KrTIUhDK+x10+Gmxt18rbzbTqaT0kxyOvva DvJJoVbpl+YgZ5/WfJ8yD1xyo4nqJKj0Dw/yLos= X-Google-Smtp-Source: ACcGV60Px/s2j3HlLnU1x2PgbRNXwhUQcgIz5jyNySqR2l5NI8uwZYWtginPdS3dXqWrNz1x3dRJmYQJIArCvdqeJfY= X-Received: by 2002:a2e:2f19:: with SMTP id v25-v6mr572720ljv.113.1537387461106; Wed, 19 Sep 2018 13:04:21 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 19 Sep 2018 14:04:04 -0600 Message-ID: To: Rasmus Schultz Cc: Rowan Collins , internals Content-Type: text/plain; charset="UTF-8" Subject: Re: [PHP-DEV] [RFC] [VOTE] Typed properties v2 From: levim@php.net (Levi Morrison) On Wed, Sep 19, 2018 at 1:06 PM Rasmus Schultz wrote: > > On Wed, Sep 19, 2018 at 7:43 PM Rowan Collins wrote: > > > I agree that this is a hard problem, but I don't agree that this decision > > is being made "for now". If we allow "non-nullable but uninitialized" > > properties now, it will be extremely hard to change their behaviour in > > future. > > I'm with Rowan on this one. > > This concept of "uninitialized" frankly seems like an allowance for > people who insist on writing poor code. > > Nulls are bad, and "unintialized" is just another kind of "null" with > a built-in run-time type-check that executes on read - too late. > > The first example given is just bad: > > class Point { > public float $x, $y; > > private function __construct() {} > > public static function fromEuclidean(float $x, float $y) { > $point = new Point; > $point->x = $x; > $point->y = $y; > return $point; > } > } > > You define two invariants: $x and $y must be floats - and then proceed > to break those constraints in the constructor? > > Wrong. The RFC itself accurately states that "this code can be > rewritten to indirect through __construct() instead" - as shown in the > previous example. > > Now why would you deliberately open the fences and knowingly invite > people to write poor code like this? > > As for the second example: > > class Point { > public float $x, $y; > > public function __construct(float $x, float $y) { > $this->doSomething(); > $this->x = $x; > $this->y = $y; > } > } > > If doSomething() attempts to read an uninitialized property while the > constructor is still executing, throwing a helpful "uninitialized" > error is fine. > > But, in my opinion, once the constructor has executed, the invariants > as declared by the class itself must be satisfied. > > If there's one meaningful use-case for allowing objects in a > partially-initialized state, it's during > hydration/unserialization/reflection scenarios, maybe - but in those > cases, you're willfully bypassing the constructor; it's not the > everyday 95% use-case and some risk is acceptable here, you'll get > around it with tests. But nobody wants to write tests all day to see > if any classes contain "unininitialized" properties - that misses half > the whole point of being able to declare those types in the first > place, e.g. makes type-hinted private/protected properties totally > unreliable. > > Once this is in a release, it'll be unfixable, and in my opinion will > likely go down in history as another one of those little things we > wish we could go back in time and fix :-/ > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php PHP permits skipping constructors. The code may not work if you do so, but it's the state of how things are. Validating after a constructor call will not catch all issues while requiring a constructor, whereas I think this code should be allowed: class User { public int $id; public string $preferred_name; public string $username; } I doubt we will come to a resolution -- these points were already pointed out in the discussion phase.