On Fri, Feb 21, 2020, at 4:29 AM, Máté Kocsis wrote:
> >
> > Yeah, I'm definitely thinking in relation to the earlier discussion, since
> > I think they're all inter-related.  (This, property accessors, and constant
> > expressions.)
> >
> 
> The biggest question is whether it's worth to support both readonly
> properties and property accessors. My answer is clear yes, because there
> are many-many
> ways to mess with private or protected properties without and public
> setters from the outside - in which case property accessors couldn't help
> much. I collected some examples I know of:
> https://3v4l.org/Ta4PM

I didn't even know you could do some of those.  That's horrifying. :-)

> > As Nikita notes above, a read-only property with a default value is...
> > basically a constant already.  So that's not really useful.
> 
> I agree that they are not very useful, however I wouldn't restrict their
> usage. Mainly because there are probably some legitimate use-cases, but I
> also think it would
> be advantageous to be consistent with the other languages in this case.

If they could do something that class constants can't, that would make them 
useful.  If not, then I feel like it would just be introducing new syntax for 
the same thing, without much benefit.  (I'm thinking of, eg, could you set them 
by default to a new Foo() object, which you could then modify the Foo but not 
change it for another object, thus moving that initialization out of the 
constructor?  That sort of thing.)

> > If we could address the performance impact, that would give us much more
> > functionality-for-the-buck, including an equivalent of read-only properties
> > including potentially lazy initialization.  Or derive-on-demand behavior
> > would also be a big increase in functionality.
> >
> > It's not that I don't see a value to this RFC; I actually have a few
> > places in my own code where I could use it.  It's that I see it as being of
> > fairly narrow use, so I'm trying to figure out how to increase it so that
> > the net-win is worth it.
> >
> 
> The reason why I brought up this RFC is that I'd really like to add
> first-class support for immutable objects, and it seemed to be a good idea
> to first go for readonly properties.
> This way, the scope of an immutable object RFC gets smaller, while it's
> possible to only have readonly properties alone.
> 
> Regards,
> Máté

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.)

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to