Re: [RFC] Asymmetric Visibility, with readonly
| From: | Larry Garfield | Date: | Sun, 13 Nov 2022 21:24:19 +0000 |
| Subject: | Re: [RFC] Asymmetric Visibility, with readonly | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-118995@lists.php.net to get a copy of this message | ||
On Sun, Nov 13, 2022, at 2:08 PM, Larry Garfield wrote:
> 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.
>
> There's two design decisions we've made at this point, both of which we
> think are logical and reasonable:
>
> 1. If specified, the set visibility must be tighter than the get
> visibility. So
protected protected(set) and VUo&‘
> ßrÆÝµðÊ{‹protected public(set)
> are not permitted, for instance.
>
> 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.
>
> These are both reasonable rules. However, it creates a conflict.
> Specifically, in the following cases:
>
> public public(set) readonly string $foo
>
> protected protected(set) readonly string $foo
>
> 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.
>
> 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.
>
> We see two possible ways to resolve this conflict:
>
> 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.
>
> 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.
>
> 3. Some other brilliant idea we've not thought of.
>
>
> 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?
Addendum: Ilija and I were talking past each other a bit, it seems. Allowing protected
protected(set) readonly only in the context of readonly would be straightforward to
implement. It's potentially not the easiest to explain that exception, but implementation-wise
it's fine.
So that gives another viable option to consider:
4. Allow get and set visibility to be both set explicitly to the same level, iff in the presence of
readonly. So protected protected(set) string $foo is not allowed, but protected
protected(set) readonly string $foo is allowed. This gives the most options and the least
pointless syntax, but at the cost of having an exception that needs to be
documented/explained/understood.
--Larry Garfield