> On 11. Jul 2025, at 14:25, Claude Pache <claude.pa...@gmail.com> wrote:
> 
>> Le 11 juil. 2025 à 06:30, Nick <p...@nicksdot.dev> a écrit :
>> 
>> To not get this buried in individual answers to others:
>> 
>> I came up with two alternative implementations which cache the computed 
>> `get` hook value.
>> One leverages separate cache properties, the other writes directly to the 
>> backing store.
>> 
>> Links to the alternative branches can be found in the description of the 
>> original PR.
>> https://github.com/php/php-src/pull/18757
>> 
>> I believe that these are fair solutions to address the concerns that came up 
>> in the discussion, and I hope people will agree.
>> 
>> Cheers,
>> Nick
> 
> 
> Hi Nick,
> 
> I think that the second alternative described as:
> 
> “Cache computed get hook to it's backing store; never run the hook again”
> 
> is near the most reasonable from my point of view (basing my judgment on the 
> description, as I have not looked the actual implementation), although there 
> are still some concerns.
> 
> Advantages of that approach:
> 
> 1. relatively to the first alternative solution: there is indeed no point to 
> have a cache separate from the backing-store, as the backing-store is 
> supposed to play that role in most cases;
> 
> 2. relatively to the manual “??=” pattern, it works correctly with nullable 
> properties.
> 
> Here are my remaining concerns:
> 
> A. It may be confusing to have a getter that is not always called.
> 
> B. The idea of returning the value directly from the backing-store if 
> initialised is useful also for non-readonly properties. (That can be emulated 
> with the “??=” pattern, but only if the property is not nullable.)
> 
> Both concerns may be resolved with the following amendment:
> 
> * Introduce a `cached` modifier, that enables the caching semantics (i.e., 
> not executing the getter if the backing-store is initialised).
> 
> The example from the RFC would be written as:
> 
> ```php
> readonly class LazyProduct extends Product {
> 
>    private DbConnection $dbApi;
>  
>    private string $categoryId;
>  
>    public Category $category {
>        cached get => $this->dbApi->loadCategory($this->categoryId);
>    }
> }
> ```
> 
> The `cached` modifier may be applied to any get hook, but it is mandatory if 
> the property is readonly.
> 
> (In practice, the “cached get hook” corresponds to my originally proposed 
> “init hook”, but with the advantage of not having a separate hook.) 
> 
> —Claude


Hey Claude,

I agree, the second alternative is more neat.

> A. 


Three people seem to think that always running the hook when returning a cached 
value would cause confusion.
You are now arguing for the exact opposite. I don’t have a very strong opinion 
here. 
However, I also came to the conclusion that caching and not running the hook is 
the more obvious and less confusing approach.
Also, naturally it’s more performant to not run the hook again. 

Running the hook again, but then not updating the value feels off. 
And updating the value would mean no caching, which brings us to the very 
beginning and your very concern.
So, yeah… that’s that. :)

> B.


I am afraid here I do have a strong opinion. Please remember my very first mail 
before discussion [1].
While for Larry the main reason for `readonly` hooks is lazy-initialisation, 
for me it is to write less code, to have less noisy classes. 
I don’t want to be forced to add readonly to each property.
Now you are proposing a mandatory `cached` modifier. Which means *checks 
notes*, I would save 2 characters on each property.
You will understand that this is not in my interest, and not what I am 
proposing here.

But aside from that I do not like to write more code. I honestly don’t see the 
benefit of having this modifier in the first place.
How “alternative implementation 2” works now is IMO just good. And it makes 
sense because it is limited to the `readonly` context. 
There is no technical need for the modifier. As we see, because we have a 
working solution at hand.

For me: It is clear, it’s solving the main issue you rightfully brought up, and 
it is less code to write.

I can imagine that `cached` could be helpful on non `readonly` properties in 
some cases.
However, I feel that brings us almost in similar territory than immutable 
classes. 
It is a whole new topic which I believe really shouldn’t be part of this RFC 
that explicitly .
Can we please agree on that it is future scope whether or not non `readonly` 
hooks should get such a modifier?

I’d appreciate if we could settle with “alternative implementation 2” as 
proposed. 

Cheers,
Nick

[1] https://externals.io/message/127529














Reply via email to