Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:108694 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 47330 invoked from network); 20 Feb 2020 10:50:25 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 20 Feb 2020 10:50:25 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id AB7B318050B for ; Thu, 20 Feb 2020 01:06:32 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-lf1-f51.google.com (mail-lf1-f51.google.com [209.85.167.51]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 20 Feb 2020 01:06:32 -0800 (PST) Received: by mail-lf1-f51.google.com with SMTP id 83so1063264lfh.9 for ; Thu, 20 Feb 2020 01:06:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=VrR4zPCGDaL0Dxtru2IDiLyY3Vcx/buFWdIirUcqRv0=; b=QWXHqRF45NNVUNat14tO89g2Epq2cnQF6FHLxff/0nISTBYWPcQYQ4ialT19tAhnO2 haRMWfB9a4W5UYO370/q4ZfxzkdIPN30k5368OdZnDAQ2VW6Z/O7XuwkX/Xf6WQ1ARwE grLPt1tbbXtwWVyP2Yb6Mpv+JBZds+7CSdw83J8u2ip4Lk/bFsUYd6XAw7LE6xi1u1ug 2uPBd3I5S1jiU/MfNGfiezlZgqHuCox01980mU2SDf/hvgCoMhgaFcohj2XQsILRbcw2 jh0gy+0v1RsMdGUefl8Mqj5tN5ehyzLb3x0njD9NLbJuIiID+Cs8Yf7mEa/TwS0y6TXG J3hA== 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=VrR4zPCGDaL0Dxtru2IDiLyY3Vcx/buFWdIirUcqRv0=; b=nnWn7Sz+M0468iby4FluBhcDTP3MQCqyba8fJhvF9ruFb4jZ2NdDu5CqgECrXRNIb1 Y0bxSwnaYimTL/VN4JVOY1iq3X7or1gvI4FFmlGuQRRkFyKCO08RDfmJnSKLDvuSA6+m jguBGe+QokOE4Nk99I+eBhISROe0s0LxYqktK7s0k5g0HmD27W7Z8fJXKD1ZmQNlyAs5 u5hiXyjP5mtYcZHlntDhZTvDC9D++hbyULGkfg2M2TkVsN+QXo+MkfCaFXw/m7VoKLcp lRFu7B1I1XaVTqhlwwRhy6oyQp3s+j8T7RRvOnO0uQyaFUhOb1az1EvjMUcfqRVNzEJb m15Q== X-Gm-Message-State: APjAAAVKsIXwjNLOocP5s5DDgYXiKh1qdMZH/V9Q0XjMOv9CT4c8bKJI 2oayYRLQEWZUTRpW6hmBvFLssXfmRbTTEblzpOo= X-Google-Smtp-Source: APXvYqwns+Z+oh32sCWfwFGPydnUqVMfm6Asi1Uy8waSppq/fQtRXI/u5jDxBe93KB2QxKgJPLVGz+oH2n8yXArsCq4= X-Received: by 2002:ac2:4add:: with SMTP id m29mr16053134lfp.190.1582189589622; Thu, 20 Feb 2020 01:06:29 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: Date: Thu, 20 Feb 2020 10:06:13 +0100 Message-ID: To: Matthew Brown Cc: =?UTF-8?B?TcOhdMOpIEtvY3Npcw==?= , PHP Internals List Content-Type: multipart/alternative; boundary="00000000000074f3cd059efe381a" Subject: Re: [PHP-DEV] [RFC] [DISCUSSION] Immutable/final/readonly properties From: nikita.ppv@gmail.com (Nikita Popov) --00000000000074f3cd059efe381a Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Thu, Feb 20, 2020 at 1:27 AM Matthew Brown wrote: > Someone recently requested something similar for a PHP static analysis to= ol > I wrote (https://psalm.dev/r/f75997a263), though that version only allows > lazy initialisation inside the class in which a given property is declare= d. > > Personally I don't like either approach =E2=80=93 I think per-property ge= tters and > setters would be a more appropriate venue for this functionality, somethi= ng > like: > > property int $s { > public get; > private set; > } > > This pattern could also be extended to support per-property getter and > setter methods. > While I certainly like the idea of per-property getters/setters, I think that both of these have their place. This RFC proposes readonly properties, that can be initialized once, and then never modified again, even within the same class. Getters/setters only provide the possibility of having asymmetric visibility: They prevent modifying the property from outside the class, but it can still be modified inside the class. In that, readonly properties offer a stronger guarantee. Of course, that does leave the question of how often you need one or the other. Maybe just the asymmetric visibility is sufficient for most practical purposes, in which case it may not be worthwhile to introduce readonly properties as a separate feature. Two comments on the specifics of the RFC: The RFC allows specifying a default value for readonly properties. However, a property for which a default value has been specified will always have that value, as it cannot be overwritten in the constructor. If you write "public readonly int $foo =3D 42", then $object->foo is *always* going to b= e 42. I'm not sure what that would ever be useful for, and it seems like something that is bound to be confusing. Maybe it would make more sense to forbid readonly properties with default values? (That way, the rule that readonly properties have to be typed falls out naturally as well -- untyped properties always have a default.) Regarding the keyword choice, I think you can drop "sealed" from the list, as it is an established term that affects inheritance, not mutability. Of the choices you present, "immutable", "readonly" and "writeonce" seem like the most viable candidates. "writeonce", while the one that is most technically accurate, is also *unnecessarily* technically accurate and not intuitive. From the perspective of an API consumer, I think that "readonly" is the most accurate description of how they are supposed to interact with the property. The API contract you want to expose is that they can only read from the property, not write to it. Calling it "writeonce" would be quite confusing in that context, because the API consumer is never expected to write to the property. In the majority of cases you will be providing fully initialized objects, in which case they are indeed readonly for the consumer -- the details of the write-once property are only relevant in special cases like ReflectionClass::newObjectWithoutConstructor() for serialization libraries, or lazy initialization like in Marco's ProxyManager. Regards, Nikita > On Wed, 19 Feb 2020 at 12:06, M=C3=A1t=C3=A9 Kocsis wrote: > > > Hi Internals, > > > > I'd like to move my RFC forward to the discussion phase: > > https://wiki.php.net/rfc/write_once_properties > > > > In short, I propose to add support for a new property modifier that wou= ld > > allow properties to be initialized, but not modified afterwards. > > > > Cheers, > > M=C3=A1t=C3=A9 Kocsis > > > --00000000000074f3cd059efe381a--