What is the difference between "sending a smalltalk message" and "calling a method" (i.e., jumping the central thread of execution to a particular label until a ret instruction is reached)? This isn't truly distributed, it's still centralized. If one method gets stuck in a loop, the entire system grinds to a halt. If each "object" or "service" gets its own process or thread however, this doesn't happen, and you get graceful system degradation which can be mitigated by spinning up redundant services.
You're right, most businesses don't need microservices, indeed "monolithic" (not distributed) architectures are totally fine and they have less overhead. And yeah probably a lot of businesses that do use microservices don't even make use of the benefits of a distributed system yet have all of the drawbacks. That's just people being people (stupid).
If we had gone down the path of Smalltalk rather than the UNIX-like path we have taken, I imagine we'd see systems with asynchronous message-passing semantics using processes/threads. Think something like E (or now Spritely Goblins, which takes inspiration from it) with at least one separate vat per "application". This would result in a system like Smalltalk, but with concurrency to prevent the situation you're describing.
I think we'd be in a much better place today had we taken that path, for a number of reasons.
In Smalltalk, calling a method is what the system does after a message is sent and the system looks up the receiver and its class hierarchy. This is a little different from C++ where the message dispatch is just vtable lookup by the calling code, because the system might have different behavior, such as changing the message to a #doesNotUnderstand: message.
However, in your question it is not much different because the default approach is synchronous. Yes, the calling process waits for the receiver to send a response. This has been one of the sticking points of remoting objects since the beginning, that you cannot treat the network as completely transparent. The options are the same as in other languages: promises, callbacks, forking a process, etc.
On the other hand, having a simple representation for network calls that the runtime can figure out for you automatically is pretty cool. You can ask Smalltalk to create proxies on the fly that act like the real thing but do the marshalling and network calls. The same was true for RMI in Java, which may have been based on Smalltalk and/or Modula-3. Comparing this to COM or CORBA, where the representation is defined externally, or to SOAP or some JSON api, where all bets are off, keeping everything in one system makes this stuff easy.
If we wrote things as objects sending messages we might be able to disregard their remoteness most of the time. The value could be in writing software which wouldn't need to change much as you changed the way it's getting used radically.
For a crappy example, a tool like rsync can talk to a copy of itself over any kind of stream and sync things that are remote so because it has this abstraction, you can rsync over ssh but you're not limited to ssh. If some future stream protocol arises rsync could probably be made to work over it without a rewrite.
You're right, most businesses don't need microservices, indeed "monolithic" (not distributed) architectures are totally fine and they have less overhead. And yeah probably a lot of businesses that do use microservices don't even make use of the benefits of a distributed system yet have all of the drawbacks. That's just people being people (stupid).