> On Feb 21, 2020, at 6:17 PM, Larry Garfield <la...@garfieldtech.com> wrote: > I'm totally on board for better value object support, so that's a good motive > for me. The question I have is whether this is really a good stepping stone > in that direction or if it would lead down a wrong path and lock us into too > much TIMTOWTDI (for the Perl fans in the room). So let's think that through > down that path. How would write-once properties lead into properly immutable > value objects? Or do they give us that themselves? > > The biggest challenge for immutable objects, IMO, is evolving them. Eg, > $result->withContentType(...) to use the PSR-7 example. Would we expect > people to do it with a method like that, or would there be some other > mechanism? If the properties are public, would we offer a more syntactic way > to modify them directly? > > The with*() method style requires cloning the object. What happens to the > locked status of a set property if the object is cloned? Are they then > settable again, or do they come pre-locked? > > Neither of those seem good, now that I think about it. If they come > pre-locked, then you really can't clone, change one property, and return the > new one (as is the standard practice now in that case). If they don't come > pre-locked, then the newly created object can have everything on it changed, > once, which creates a loophole. I'm not sure what the right answer is here. > > My other concern is a public property (the most likely use case) would have > to be set in the constructor. If it's not, then callers cannot rely on it > having been set yet if it's set lazily. And if code inside the class tries > to set it lazily, it may already have been set by some external code (rightly > or wrongly) and cause a failure.
> > How do we address that? There's absolutely use cases where setting > everything in the constructor ahead of time is what you'd do anyway, but > there are plenty where you wouldn't want to, either, which creates a race > condition for who sets it first, or tries to access it before it gets set, > etc. (This is where my repeated questions about lazy initialization come > from.) I have struggled to follow this RFC thread fully, so if I am getting something out of context, please note that and I apologize in advance. However, it would see that rules for `write once` properties to support lazy loading would be rather simple: 1. Write-once properties can only be updated once. 2. Write-once properties can only be updated within the class where they are declared. 3. If you want to update a property from outside the class, create a set_<property>() method to allow it to happen. 4. If you do not want it to be set externally, do not implement a set_<property>() method. 5. If you want it to be implemented externally sometimes but not others, implement guard classes inside the set_<property>() method. I think that addresses all scenarios, no? -Mike -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php