Re: RFC - Immutable classes
| From: | Silvio Marijić | Date: | Fri, 02 Sep 2016 14:59:07 +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-95571@lists.php.net to get a copy of this message | ||
Michal I'm talking about __clone() callback after clone operation. But I
agree with you about syntax part.
2016-09-02 16:46 GMT+02:00 Michał Brzuchalski <michal.brzuchalski@gmail.com>
:
> 02.09.2016 16:29 "Larry Garfield" <larry@garfieldtech.com> napisał(a):
> >
> > 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;
> > }
> > }
> >
>
> I see only way in somehow invoking closere with cloning. That'll need
> additional syntax. Clone is left side operator not a function - it's not
> being called with parenthesis. If this was an object method accessible from
> public it coud gace such closure injected...
>
> > 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