Unfortunately unless there's an explicit way to state what has side effects like a mut keyword, a lot of fp programming advantages lose value because most devs default to mutable stuff, so the fp benefits don't compound

I think this works quite well with IO in Haskell. Most of my code is pure, but the parts which are really not, say OpenGL code, is all marked as such with IO in their type signatures.

Also, the STM monad is the most carefree way of dealing with concurrency I have found.