4

I already know the benefit of immutability over mutability in being able to reason about code and introducing less bugs, especially in multithreaded code. In creating structs, though, I cannot see any benefit over creating a completely immutable struct over a mutable one.

Let's have as an example of a struct that keeps some score:

struct ScoreKeeper {
    var score: Int
}

In this structure I can change the value of score on an existing struct variable

var scoreKeeper = ScoreKeeper(score: 0)
scoreKeeper.score += 5
println(scoreKeeper.score)
// prints 5

The immutable version would look like this:

struct ScoreKeeper {
    let score: Int

    func incrementScoreBy(points: Int) -> ScoreKeeper {
        return ScoreKeeper(score: self.score + points)
    }
}

And its usage:

let scoreKeeper = ScoreKeeper(score: 0)
let newScoreKeeper = scoreKeeper.incrementScoreBy(5)
println(newScoreKeeper.score)
// prints 5

What I don't see is the benefit of the second approach over the first, since structs are value types. If I pass a struct around, it always gets copied. So it does not seem to matter to me if the structure has a mutable property, since other parts of the code would be working on a separate copy anyway, thus removing the problems of mutability.

I have seen some people using the second example, though, which requires more code for no apparent benefit. Is there some benefit I'm not seeing?

Peter O.
  • 32,158
  • 14
  • 82
  • 96
  • Surely the second only takes more code if there is only a single location in the entire code base creating values of that type? –  Apr 12 '15 at 11:52
  • 2
    [This thread](http://stackoverflow.com/questions/441309/why-are-mutable-structs-evil) is about C#, but it seems to me that some of the arguments apply to Swift as well. – Martin R Apr 12 '15 at 12:37

5 Answers5

2

Your remark about copying value types is very good. Maybe this doesn't make much sense in particular language (swift) and particular compiler implementation (current version) but in general if the compiler knows for sure that the data structure is immutable, it could e.g. use reference instead of a copy behind the scenes to gain some performance improvement. This could not be done with mutable type for obvious reasons.

Even more generally speaking, limitation means information. If you limit your data structure somehow, you gain some extra knowledge about it. And extra knowledge means extra possibilities ;) Maybe the current compiler does not take advantage of them but this does not mean they are not here :)

Miroslav Prymek
  • 1,783
  • 2
  • 10
  • 12
2

Different approaches will facilitate different kinds of changes to the code. An immutable structure is very similar to an immutable class object, but a mutable structure and a mutable class object are very different. Thus, code which uses an immutable structure can often be readily adapted if for some reason it becomes necessary to use a class object instead.

On the flip side, use of an immutable object will often make the code to replace a variable with a modified version more brittle in case additional properties are added to the type in question. For example, if a PhoneNumber type includes methods for AreaCode, LocalExchange, and LocalNumber and a constructor that takes those parameters, and then adds an "optional" fourth property for Extension, then code which is supposed to change the area codes of certain phone numbers by passing the new area code, LocalExchange, and LocalNumber, to the three-argument constructor will erase the Extension property of every phone number, while code which could write to AreaCode directly wouldn't have had that problem.

supercat
  • 77,689
  • 9
  • 166
  • 211
1

Good analysis, especially pointing out that structs are passed by value and therefore will not be altered by other processes.

The only benefit I can see is a stylistic one by making the immutability of the element explicit.

Mundi
  • 79,884
  • 17
  • 117
  • 140
1

It is more of a style to make value based types be treated on par with object based types in object oriented styles. It is more of a personal choice, and I don't see any big benefits in either of them.

TavoloPerUno
  • 549
  • 2
  • 7
1

In general terms, immutable objects are less costly to the system than mutable ones. Mutable objects need to have infrastructure for taking on new values, and the system has to allow for the fact that their values can change at any time.

Mutable objects are also a challenge in concurrent code because you have to guard against the value changing out from under you from another thread.

However, if you are constantly creating and destroying unique immutable objects, the overhead of creating new ones becomes costly quite quickly.

In the foundation classes, NSNumber is an immutable object. The system maintains a pool of NSNumber objects that you've used before, and under the covers, gives you back an existing number if you ask for one with the same value as one you created before.

That's about the only situation in which I could see value in using static structs - where they don't change very much and you have a fairly small pool of possible values. In that case you'd probably want to se up your class with a "factory method" that kept recently used structs around and reused them if you asked for a struct with the same value again.

Such a scheme could simplify concurrent code, as mentioned above. In that case you wouldn't have to guard against the values of your structs changing in another thread. If you were using such a struct, you could know that it would never change.

Duncan C
  • 128,072
  • 22
  • 173
  • 272