@Mathieu, Object can not be modified neither internally or externally, question is if you clone object where should we allow modification of cloned object On Sep 7, 2016 12:13 PM, "Mathieu Rochette" <math...@rochette.cc> wrote:
> > > On 07/09/2016 11:05, Stephen Reay wrote: > >> (Sorry for any dupes, sent from wrong address originally) >> >> From a developer point of view, I would suggest that a feature should >> aim to be as clear to understand with as little “magic" as possible. >> >> >> If the goal of an immutable class is to allow public properties to be >> made read-only, my expectation would be that: >> > I don't think this is the goal, in immutable classes, the object itself > should not be able to alter itself either (whatever the visibility of the > property is) > >> >> - write access to any public property from outside class context, is an >> error. >> >> This seems to be pretty much accepted by everyone >> >> >> - clone still works as expected >> >> There has been some suggestion that clone $immutableObj should not be >> allowed. Unless there is some specific language/engine gain by that, what >> is the point of having this behaviour? >> Existing built-in immutable classes (like DateTimeImmutable) do not >> prevent cloning, so why should this? >> >> - regular cloning from within class method(s) is the suggested way to >> provide “create a copy of the object with a new value” functionality. >> >> This example was given before, effectively: >> >> public function withValue($val) { >> $clone = clone $this; >> $clone->val = $val; >> >> return $clone; >> } >> >> >> >> >> >> On 7 Sep 2016, at 13:57, Michał Brzuchalski <mic...@brzuchalski.com> >>> wrote: >>> >>> 06.09.2016 9:13 PM "Fleshgrinder" <p...@fleshgrinder.com> napisał(a): >>> >>>> I understand the concerns of all of you very well and it's nice to see a >>>> discussion around this topic. Fun fact, we are not the only ones with >>>> these issues: https://github.com/dotnet/roslyn/issues/159 >>>> >>>> On 9/6/2016 6:01 PM, Larry Garfield wrote: >>>> >>>>> How big of a need is it to allow returning $this instead of $clone, >>>>> and/or can that be internalized somehow as well? With copy-on-write, >>>>> is that really an issue beyond a micro-optimization? >>>>> >>>> I asked the same question before because I am also unable to answer this >>>> question regarding the engine. >>>> >>>> However, for me it is more than micro-optimization, it is about >>>> identity. >>>> >>>> final class Immutable { >>>> // ... the usual ... >>>> public function withValue($value) { >>>> $clone = clone $this; >>>> $clone->value = $value; >>>> return $clone; >>>> } >>>> } >>>> >>>> $red = new Immutable('red'); >>>> $still_red = $red->withValue('red'); >>>> >>>> var_dump($red === $still_red); // bool(false) >>>> >>>> This is a problem in terms of value objects and PHP still does not allow >>>> us operator overloading. A circumstance that I definitely want to >>>> address in the near future. >>>> >>>> But the keyword copy-on-write leads me to yet another proposal, actually >>>> your input led me to two new proposals. >>>> >>>> # Copy-on-Write (CoW) >>>> Why are we even bothering on finding ways on making it hard for >>>> developers while the solution to our problem is directly in front of us: >>>> PHP Strings! >>>> >>>> AFAIK CoW in case of objects would be impossible to implement. >>> >>> Every place in a PHP program refers to the same string if that string is >>>> the same string. In the second someone mutates that string in any way >>>> she gets her own mutated reference to that string. >>>> >>>> That's exactly how we could deal with immutable objects. Developers do >>>> not need to take care of anything, they just write totally normal >>>> objects and the engine takes care of everything. >>>> >>>> This approach also has the advantage that the return value of any method >>>> is (as always) up to the developers. >>>> >>>> (Cloning is disabled and results in an error as is because it makes no >>>> sense at all.) >>>> >>>> # Identity >>>> This directly leads to the second part of my thoughts and I already >>>> touched that topic: identity. If we have two strings their binary >>>> representation is always the same: >>>> >>>> var_dump('string' === 'string'); // bool(true) >>>> >>>> This is the exact behavior one wants for value objects too. Hence, >>>> immutable objects should have this behavior since they identify >>>> themselves by their values and not through instances. If I create two >>>> instances of Money with the amount 10 and the Currency EUR then they are >>>> always the same, no matter what. This would also mean that no developer >>>> ever needs to check if the new value is the same as the existing one, >>>> nor does anyone ever has to implement the flyweight pattern for >>>> immutable objects. >>>> >>>> A last very important attribute is that it does not matter in which >>>> thread an immutable value object is created because it always has the >>>> same identity regardless of it. >>>> >>>> This could easily be achieved by overwriting the object hashes >>>> (spl_object_hash) with something that hashes based on the values, and >>>> predictably across threads (UUIDs?). >>>> >>>> # Full Example >>>> <?php >>>> >>>> final immutable class ValueObject { >>>> >>>> public $value; >>>> >>>> public function __construct($value) { >>>> $this->value = $value; >>>> } >>>> >>>> public function withValue($value) { >>>> $this->value = $value; >>>> } >>>> >>>> } >>>> >>>> class A { >>>> >>>> public $vo; >>>> >>>> public function __construct(ValueObject $vo) { >>>> $this->vo = $vo; >>>> } >>>> >>>> } >>>> >>>> class B { >>>> >>>> public $vo; >>>> >>>> public function __construct(ValueObject $vo) { >>>> $this->vo = $vo; >>>> } >>>> >>>> } >>>> >>>> $vo = new ValueObject(1); >>>> >>>> $a = new A($vo); >>>> $b = new B($vo); >>>> >>>> var_dump($a->vo === $b->vo); // bool(true) >>>> >>>> $a->vo->withValue(2); >>>> >>>> var_dump($a->vo === $b->vo); // bool(false) >>>> >>>> $a->vo->withValue(1); >>>> >>>> var_dump($a->vo === $b->vo); // bool(true) >>>> >>>> // :) >>>> >>>> ?> >>>> >>>> -- >>>> Richard "Fleshgrinder" Fussenegger >>>> >>>> >> > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >