The example I'm about to give is for the PHP language, but I think this scenario applies to most languages.
Let's say I have an object called
Response and I want it to be immutable. Every method should return a new instance rather than modifying the state of the current instance.
Responses have headers, so I create a method called
withHeader($name, $value) that makes a copy of my response object, sets the header, and returns the new instance. It's pretty simple to use:
$newResponse = $oldResponse->withHeader('Content-Type', 'application/json');
Then I decide the headers actually have quite a few properties and I'd rather separate this out into a separate object called a
HeaderBag. Now I want my
Response to hold a
HeaderBag but I still want it to be immutable.
I can't make the the bag a public property, like
$response->headers because even if the
$headers object is immutable, the property can still be reassigned. So maybe I add something like
$response->getHeaders() which returns my
HeaderBag object, but now how do I manipulate it?
If I move my
withHeader method into this sub-object, then I wind up with something like
withHeader method would presumably return a new
HeaderBag since it too is immutable, but then what? I guess I'd end up with something like this:
$newResponse = $oldResponse->withHeaders($oldResponse->getHeaders()->withHeader($name, $value));
Which seems a bit ridiculous; to add a single value we have to clone two objects and write this abomination of a line. Sure, we can write a helper method on the
Response object to shorten it, but the whole idea was to move all the header-related methods into the
- Is there a better way to do this?
- If there isn't, is it even worth the effort/cost to make objects immutable?
- If we could design a new language with immutability in mind, what would this look like?