How does passing a message to an object differ from just calling an object's methods with parameters? Is there other good sources for understanding the differences and rewiring the mental model?
How does passing a message to an object differ from just calling an object's methods with parameters? Is there other good sources for understanding the differences and rewiring the mental model?
I think in some languages and frameworks, message passing is associated with expressing a GUI, so objects have handlers for events, and there is more structure around how events can be signalled and handled. I'm thinking of Smalltalk, Hypercard and modern browsers.
It's also more distinct in concurrent programming with something like communicating sequential processes (CSP), where message passing is a way for concurrent processes to agree on how to share state. So when process A writes some data to a channel C it explicitly hands that data off, thus process B can read from C and operate on the data without corrupting anything. (Contrast with threads where you can modify anything, any time, so you have to use locks and deal with deadlock and such.)
Message passing allows for you to have the receiver of the message run in a different execution context; for example erlang.
Calling an objects methods with parameters is tied to that execution context.
Message passing is a larger concept than OOP. Microkernels for example are built around message passing as the means of communication.
Not necessarily - this depends on the language, or rather, on the object model. But consider COM or CORBA: you call a method, but the object might be on a different machine altogether.
On the other hand, sending a message would allow for only a single thread of execution owning that object, and calling methods on the object in response to incoming messages.
So I'd say it's not really "sending a message to an object", it's rather "sending a message to some kind of thread of execution, which owns that object uniquely".
Result: there is a "single writer" with regards to the internal state of that object.
I actually wrote an article on this for Rust, perhaps it could help rewiring your mental model: https://medium.com/@polyglot_factotum/rust-concurrency-the-s...
With message passing, the callee can decide not to respond to a message. Or to respond at a later time.
In a broader sense, I'd say the difference is between pressing a button on a robot that 'forces' it to walk, or asking said robot to please go and walk. In the former case, you're essentially reaching 'into' the robot's behavior via an exposed control. The caller is in charge. In the latter case you have no control and the callee, the robot, has the freedom to decide what to do and when to do it.
The way i see it OOP is about encapsulating/bundling data and the code that processes that data into one "object", that is isolated from other objects. The objects could only "communicate" with other objects by sending "messages" (data/events/something).
Personally i don't like OOP, and think that focusing on data and how it's processed is a better way forward (CSP and such). It's.. a complicated matter.
Most people probably go straight into the multi-node pub/sub universe when "messaging" starts being thrown around, but it could just as well be direct method invocation with objects in the single node/process case.
The nuance and complexity seems to come from where those messages are stored, and how access to them (or knowledge of their availability).
When you design with message-passing in mind, you don't expect an immediate answer to the message; instead, you expect to get an answer as another message. In some cases, this adds overhead: two messages, vs one function call. In others, you can do something else useful immediately after sending the message, and handle the return message whenever it arrives, maybe much later.
It is common to overlay a function calling mechanism on top of message passing. This is called "RPC", and is often a bad idea. The failure modes of message systems differ from those for function calls, so that assuptions higher up in the abstraction tend to be wrong.