When To Use Mutating Functions in Swift Structs

One of the best things about Swift is that it has built-in features that allows for a lot of immutability in the architecture, making our code a lot cleaner and safer (highly recommend this talk on the subject if you haven’t seen it already!).

But what should you do when you actually need some mutability?

The Functional Approach

As an example, I have a tic-tac-toe board, and I need to change the state of a position on the board…

According to a clean functional programming approach, you would simply return a new board!

I prefer to use the functional approach because it doesn’t have any side-effects, I can keep my variables as constants, and of course, it is super clean to test!

However, this approach is not the best in all cases…

Using the Mutating Keyword

Let’s say I’m keeping track of how many tic-tac-toe games each user has won, so I create a Counter:

I can choose to use the functional approach here as well:

However, if you actually try to use the incrementing function, it will read like this:

This is super unintuitive and unreadable! So this is where I prefer to use the mutating keyword instead:

I don’t like the side-effects of the increment function, but it’s more than worth is for the readability:

Further, I can minimize the damage by making sure that the count variable cannot be reset externally (since it now has to be a var) by using a private setter:


When choosing whether to use the mutating keyword or the functional approach, I prefer to use the functional approach, but NOT at the expense of readability.

Writing tests is a good way to test out your interface to see if you the functional approach makes sense. If it feels way out of wack and unintuitive, go ahead and change it! Just make sure to use a private setter for the var!

Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.

  • Raphael Oliveira

    Hey nice post, I kind of don’t agree with your sentence though “I don’t like the side-effects of the increment function”. There are no side effects in my point of view, the function is doing exactly what it’s name suggests, incrementing. I think side effects are things that we don’t expect on can’t be inferred from the method name like a getter that modifies state.

    • I agree. I understand that this is a contrived example, but in this case there really aren’t any “dangerous side-effects”.

      • Kostiantyn Koval

        In my opinion “side-effects” term is used correctly here. It updates the state.
        The other question is it dangerous “side-effects” or not (and I think it’s not)

        I also like functional approach “f(x) = y” more. But because struct is a value type it’s actually more safer to use mutating methods with them than for reference types. So both are ok you just pick which you like more (as shown in the article).

      • In a mathematical function, you have an input and a clear input. With the mutating approach, you’re changing the internal variable without a clear output – that is the side-effect.

        It is dangerous because you now have to make count a var, and if you forget to make the setter private, it can now be modified externally, which is not the intention of the Counter. By using the mutating keyword, you’re adding room for unintended consequences.

        • After trying to write “cleaner code” lately, I agree that this is indeed an example of “dangerous side-effects”. Thanks for a great post.

  • Vince O’Sullivan

    Mutability is a property of the instance variable not the type (class, struct, etc.)

    The signature of the function “Counter.increment” is not “Counter -> () -> ()” which it would be if Counter was a class. Because Counter is a struct the signature is “inout Counter -> () -> ()”. So, the act of incrementing the counter variable results in a different/new value object being returned despite the function apparently returning void; hence the need for var instead of let when declaring the counter variable.

    It turns out that both functions “increment()” and “counterByIncrementing() -> Counter” are basically identical in effect (for structs) in that the result of calling either function results in the creation and assignment of a new counter value. Which you use is down to personal preference and readability.

  • matthew

    counter = counter.counterByIncrementing()

    I agree, as it’s written. that is overly verbose and not entirely clear.

    It is, however, not uncommon (and, indeed, it is mentioned specifically in Apple’s Swift API Style Guide) to have both a non-functional method called, e.g. “increment()”, and a functional variant, called e.g. “incrementing()”.

    Though this convention might not yet be commonplace, it’s not unreasonable to think it will become moreso. I feel that when written properly, and in a way that a team has agreed on, this functional style of method is no less readable than the mutating style, and is arguably safer. (I understand this is sort of unrelated to the point of the post in general, but felt it worth mentioning).

    It is also definitely worth mentioning that you can write the mutating func as follows, and this avoid the count property being mutable:

    mutating func increment() {
    self = Counter(count: self.count + 1)

    • vanylapep

      Is the mutating keyword used for mutating “self” in this case as we’re not mutating “count” anymore.

      • matthew

        Yeah, exactly. Though you’re mutating “self” in both instances really. With value types, mutating a property of “self” basically creates a new instance of the type with the mutated value, so they’re really no different. I think this just makes it more explicit.

        • vanylapep

          Interesting, I didn’t know this. Thanks.