Hi Larry,

> On 13 Sep 2016, at 03:11, Larry Garfield <la...@garfieldtech.com> wrote:
> 
> On 09/12/2016 11:40 AM, Fleshgrinder wrote:
>> On 9/11/2016 10:04 PM, Larry Garfield wrote:
>>> On 09/10/2016 05:55 AM, Fleshgrinder wrote:
>>>> @Larry what do you think about the CoW proposal?
>>> I'm afraid I got lost in the thread somewhere with the back and forth
>>> about implementation details. Can you repost the current proposal, or
>>> has the RFC page been updated with the latest CoW-based recommendation?
>>> 
>>> --Larry Garfield
>>> 
>> No worries, here is the original message of mine in response to you (but
>> I guess that I did not include you in the recipients):
>> 
>> https://marc.info/?l=php-internals&m=147318929726088&w=2
>> 
> 
> Ah, I did see that one, but there was a lot of discussion after it so I 
> thought the idea evolved.  Response below based on skimming the responses 
> after that as well...
> 
> It sounds like there's more that needs to go on, though.  It sounds like that 
> thread is suggesting that $this in a method of an immutable object is always 
> cloned, which seems excessive to me.
> 
> The point about identity is well-taken.  However, it's more complex on 
> objects because equality is not as simple as it is on strings. Two objects 
> can be logically identical but physically different. For instance:
> 
> class HttpHeaders {
>  public $attributes = [];
> }
> 
> $a = new HttpHeaders();
> $a->attributes['foo'] = 'bar';
> $a->attributes['baz'] = 'buzz';
> 
> $b = new HttpHeaders();
> $b->attributes['baz'] = 'buzz';
> $b->attributes['foo'] = 'bar';
> 
> $a and $b are now not physically identical,  since their attributes array is 
> in a different order.  However, header order doesn't matter in HTTP, or 
> rather isn't supposed to.  (Modulo buggy implementations, of course.)  So are 
> $a and $b identical?  I could very easily argue both directions on that.  
> Physical identity would be easier to automate checking in the engine; logical 
> identity would require user-space code to make such decisions.
> 
> From the discussion of "transformer" methods, I'd propose a slightly 
> different keyword.  To wit:
> 
> 1) A class marked as "immutable" may not have any of its properties altered, 
> EXCEPT in certain unlocked scopes.  The constructor is an unlocked scope.
> 
> 2) A method may be marked "clone": public clone function foo() {}. A clone 
> method is identical to any other method except that A) $this in its scope is 
> not the original object, but the result of clone($this); B) A clone method is 
> an unlocked scope, so modifying $this (the clone) is legal.  That is more 
> self-descriptive than "transformer", and also doesn't require a new keyword.  
> (By implication, clone and static are mutually exclusive since clone requires 
> an object to clone.)
> 
> I don't know that there are any other unlocked scopes to consider...
> 
> #2 does leave us with the identity question that Richard raises, in that 
> returning an unmodified $this from a clone method still creates a new object 
> identity.  However, I posit that is to be expected.  In Python, eg, while 
> some built-in objects are immutable they are not, necessarily, always the 
> same physical object in memory.  (999+1 is not the same object as 1000, but 
> 1+2 and 2 likely will be due to internal engine optimizations.)  You need to 
> do a value comparison of them.
> 
> I don't see the identity case being resolved without an __identity() method, 
> or similar.  Which could be useful in its own right so I'm not necessarily 
> against it, but it's an extra, and I'd argue optional, piece of the puzzle.
> 
> Related to whether or not the properties of an object may be mutable (arrays, 
> other objects, etc.), they would in practice probably need to blacklist 
> resources.  We ran into that issue in PSR-7, where the body stream has to be 
> mutable, because streams.  Since PSR-7 is based on PHP 5.3 that doesn't cause 
> any syntactic issues, just logical issues.  If the classes were marked 
> immutable explicitly, it likely would be a problem since the streams cannot 
> be immutable, thus they can't be used on an immutable object.  Which is... 
> very sad making. :-(
> 
> --Larry Garfield
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 

I like your suggestion with the ‘clone’ keyword on methods. 

As I said before, I think it’s a mis-step to prevent manual cloning at the 
engine level (even if the result is that you return the same instance) - there 
is *bound* to be user land code that clones objects. Without this, any use of 
clone in a distributed library/framework will have to do a check to see if an 
object (except those accepting final classes of known definition) is immutable 
before attempting to clone it.

Regarding identity, I’m going to refer back to the DateTimeImmutable class. I 
know its not the same implementation, but honestly I don’t think that matters. 
Developers use PHP because they generally *don’t* have to worry about the 
internal details of the engine.

e.g.: 
$d = new DateTimeImmutable();
$e = $d->add(new DateInterval('PT0S'));

var_dump($d === $e);  // bool(false)


Personally I think if we want to worry about whether two objects represent the 
same value, wouldn’t that be better handled (and with much greater positive 
effect for developers) by finalising & passing the Comparable RFC 
(https://wiki.php.net/rfc/comparable)?

Cheers

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

Reply via email to