Question

I like the immutability concept but sometimes I wonder, when an application isn't meant to be parallel, should one avoid making things immutable?

When an application isn't multi-threaded, you aren't plagued by shared state problems, right?

Or is immutability a concept like OOP that you either use all the way or not? Excluding the cases when something shouldn't be immutable based on use/performance, etc.

I am faced with this question when writing an application for myself, that is moderately big (maybe like 1-2k lines).

Was it helpful?

Solution

I love immutability because it means I don't have to trust other peoples code not to mess around with objects I expect to stay the same.

When you pass an object off to another component such as a List<T>, you are at the mercy of what that component does. This is especially important when you return collections as properties.

public class Foo { 
  private List<Bar> _barList;
  public ICollection<Bar> BarList { get return _barList; } 
}

There's nothing stopping a consumer of this class from clearing the collection out from under me. Even switching the return type to IEnumerable<Bar> is not entirely safe. There's nothing stopping some piece of badly written code from casting this back to List<T> and calling .Clear().

However if I really want the collection to stay consistent I could rewrite it as followis

public class Foo {
  private ImmutableCollection<Bar> _barList;
  public ImmutableCollection<Bar> BarList { get { return _barList; } }
}

Now I'm safe from having to trust other code from using my class incorrectly. They can't mess it up.

OTHER TIPS

I like the advantage from immutability that you need to validate it only once - at creation of object. That's a huge bonus actually.

A major benefit of immutability is that one need not track ownership of immutable objects. They just exist as long as anybody needs them, and then vanish into nothingness when they are no longer required. While using a garbage-collector in many cases means it's not necessary to write any expressly code dealing with ownership of mutable objects (the biggest exception being those that implement IDisposable), in many cases it's very difficult to write correct code in which objects that have mutable state do not have one clearly-defined "owner". Confusion about who owns the state of mutable objects can be a very frequent source of bugs; when using immutable objects (aside from a few that implement IDisposable) one can generally ignore ownership issues.

Another point to consider is that it is far easier to reason about a mutable reference to a semantically-immutable object, or an immutable reference to a mutable object, than it is to reason about a mutable reference to a mutable object. If one has a mutable reference to a mutable objects, it can often be unclear whether the correct approach to updating state is to simply mutate the object directly, or copy its state to a new object, mutate that, and update the reference. In some cases, there will be circumstances requiring each type of operation (as with List<T>, which sometimes replaces an array with a bigger one, but usually does updates in-place), but such an approach only works if the type maintains exclusive control over the mutable objects in question. It's often more helpful to either have an immutable reference to a mutable type (in which case code may expose the reference, possibly through a read-only wrapper, to other objects which want a "live view" of its state) or else have a mutable reference to an object which is immutable or, at minimum, will never be mutated during the lifetime of the reference.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top