"My second remark is that our intellectual powers are rather geared to master static relations and that our powers to visualize processes evolving in time are relatively poorly developed."And from Moseley and Marks' "Out of the Tar Pit" essay:
"We believe that the major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyse and reason about the system."We find it difficult to reason about how system state changes over time, particularly when lots of things can modify that state. It therefore makes sense to (mentally) partition our systems into stateless and stateful parts.
If we can shovel most of the essential complexity into the stateless parts, we can make sure that this complexity is (at least) easily testable.
Equally, if we can keep the stateful parts of the program relatively free of complexity, then we can (at least) reason about (and control) how the state can change.
This argues for a system architecture that has parts that are programmed in an Object-Oriented manner as well as parts that are programmed in a pure-functional manner.
Objects enable us to make state private, and to limit and control how that state is manipulated (through public interfaces).
The use of pure functions makes it easier to reason about and test the more complex parts of system functionality.
It is when we mix statefulness and complexity that we really come unstuck.
Of course, it goes without saying that if you can avoid state you should, and if you can avoid complexity, you should ... but in my experience at least a little of both is usually required as a cost of doing business.