> On Feb 23, 2020, at 12:06 PM, Larry Garfield <la...@garfieldtech.com> wrote:
> 
> On Sun, Feb 23, 2020, at 2:39 AM, Mike Schinkel wrote:
>>> 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.
> 
> This is the common use case I think many envision, but nothing in the 
> proposal requires that.  A public write-once property (as currently written) 
> would be world-readable, and world-writeable, once.
> Separate visibility for internal and external access is a separate matter.  
> (Also potentially useful, but not part of the write-once proposal at the 
> moment.)

This just hit me, so I think I will mention it.  

The culture on the list seems not to be one of collaboration on RFC to find 
solutions to improve PHP but instead waiting for someone to stick their neck 
out with an RFC and then see who can shoot the most holes through it.

I did not actually expect that.  I would have hoped for a collaborate culture 
of the nature I am used to in local startup-oriented meetups where most 
everyone is trying to help each other rather than just pointing out that the 
work someone else has done is deficient and not worthy of moving forward.

If that is the desired culture that most want to have on this list, then I will 
accept it even though I will lament how much better it could be otherwise.

If I misunderstand, please help me understand how wording like "but nothing in 
the proposal requires that" and "not part of the write-once proposal at the 
moment" rather than "the proposal does not require that but lets's explore how 
adding that requirement can make the proposal better" should not leave the 
impression I just mentioned above?

Or maybe the problem is the mailing list is just not a mechanism for 
collaborative work and we need a new mechanism.  Like Github, comments, and 
pull requests?

Moving on...

>> 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
> 
> It does not.  
> 
> 1) Race condition if I assume that a public write-once property is a 
> materialized value, but access it before it gets materialized.

Can you please explain what "materialized value" means in this context?   Are 
you speaking in Scala again?

If you mean that a write-once property just has not yet been assigned, I am not 
sure how that differs from just accessing a property that has not yet been 
assigned today?


> 2) Race condition if internal non-constructor code wants to set the value, 
> but some external routine has set it first.

As I said, don't let the external routine set it directly.   Which you did note.

(I am interested in finding solutions in the same solution space as selected 
proposals and not just limiting myself to the exact specifics of the proposal 
because IMO limiting ourselves in that way has all the bad aspects of 
bureaucracy and none of the good aspects.)

> 3) Cloning creates an interesting and complicated case of both of the above.  
> Does a cloned object start with its write-once bits reset or no?  There's 
> problems both ways.

If there are problems, let us find solutions. 

1. Only allow internal methods to change write-once properties.
2. Options:
        2a. Extend clone statement to have `clone rewrite $foo` that would 
allow rewriting the write-once properties.
        2b. Allow rewriting once of write-once object properties until some 
operation is performed to seal or lock the object (operation being a method 
call, a function call with the object as param, or a statement with the object 
as argument.)
        2c. Don't allow rewriting of cloned objects. See if it is really a 
problem.  Fix it in a future RFC if so.
        2d. Something else I am someone we can think of.


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

Reply via email to