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