I like to see message passing as method calls as conceptually about who is responsible.
A method call is "done to" an object. The caller decides which code is invoked. It does so with information about the object or its class, but ultimately the object has no direct say.
Message passing on the other hand conceptually grants the object the role of deciding what happens to a message.
Message passing is often implemented in terms of method calls for the simple cases, but an object has the ability to dynamically define how a message should be handled based on state that may be known to the object but not the caller.
A typical Ruby example (and Ruby is a good example - it "stole" most of its object model from Smalltalk) is Ruby ORMs like Sequel (same applies to most Ruby ORMs) that dynamically define accessors for columns etc when connecting to a database and dynamically querying the database for the schema.
In Ruby, method calls is a veneer - you can define a method that looks like it's just like a C++ method call, decided at the callsite, but at runtime the receiving object can be redefined at any point, up to and including changing which methods the object responds to on an object-by-object basis, or defining "method_missing" so that what looks like method calls are entirely dynamic.
> It it supposed to be remotable? So are method calls.
I'd say there is a difference in degree of complexity in remoting. In a message passing system you typically do not need to have any kind of definition of the interface available client side. E.g. Drb for Ruby lets you expose any Ruby code over a network connection this way.
E.g. here is a real example, using the "pry" Ruby REPL. Server side:
The above exposes "self" which is this case is the "main" object of that Ruby instance, but you can pass it any object you want, and all public instance methods on that object will then be remoted, and any objects returned from those methods will be remoted dynamically as needed.
It then defines the "hello" method on main after the server has been set up. Doesn't matter when the methods are defined, as long as they're there when you call them.
The redefinition of "hello" in [5] happens after I've called hello the first time from the client (the "Hello World" in [4] was triggered by the client. The redefined version returns the string to the client instead of printing it on the server:
$ pry
[1] pry(main)> require 'drb/drb'
=> true
[2] pry(main)> client = DRbObject.new_with_uri("druby://localhost:8787")
=> #<DRb::DRbObject:0x000055828909f220 @ref=nil, @uri="druby://localhost:8787">
[3] pry(main)> client.hello
=> nil
# Here we redefine "hello" on the server.
[4] pry(main)> client.hello
=> "Hello world"
A method call is "done to" an object. The caller decides which code is invoked. It does so with information about the object or its class, but ultimately the object has no direct say.
Message passing on the other hand conceptually grants the object the role of deciding what happens to a message.
Message passing is often implemented in terms of method calls for the simple cases, but an object has the ability to dynamically define how a message should be handled based on state that may be known to the object but not the caller.
A typical Ruby example (and Ruby is a good example - it "stole" most of its object model from Smalltalk) is Ruby ORMs like Sequel (same applies to most Ruby ORMs) that dynamically define accessors for columns etc when connecting to a database and dynamically querying the database for the schema.
In Ruby, method calls is a veneer - you can define a method that looks like it's just like a C++ method call, decided at the callsite, but at runtime the receiving object can be redefined at any point, up to and including changing which methods the object responds to on an object-by-object basis, or defining "method_missing" so that what looks like method calls are entirely dynamic.
> It it supposed to be remotable? So are method calls.
I'd say there is a difference in degree of complexity in remoting. In a message passing system you typically do not need to have any kind of definition of the interface available client side. E.g. Drb for Ruby lets you expose any Ruby code over a network connection this way.
E.g. here is a real example, using the "pry" Ruby REPL. Server side:
The above exposes "self" which is this case is the "main" object of that Ruby instance, but you can pass it any object you want, and all public instance methods on that object will then be remoted, and any objects returned from those methods will be remoted dynamically as needed.It then defines the "hello" method on main after the server has been set up. Doesn't matter when the methods are defined, as long as they're there when you call them.
The redefinition of "hello" in [5] happens after I've called hello the first time from the client (the "Hello World" in [4] was triggered by the client. The redefined version returns the string to the client instead of printing it on the server: