Nick, Larry, On Fri, Jul 18, 2025 at 2:01 PM Nicolas Grekas <nicolas.grekas+...@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. > > >> >> 6. >> >> > So no guarantees are softened by this RFC. >> >> Yes, they are. Unless `__get()` is implemented on a class (which is >> explicitly visible as part of the public API), readonly guarantees the >> immutability of identity. > > > Which is not really relevant when talking about immutability. > What everybody is looking for when using that word is immutable objects. This is not what I am looking for, so I disagree. I would like immutable objects as well, but unless the object itself is a readonly class as noted above, I would not expect it to mean immutable objects. > > >> 7. >> >> > While that is an interesting idea that has been floated a few times, it >> > has enough complexities and edge cases of its own to address that we feel >> > it is out of scope. >> >> While it certainly is your right as the RFC authors to consider certain >> things out of scope for an RFC, I strongly oppose the notion of shipping >> something that is strictly inferior and comes with obvious semantic >> issues due to perceived complexity of another solution and then >> following up with the proper solution that has already been identified. >> As I've outlined in my previous emails, I found defining semantics for >> an 'init' hook straight-forward when looking at how PHP works as of today. >> >> 8. >> >> > However, this RFC is in no way incompatible with adding an init hook in >> > the future should it be proposed. >> >> This is true, but as I've mentioned before, an 'init' hook would enable >> the same use cases without bringing along issues. So it really should be >> "one of them, but not both" (with "one of them" being the init hook). >> >> -------- >> >> After reading through the discussion, it seems the only argument against >> the 'init' hook is perceived complexity. It is not at all clear to me >> why this means that we must now rush something with clear issues into >> PHP 8.5. > > > I'd understand the arguments you're pushing for if readonly were appropriate > to build immutable objects. Yet that's not the case, so such reasoning is > built on sand I'm sorry... > > To me the RFC enables useful capabilities that authors are going to need. Or > find workarounds for. Which means more ugliness to come... 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*.