Re: [RFC] Readonly property hooks
| From: | Nicolas Grekas | Date: | Tue, 08 Jul 2025 15:32:44 +0000 |
| Subject: | Re: [RFC] Readonly property hooks | ||
| References: | 1 2 3 4 5 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-127959@lists.php.net to get a copy of this message | ||
Hi Larry et al.
Le mar. 8 juil. 2025 à 17:12, Larry Garfield <larry@garfieldtech.com> a
écrit :
> On Tue, Jul 1, 2025, at 9:27 AM, Tim Düsterhus wrote:
> > Hi
> >
> > Am 2025-06-09 17:11, schrieb Larry Garfield:
> >> I also fleshed out the __get mention with an example that shows what
> >> you can already do today, and in fact could since 8.1 when readonly was
> >> introduced. The hard guarantee of idempotency has never actually been
> >> there. (This also speaks to Claude's concern.)
> >
> > I don't think this really resolves Claude's concern. While it is
> > certainly true that the guarantees do not currently hold, I don't
> > believe this is strong enough of a reason not to provide for stronger
> > guarantees in a *newly introduced feature*. The point of property hooks
> > is for me that “dynamic properties” are easier to reason about compared
> > to
__get(). As a user when accessing a proper
> > readonly property, I
> > do not want to check if there is a property hook that might result in
> > non-readonly behavior. As an engine developer I want to be able to
> > optimize based on the readonly-ness of a property. Without
> > such
> > guarantees, the “readonly” keyword does not provide value to me.
>
> The only way to make the readonliness fully guaranteed would be to force a
> readonly property to be cached; (IE, the hook is only called at all if the
> property is uninitialized.) But there's no obvious way to make that clear
> in the code that it's what's happening.
>
> > I also believe the LazyProduct example to be broken, since lazy-loading
> > individual properties might result in an object that is internally
> > consistent if the database changes in-between.
>
> That's true with any lazy-loading scenario. The use of hooks doesn't
> change that at all.
>
This RFC makes sense to me.
I read Claude's concern, and I agree with Larry's response: the engine
already allows readonly to be bypassed using __get. The added hook doesn't
make anything more lenient.
I also read Tim's argument that new features could be stricter. If one
wants to be stricter and forbid extra behaviors that could be added by
either the proposed hooks or __get, then the answer is : make the class
final. This is the only real way to enforce readonly-ness in PHP.
If a class is final and uses readonly with either hooks or __get, then
that's the original author's choice. There's no need for extra
engine-assisted strictness in this case. You cannot write such code in a
non-readonly way by mistake, so it has to be by intent.
Nicolas
PS: as I keep repeating, readonly doesn't immutable at all. I know this is
written as such in the original RFC, but the concrete definition and
implementation of readonly isn't: you can set mutable objects to readonly
properties, and that means even readonly classes/properties are mutable, in
the generic case.