| > To achieve the same result with recursion requires a whole other can of worms: memoization and tail recursive style and compiler optimizations to shed stack frames. It’s a lot more work to understand all that (to get to an equivalent solution) than it is to understand mutation! It's true, you can't rely on tail call optimizations on every language. But practically all modern compilers for imperative languages transform your code into SSA form[1] in one of their intermediate stages, so the code: int x = 1
x = x + 1
will invariably be transformed into: int x0 = 1
int x1 = x0 + 1
in one of the intermediate stages - before applying further optimizations and finally converting it to stack-based bytecode or register-based machine code.This means that mutating a variable, at least when dealing with local primitive values, is equivalent to assigning the value to a new variable. Even in other cases, in-place mutation is not necessarily more efficient than copying and modifying values. For multi-threaded code, mutation often requires relying on synchronization which can be more expensive than copying around data. > Simply stated, the goals of mathematics and programming are quite differently aligned. The former is about understanding a thing, and the latter is more often about describing a concrete process under threat of limited resources. In the current day and age, if a programmer would wants to write the most efficient code, they need to understand a lot about their multi-stage optimizing compiler, Out-of-order CPUs, OS threads and so on - and they would still need to benchmark their implementation against others. It is not clear anymore that mutation is always faster. I think that in 99% of the cases, clear, safe and maintainable code trump the micro-optimizations that may (and often may not) be gained from using mutable data. Immutable data is generally easier to reason about, always safer from data races and other bugs, and - in most languages languages - more maintainable. The age of limited resources and straightforward compilers is long over, but it left mutable variables as its heritage. I'd argue they're still common not because they are necessary to deal with hardware limitations, but just because generations of programmers have gotten so used to them, it's hard to give up on them. [1] https://en.wikipedia.org/wiki/Static_single_assignment_form |