In C++, we usually copy the resources that we want to share, so as that accidental modification of a resource doesn't take place.
However, the copying becomes impractical from a performance point of view if the resources are big, so immutable resources offer an alternative that does not have the performance issues.
For example, if you have multiple threads computing sub-graphs of a graph and passing those sub-graphs around to other threads, copying the whole graph each time a thread needs to compute something that may potentially alter the graph is a killer for performance. You then have two choices:
Choice 1: make the graph thread-safe. Which is the usual route C++ takes.
Choice 2: make the graph out of immutable data structures.
Choice 1 is the practical choice when the scope of the work is limited, and therefore thread safety is easy to implement.
When the problem at hand becomes very complex though, and it's difficult to reason about the ordering of locks, immutable data structures is an easier choice.
However, the copying becomes impractical from a performance point of view if the resources are big, so immutable resources offer an alternative that does not have the performance issues.
For example, if you have multiple threads computing sub-graphs of a graph and passing those sub-graphs around to other threads, copying the whole graph each time a thread needs to compute something that may potentially alter the graph is a killer for performance. You then have two choices:
Choice 1: make the graph thread-safe. Which is the usual route C++ takes.
Choice 2: make the graph out of immutable data structures.
Choice 1 is the practical choice when the scope of the work is limited, and therefore thread safety is easy to implement.
When the problem at hand becomes very complex though, and it's difficult to reason about the ordering of locks, immutable data structures is an easier choice.