On Wed, Sep 19, 2018 at 1:06 PM Rasmus Schultz <ras...@mindplay.dk> wrote:
>
> On Wed, Sep 19, 2018 at 7:43 PM Rowan Collins <rowan.coll...@gmail.com> 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.

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to