On Tue, Feb 27, 2024, at 8:51 PM, Benjamin Außenhofer wrote: > thank you for this proposal. there are some points i'd like to make > into this discussion: > > * Thank you for the removal of $field, it was non-idomatic from a PHP POV. > > * I would prefer that the short syntax $foo => null; be voted upon > separately. Personally I think it could be confusing and is too close > to a regular assignment for default value and I prefer not to have it > and keep the rest of the RFC.
See my long reply to Rowan just now, where I go into this. > * The magic of detecting if a property is virtual or backed is - like > Rowan said - subtle. I would also prefer this to be managed via an > explicit mechanism, by for example keywording the property as > "virtual", instead of the implicit way with the parsing based detection. See my long reply to Rowan just now, where I go into this. > * As Doctrine project maintainer, we have had some troubles supporting > read only properties for proxies. I would have hoped that with hooks I > can overwrite a readonly property and "hook" into it instead by > defining a getter, but "no setter". From my read of the RFC this would > not be allowed and throws a compile time error. Could you maybe clarify > why at least this special case is not possible? I didn't immediately > get it from the RFC section on readonly as it only speaks about the > problems in abstract. Once again, readonly properties were designed sloppily without consideration of how they would interact with other features. Full asymmetric visibility would have been much better suited to what you describe, but that was rejected. (If hooks pass, we are considering taking a second attempt at aviz. Haven't decided yet.) As for details, consider this technically legal (if ill-advised) code: public DateTimeImmutable $now { get { return new DateTimeImmutable(); } } If that property is non-readonly, then while that may be weird, it's not really unexpected. There's no guarantee a property won't change value from one access to the next. UNLESS that property is readonly. But if it's readonly, what the heck does the above code do? It would be returning a different value on every request, so it violates one of the constraints on readonly. The hook can do arbitrary logic, which means there's really no way for the engine to detect at compile time "wait, you're doing something dynamic." (That would be an extreme amount of work unless PHP was pure-by-default, which it is not.) For inheritance, this is the same reasoning for why a property cannot have the readonly marker removed in a child class. It breaks one of the expected constraints of the property, even if not the type per se. (So it's kinda a Liskov issue.) This is true regardless of whether the property is virtual or not. Virtual properties just have the extra complication of "when you try to set it, there's an if (is_uninitialized()) check in the engine. What does that even mean when there's no backing property??" There's one carve out that might be supportable, which is just a set hook on a readonly property. That MIGHT be able to work around readonly's flaws by making sure the set hook calls parent::$foo::set($value), to ensure the actual write happens in the parent (since readonly is private-set, not protected-set). Ilija tells me that could be tricky to do, however, so we'd rather punt on that for now. Follow-up RFCs (even this version) could flesh out that edge case alone without impacting the rest of the design. --Larry Garfield