> I personally have found FP hard to debug.
I can very honestly say pure functions are the easiest thing to debug and test: Inputs, outputs. Trivial for unit testing.
I can't speak for MLs/Haskell, but debugging pure functions in any language tend to just be glancing at the stack trace, seeing the values on the stack going in, and then seeing where the unexpected wrong output came out, and being fairly confident knowing the issue is going to be in that function.
> The "naked state" of imperative programming
Are we including OO in this definition? The fundamental design pattern of OO is to encapsulate state. It's anything but naked, always being wrapped in object instances, only accessible via getters/setters, scattered into a million pieces across many instances of the system.
Conversely, Clojure has the most naked state ever. There's usually little to no state, and the current state is right there on the stack. Most simple Clojure programs with state have a singular atom aptly named "state" which is passed around, easy to inspect and modify as it's a simple data structure.
I think, ultimately, there's a common conflation of "Functional Programming" meaning "Declarative Type-Driven Functional Programming", when the reality is there are alternatives to ML/Haskell, aside from applying Functional patterns in "non-functional" languages.