APIs like Spark, for instance, make it largely transparent - processes are scheduled by the driver in nodes w/ hot data caches, and processes that fail are transparently retried; and yet this doesn't impact how you write your query. Effects systems are another thing can help us reason around i/o as function calls and handle the fail-ability.
I would bet it's a matter of lacking good accepted patterns instead of a theoretical impossibility.
> A function call or a remote call won't change the domain logic
Understanding performance and minimizing failure modes and their impact on larger systems makes for a whole career as "SRE". Making remote calls all over a codebase creates behaviors that are practically impossible to debug or optimize. But the blocker is the network impact of large applications and the emergence of cascading failures.
Ex-Amazon SDE here. Message-passing libs like 0mq tried to push this idea.
They never became very popular internally because passing data between green threads vs OS threads vs processes vs hosts vs datacenters is never the same thing.
Latencies, bandwidths and probability of loss are incredibly different. Also the variance of such dimensions. (Not to mention security and legal requirements)
Furthermore, you cannot have LARGE applications autonomously move across networks without risks of cascading failures due to bottlenecks taking down whole datacenters.
Often you want to control how your application behaves on a network. This is also a reason why OTP (in Erlang or implemented in other languages) is not popular internally.