@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
>
>

Reply via email to