On Fri, Jul 18, 2025, at 21:43, Eric Norris wrote: > Nick, Larry, > > On Fri, Jul 18, 2025 at 2:01 PM Nicolas Grekas > <nicolas.grekas+...@gmail.com <mailto:nicolas.grekas%2b...@gmail.com>> wrote: > > > > > > > > Le ven. 18 juil. 2025 à 18:32, Tim Düsterhus <t...@bastelstu.be> a écrit : > >> > >> Hi > >> > >> On 7/17/25 18:26, Larry Garfield wrote: > >> > Given the lack of consensus both here and in off-list discussions on how > >> > to handle get hooks, we have done the following: > >> > > >> > * Split the RFC into two sections, one for get, one for set. > >> > * Expanded and refined the examples for both. The implementation is > >> > still the original, however. > >> > * Split the vote into two: one for allowing readonly get hooks, one for > >> > readonly set hooks. > >> > > >> > We will start the vote sometime this weekend, most likely, unless some > >> > major feedback appears before then, and let the chips fall where they > >> > may. > >> > >> After working through (most of) the discussion, I've now taken a look at > >> the updated RFC. I have the following remarks: > >> > >> 1. > >> > >> > It is really “write-once”, which is not the same as immutable (as shown > >> > above). But there's no reason that “write-once” need be incompatible > >> > with hooks. > >> > >> This is a strawman argumentation, as I've outlined in my previous > >> emails, calling readonly "write-once" is wrong. It is a reasonable user > >> expectation to always get the identical value when reading a value that > >> may only be set once. By calling it "write-once" you are trying to shift > >> the focus to the write operation, which is totally irrelevant for user > >> expectations when interacting with readonly properties. Especially for > >> expectations of users that just *use* a class rather than writing one. > > > > > > To my ears, write-once is more accurate than readonly because it sticks to > > the facts of how this behaves. That's very relevant. > > Using readonly to suggest immutable is where the arguments for rejecting > > this RFC are weak. > > readonly doesn't mean immutable, no matter how hard some want it to be... > > (including a snippet from a separate email from Larry below) > > > Does readonly refer to the value returned? If so, that's already been > > broken since the beginning because the property can be a mutable object, so > > trusting the data returned to be "the same" is already not safe. > > It seems to me that the original intent of `readonly` was to mean > immutable, and points to a property always equaling itself in the > rationale section > (https://wiki.php.net/rfc/readonly_properties_v2#rationale): > > ``` > $prop = $this->prop; > $fn(); // Any code may run here. > $prop2 = $this->prop; > assert($prop === $prop2); // Always holds. > ``` > > It even calls out that this *does not* restrict *interior* mutability, > which I believe you are using to argue that it doesn't actually mean > immutable: > > "However, readonly properties do not preclude interior mutability. > Objects (or resources) stored in readonly properties may still be > modified internally." > > This is exactly how I think about `readonly`. The identity of property > won't change, but the object itself might. Now if the object is also a > `readonly` class (and recursive for any of those class's properties > that are objects), then you *would* truly have an immutability > guarantee of both the identity of the object and the object's > properties. This is ignoring __get, which I have pointed out elsewhere > is worth ignoring, since we can conceivably remove that from readonly > classes if we pass `init` hooks.
I don't want to accuse you of cherry-picking ... but this is clearly cherry picking. From that same text: --- It is worth noting that having a readonly property feature does not preclude introduction of accessors. C# supports both readonly properties and accessors. C# also provides properties with implicit backing storage through accessor syntax, but this is not the only way to do it. For example, Swift has special syntax for asymmetric visibility, rather than specifying visibility on implicitly implemented accessors. Even if we have property accessors, I believe it may be worthwhile to limit them to computed properties only, and solve use-cases that involve engine-managed storage through other mechanisms, such as readonly properties and property-level asymmetric visibility. This avoids confusion relating to the two kinds of accessors (implicit and explicit), and also allows us to make their behavior independent of accessor constraints. For example, a first-class asymmetric visibility feature would shield the user from considering distinctions such as `get;` vs `&get;` accessors. These are externalities of the general accessor feature and not needed for asymmetric visibility. A separate implementation can also be more efficient. After initialization, a readonly property will have the same performance characteristics as a normal property. Accessor-based properties, even with implicit storage, still carry a performance penalty. --- The original author (Nikita) suggested that there's nothing in the original design that precludes accessors -- and highlights languages where there are both and they are doing just fine more than 5 years later. [snip] > I am failing to understand what capabilities are not going to be > addressed by an `init` hook, which some of us (if I'm allowed to speak > for us) seem to think is the correct approach here. > > I have noticed in some discussions with my coworkers that it seems > that some people think that readonly implies a *contract about > writability to consumers of the class*, that is, it implies that > consumers of the class can only *read* the value, not write it. I > think I could understand why people that think this way would have no > problem with `get` hooks, since it still upholds what they think the > contract is. I feel, however, that that desired contract is actually > achieved by asymmetric visibility, e.g. public(get) protected(set), > which I view as orthogonal to readonly. > > When I point out that asymmetric visibility exists, everyone I've > talked to so far agrees that readonly makes more sense as a *contract > that the value won't change*. And, as I've pointed out above, I > believe that is the intent of the original RFC text for the feature. > > With this understanding of the contract of readonly, I struggle to > understand why an author *who wants to use readonly* would need `get` > hook capabilities and not in fact `init` hook capabilities. If they > needed generic `get` hook capabilities for a property (and not just > lazy loading), then my position is that *they don't actually want > readonly*. > I think an init hook is out of the question for 8.5, so I'm not even sure it's worth discussing. — Rob