I think there's a fundamental concept here about dealing with IO in a pure functional programming (FP). For me, stuff like monads make reasoning about IO in FP languages like Haskell really difficult.
But I haven't really encountered that difficulty with ClojureScript. It pauses and resumes endlessly alongside Javascript, and uses that stop-the-world mechanism to provide and accept data for IO without using monads. So we can write all of the pure functional ClojureScript we want, blissfully unaware that monads even exist. Whereas, other FP languages seem to think of IO as this thing that happens while your program is running, and get lost in the weeds.
Where this is important is for static analysis. Without mutability, we can take the whole syntax tree and turn it into intermediate code (I-code) and transform that tree in all kinds of fun ways with concepts from Lisp. But once we have a mutable variable, that entry/exit point of the logic has to be carried along like an imaginary number, which creates forks in the road that are more difficult to analyze because every fork doubles the analysis required, which eventually leads to an explosion of complexity that limits how far we can optimize or even understand imperative programming (IP) languages.
Now imagine an IP language like C, with its myriad of mutable variables on almost every line. If we transpiled that to an FP language, we'd see countless entry/exit points around pure functional code, with intractable complexity around the mutable state stored in the variables. To the point that it can't really be statically analyzed. Then we get excited about fractional improvements in performance, without realizing that we missed out on orders of magnitude higher gains with parallelization and other transformations that could have happened.
To me, once programmers see this, they can't really unsee it. Our whole world is built on imperative code that we just don't understand. And I am starting to feel that this mutable/monadic/async behavior (whatever we want to call it) is an anti-pattern. We should be trying to get to programming that works more like a spreadsheet, where we can play with the inputs and see the results of the logic in real time without side effects.