Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:103212 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 86282 invoked from network); 21 Sep 2018 11:51:43 -0000 Received: from unknown (HELO mail-pl1-f173.google.com) (209.85.214.173) by pb1.pair.com with SMTP; 21 Sep 2018 11:51:43 -0000 Received: by mail-pl1-f173.google.com with SMTP id p5-v6so5594816plk.3 for ; Fri, 21 Sep 2018 00:58:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mindplay-dk.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=dgM7Nv7ksqwHaA1ZUKy9N4IOtf5sokdlgVGMyyTZSTA=; b=G9uBE5Sm2clmwyp2TPPvwyRsd+2dAFXJyeptNWg7BGp67GV/8D1NtIUune6A8wNGH5 UiQ7ZqrZYaJem7gmG+xClAHtQ3hcr/7C8zCdpALUTnOj2tHE83A5oSY0FxgheYNdy5Qo 0O0X5AUEtz8eeDaTyjmA0oPdjyZEDLgXMBslesrENj9hvd2RRD65OVO+AFbDfTrmw2Y3 QVpCfke+O2UvU1mjc9HAdGUaJWIC+KJ0/hQQAPmg1SwczEYzIDIo50vV5GuHUyL60u/M +vCuEPbYStgY071fVOcRYdLQ53CpsjuT/FAWBCU2Ncjowd0yHEvp3S2Q7phS56G2V3D4 WI0Q== 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=dgM7Nv7ksqwHaA1ZUKy9N4IOtf5sokdlgVGMyyTZSTA=; b=niOzZWkfP/cFmhVtOl2DsjtPxY4725yICivcj+ZoaI3KbVjIzg7EixPKrsPAjjEh1C 278r57cc5MUlYhhfWustEtiG8VWnysbbvajdtxsTkc4A/ySSl8Px4DgFN86cJCX11W91 axB7Pl+S7KcAGUk18L8+9POwZHTtWmrf3boKpuNZRvjDPTlSCc9Yw5rBiBAB4uyWW8NO W+DX6kQx5+zeW+kg3ipuule/4crPZ1Lki2MM7aVaQtCM0JH+3OCCbobCX01/CDV92sfM bVt2qsjKlGDavb7lif0CHD32qv1KjnnZ5jMne2L78Y+IiaqG+HBZ3VJDmFAQV4rHf981 TPYw== X-Gm-Message-State: APzg51D/sHcSUAbg/QpTJBGkTwvOEKp+f5/F2rpdSi7sFaP4uswsEMVU 5JNOtO4q21EZWdtdZLWX/k1peeLhJzwO/x2XnBlxziRH X-Google-Smtp-Source: ANB0VdZoYTvNSp2ByHhyT2Jl0RLA/rNe7drnV4XyWqz6BKZI5/e3DKbICeTrhxT1DK+GNBypItiA2ZKQ1CFoaH6KFJA= X-Received: by 2002:a17:902:76c1:: with SMTP id j1-v6mr7298448plt.278.1537516711675; Fri, 21 Sep 2018 00:58:31 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Fri, 21 Sep 2018 09:58:21 +0200 Message-ID: To: levim Cc: rowan.collins@gmail.com, PHP internals Content-Type: text/plain; charset="UTF-8" Subject: Re: [PHP-DEV] [RFC] [VOTE] Typed properties v2 From: rasmus@mindplay.dk (Rasmus Schultz) On Thu, Sep 20, 2018 at 4:50 PM Levi Morrison wrote: > > This will be my last reply to this thread. Fundamentally: > > class User { > public ?int $id; > public ?string $preferred_name; > public ?string $username; > } > > ^ This permits null properties at all times. This is acceptable > behavior if null is valid for the domain. It is not valid for this > domain -- all 3 are required. If all three are required, your constructor needs to reflect that. The reason constructors even exist in the first place is to initialize the object's data members and establishing the invariant of the class. Constructors are supposed to prepare objects for use. Your (empty, implicit) constructor isn't doing that. Your reasoning about this is circular - you want your properties to be optionally initialized and non-null at the same time. You get around this by coming up with a new term "undefined" for a special kind of null that triggers run-time exceptions on read. The whole idea is unnecessarily complex, and will certainly lead to silent bugs that allow partially-initialized domain objects to pass through many layers of a system without getting caught until some code tries to read an "uninitialized" property. function make_foo(): Foo { return new Foo(); // missing a property } function x() { ... } function y() { ... } function z() { ... } x(y(z(make_foo())); The instance travels through layers and layers of callls and fails somewhere in the x() or y() function because of a missing value ... why was the value missing? why wasn't it initialized? where was it supposed to have been initialized? where did this bad instance of Foo even come from? All that information is lost in a call-stack that's long gone by the time you invoke x() and you'll have to backtrack through layers and layers of code to try to figure out where this bad instance came from. This will be an everyday thing with code like that. To say that we don't need to enforce invariants at the time of construction is to say we don't need to enforce them at all - enforcing them "maybe later" is the same as not enforcing them. That is, when they trigger an error, it's no different from a null-value triggering a similar error. No matter how you twist it, uninitialized is the new null. I'm fine with unintialized as an implementation detail that ensures you can't read from properties while the constructor is busy establishing the invariant. I'm not at all fine with unintialized as a new language feature.