HACKER Q&A
📣 revskill

If OOP is about message passing, why not sender.send(receiver, message)?


I learnt that (from Alan Kay), OOP is about message passing, but in most of OOP supported language, the syntax is always

receiver.message(params).

While i think it should be

sender.message(receiver, params)

or

sender.send(receiver, message, params)

Am i missing anything ?


  👤 jasonhansel Accepted Answer ✓
I would argue (contra Kay) that OOP really isn't about message passing; an object is fundamentally a state machine, not an actor or a fiber. So it should really be:

thing_undergoing_state_change .state_change(params)


👤 streetcat1
Yes. You miss polymorphism.

The reason for receiver.method(), is that the binding to the receiver is done in runtime and not in compile time. Hence, you can change the ACTUAL receiver object without changing the sender.


👤 al2o3cr

    While i think it should be

    sender.message(receiver, params)
Why do you think that? Not trolling - it's hard to understand what you might or might not be "missing" without understanding your thought process.

In the overwhelming majority of cases, "sender" is implied by context; objects do not send messages on behalf of other objects.


👤 hedora
You might want to look at Barbara Liskov’s work on object oriented programming. It refined a lot of those concepts, and looks closer to modern OOP than Kay’s sender model.

https://arstechnica.com/science/2009/03/acm-gives-turing-awa...

https://en.m.wikipedia.org/wiki/CLU_(programming_language)


👤 spacechild1
> I learnt that (from Alan Kay), OOP is about message passing

I just like to point out that Alan Kay has a very particular idea of OOP that doesn't match the current mainstream usage. None of the modern OOP languages are “object oriented“ in Alan Kay's meaning of the term.


👤 jecel
Imagine that you have three friends helping you with a task. You might give them these instructions:

    Jack, clean the shelves.
    Helen, sort the reports.
    Lucy, turn on the printer.
You can see that the receiver of each message is the first thing in each line while the message follows it. That is the syntax of imperative expressions in English.

If your name is Kevin and you are the one sending on the messages, where is "Kevin" in the above text? And you sent three messages and yet there is not a single "send" command to be seen.

Here is a less trivial example:

     Jack hire a carpenter build cabinet store reports.
This is not valid English, but is a valid Smalltalk-72 expression. A variation which would have the same result is:

     ((Jack hire a carpenter) build cabinet) store reports.
The first message requests that Jack hire a carpenter. The result of the message is a carpenter who is not named by us, but which we can tell to build a cabinet. The result of this second message is a new cabinet, which we did not name either but which can be asked to store the reports.

So Smalltalk got its syntax from English and that inspired OOP languages that followed.


👤 the-alchemist
Great question! I've thought about this too, in my younger days.

All of this is IMHO:

* an abstract concept like Alan Kay's OOP is not the same as programming language syntax * your examples are programming language specific. Python, C++, Java-ish, from the looks of it * Alan Kay's OOP, as far as I understand it, is about /disconnecting/ the sender and receiver, and have them "communicate" via messages. * the difference between `receiver.message(params)`, `sender.message(receiver, params)`, or `sender.send(receiver, message, params)` is skin-deep. You can easily write a library that converts one to the other in almost any of the languages.


👤 amw-zero
You're taking a complicated subject and reducing it to talking about what amounts to be pretty superficial syntax. There's more to messaging than just how the syntax of sending a message - how do you represent messages? Call by value or reference? Is the call synchronous or asynchronous (e.g. Erlang)?

Also, in terms of syntax, why not:

    send(receiver, sender, message)
Why is the act of sending tied to the subjects at all, and not the responsibility of the system itself?

👤 pornel
Kay’s favorite OOP language was Smalltalk:

    receiver message:params

    condition ifTrue:[dog bark]
There isn’t an explicit sender here.

Order of arguments is just an irrelevant syntactic detail as long as only the receiver chooses the method implementation.

There is an alternative approach called multiple dispatch or multimethods where every function argument can be used to look up the appropriate method to call. It’s implemented in e.g. Julia.


👤 mikewarot
Objects are records with a controlled interface, so that you don't have to see the internal details. This allows restructuring of the internals without disrupting the code that uses the objects. It is a fairly well understood mechanism for preventing unwanted side effects.

The interface is type checked, and the appropriate way set the type rules is to bundle them with the interface (and thus the object), not with the user code.


👤 jolmg
> Am i missing anything ?

> sender.message(receiver, params)

