This is a really interesting article (and a blog I want to come back to). Thanks, OP.<p>What Haskell seems to achieve, and I'm not an expert on it yet, is an incentive system that encourages small functions <i>especially</i> when you're "in" a monad, because of the "any side effects makes the whole function 'impure'" dynamic as seen in the type system (also known as "you can't get out of the monad"). Of course, it's sometimes a pain in the ass to thread your RNG state or other parameters (that remain implicit in imperative programming) through the function, and that's where you get into the rabbit hole of specialized monads (State, Reader, Writer, RWS, Cont) and, for more fun yet, monad transformers.<p>I think that the imperative approach to programming has such a hold because, at small scale, it's far more intuitive. At 20 lines, <i>defining functions</i> feels dry and mathematical and we're much more attracted to the notion of <i>doing</i> things (or, making the computer do things). And, contrary to what we think in functional programming, imperative programming <i>is</i> more intuitive and simpler at small scale (even if more verbose). It's in composition and at scale (even moderate scale, like 100 LoC) that imperative programming starts to reach that high-entropy state where it's hard to reason about the code.