The reality is just that such mutable cases are extremely rare, contrary to what my Java algorithms course taught me. Also, mutation is overhyped for many algorithms: pureness allows for un-restricted sharing in algorithms, and if you take a look at Seq
, for example, the computational complexities are pretty great…
To the bigger point: the most expensive thing today is dev time, by A LOT. Devs and managers have a choice between:
- Use mutable data structures and cause dev problems for maybe 5-10% application speed up, but require a headache of managing mutable state throughout the codebase.
- Don’t use mutable data structures and don’t get harassed at 11pm on a Friday about some mutation-related bug report and require more dev time as a result
Are there cases that require mutable data structures? Yes. But they are very rarely required or worth it. Good devs will isolate such mutation like a virus, such as DB boundaries or behind type safe APIs (e.g. LinearTypes).
For example, my current workbase, mutation happens all the time, but we hide it, as is the Haskell way. The codebase looks immutable because we’ve pushed the IO/STM stuff right down to the bottom of our application monad (in this case a event-based simulator).
But where are the critical examples? The most common cases for mutation are, as you say, production use cases, where heavier workloads necessitate mutation. The reason you don’t see such code is because it’s proprietary, and so these repos aren’t up on GitHub. Libraries rarely require mutation in order to function. I looked through my work’s dependencies, and found exactly zero libraries that expose any mutation (there’s barely even exposed IO). tasty
has some MVars underneath to get the test runners going, but that’s the only case I can think of.
Your question is understandable, but it’s hard to think of where Haskellers are underusing mutation… If we get past our reflexive “surely Haskellers aren’t using mutation enough”, and ask more pointed questions, it’s hard to think where the community is erring:
- What libraries are too slow to use in practice? Why don’t they use mutation? Should they use mutation?
- What problems require mutation? Are those problems unaddressed in the Haskell community? If those problems are addressed, are they in fact using mutation?
Some open-source libraries I can think of that do require mutation include: FRP libraries (reflex, reactive-banana); reactive UIs (elm, miso et al.); mutable APIs in containers/vector; STM/ST monads and their reference types; Bodigrim’s recent text-builder library which leverages LinearTypes. But note that without exception their APIs are pure/mutation-free.