receiver.message(params).
While i think it should be
sender.message(receiver, params)
or
sender.send(receiver, message, params)
Am i missing anything ?
thing_undergoing_state_change .state_change(params)
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.
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.
https://arstechnica.com/science/2009/03/acm-gives-turing-awa...
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.
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.
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.
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?
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.
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.
> 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.
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!
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)
Racket [1] has a non conventional syntax too.
[1] https://docs.racket-lang.org/reference/ivaraccess.html#%28fo...
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"
objc_msgSend(receiver, message, params)
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
> 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).
https://docs.godotengine.org/en/latest/classes/class_signal....
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.
A lot of very bad corporate software has informal object-oriented-programming implementations that either look like this, or map to it directly.