Re: Analysis of property visibility, immutability, and cloning proposals
| From: | Rowan Tommins | Date: | Thu, 31 Dec 2020 12:37:29 +0000 |
| Subject: | Re: Analysis of property visibility, immutability, and cloning proposals | ||
| References: | 1 2 3 4 5 6 7 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-112696@lists.php.net to get a copy of this message | ||
Hi Mike and Olle,
On 31/12/2020 00:24, Mike Schinkel wrote:
A different perspective is that "withX" methods require a mental translation where "addX" methods do not, much like how a person whose native language is English will find it a challenge to (or cannot) "think" in French.I wonder if that's just about the choice of names, rather than the mutability/immutability itself?
Ignoring the distinction between "scalar" and "object" was kind of the point: they are both "values", and are more naturally treated the same as differently. To take a different example, consider writing a new number type (for arbitrary precision, or complex numbers, or whatever), with an "add" method. The mutable version looks something like this: public function add($other) {$start = MyDate::today(); $end = $start->withAddedDays(5); vs $start = MyDate::today(); $end = clone $start; $end->addDays(5);Ignoring that you are comparing apples and oranges (scalars to objects,) the latter is easier to reason about IMO.
$this->value = $this->value + $other;} and has to be used like this: $start = new MyNumber(1); $end = clone $start; $end->add(5); The immutable version might look more like this: public function add($other) {
return clone $this with { value: $this->value + $other };
}
and is used like this:
$start = new MyNumber(1);
$end = $start->add(5);
That's much closer to the "$end = $start + 5;" we're used to.
On 30/12/2020 18:42, Olle Härstedt wrote:
Whether or not the type system forced you to, you'd have to use clone if the values were implemented as mutable. Switching to methods again may make that clearer: $c = new MyNumber(299_792_458); $m = new MyNumber(10); $e = $m->multiply( $c->square() ); If multiply() and square() are mutating state, rather than returning new instances, $c is now 89875517873681764, which is going to totally mess up the universe... Regards, -- Rowan Tommins [IMSoP]To put it a different way, value types naturally form*expressions*, which mutable objects model clumsily. It would be very tedious if we had to avoid accidentally mutating the speed of light: $e = (clone $m) * ((clone $c) ** 2);Using a variable on right-hand side does not automatically create an alias, so in the above case you don't have to use clone.