In the types of OO systems Kay discusses, it's up to the receiver to determine whether or not to respond to a message and how to behave if it doesn't "understand" the message. That's how you get maximum polymorphism as well -- for example, all kinds of objects are "cancelable" if they respond to / understand the message #cancel, etc, etc
This seems exactly analogous to how a collection of webservers interact. They can only communicate with each other by tossing a chunk of bytes around hoping that the target knows what it's supposed to be doing with those bytes.
It's a horrible programming model, though. We should be glad this is not how most languages work.
Have you ever actually programmed in this model? I wrote a correct RAFT library in ~300 lines of code that are extremely legible using this model.
This is not only about languages, but also environments. The argument Kay makes is that in order to make very large complex systems that are resilient, you need something like this kind of message passing. And indeed, this is how the Internet works too
Objects in contrast are not stateless things. They can know the history of the messages they have received earlier, as reflected in their internal state.
The distinguishing feature of message-passing an OOP I think is that the receiver of a message is free to decide how it will respond to it. Will it always return the same result for the same inputs? Not necessarily. I decides. It is the decider.
One way to think about Objects is as independent computers which get inputs from their surrounding and then somehow process such inputs. They might not return any result, but still do something useful. The point is they a PROGRAMMABLE objects, they are "live".
1) that objects are acting like async, independent machines (I picture the erlang actor model, but maybe that’s a stretch.). This makes messages a more natural way to emphasize that these actions can happen across networking or threading boundaries;
2) the message is explicitly not inheritance and therefore doesn’t contain implementation. This means it’s really a messaging contract and only the interface matters!
3) redirecting, storing, or replaying messages are each very powerful concepts that lead to many useful features (networking state, save/load, undo/redo, logging, debugging). Thinking in these terms is much harder to express with functions, so I see this as messages are the _data_ of function calls, and function calls are more the _act_ of calling.
That said, I’d love to hear other’s take on this as well. The differences from functions are subtle and it doesn’t help that we use the same/similar words to mean different things.