- hide information so that it's not queryable
- force information to flow through multiple hops
- make it hard/impossible to set the true state of the system in its entirety
- allow state to be mutated silently
- give interfaces roles and force certain state to have to flow through specific paths
- multiple concurrent access
- pointers
- spray the app across as many machines as possible
Sounds familiar, maybe like a scathing criticism of OOP? Well check this out. What if I wanted to make a program as slow and bloated as possible?
- put all state in one place. Bonus points if you can bottleneck it and force all changes to be well-ordered and sequential
- all data has to be immutable and copied over in its entirety when propagated
- use larger data structures than necessary. Lots of wrapping and indirection
- no caching. Can't trust data unless it's fresh
- read/write from disk/net tons
- use scripty garbage collected languages
- spray the app over as many machines as possible
The latter kind of feels like a criticism of FP, though really it's more critical of distributed monolith. What if I want to make my app as vulnerable to outage and overload as possible?
- concentrate the app in as few machines as possible
It's really interesting how all the different tradeoffs of approaches just kinda appear when you take this inverted approach. It's all too easy to get caught up on the positives of an approach.
(opinion - I still think FP comes out looking better than OOP, but it does suggest that you need a lot of techniques to safely hide optimizations to make FP more performant, which can make it harder to scrutinize all the layers)