It's also not just a syntax difference, mainstream languages are embracing immutability more and more, often as a default.
The point is that calling FP academic is a tired trope and even if it is far from the dominant paradigm, there is clearly practical lessons to be learned whatever paradigm you program in.
A Haskell program covered in piles of monads to abstract all state away still follows the functional core imperative shell pattern, because the runtime is the imperative shell. This doesn't make such a thing desirable for other languages.
The practical lesson I learned from dabbling with functional programming in academia is that functional programming is often impractical and does not offer any of the purported benefits of better code.
A shell is not more imperative than a processor - both are Turing machines, a completely functional mathematical object. Seeing them as imperative is a semantic interpretation of the people watching it, not an inherent property.
This is what state monads are doing anyway under a hidden syntax, and for simple cases it may be easier that building a full dedicated monad.
Most mainstream languages are old, they can't be immutable my default without breaking backwards compatibility. I'm talking about the design direction of languages that are already based on mutability. For example, Java added Records which are immutable, as well as overhauling the date/time api with an immutable version.
> This doesn't make such a thing desirable for other languages.
I've used this pattern in other languages, none of this is a silver bullet that makes software engineering easy; but I do find it makes some code much easier to test and reuse.