Re: RFC - Immutable classes
| From: | Silvio Marijić | Date: | Fri, 02 Sep 2016 14:45:23 +0000 |
| Subject: | Re: RFC - Immutable classes | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-95568@lists.php.net to get a copy of this message | ||
Basically I'm concerned about __clone() since you can not pass parameters
2016-09-02 16:44 GMT+02:00 Silvio Marijić <marijic.silvio@gmail.com>:
> Hi Larry,
> I'm aware of that but we do have make some strong constraints there
> otherwise we are undermining the strong guarantee of immutability. I would
> agree to allow object modification only and only *inside* __construct()
> and __clone methods. I'm trying to come up with idea how would that look
> like. If you guys have some suggestions, that would be great.
>
> 2016-09-02 16:27 GMT+02:00 Larry Garfield <larry@garfieldtech.com>:
>
>> On 09/02/2016 09:06 AM, Silvio Marijić wrote:
>>
>>> Well at the moment expection is thrown in case when you try to clone
>>> immutable object. But you do seem to have valid point there regarding
>>> __clone method. I'm definitely going to give it a thought.
>>>
>>> Best,
>>> Silvio.
>>>
>>> 2016-09-02 15:52 GMT+02:00 André Rømcke <andre.romcke@ez.no>:
>>>
>>>
>>>> On Sep 2, 2016, at 09:10 , Silvio Marijić <marijic.silvio@gmail.com>
>>>>>
>>>> wrote:
>>>>
>>>>> Hi Fleshgrinder,
>>>>>
>>>>> Since Michal answered most of the questions, I'll just add some notes..
>>>>> Initially I added restrictions to abstract classes, but I did think
>>>>> about
>>>>> that over the last couple of days and couldn't find any concrete reason
>>>>>
>>>> for
>>>>
>>>>> that restriction, so I think I'm going to remove that. As far as
>>>>> cloning,
>>>>> it is disabled for immutable objects, because you'll end up with the
>>>>> copy
>>>>> of object that you can not modify. I did mention in Cons sections that
>>>>> cloning is disabled, maybe it should be made more clear.
>>>>>
>>>>
>>>> _If_ there are use-cases for it, wouldn’t it also be safe that the clone
>>>> is allowed to be modified during __clone() and afterwards sealed? Like
>>>> in
>>>> __construct().
>>>> And if you don’t want to allow cloning, throw in __clone.
>>>>
>>>> Best,
>>>> André
>>>>
>>>
>> I'd have to agree here. I love the idea of "lockable" immutable
>> objects. However, the __clone() method has to be a modifiable area just
>> like __construct() or else it's effectively useless for anything more than
>> a trivial object.
>>
>> This was one of the main concerns with immutability in the PSR-7
>> discussions. Consider this sample class, with 8 properties (entirely
>> reasonable for a complex value object):
>>
>> immutable class Record {
>> public $a;
>> public $b;
>> public $c;
>> public $d;
>> public $e;
>> public $f;
>> public $g;
>> public $h;
>>
>> public function __construct($a, $b, $c, $d, $e, $f, $g, $h) {
>> $this->a = $a;
>> $this->b = $b;
>> $this->c = $c;
>> $this->d = $d;
>> $this->e = $e;
>> $this->f = $f;
>> $this->g = $g;
>> $this->h = $h;
>> }
>> }
>>
>> Now I want a new value object that is the same, except that $d is
>> incremented by 2. That is, I'm building up the value object over time
>> rather than knowing everything at construct time. (This is exactly the use
>> case of PSR-7.) I have to do this:
>>
>> $r1 = new Record(1, 2, 3, 4, 5, 6, 7, 8);
>>
>> $r2 - new Record($r1->a, $r1->b, $r1->c, $r1->d + 2, $1->e, $r1->f,
>> $r1->g, $r1->h);
>>
>> That's crazy clunky, and makes immutable objects not very useful. Imagine
>> a money object where you had to dissect it to its primitives, tweak one,
>> and then repackage it just to add a dollar figure to it. That's not worth
>> the benefit of being immutable.
>>
>> The way PSR-7 addressed that (using fake-immutability, basically), was
>> this:
>>
>> class Response {
>> // ...
>>
>> protected $statusCode;
>>
>> public function withStatusCode($code) {
>> $new = clone($this);
>> $new->statusCode = $code;
>> return $new;
>> }
>> }
>>
>> That is, outside of the object there's no way to modify it in place, but
>> it becomes super easy to get a slightly-modified version of the object:
>>
>> $r2 = $r1->withStatusCode(418);
>>
>> And because of PHP's copy-on-write support, it's actually surprisingly
>> cheap.
>>
>> For language-level immutable objects, we would need some equivalent of
>> that behavior. I'm not sure exactly what form it should take (explicit
>> lock/unlock commands is all I can think of off hand, which I dislike), but
>> that's the use case that would need to be addressed.
>>
>> --Larry Garfield
>>
>>
>> --
>> PHP Internals - PHP Runtime Development Mailing List
>> To unsubscribe, visit: http://www.php.net/unsub.php
>>
>>
>
>
> --
> Silvio Marijić
> Software Engineer
> 2e Systems
>
--
Silvio Marijić
Software Engineer
2e Systems