On 13.07.25 18:17, Nick wrote:
On 13. Jul 2025, at 20:38, Marc Bennewitz <marc@mabe.berlin> wrote: Hi Nick, Claude,Hey Marc,The most here made the argument that "a changing value from a readonly get hook" would be the unexpected behaviour. That’s why we ended up with the current “alternative implementation 2”. Please see my last answer to Rob for a fair example [1] .I think it's important to explicitly mark it as "this value will be stored in memory", I mean just silently caching the get hook could quickly lead to unexpected behavior. Like one would expect the value to be changedThe current preferred alternative implementation covers both situations... If a property is `readonly`: - you can set *once* - on read you always get the same (_once_ computed) value back
This is exactly the behavior I mean which is somehow unexpected if not marked explicitly as the result could be cached and the property value will never change.
Not being able to write to something doesn't generally mean reading the value will never change. `get => random_int(0, 100);`
I don't want to say that the path we want to go with readonly being able to assume the value will never change is wrong but I think it's not clear for the user and can be missed quickly - even with a test as you have to read the property multiple time to notice the difference.
If a property is NOT `readonly`: - you can set *often* - on read you always get the fresh (_often_ computed) value back I argue that this is a very easy mental model.I hope that voters agree on “|cached| may be implied by |readonly|”, as Claude called it.
All what I'm saying is that this behavior should be explicit and not applied implicitly on a readonly get hook.
and another one wonders why a big chunk of memory will not be freed `get => $this->readBigFile();`.Where do you see non-freed memory in one but not the other?- in both scenarios, readonly or not, the `readBigFile()` will end up in memory. - on each consecutive property call the usage in both scenarios is the same. - when assigning a call the same property to multiple tmp vars the cached, once-computed version uses less memory than the non-cached versionDo I miss something? Did I misunderstand something?
yes, in both cases the data will end up in memory until all references are garbaged. The difference is that the object of that property now has a reference as well and needs to be destroyed as well be able to free the memory.
Additionally, the cached version has the benefit that the expensive computation only happens once.On the one hand I like the cached modifier but personally I would prefer a separate init hook because it seems to be more clear that this is a backed property that will be initialized once.To have an `init` hook doesn’t solve the get hook issue.
As far as I understood the init hook it would still disallow readonly+get but allow readonly+init and init would be called once the first time the property gets read and the result would end up in the backing store.
As a result you get the same behavior as `cached get` with the only difference that you write `init => random_int();` instead of `cached get => random_int();`
Additionally it can be used to initialize a property for non readonly properties as well.
``` class Test { public int $seek {init => random_int(0, 100); // called once on read if not initialized
get => $this->seek + 100; set => $this->seek = $value + 100; } } ```var_dump((new Test())->seek); // number between 100-200 OR 200-300 depending of the set hook be called once with the result of init as well.
Or did I misunderstand it?
The cached modifier I would expect to be an attribute applicable to any function which uses another cache store similar to how it's possible in python to memorize function calls which would be a very different feature.As earlier answered to Claude [2], I seek to write less code. To introduce a `cached` modifier voids this for no strong reason (please see “mental model” above).
See above - and `init` is just once more character.
-- *Cheers,* Nick [1] https://news-web.php.net/php.internals/128010 [2] https://news-web.php.net/php.internals/128007
OpenPGP_0x3936ABF753BC88CE.asc
Description: OpenPGP public key
OpenPGP_signature.asc
Description: OpenPGP digital signature