" in 99% of my experience the services aren't a real distributed system anyway and are vaguely organized by function, developer interest, and yes, control."
But, that's kind of the point. They're a networked system of interacting processes, but not a distributed system. A distributed system generally is a tightly coupled and coordinated set of services running on many machines for purposes of resilience or scale-out. Microservices are more for organizational scale-out. A microservices might BE a distributed system, but several interacting microservices probably isn't one (pedantically speaking).
Microservices are an evolution of how large-scale integrated systems have played out as a pendulum swing between tightly coupled systems and loosely coupled systems.
After the mainframe, into the client-server era, most non-web software in a large organization (eg. most IT back offices dating back to the 90s) were NOT built as a single application, it was built as a set of independent applications that were coordinated by something: a shared database, data extracts, message queues, transaction processors and RPCs.
Data extracts were the ultimate in loose coupling. You got an update every night from other databases, and could do whatever you wanted with the data. But of course, this led to data quality problems, when customer records or inventory couldn't reconcile.
So we moved to "a service owns its data" type situations, and wrapped them in message queues or RPCs. This is basically how something like SAP works - it's a set of modules with their own schemas that are tightly coupled through a set of RPCs and messages.
But this eventually had none of the benefits of networked modularity - everything was so coupled and intertwined, it was a mess to change and upgrade - you had to do the whole thing at once (which is why SAP upgrades are so notorious).
What makes microservices different is that we've evolved them to have truly independent interface from implementation by having the implementation lifecycle of a module be tied to the server down to the metal, so it can be completely autonomous from other services. Therefore I can upgrade/replace/scale/move these runtimes whereever I want, whenever I want. I can also place proxy or gateway intermediaries between them more easily. This is "SOA done well", in effect.
We've also evolved our practice of service interface design beyond rigid IDLs and WSDLs and schemas into more permissive, extensible, and better documented APIs or Events, along with easier versioning, but the state of the art still has a long way to go there.
Not a panacea, but on the flip side, I've rarely seen a maintainable, scalable, and easy to change networked monolith. They do exist, but required the controlling designers to be deeply talented with full control over architecture decisions, and they didn't get into analysis paralysis. But even they eventually couldn't keep up with changes, so they're breaking their monoliths up today, IME.