Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I see myself using more and more immutable types when the instances of the class are not expected to be changed. It requires more work (see example below), but makes it easier to use the types in a multithreaded environment.

At the same time, I rarely see immutable types in other applications, even when mutability wouldn't benefit anyone.

Question: Why immutable types are so rarely used in other applications?

  • Is this because it's longer to write code for an immutable type,
  • Or am I missing something and there are some important drawbacks when using immutable types?

Example from real life

Let's say you get Weather from a RESTful API like that:

public Weather FindWeather(string city)
{
    // TODO: Load the JSON response from the RESTful API and translate it into an instance
    // of the Weather class.
}

What we would generally see is (new lines and comments removed to shorten the code):

public sealed class Weather
{
    public City CorrespondingCity { get; set; }
    public SkyState Sky { get; set; } // Example: SkyState.Clouds, SkyState.HeavySnow, etc.
    public int PrecipitationRisk { get; set; }
    public int Temperature { get; set; }
}

On the other hand, I would write it this way, given that getting a Weather from the API, then modifying it would be weird: changing Temperature or Sky wouldn't change the weather in real world, and changing CorrespondingCity doesn't make sense neither.

public sealed class Weather
{
    private readonly City correspondingCity;
    private readonly SkyState sky;
    private readonly int precipitationRisk;
    private readonly int temperature;

    public Weather(City correspondingCity, SkyState sky, int precipitationRisk,
        int temperature)
    {
        this.correspondingCity = correspondingCity;
        this.sky = sky;
        this.precipitationRisk = precipitationRisk;
        this.temperature = temperature;
    }

    public City CorrespondingCity { get { return this.correspondingCity; } }
    public SkyState Sky { get { return this.sky; } }
    public int PrecipitationRisk { get { return this.precipitationRisk; } }
    public int Temperature { get { return this.temperature; } }
}
share|improve this question
add comment

4 Answers

up vote 7 down vote accepted

I program in C# and Objective-C. I really like immutable typing, but in real life I've been always forced to limit its usage, mainly for data type, for the following reasons:

  1. Implementation effort comparing to mutable types. With immutable type, you would need to have constructor with all properties. Your example is a good example for this already. Try to imagine if you have 10 classes, which each has 5-10 properties. To make thing easier, you might need to have a builder class to construct or create modified immutable instance in the same manner like StringBuilder or UriBuilder in C#, or WeatherBuilder in your case. This is the main reason for me as many class I design does not worth this effort.
  2. Consumer usability. The immutable type is more difficult to use comparing to mutable type. The instantiation need all values beforehand. Immutability also means that we cannot pass the instance to a method to modify its value without using builder, and if we need to have a builder then the drawback is in my (1).
  3. Compatibility with the language's framework. Many of the data framework require mutable type and default constructor to operate. For example, you cannot do nested LINQ-to-SQL query with immutable types, and you cannot bind its properties to be edited in editor such Windows Form's TextBox.

In short, immutability is good for object that looks like value, or have only few properties. Before making anything immutable, you must consider the effort needed and the usability of the class itself after making it immutable.

share|improve this answer
1  
"The instantiation need all values beforehand.": Also a mutable type does, unless you accept the risk of having an object with uninitialized fields floating around... –  Giorgio Apr 29 '13 at 21:53
    
@Giorgio For mutable type, default constructor should initialise the instance to the default state and the state of the instance can be altered later after instantiation. –  tia Apr 30 '13 at 2:53
1  
For an immutable type you can have the same default constructor, and make a copy later using another constructor. If the default values are valid for the mutable type, they should be valid for the immutable type too because in both cases you are modelling the same entity. Or what is the difference? –  Giorgio Apr 30 '13 at 5:45
    
One more thing to consider is what the type represents. Data contracts don't make for good immutable types because of all these points, but service types that get initialized with dependencies or read only data and then perform operations are great for immutability because the operations will perform consistently and the state of the service cannot be changed to risk that. –  Kevin Jan 18 at 19:35
    
@Giorgio The point is the consumer's convenience. Making a copy is technically another instantiation, and it is also quite tedious if you use constructor. Fluent interface might be really helpful in some language for making immutable type manipulated copy, but the usability is still lower than simple assignment, take time to implement and definitely has more or less performance impact comparing to plain mutable type. –  tia Jan 19 at 2:55
add comment

