objectionary / eo

EOLANG, an Experimental Pure Object-Oriented Programming Language Based on 𝜑-calculus
https://www.eolang.org
MIT License
940 stars 123 forks source link

OOP Messages #45

Closed OneWingedShark closed 3 years ago

OneWingedShark commented 7 years ago

Dr. Alan Kay notes here and here how messages are the central point of Object Oriented Programming, even though it's been relegated to at least a second-class position because "Object Oriented" tends to make people think [only] about the objects.

Now, while he advocates an extreme late-binding, there are drawbacks that should be considered -- namely that (1) late-binding makes static analysis much harder [eg proving statically-typed languages vs proving dynamically-typed languages], (2) late binding makes certain optimizations impossible for the same reason that it makes static-analysis hard [increasing the types and number of unknowns]; (3) it makes debugging more difficult [the best debugging is the kind that never happens because it's "Correct by Construction"]. -- Because of this it may be worthwhile to consider messages themselves as a type/class/object/meta-type/however-you-want-to-say-it.

yegor256 commented 7 years ago

@OneWingedShark if you ask me, I would say that Alan Kay was/is wrong about messages and OOP. I don't think that objects should communicate through messages. Moreover, I think that horizontal communications between objects must be prohibited minimized. Objects should encapsulate each other and communicate vertically, from a bigger one to the encapsulated one and backward (!).

Messages are a perfect idea for the architecture, where sub-systems or sub-services (micro-services) communicate. There we definitely need messages and message hubs. But inside each sub-system objects must stay solid, encapsulating data and preventing them from being naked.

Do I make sense?

nqafield commented 7 years ago

@yegor256 This is a big deal it seems. (Or as a certain President-Elect might say, It's yuge!) I maybe should have seen before that this is your view, but this seems like a much clearer statement of it. (I'm not commenting, one way or another, on what I think of your approach, I'm just trying to draw attention to it.)

The AK approach is something like this:

A single, simple idea, repeated at all levels of abstraction?

But, here, we're talking about at least two distinct layers. Maybe an Erlang metaphor is the thing. On the level of processes Erlang is very AlanKay-OO; while - internal to the processes - it's also very "functional".

Does the big idea of EO, then, advocate an AlanKay-OO approach on the level of "modules", while the internals of those modules - those sub-systems - are written in an EO-style, "declarative Lisp" (?), vertically-communicating, encapsulated-object-kinda-thing?

I'm struggling for the words of course, but there's something here that we need to pay attention to it seems.

OneWingedShark commented 7 years ago

@yegor256

I would say that Alan Kay was/is wrong about messages and OOP. I don't think that objects should communicate through messages.

A object's method is a message though.
A good example would be a state-machine:

-- An enumeration of the transitions.
Type Transition is ( A, B, C, D, E, F );

-- An enumeration of the states.
Type State is ( Z, X, Y, W, V, U, T );

Type State_Machine is private;
Procedure Next( Machine : in out State_machine );
Function Get_State( Machine : in State_Machine ) return State;

The method State_Machine_Object.Next(D) is a message to the object telling it to preform the transition D, the method State_Machine_Object.Get_State is a message to the object to return the [value of] the internal state.

@pa9ey

I'm struggling for the words of course, but there's something here that we need to pay attention to it seems.

There is!
In #5 someone posted a video titled "Nothing is Something" and the presenter is very big on messages -- one of the first things she does is shows how you can use objects and their messages to handle control-flow by getting rid of the need for an if in Ruby.

aravindps commented 7 years ago

I agree with @pa9ey. I too feel objects should be message driven, only then it can be reused across domains and sharing in objectionary

ShawnFuller commented 7 years ago

Is message passing really a language construct? In order to pass a message to another object that object has to be inside it's encapsulation barrier (?) Sending a message means calling a method on an object, in this case. Unless by messaging you mean raising events (Javascript/DOM) or publishing and subscribing to a queue. But these are framework level constructs rather than language level. I am probably missing something here.

nqafield commented 7 years ago

The distinction between objects communicating vertically vs between each other is intriguing. But I think I'll reserve judgment on it until we've created some non-trivial, working code examples. Maybe the microservices idea "saves" things, although at the moment it seems that they will have to be pretty much nanoservices. And the messaging idea there will have to be a major aspect of the language. (Again, see the Erlang analogy.)

aravindps commented 7 years ago

The example from Object Thinking Book. If we have traffic signal object and the vehicle object. When a vehicle reaches a signal, it will become an observer of the traffic signal. When there is a state change in traffic signal, it will notify the vehicles that are subscribed to it. Here the vehicle may or may not respond to the message, but traffic signal don't need response for its' messages.

NikoGJ commented 7 years ago

I've taken the first lines of the definition of "Actor model" from wikipedia and replaced the Actor word with Object and it gets very close to what an object should be (IMO):

[...] It treats objects as the universal primitives of computation. In response to a message that it receives, an object can: make local decisions, create more objects, send more messages, and determine how to respond to the next message received. Objects may modify private state, but can only affect each other through messages

The "method" term is kinda too much restricted to the computer domain language. It implies that method calls are just somehow some procedure calls with a specific scope or context... because that's how they are implemented in the computer. The messaging metaphor doesn't imply a specific implementation, it does leverage the importance of the communication between objects as a more human way to communicate, that is a central point for any working organization.

Btw, for those who don't know Sandi Metz, the presenter of the video "Nothing is something" above, I highly recommend to go read her book "Practical Object Oriented Design in Ruby" (even if you don't do Ruby, that's my case) A must-read.

aravindps commented 7 years ago

@NikoGJ this is exactly what I have in my mind. Thanks for the book reference.

yegor256 commented 7 years ago

@pa9ey I believe that "communications" between objects, which we have now, are simply data sending operations. We use methods to do that. We can also use some message hub and events. We can use whatever we want, but the problem is that the data is naked. The data escapes our objects, in order to arrive to some other objects. What that objects will do with the data is not known to us, originators of the data. Here is an example:

print("Hello" + "world");

Here, both "Hello" and "world" are objects that have to expose their data, in order to allow us to concatenate them and build a new object. They have no control over that operation. They don't know how the data will be used. We message them and they return back the data/message. I believe, we must do something else instead:

print(new Text("Hello", "world"));

Here, we build a new object of class Text, encapsulating two objects. Then, this new Text privately communicates with them, working with data the way nobody else can work with them. Maybe even directly touching their private attributes, etc.

The point is that the new object of class Text becomes a new text, encapsulating two existing ones. It doesn't wire them together, dispatching messages and data (as Alan Kay, I believe, was suggesting), but becomes a new one. See my point?

mdbs99 commented 7 years ago

@yegor256 and at the end, what Text will send or give for print?

yegor256 commented 7 years ago

@mdbs99 it won't give anything. There won't be any print. It will be something like this:

text = new Printable(
  new Text(
    "Hello", 
    "world"
  ),
  new Console()
);

And then:

text.live_a_long_and_happy_life(); // :)

See?

mdbs99 commented 7 years ago

@yegor256 but your first example was using pri..... anyway.

You mean that Text instance has a to_str method (or something like that) to Printable instance use it, right? So the data will continue passing between these objects.

yegor256 commented 7 years ago

@mdbs99 yes, Printable will have direct access to Text.the_text, even though that attribute is private. Objects should have access to each other's data, I believe, but only when they encapsulate each other.

mdbs99 commented 7 years ago

@yegor256 that way you can do whatever you want using objects. We're talking about friendly classes (like in Object Pascal or C++), right? I know about your "trust object" article, but it's the same.

Don't you think this break encapsulation?

fabriciofx commented 7 years ago

@yegor256 I agree with @mdbs99: access to private attribute (IMHO) breaks encapsulation. And you already said (not with the same words) "Encapsulation is the most important feature of OOP. Must be preserved at all cost". So, I don't like any solutions to break encapsulation. We should think in another solution to this very serious problem.

yegor256 commented 7 years ago

@fabriciofx yes, indeed, it looks like we break encapsulation, I agree. Let's try to think about a better approach. But sending data through methods (making them naked data) is even worse, because anyone can access them, while in my approach only friendly objects can touch that data.

nqafield commented 7 years ago

@yegor256 So then I presume the printers/media stuff was also related to this idea of avoiding naked data and of doing vertical communication rather than messages. Are the friendly objects an extention (a progression) of that? Have you given up, in some sense, on the printers/media idea?

goqp commented 7 years ago

@yegor256

Here, both "Hello" and "world" are objects that have to expose their data, in order to allow us to concatenate them and build a new object... I believe, we must do something else instead:

print(new Text("Hello", "world"));

I agree with you theoretically about constructing a new object that has access to its components' private attributes. In fact, if you recall I did some experiments with this idea a long time ago using operator overloading. But this proved to be both tedious and restricting because it only works when objects are of the same class. Actually we want to be able to do this for potentially different types of objects, right?

@mdbs99 yes, Printable will have direct access to Text.the_text, even though that attribute is private. Objects should have access to each other's data, I believe, but only when they encapsulate each other.

Without operator overloading how can you do this? Maybe using reflection? In either case it sounds like a lot more trouble than it is worth.

Guys, I think we are possibly making a huge mistake in our thinking because we are focusing on 'data' rather than information. I am still confused on the distinction and the implications however. I will come back and write about it in 30 minutes or so when I have figured it out a little better, hopefully.

FOR NOW, I have a strong suspicion that the central problem is that an object CAN NOT be both an actor and represent information at the same time. The two things are probably very different and have to behave according to different rules. Exciting idea, need to think.

yegor256 commented 3 years ago

@OneWingedShark here is what I think about Alan's idea about messages: https://www.yegor256.com/2017/12/12/alan-kay-was-wrong.html