Hacker News new | ask | show | jobs
by kazinator 3727 days ago
Moreover, getters and setters can be readily modeled with messages.

That messages and (at least single dispatch) methods are identical was settled decades ago.

(Has someone worked out a multiple dispatch OOP based on message passing?)

2 comments

The conceptual difference between messages and methods to me is that messages implies that it is the object itself that is the arbiter of whether or not it can handle a specific call, and the decision may depend on factors not knowable before the call. While "method" implies to me that it is something that may be applied to the object by an external actor.

E.g. if I do "foo.bar()" in C++, the compiler will simply not compile the code if "bar" is not already defined on the class "foo" is declared as. The object at runtime has no influence on the dispatch.

In Ruby, on the other hand (as well as Smalltalk and other languages with late binding and message passing), regardless of implementation details, whether or not "bar" is not defined when the code is parsed is irrelevant. You can in the general case not know before reaching the call-site whether or not "bar" is defined, and even if it is not, it is not up to the interpreter to throw an error if e.g. a method_missing is defined, and you can't in the general case determine in advance whether or not there will be a method_missing defined when you get to the call site. The object can decide to process different messages depending on the time of day if it pleases.

See also the Alan Kay quote elsewhere in this thread - especially the part about late binding.

You can achieve this with e.g. vtable based dispatch (fill in "missing" slots with thunks that loads a symbol and calls method_missing, and fill in the "method_missing" slot with a generic one that raises an exception), so this can still lead to similar implementations. It's a different way of looking at things, coupled with the dynamism of very late binding.

> if I do "foo.bar()" in C++, the compiler will simply not compile the code if "bar" is not already defined on the class "foo" is declared as

In a more dynamic language, in fact "foo.bar()" may be equivalent of asking foo whether it understands how to bar, and if so, then please do it. If foo doesn't understand, there could be some mechanism for handling that, like a catch-all function that can be defined that gets invoked.

Likewise, we could also have a static language with message passing OOP in which the same check is implemented. The classes declare statically which messages they understand and the compiler checks that.

Quite simply, "late binding" != "message passing". There can be late binding of messages, and late binding of function calls.

There is no real conceptual difference between single dispatch and (synchronous) message passing.

What is Unix ioctl? Message passing or function call?

> That messages and (at least single dispatch) methods are identical was settled decades ago.

This has been modeled out from message passing and procedural code semi-formally, with the first discussion (that named the duality) being available here: https://cseweb.ucsd.edu/classes/wi08/cse221/papers/lauer78.p...

And it's fine for multiple dispatch as well, btw. Higher kinded types reward everyone equally here.