The only drawback I can think of is that in theory use of immutable data may be slower than mutable ones - it is slower to create a new instance, and collect previous one than to modify existing one.

The other "problem" is that you can't only use immutable types. In the end you have to describe the state and you have to use mutable types to do so - without changing state you can't do any work.

But still general rule is to use immutable types wherever you can and make types mutable only when there really is a reason to do so...

And to answer the question "Why immutable types are so rarely used in other applications?" - I really don't think they are... wherever you look everyone recommends making your classes as immutable as they can be... for example: http://www.javapractices.com/topic/TopicAction.do?Id=29

share|improve this answer
    
Both of your problems aren't in Haskell though. –  Florian Margaine Apr 27 '13 at 21:16
    
@FlorianMargaine Could you elaborate? –  mrpyo Apr 28 '13 at 8:33
    
The slowness is not true thanks to a smart compiler. And in Haskell, even I/O is through an immutable API. –  Florian Margaine Apr 28 '13 at 8:57
1  
A more fundamental problem than speed is that it is difficult for immutable objects to maintain an identity while their state changes. If a mutable Car object is continuously updated with the location of a particular physical automobile, then if I have a reference to that object I can find out the whereabouts of that automobile quickly and easily. If Car were immutable, finding the current whereabouts would likely be much harder. –  supercat Jan 18 at 17:27
    
You have to code quite smartly sometimes for the compiler to figure out that there's no reference to the previous object left behind and thus can modify it in place, or do deforestation transforms, et al. Especially in larger programs. And as @supercat says, identity can indeed become a problem. –  Macke Jan 18 at 19:11
show 3 more comments

Why immutable types are so rarely used in other applications?

Ignorance? Inexperience?

Immutable objects are widely regarded as superior today, but it's a relatively recent development. Engineers who haven't kept up to date, or are simply stuck in 'what they know' won't use them. And it does take a bit of design changes to use them effectively. If the apps are old, or the engineers weak in design skills then using them might be awkward or otherwise troublesome.

share|improve this answer
    
"Engineers who haven't kept up to date": One could say that an engineer should also learn about non-mainstream technologies. The idea of immutability is only recently becoming mainstream, but it is a quite old idea and is supported (if not enforced) by older languages like Scheme, SML, Haskell. So anyone who is used to looking beyond mainstream languages could have learned about it even 30 years ago. –  Giorgio Apr 28 '13 at 8:29
    
@Giorgio: in some countries, many engineers still write C# code without LINQ, without FP, without iterators and without generics, so actually, they somehow missed everything which happened with C# since 2003. If they don't even know their language of preference, I hardly imagine them to know any non-mainstream language. –  MainMa Apr 28 '13 at 9:18
    
@MainMa: Good that you wrote the word engineers in italics. –  Giorgio Apr 28 '13 at 10:47
    
@Giorgio: in my country, they are also called architects, consultants, and lots of other vainglorious terms, never written in italics. In the company I'm currently working at, I'm called analyst developer, and I'm expected to spend my time writing CSS for crappy legacy HTML code. Job titles are disturbing on so many levels. –  MainMa Apr 28 '13 at 10:56
    
@MainMa: I agree. Titles like engineer or consultant are often just buzzwords with no widely-accepted meaning. They are often used to make someone or their position more important / prestigious than it actually is. –  Giorgio Apr 28 '13 at 11:02
show 2 more comments

To model any real-world system which where things can change, mutable state will need to be encoded somewhere, somehow. There are three main ways an object can hold mutable state:

  • Using a mutable reference to an immutable object
  • Using an immutable reference to a mutable object
  • Using a mutable reference to a mutable object

Using first makes it easy for an object to make an immutable snapshot of the present state. Using the second makes it easy for an object to create a live view of the present state. Using the third can sometimes make certain actions more efficient in cases where there's little expected need for immutable snapshots nor live views.

Beyond the fact that updating state stored using a mutable reference to an immutable object is often slower than updating state stored using a mutable object, using a mutable reference will require one to forgo the possibility of constructing a cheap live view of the state. If one won't need to create a live view, that's not a problem; if, however, one would need to create a live view, an inability to use an immutable reference will make all operations with the view--both reads and writes--much slower than they otherwise would be. If the need for immutable snapshots exceeds the need for live views, the improved performance of immutable snapshots may justify the performance hit for live views, but if one needs live views and doesn't need snapshots, using immutable references to mutable objects is the way to go.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.