2020-12-30 18:31 GMT, Larry Garfield <la...@garfieldtech.com>:
> On Wed, Dec 30, 2020, at 12:15 PM, Rowan Tommins wrote:
>> On 30/12/2020 13:49, Olle Härstedt wrote:
>> > Uniqueness is when you only allow _one_ reference to an object (or
>> > bucket of memory).
>> > [...]
>> >
>> > You can compare a builder pattern with immutability vs non-aliasing
>> > (uniqueness):
>> >
>> > ```
>> > // Immutable
>> > $b = new Builder();
>> > $b = $b->withFoo()->withBar()->withBaz();
>> > myfun($b);  // $b is immutable, so $b cannot be modified by myfun()
>> > return $b;
>> > ```
>> >
>> > ```
>> > // Uniqueness
>> > $b = new Builder();  // class Builder is annotated as
>> > non-aliasing/unique
>> > $b->addFoo();
>> > $b->addBar();
>> > $b->addBaz();
>> > myfun(clone $b);  // HAVE TO CLONE TO NOT THROW EXCEPTION.
>> > return $b;
>> > ```
>>
>>
>> Thanks, I can see how that solves a lot of the same problems, in a very
>> robustly analysable way.
>>
>> However, from a high-level user-friendliness point of view, I think
>> "withX" methods are actually more natural than explicitly cloning
>> mutable objects.
>>
>> Consider the case of defining a range: firstly, with plain integers and
>> familiar operators:
>>
>> $start = 1;
>> $end = $start + 5;
>>
>> This models integers as immutable values, and + as an operator which
>> returns a new instance. If integers were mutable but not aliasable, we
>> would instead write something like this:
>>
>> $start = 1;
>> $end = clone $start;
>> $end += 5; // where += would be an in-place modification, not a
>> short-hand for assignment
>>
>> I think the first more naturally expresses the desired algorithm. It's
>> therefore natural to want the same for a range of dates:
>>
>> $start = MyDate::today();
>> $end = $start->withAddedDays(5);
>>
>> vs
>>
>> $start = MyDate::today();
>> $end = clone $start;
>> $end->addDays(5);
>>
>>
>> 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);
>>
>>
>> > The guarantee in both above snippets is that myfun() DOES NOT modify
>> > $b before returning it. BUT with immutability, you have to copy $b
>> > three times, with uniqueness only one.
>
> That's a good summary of why immutability and with-er methods (or some
> equivalent) are more ergonomic.
>
> Another point to remember: Because of PHP's copy-on-write behavior, full on
> immutability doesn't actually waste that much memory.  It does use up some,
> but far less than you think.  (Again, based on the tests MWOP ran for PSR-7
> a ways back.)

I thought copy-on-write was only for arrays, not objects?

Olle

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

Reply via email to