It's the receiver that determines what messages they can understand, and the sender itself rarely has anything to do with the message apart from sending it. It doesn't make sense to make the sender an important part of the syntax for message-sending. By keeping the sender out of the syntax, the syntax of a particular call is the same no matter how the sender changes from moving the code around.

Also, writing it as receiver.message(params) follows English grammar of subject-verb-object ordering, allowing the code to read more naturally.

> sender.send(receiver, message, params)

If you're asking about the use of the word "send", at least Ruby uses it, but it's receiver.send(message, params). That particular call does not follow English grammar, but you only ever use the "send" message when the message is variable. It's not common.


👤 rgoulter
It could even be expressed as `(params message receiver)`, or `message; .{{receiver}}` or whatever other syntax.

But it's going to be more thoughtful to explain what parts of programming or of software design or architecture are emphasised by different ways of arranging things.

`receiver.message(params)` puts an emphasis that it's the receiver which receives and acts upon the message. The receiver will conform to some kind of interface with which we can interact.

`sender.message(...)` seems completely bizarre to me. -- Some module's interaction with other things is where the interactions are defined? Sounds interesting if it works!


👤 srivathsaharish
I think you are right in thinking it must be sender based. But it might not sit well with dev ergonomics. But almost every actor based implementations do what you are suggesting in one form or the other

👤 PaulHoule
The ‘sender’ is the code doing the call and the context. Most languages don’t let a method know who called it, so it is not a ‘full fat’ implementation of messaging which would be more like email.

👤 thesuperbigfrog
The Quicksilver word processor / desktop publishing system offered a user programming interface in lisp.

The Quicksilver lisp used object-oriented programming and most of the documents and desktop system were objects. Calling methods on those objects originally used a function called "tell" for message passing:

(tell object method parameter1 parameter2)

Later they deprecated "tell" in favor of:

(method object parameter1 parameter2)


👤 rodrigosetti
I think usually the sender is implicit (the calling context) so it could me omitted.

Racket [1] has a non conventional syntax too.

[1] https://docs.racket-lang.org/reference/ivaraccess.html#%28fo...


👤 gjvnq
Learn Smalltalk.

  myObj 4 "this sends the number four to myObj. Yes, comments are in quotation marks"
  4 factorial "yep, numbers are objects too"
  0 + 4 "sends the 4 as a message to 0"
  myObj arg1: 1 arg2: 'a' "if you need more than 2 arguments you use keyword messages"

👤 seanalltogether
This is effectively how all calls in Objective-C work. Everything turns into

objc_msgSend(receiver, message, params)


👤 dragonwriter
> Am i missing anything ?

Conventionally, the send is always implemented in the sender, so explicit sender makes no sense.

This is true even in Erlang as opposed to class based OOP, though there the syntax is:

  receiver ! message

👤 hypertele-Xii
> receiver.message(params)

> sender.message(receiver, params)

The only difference here is that sender is implicit. Since you are writing code in an object's context, the sender is this object (a keyword in many languages).


👤 keeeeeeeem
You're missing nothing. Class based OOP is essentially a set of arbitrary ontologies forced upon you by library authors. Your interpretation is no more or less meaningful than the others.

👤 stevenalowe
Within the execution environment the sender is known (it’s the current object) and the verb “send” is generic and thus not informative so typing sender.send over and over is unnecessary

👤 steve_coral

👤 toast0
sender.send(receiver, message, params)

is really sending a message to sender with content {send, receiver, message, params}

If you want the receiver to know who the sender is, you need to pass that along in the message. Personally, I find that's easier to manage if it's explicit rather than implicit. If I want to send a message and have replies go to me, I'd say the sender is self or this or what have you; but if replies should go elsewhere, I can easily do that. With an implicit sender, you have to route the sending through the sender to get the reply to the right place and it adds considerable structual complexity.


👤 archsurface
I don't know the actual answer, but that would be a lot of useless typing.

👤 stevefan1999
Well, at least that was how Smalltalk (which is what Kay does contribute to) works. And if you have actors, it also looks similar as well (when you pass a message to a mailbox).

👤 bediger4000
> sender.send(receiver, message, params)

A lot of very bad corporate software has informal object-oriented-programming implementations that either look like this, or map to it directly.


👤 aryehof
Look to the inventors of Object Orientation to learn what it is about. They won a Turing award for it after all. Hint: It wasn't Alan Kay.