Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:119061 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 33496 invoked from network); 30 Nov 2022 15:10:21 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 30 Nov 2022 15:10:21 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 281E1180504 for ; Wed, 30 Nov 2022 07:10:20 -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.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS, SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS29838 64.147.123.0/24 X-Spam-Virus: No X-Envelope-From: Received: from wout5-smtp.messagingengine.com (wout5-smtp.messagingengine.com [64.147.123.21]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 30 Nov 2022 07:10:19 -0800 (PST) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.west.internal (Postfix) with ESMTP id 68E46320093F for ; Wed, 30 Nov 2022 10:10:18 -0500 (EST) Received: from imap50 ([10.202.2.100]) by compute4.internal (MEProxy); Wed, 30 Nov 2022 10:10:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-transfer-encoding:content-type :date:date:from:from:in-reply-to:in-reply-to:message-id :mime-version:references:reply-to:sender:subject:subject:to:to; s=fm1; t=1669821017; x=1669907417; bh=m3YPSBhOUa5Fhfg8AWrALI9uS 8T1NzG8a3FozT/UBLM=; b=DtjmXKkSlMaVe/WtOWaux/ZKE2HTbonCwKg7gcpiY KgvpQR1ZbwVvXurdX5aI/WNy5tg5vKFPM88CwN2tTd0FTEP9+JmFm/FznzGAkT5A a6f+6qgo3c4jc9SxbiVa+Mi6sQNs74mTIk5XsDRwNFdZ1/2bP907bu4dJBaX8Hov T8GBbYtUJMpAHdPfoPOQWGaj5ku0c1kEjJIucF53qhG1bFwJglS7FD9lC00Aczol BOJyb+BY9/iDQQboI/uYwdMY2uRgk52Kl1qDuT2+7VhreO/YLAAfVRdGcgsRYM86 B49rop7xGGyAbxksIjZPlpdKVTULw3jMcixCbONlxAZdQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:date:feedback-id:feedback-id:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1669821017; x=1669907417; bh=m 3YPSBhOUa5Fhfg8AWrALI9uS8T1NzG8a3FozT/UBLM=; b=wuYshtGuXFYiSftdH QkrzltkQoeuQshAPIaqd8Isxgnp8qyBiYNknHKinapLdTp1v7UY6kYU9+XjxNNz5 1MHCQSLMuTMFjzqbDvB65oWJiWyCxQuBUc46W7axJn6R6qsvwCQlKkcfx/pLPAs7 wlA1sebKzsz1tMLUmgw2TyI4jyL0wtX77YW//MyNxka4+iq95uGujM/HBPijf/vc Tjvln7CF/eTRBeZ9Wn1bqtI3DEBA/YFQhLT7dpnSD4KkL+p04eZ403pShR0z1vuF ZfWIV+aVi1Qnvw9cyysi6ng/0b/6b6FNAsfN3mytImkaERDNq141p0fmvg0xVH1r 2NoqQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrtdefgdejudcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefofgggkfgjfhffhffvufgtgfesthhqredtreerjeenucfhrhhomhepfdfnrghr rhihucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtoh hmqeenucggtffrrghtthgvrhhnpedtgfdtvefghfejhfffgeeuledttdeihfeugfdtuefg heejgeejvdeitedtheffkeenucffohhmrghinhepphgvrghkugdrtghomhenucevlhhush htvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehlrghrrhihsehgrghr fhhivghlughtvggthhdrtghomh X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id A6AC51700089; Wed, 30 Nov 2022 10:10:17 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.7.0-alpha0-1115-g8b801eadce-fm-20221102.001-g8b801ead Mime-Version: 1.0 Message-ID: <29f2a6a5-08f7-4abb-965f-56bb1cc49565@app.fastmail.com> In-Reply-To: References: <0854b030-c51c-4c1b-a7dd-22835a1e5da9@app.fastmail.com> <831b9906-dc0c-420c-b22f-8a0cc8a1ad64@app.fastmail.com> <434BDABD-8551-46C8-98EC-8CA87952AE25@gmail.com> Date: Wed, 30 Nov 2022 09:09:40 -0600 To: "php internals" Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly From: larry@garfieldtech.com ("Larry Garfield") On Tue, Nov 29, 2022, at 11:25 PM, Stephen Reay wrote: > Hi Larry, > > Thank you for clarifying the setter behaviour in more explicit terms,=20 > but I have to say I=E2=80=99m quite disappointed in this continued =E2= =80=9Cuse the=20 > logic of readonly to apply to something that is explicitly not=20 > readonly=E2=80=9D - this is even more stark now that you=E2=80=99ve ex= plicitly made=20 > them mutually exclusive behaviours. > > I=E2=80=99m generally very in favour of maintaining consistency, but t= his seems=20 > like it=E2=80=99s using technical consistency as an excuse to justify=20 > unintuitive behaviour that breaks consistency in another, much more=20 > obvious way. > > > Can you explain why it makes more sense to maintain consistency with=20 > =E2=80=9Creadonly=E2=80=9D than it does to maintain consistency with t= he existing=20 > =E2=80=9C__set()=E2=80=9D behaviour for properties, particularly now t= hat you=E2=80=99ve=20 > indicated these features (asymmetric visibility and readonly) are=20 > mutually exclusive?=20 > > While it=E2=80=99s stated multiple times that =E2=80=9Creadonly=E2=80=9D= introduced a limited=20 > form of asymmetric visibility, and thus this is a continuation, in=20 > terms of intuitiveness, the existing __set() rules are very easy to=20 > comprehend even with readonly: > > - if the property is declared as public, __set() is never called; if=20 > it=E2=80=99s declared as protected, __set is called when the property = is=20 > accessed from outside that class or it=E2=80=99s hierarchy. Yes, I kno= w that=20 > readonly imposes an implicit visibility difference - but that is=20 > essentially an implementation detail, from the point of view of the=20 > userland developer, it=E2=80=99s not a clear statement of intended beh= aviour on=20 > their part, expressed through the code as written. > > For example, with `public readonly int $foo` it=E2=80=99s quite obviou= s why=20 > __set() isn=E2=80=99t called, using the exiting well-understood logic:= it=E2=80=99s a=20 > public property. PHP applies a kind of asymmetric visibility to the=20 > property behind the scenes, but that isn=E2=80=99t what the developer = declared,=20 > it=E2=80=99s the implementation. This behaviour matches that of regula= r,=20 > non-readonly fields: when the field is declared public (or has implici= t=20 > public visibility) __set() is never called. > > If we make that field protected, __set() will be called when the=20 > property is written to from outside the class, regardless of whether=20 > it=E2=80=99s readonly or not. > > > What you=E2=80=99re proposing changes that, in a way that is completel= y=20 > unintuitive: when attempting to *write* data to a property that is=20 > marked as protected(set), the __set() method will not be called. > > > So please, can you explain to me why consistency with an implementatio= n=20 > detail of readonly properties is more important than consistency with=20 > declared developer intention for regular properties via the magic=20 > setter method? There's a couple of reasons. One, and arguably the most important, readonly and aviz being incompatib= le is, hopefully, a temporary situation. There's some fiddly bits to wo= rk out design-wise, and based on earlier comments in the thread we're go= ing to punt on that for now to avoid that dragging down the whole RFC. = I believe we absolutely should allow them together in the future (maybe = in a later 8.3 RFC, maybe a future version, TBD), which means ensuring, = now, that they are compatible in the future. This approach involves the= fewest future BC breaks. Second, I wouldn't call the current behavior of readonly a mere implemen= tation detail. It's weird and unexpected, I'd agree, but only as a side= effect of previous design decisions, some of which are even older than = readonly. But it's an observed behavior that code can rely on, and in s= ome cases does. For example: https://peakd.com/hive-168588/@crell/php-tricks-lazy-public-readonly-pro= perties The "unset a declared property to force it through __get once" is a tric= k that some ORMs use extensively. readonly just inherited that, leading= to the current behavior: __set depends on the write/set visibility of t= he property and its settedness. This RFC doesn't change anything there.= =20 The alternative would be to have __set called always for a non-public-se= t property. However, that is a place for bugs, as you then can't not ha= ve a back-door way to publicly set a property even if it's declared priv= ate(set). (Or, you have to be very careful in your __set to avoid it.) = That is both inconsistent with the language today, and error prone. Finally, we're planning to work in the near-future on property hooks (ak= a property accessors), which would allow per-property custom set routine= s. That would largely remove the issue entirely, as the use of __set wo= uld go way down and you'd basically never have to use it with a declared= property, fancy tricks or no, so this issue would never come up at all. --Larry Garfield