What's so special about messaging in smalltalk

I met Smalltalk. In C ++, functions declared inside a class can be called by objects of this class, and similarly in Smalltalk, a keyword called a message is written next to the name of the object. (I don’t know much, but I would like to ask here, will there be a unique method in response to the message that must be executed?)

Basically, for my naive mind, this is apparently just the difference in syntax style. But, I wonder if, internally, from the point of view of compilation or memory structure, this difference in the call has some significance.

Thanks in advance.

PS: I worship all of you for your time and answers. Thank you very much.

+5
source share
4 answers

The main difference is that in Smalltalk, the message recipient has full control over how this message is processed. This is a true object, not a data structure with functions that work on it.

This means that in Smalltalk you can send any message to any object. The compiler does not impose any restrictions on this; all this is processed at runtime. In C ++, you can only call functions that the compiler knows about.

In addition, Smalltalk messages are simply characters (unique character strings), not the address of a function in memory, as in C ++. This means that it is easy to send messages online or over a network connection. There is a perform: method that lets you send a message specifying its string name.

An object even receives messages that it does not implement. The virtual machine detects this case and creates a Message object, and then sends a messageNotUnderstood: message. Again, the entity is responsible for how to process this unknown message. Most objects simply inherit the default implementation, which causes an error, but the object can also handle it itself. It can, for example, redirect these messages to a remote object or write them to a file, etc.

+13
source

You call a function in C ++ because at compile time you know which function will be called (or at least you have a finite set of functions defined in the class hierarchy.

Smalltalk is dynamically typed and late, so at compile time you have no idea which method will be evaluated (if any). So you send a message, and if the object has a method with this selector, it is evaluated. Otherwise, the message "incomprehensible" exception is thrown.

+10
source

There are already good answers here. Let me add some details (initially, part of this was in a comment).

In simple C, the purpose of each function call is determined during the call (unless you use function pointers). C ++ adds virtual functions for which the actual function called by the call is determined at runtime (dynamic dispatch, late binding). Function pointers allow you to customize sending mechanisms to some extent, but you need to program them yourself.

In Smalltalk, all messages are sent dynamically. In terms of C ++, this roughly means: all member functions are virtual, and there are no autonomous functions (there is always a receiver). Therefore, the Smalltalk compiler never decides which method will be called by sending the message. Instead, the invoked method is determined at run time by a virtual machine that implements Smalltalk.

One of the ways to implement virtual function scheduling is through virtual function tables. The approximate equivalent in Smalltalk is method dictionaries. However, these dictionaries change, unlike typical virtual function tables, which are generated by the C ++ compiler and do not change at run time. All Smalltalk behaviors ( Behavior , which are the superclass of Class ), have such a dictionary of methods. As @ aka.nice noted in his answer, method dictionaries can be requested. But methods can also be added (or removed) while the Smalltalk system is running. When the Smalltalk VM sends a message, it looks in the method dictionaries for the chain of the receiver superclass for the correct method. Caches are commonly used to avoid the recurring cost of this search.

Also note that messaging is the only way objects interact in Smalltalk. Two objects cannot access other instance variables, even if they belong to the same class. In C ++, you can write code that breaks this encapsulation. Therefore, sending messages is fundamental in Smalltalk, whereas in C ++ it is basically an optional feature.

In C ++, Java, and similar languages, there is another form of dispatch called function overloading. This happens exclusively at compile time and selects a function based on the declared argument types on the call site. You cannot affect it at runtime. Smalltalk obviously does not provide this form of submission because it does not have static typing of variables. It can be implemented, however, using idioms such as double dispatch . Other languages, such as Common Lisp CLOS or Groovy, provide even more general multiple dispatch, which means that the method will be selected based on both the receiver type and the runtime types of all arguments.

* Some special messages, such as ifTrue: ifFalse: whileTrue: are usually compiled directly into conditional branches and transitions in bytecode, and not in messages. But in most cases this does not affect semantics.

+6
source

Here are some examples of what you did not find in C ++

In Smalltalk, you create a new class by sending a message (either to the superclass or to the namespace depending on the dialect).

In Smalltalk, you compile a new method by sending a message to the compiler.

In Smalltalk, the debugger opens in response to an unhandled exception by sending a message. All exception handling is implemented in terms of sending messages.

In Smalltalk, you can request class methods or collect all its instances by sending messages.

More trivially, all control structures (branch, loops, ...) are executed by sending messages.

He sends messages down.

+5
source

Source: https://habr.com/ru/post/1264810/


All Articles