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.

2.

The concern would only appear if someone is deliberately doing something 
non-stable

Or if someone accidentally calls a (deep) function chain that is non-pure.

3.

Or, for a more real-world and larger example, PHP 8.4 requires this:

This is false. You are perfectly able to write this in PHP 8.4:

    final readonly class Entry
    {
        public readonly $terms;

        public function __construct(
            public string $word,
            public string $slug,
            array $terms,
        ) {
            $this->terms = $this->upcastTerms($terms);
        }

        private function upcastTerms(array $terms): array
        {
            $upcast = static fn (Term|array $term): Term
                => $term instanceof Term ? $term : new Term(...$term);
            return array_map($upcast, $value)
        }
    }

In no way do you need to use a property hook.

4.

// New code in 8.5:
$p = new PositivePoint(3, 4);
$p2 = clone($p, ['x' => -10]);

This is not legal code in PHP 8.5. Clone-with respects visibility and since your asymmetric visibility RFC included the change, you are probably aware that `readonly` implies `protected(set)`.

5.

but are now necessary to ensure that invariants are enforced.

And therefore with PHP 8.5 hooks are not necessary to enforce invariants, except in the rare case where a `public(set) readonly` property is used.

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.

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.

Best regards
Tim Düsterhus

Reply via email to