> > 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
Copy on write applies to all values; the caveat is that with objects, the value being copied is the handle that points to an object in memory, rather than the object itself. That means passing an object by reference can do some seriously unexpected things, which is why you basically never do so. The point here is that if you have an object with 15 internal properties, it's memory usage is 15 zvals plus one zval for the object, plus one zval for the variable that points to it. (I'm over-simplifying here. A lot.) If you pass it to a function, only the one zval for the handle is duplicated, which is the same as for an integer. If you clone the object, you don't duplicate 15+1 zvals. You duplicate just the one zval for the object itself, which reuses the existing 15 internal property entries. If in the new object you then update just the third one, PHP then duplicates just that one internal zval and modifies the new one. So you still are using only 18 zvals, not 36 zvals. (Engine people: Yes, I am *very* over-simplifying. I know.) Basically, what in most languages would require manually implementing "immutable data structures" we get for free in PHP, which is seriously sweet. The net result is that a with-er chain like this: $foo2 = $foo->withBar('x')->withBaz('y')->withBeep('z'); is way, way less expensive than it looks, both on memory and CPU. It is more expensive than setters, but not by much. That's why I don't think the distinction between unique and immutable mentioned up-thread is that big of a deal in PHP, specifically. Yes, they're different things, but the cost of them is not all that different because of CoW, so considering them separately is not as important as it would be in a language that doesn't automatically do CoW in the background for us. (Whoever in the 90s decided to bake CoW into the engine, thank you. It's an incredibly nice foundational feature.) --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php