C-SHARP - 7.3 Depression of side effects
A side effect is any change a function causes outside of its own scope: modifying a global variable, writing to a file, updating the property of a shared object. That's not bad by itself, but accumulated without discipline, it's one of the leading causes of hard-to-reproduce bugs. This lesson explains why limiting these effects makes code easier to debug.
A pure function is the opposite: it takes inputs, returns a result, and touches nothing else. For identical inputs, it always produces the same output. In C#, you move toward this style by avoiding mutating the parameters you receive, favoring returning new values over modifying in place, and limiting access to mutable static variables. LINQ perfectly illustrates this philosophy: Where, Select, and OrderBy never modify the source collection.
Immutability goes in the same direction. An immutable instance cannot be changed after it's created; instead, you return a new instance reflecting the desired change. That's exactly what string does, and it's what the record type introduced in C# 9 offers. Adopting these habits improves readability, simplifies unit tests, and makes reasoning about code easier, especially in multi-threaded environments.
In practice, the rule isn't to eliminate every side effect (impossible: you still need to display, save, and send requests) but to concentrate them in identified layers, and keep the rest of the code purely functional. This separation between "pure computation" and "observable effects" is one of the most effective levers for reducing technical debt.