[RFC][DISCUSSION] - Immutable classes and properties

php.internals

Silvio Marijić

9 years ago
Hi, Discussion is open for following rfc https://wiki.php.net/rfc/immutability Cheers

Larry Garfield

9 years ago
On 12/11/2016 10:57 AM, Silvio Marijić wrote:
> Hi, > > Discussion is open for following rfc https://wiki.php.net/rfc/immutability > > Cheers >
Some grammar issues: "After object is constructor" => should be "After the object's constructor has run". " If immutable property contains object, to preserve immutability, object that is beeing assigned to immutable property must also immutable." => "If an immutable property contains an object, then in order to preserve immutability the object being assigned must be of an immutable class." The File class/resource example should note that the last line in it will create a fatal error, as the earlier examples do. It's not clear that the example is an invalid one. In a few places, "If immutable property..." should be "If an immutable property..." There's several places where articles (the, an, etc.) are missing. "Notice in above examples removing getters and setting properties to public is optional. They simply doesn't need to be protected anymore in fact that immutable class objects are deeply frozen with eceptions on write." => "Notice in the above examples that removing getters and setting properties to public are optional. They simply don't need to be protected given the fact that immutable class objects are frozen on write." (Several grammar fixes, plus it's a fatal error, not an exception.) Content issues: Currently the only "unlocked context" for an object is its constructor. As discussed previously, that is insufficient. For any non-trivial object (more than 1-3 internal properties) creating a new one via the constructor only when incrementally building is prohibitively difficult. The pattern of with*() methods that spawn new objects via clone(), a la PSR-7, needs to be supported. That is: immutable class Money { // ... public function add(Money $other) : Money { $new = clone($this); $new->amount += $other->amount; return $new; } } I'm not sure how easily we can denote that sort of case. It's outside the __clone() function itself, which is what makes it difficult. Without that, though, such immutable objects are of only limited use. --Larry Garfield

Marcio Almada

9 years ago
2016-12-11 12:57 GMT-04:00 Silvio Marijić <marijic.silvio@gmail.com>:
> Hi, > > Discussion is open for following rfc https://wiki.php.net/rfc/immutability > > Cheers >
Hi, Can you make a pull request? I'd like to comment the patch but it's not possible to make inline reviews only with a diff uri on github.

Silvio Marijić

9 years ago
@Larry, first of all thanks for pointing out grammar issues, I will correct them. Now, regarding cloning of the immutable object, I'm aware of that issue and I'm not sure if we could even use clone operation for this purpose, I do have one proposal for that matter, consider example: immutable class User { public $firstname; public $lastname; public $email; public function __construct($firstname, $lastname, $email){ // } } $user = new User('Foo', 'Bar', 'foo@bar.com'); $new = copy($user, ['firstname' => 'John', 'email' => 'john@bar.com']) Copy function would take as a first argument an immutable object and as a second argument associative array where keys represent property names and values specified will be assigned to those properties on a new object. @Marcio I will submit PR, have you found bug or? Cheers 2016-12-11 23:35 GMT+01:00 Marcio Almada <marcio.web2@gmail.com>:
> > 2016-12-11 12:57 GMT-04:00 Silvio Marijić <marijic.silvio@gmail.com>: > >> Hi, >> >> Discussion is open for following rfc https://wiki.php.net/rfc/immut >> ability >> >> Cheers >> > > > Hi, > > Can you make a pull request? I'd like to comment the patch but it's not > possible to make inline reviews only with a diff uri on github. > >
-- Silvio Marijić Software Engineer 2e Systems

Fleshgrinder

9 years ago
On 12/11/2016 5:57 PM, Silvio Marijić wrote:
> Hi, > > Discussion is open for following rfc https://wiki.php.net/rfc/immutability > > Cheers >
-1 from my side for all the things previously mentioned. The copy-on-write topic must be solved along with the introduction of immutable classes or we end up with this being implemented and not way to mutate them in a controlled fashion. Also -1 on the proposed `copy` or `modify` function. Not only does it seem to allow anyone to mutate the immutable object, it also requires magic strings of the property names. No usage search, no refactoring, no ... I still strongly believe that `__clone` should be made `private` or `protected` for immutable classes to avoid useless cloning. After that we either stick to cloning as we currently do in our `with*` methods or we provide a keyword that changes the behavior of a method. I also propose to use `data` or `value` instead of `immutable` as the class modifier keyword. Its shorter and properly as well as fully communicates what kind of object we are building.
-- Richard "Fleshgrinder" Fussenegger

Silvio Marijić

9 years ago
@Fleshgrinder My opinion on that subject is still that features are mostly complete but I'am willing to find also solution to ease modifying. Modify function does not modify object in any way, it will operate on the clone of the object and this was just prototype. Moreover it should be restricted to be only callable from the scope of the object. Introducing method modifier causes more problems then it solves, and has whole another level of complexity. Regarding changing keyword, 'data' does not fit because object is behaviour + data, with behaviour beeing (or at least it should be) at the first place. Value can imply or create confusion with Value Objects, on the other hand immutable clearly states what it is. Cheers, 2016-12-12 19:44 GMT+01:00 Fleshgrinder <php@fleshgrinder.com>:
> On 12/11/2016 5:57 PM, Silvio Marijić wrote: > > Hi, > > > > Discussion is open for following rfc https://wiki.php.net/rfc/ > immutability > > > > Cheers > > > > -1 from my side for all the things previously mentioned. The > copy-on-write topic must be solved along with the introduction of > immutable classes or we end up with this being implemented and not way > to mutate them in a controlled fashion. > > Also -1 on the proposed `copy` or `modify` function. Not only does it > seem to allow anyone to mutate the immutable object, it also requires > magic strings of the property names. No usage search, no refactoring, no > ... > > I still strongly believe that `__clone` should be made `private` or > `protected` for immutable classes to avoid useless cloning. After that > we either stick to cloning as we currently do in our `with*` methods or > we provide a keyword that changes the behavior of a method. > > I also propose to use `data` or `value` instead of `immutable` as the > class modifier keyword. Its shorter and properly as well as fully > communicates what kind of object we are building. > > -- > Richard "Fleshgrinder" Fussenegger >
-- Silvio Marijić Software Engineer 2e Systems

Fleshgrinder

9 years ago
On 12/12/2016 8:19 PM, Silvio Marijić wrote:
> @Fleshgrinder > > My opinion on that subject is still that features are mostly complete but > I'am willing to find also solution to ease modifying. > Modify function does not modify object in any way, it will operate on the > clone of the object and this was just prototype. Moreover it should be > restricted to be only callable from the scope of the object. Introducing > method modifier causes more problems then it solves, and has whole another > level of complexity. Regarding changing keyword, 'data' does not fit > because object is behaviour + data, with behaviour beeing (or at least it > should be) at the first place. Value can imply or create confusion with > Value Objects, on the other hand immutable clearly states what it is. > > Cheers, >
The term data class comes from data transfer object (DTO). Uncle Bob uses the term extensively in his books. https://sourcemaking.com/refactoring/smells/data-class https://kotlinlang.org/docs/reference/data-classes.html https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.idas200/underdc.htm So it would be rather `$this->modify()` or `$this->copy()` and not simply `modify()` nor `copy()`. ;) The problem persists that you end up with lots of magic strings ... :(
-- Richard "Fleshgrinder" Fussenegger

Andrew Faulds

9 years ago
Hi Silvio, Silvio Marijić wrote:
>Discussion is open for following rfc https://wiki.php.net/rfc/immutability
The restriction that immutable properties may only hold immutable values seems potentially overzealous. Consider that not all immutable classes will actually be marked as such. Any code written in, say, PHP 7.2 if it included this feature, would not be able to make an immutable property if it pointed to an immutable object made before PHP 7.2 which couldn't use this feature. Another consideration is that your existing restrictions (only objects of immutable classes and resources) are not restrictive enough to achieve the desired end of enforcing deep immutability. Arrays can contain object values, as well as array values which might themselves contain values that are objects. They also can contain references. In order to enforce that immutable properties do not point to anything mutable, you would have to search any given array for mutable values, including sub-arrays. You would need to make sure you check for recusion here, lest assigning to an immutable property potentially crash the interpreter. This could be a significant runtime cost, it's at least an O(n) operation. I think that, realistically, trying to enforce immutability of values in an immutable class is not worth it, and makes the feature less useful. Consider that some popular applications of immutability ultimately contain a reference to something mutable: PSR-7's immutable HTTP message objects point to mutable streams, and Docker's immutable containers point to mutable volumes. Thanks.
-- Andrea Faulds https://ajf.me/

Paul M Jones

9 years ago
> On Dec 12, 2016, at 13:36, Andrea Faulds <ajf@ajf.me> wrote: > > Consider that some popular applications of immutability ultimately contain a reference to something mutable: PSR-7's immutable HTTP message objects point to mutable streams
Which subverts its overall promise of immutability (and the streams are not the only place where the promise of immutability is subverted).
-- Paul M. Jones pmjones88@gmail.com http://paul-m-jones.com Modernizing Legacy Applications in PHP https://leanpub.com/mlaphp Solving the N+1 Problem in PHP https://leanpub.com/sn1php

Silvio Marijić

9 years ago
After much thinking regarding array in immutable objects I'm thinking of revoking this RFC. If someone has some suggestion on that matter now is the time, but otherwise my work is done on this one. Cheers, 2016-12-12 20:56 GMT+01:00 Paul Jones <pmjones88@gmail.com>:
> > > On Dec 12, 2016, at 13:36, Andrea Faulds <ajf@ajf.me> wrote: > > > > Consider that some popular applications of immutability ultimately > contain a reference to something mutable: PSR-7's immutable HTTP message > objects point to mutable streams > > Which subverts its overall promise of immutability (and the streams are > not the only place where the promise of immutability is subverted). > > > -- > Paul M. Jones > pmjones88@gmail.com > http://paul-m-jones.com > > Modernizing Legacy Applications in PHP > https://leanpub.com/mlaphp > > Solving the N+1 Problem in PHP > https://leanpub.com/sn1php > > > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- Silvio Marijić Software Engineer 2e Systems

Markus Fischer

9 years ago
Hello, On 13.12.16 10:17, Silvio Marijić wrote:
> After much thinking regarding array in immutable objects I'm thinking of > revoking this RFC. If someone has some suggestion on that matter now is the > time, but otherwise my work is done on this one.
It would be nice if you could summarize the feedback into the RFC too (i.e. the "Cons" points), maybe someone wants to pick it up later or learn from it. And thanks for the effort! - Markus

Yasuo Ohgaki

9 years ago
Hi Silvio, On Tue, Dec 13, 2016 at 6:17 PM, Silvio Marijić <marijic.silvio@gmail.com> wrote:
> After much thinking regarding array in immutable objects I'm thinking of > revoking this RFC. If someone has some suggestion on that matter now is the > time, but otherwise my work is done on this one. >
It may be good to start from constant scalars. ES6 has "let" and "const". PHP has "const", but PHP's constant does not have scope other than class. It would be nice if const can be used like JS. e.g. Following is syntax error. <?php function foo($v) { const v=$v; // Some complex code here. return v * $var; } var_dump(foo(123)); ?> It would be large enough changes for 8.0, though. Regards,
-- Yasuo Ohgaki yohgaki@ohgaki.net

Silvio Marijić

9 years ago
Hi Yasuo, Yes, that looks like interesting idea. I can open another RFC and start working on that one, if there is a interest for that. Why can't we fit that into 7.2 ? Cheers, 2017-01-17 10:12 GMT+01:00 Yasuo Ohgaki <yohgaki@ohgaki.net>:
> Hi Silvio, > > On Tue, Dec 13, 2016 at 6:17 PM, Silvio Marijić <marijic.silvio@gmail.com> > wrote: > >> After much thinking regarding array in immutable objects I'm thinking of >> revoking this RFC. If someone has some suggestion on that matter now is >> the >> time, but otherwise my work is done on this one. >> > > It may be good to start from constant scalars. > ES6 has "let" and "const". PHP has "const", but PHP's constant does not > have scope other than class. It would be nice if const can be used like JS. > > e.g. Following is syntax error. > <?php > function foo($v) { > const v=$v; > // Some complex code here. > return v * $var; > } > > var_dump(foo(123)); > ?> > > It would be large enough changes for 8.0, though. > > Regards, > > -- > Yasuo Ohgaki > yohgaki@ohgaki.net >
-- Silvio Marijić Software Engineer 2e Systems

Andrew Faulds

9 years ago
Hi, Paul Jones wrote:
> >> On Dec 12, 2016, at 13:36, Andrea Faulds <ajf@ajf.me> wrote: >> >> Consider that some popular applications of immutability ultimately contain a reference to something mutable: PSR-7's immutable HTTP message objects point to mutable streams > > Which subverts its overall promise of immutability (and the streams are not the only place where the promise of immutability is subverted).
Indeed. It's not necessarily a good feature, don't get me wrong.
-- Andrea Faulds https://ajf.me/

Stas Malyshev

9 years ago
Hi!
> Discussion is open for following rfc https://wiki.php.net/rfc/immutability
The RFC says:
> Safe for concurrency.
I'm not sure - what concurrency are you talking about?
> Value objects, DTO's etc. can be easily created.
Value objects can be easily created right now if you follow generic best practices - private properties and no setters, here you go with value object.
> Properties can be public which removes need for getters without
allowing state modification. Not sure why it is a good thing to have public properties? Also, not sure how you are going to resolve references to such properties.
-- Stas Malyshev smalyshev@gmail.com