> Second, you need to be extremely familiar with the language and ensure that you know that you're not mixing and matching mutable and immutable system calls, which will be hell to debug, see 1
How is this not the case, for say, python?
E.g. You can get yourself into real trouble with a function like this in python.
Right, but the point is that you can't actually write the equivalent of that function in Haskell. You'd have to write something like this:
defaultMap :: Map k v
defaultMap = ...
f :: TVar (Map k v) -> IO (Map k v)
f = \case
Nothing -> newTVarIO Map.empty
Just m -> pure defaultMap
which would make it hard to be unaware of the possibility that the dictionary you get each time you pass `Nothing` would be the same one. And then the type signature returns an IO action, so you would know that "anything could happen here", whereas there's no such indication in python.
Conversely, if you had your `f` function in Haskell has a type like `Maybe (Map k v) -> Map k v` then you know that it can't possibly be creating a mutable map and inserting it in the process somewhere without your knowledge. (Modulo `unsafePerformIO` and other evils like that).
How is this not the case, for say, python?
E.g. You can get yourself into real trouble with a function like this in python.