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*.

Reply via email to