side effects are quite the thorn in this theories side. hard to describe message passing in purely applicative terms.
One of the problems of the purely applicative approach is that you get a nice algebra for describing your results, including the sequence of effects, but reasoning about the resources spent by the computation becomes harder.
I might argue that laziness makes haskell something different than purely applicative.
It's not just pure values being passed around. It's a language built atop suspended self-caching invocable thunks getting knotted up and then firing off in chain reaction.
main = do
let
hello = foo world
world = bar hello
putStrLn $ show hello
putStrLn $ show world
where
foo v = [v]
bar v = length v