But we can't because nothing after the return will get executed. So instead we stick our state in a tmp variable, do what we gotta do, and then return the tmp.

So what? It's just one more line of code, right?

The danger here (and with tmp variables everywhere) is that, by definition, they're exact copies of types we're actively working with in the same scope. How they differ isn't semantically clear, and neither the compiler nor code review can stop us from accidentally substituting one for the other:1

Thankfully Swift does provide a way for us to squeeze code in after the return of a method — the documentation just doesn't make this immediately obvious:

Use defer to write a block of code that is executed after all other code in the function…

Yay!

…just before the function returns.

Oh… Um… Well it turns out they're talking about the function returning on the stack and not the return statement executing in code. So doing something like this works perfectly:

func makeNext() -> Int {
defer {
state += 1
}
return state
}

This is true regardless of whether state has value semantics or not.

Note this not only avoids confusing our original and tmp variables, but now the intent of our code has been made clear:

Before we couldn't know why we were forking off a tmp unless we analyzed everything that messed with the original and followed it all the way through to the eventual return of its tmp copy.2 Here, it's clear from the get-go we want to do some stuff with state. But first we're going to return it.

1: Actually, in this trivial example, the compiler will warn us that tmp is unused. But we can easily imagine situations where that will not be the case.↩︎

2: And then, if you're anything like me, all the way back to the top to find where tmp was made in an attempt to remember what it was before we changed it.↩︎