I find it a bit amusing to think of the evolution of things, in basic terms... within a program, we have these things called "functions", which have "prototypes" / definitions that define the number and types of arguments (using the C terminology).<p>We didn't always have those things... in the bad old days, there were just "subroutines" and gotos (without a call stack), and functions in C (pre-C89) with no prototype that you could just call with whatever arguments you felt like... and if the caller and callee agreed on the types, great, if not... maybe it worked, or maybe some crash, who knows, depending on the nature of the argument mismatch (too many vs too few, the types involved, etc).<p>So, prototypes and functions with a stack were invented to solve a problem, and meant that if the program compiled and linked, then at least all the callers and callees agreed on the prototypes and argument types, and things might work, and if not, then there would be a core dump or a stack trace where we could look at the stack and that would tell us quite a lot about the system/program execution state.<p>Fast forward to today... and now we throw a lot of those inventions out the window and use "microservices" or "REST" or JSON etc, where there is no prototype that the caller and callee agree on, it's all just unstructured or semi-structured (like the bad old, pre-prototype days in C...), and if the caller and callee don't agree on some vague notion of what the parameters are then chaos ensues, and there is no one place to look at to debug (like a core or stack) because the system state is now spread across many machines and so there are lots of logs to correlate (at best).<p>A lot of people even describe this as a selling point... "yeah, it's great that we have microservices and loose coupling so we can upgrade the different parts separately!". If a strict schema is in use, like (like xsd, wsdl, protobufs, etc), then it can almost work, because so long as everybody agrees on the schema then sure, the individual parts can be upgraded separately. Oh, but... then how to we change the schema? Oops, now everything needs to be re-released all at once and we're back to where we started.<p>If the schema/protocol never changes, then it can work... and indeed that's what IP, HTTP, etc., are, they are set in stone for decades and then the clients/servers can change and that's fine, but if you have an elaborate distributed system with either a loose schema, or a strict (and therefore necessarily changing often) schema, which are the popular choices, then you're screwed.<p>At least in the classical analogy with C/C++/Java whatever, we admit to ourselves that if the function prototypes, arguments, etc. need to change, then that's a recompile, relink, and restart the whole system, not just some parts of it.