Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:119001 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 15746 invoked from network); 14 Nov 2022 09:15:16 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 14 Nov 2022 09:15:16 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 04B3E180503 for ; Mon, 14 Nov 2022 01:15:15 -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=-1.9 required=5.0 tests=BAYES_00,HTML_MESSAGE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS17378 206.123.64.0/18 X-Spam-Virus: No X-Envelope-From: Received: from mail1.25mail.st (mail1.25mail.st [206.123.115.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 14 Nov 2022 01:15:14 -0800 (PST) Received: from smtpclient.apple (unknown [49.48.218.224]) by mail1.25mail.st (Postfix) with ESMTPSA id 5099160419; Mon, 14 Nov 2022 09:15:08 +0000 (UTC) Message-ID: Content-Type: multipart/alternative; boundary="Apple-Mail=_726282F7-F28E-4CD4-AE0B-81B3594DE458" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.1\)) Date: Mon, 14 Nov 2022 16:15:04 +0700 In-Reply-To: <0854b030-c51c-4c1b-a7dd-22835a1e5da9@app.fastmail.com> Cc: php internals To: Larry Garfield References: <0854b030-c51c-4c1b-a7dd-22835a1e5da9@app.fastmail.com> X-Mailer: Apple Mail (2.3696.120.41.1.1) Subject: Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly From: php-lists@koalephant.com (Stephen Reay) --Apple-Mail=_726282F7-F28E-4CD4-AE0B-81B3594DE458 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On 14 Nov 2022, at 03:08, Larry Garfield = wrote: >=20 > Hi folks. Ilija is nearly done with the implementation for asymmetric = visibility and flushing out edge cases, but we've run into one design = question we'd like feedback on. >=20 > There's two design decisions we've made at this point, both of which = we think are logical and reasonable: >=20 > 1. If specified, the set visibility must be tighter than the get = visibility. So `protected protected(set)` and `protected public(set)` = are not permitted, for instance. >=20 > 2. `readonly` is a "write once" flag that may be combined with = asymmetric visibility. If no set visibility is specified, `readoly` = implies `private(set)`, but a different set visibility may also be = provided. >=20 > These are both reasonable rules. However, it creates a conflict. = Specifically, in the following cases: >=20 > public public(set) readonly string $foo >=20 > protected protected(set) readonly string $foo >=20 > These would be the only way to have a non-private-set readonly = property. While the first is in practice quite unlikely, the second has = valid use cases. (In particular, a base class that provides properties = expected to be set by a child constructor, and then used by a method in = the parent class.) However, it would not be allowed under the rules = above. Working around it would require specifying `public = protected(set) readonly...`, which means exposing a property that likely = should not be exposed. >=20 > That creates an odd situation where readonly and asymmetric visibility = may only be combined "sometimes." That is not deesireable. The only = way to combine them in their current form is to allow `protected = protected(set)` only if readonly is in use, which is excessively = complicated both to implement and to explain/document/use. >=20 > We see two possible ways to resolve this conflict: >=20 > 1. Relax the set-is-tighter restriction. That would allow `protected = protected(set)` etc. on any property. It wouldn't be particularly = useful unless readonly is being used, but it would be syntactically = legal and behave as you'd expect. We could still disallow "set is more = permissive" combinations (eg, `private public(set)`), as those have no = apparent use case. >=20 > 2. Disallow readonly and asymmetric visibility being combined, because = readonly already has a hard-coded implied asymmetric visibility. This = option removes some potential use cases (they would most likely drop the = readonly), but has the upside that it's easier to re-allow at some point = in the future. >=20 > 3. Some other brilliant idea we've not thought of. >=20 >=20 > Both are viable approaches with pros and cons. We're split on which = way to go with this, so we throw it out to the group for feedback. = Which approach would you favor, or do you have some other brilliant idea = to square this circle? >=20 >=20 > --=20 > Larry Garfield > larry@garfieldtech.com >=20 > --=20 > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php >=20 Hi Larry, I asked for some clarification / further thought about the magic = getters/setters interaction of this RFC back when you announced it, and = never heard much besides saying that you=E2=80=99re working on a = consolidated response to the feedback, but I=E2=80=99ve not seen = anything regarding what I=E2=80=99d asked about, and the RFC still seems = to have the (IMO) confusing and inconsistent magic getters/setters = interaction described. As I understand it, you=E2=80=99re suggesting that a property declared = as `public protected(set)` would never trigger __set(). While I understand that this is meant to =E2=80=9Ckeep consistency with = readonly=E2=80=9D, I would imagine people would want to use native = asymmetric visibility on objects that currently have protected (or = private) properties that are accessed via magic getters and setters. I = think it would be a natural assumption that asymmetric visibility would = allow the user to remove the often boilerplate __get method, while = maintaining the ability to have checks/other logic beyond simple type = checks when a property is being set. Having the association of a *set* = action tied to the *get* visibility is very unintuitive to me. The impact of this =E2=80=9Csame=E2=80=9D limitation on readonly = properties is IMO greatly reduced, because of the nature of something = being readonly. The ability to run some logic when writing to a property = that=E2=80=99s otherwise readable is surely a concept that=E2=80=99s = very common and easy to understand, it=E2=80=99s literally the next = example after (1) =E2=80=9Creadonly=E2=80=9D and (2) =E2=80=9Casymmetric = visibility=E2=80=9D in Nikita=E2=80=99s original property accessors RFC. The stated reason (on both this and the readonly RFC) for not allowing = __set() is "to avoid surprising behaviour=E2=80=9D. To me, having a = field marked as `public protected(set)` then not call __set() when = setting a property from outside the class **is** the surprising = behaviour. Cheers Stephen --Apple-Mail=_726282F7-F28E-4CD4-AE0B-81B3594DE458--