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?


$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.


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) {
    $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:
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.


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]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to