What is message passing?
There are two definitions in widespread use, which refer to two completely different things.
The definition from SmalltalkLanguage:
is simply a method call on an object. Smalltalk messages are perfectly synchronous (the caller waits for the callee to return a value), and not terribly different then function/method calls in other languages. A few key points about Smalltalk message passing:
The definition from many concurrent programming paradigms:
- Like C/C++/Java/ML/Lisp/Scheme, and unlike Haskell, Smalltalk messages are strict--all arguments are evaluated before the message is sent.
- Like C++ and Java (and unlike CommonLispObjectSystem, DylanLanguage, etc.), Smalltalk messages are SingleDispatch. The types of the arguments have no say in what method is selected to receive the message), though Smalltalk makes delegation easy.
- The syntax of Smalltalk message invocations is somewhat unusual, though highly readable once you get used to it.
is a method for asynchronous
dispatch, and used to communicate between different processes (which may run on different machines). Different concurrent models have different semantics regarding messages, such as whether or not the receiver and sender must rendezvous, whether or not the receiver must name the sender, etc. See MessagePassingConcurrency
for more information.
story arises entirely out of a tragic confusion engendered by AlanKay
's research group. The initial variants of the SmallTalk
family of languages were strongly inspired by AlanKay
's knowledge of CarlHewitt
's research on the ActorSystem
model of computation.
research was based on the assumption that massively parallel, distributed, computer systems could become prevalent, and therefore a convenient and efficient way to structure a computation
was as a large number of self contained processes, called actors
, communicating by sending messages to each other.
had also been exposed to the ObjectOriented
ideas in SIMULA-67, which were about a program decomposition paradigm, a way to structure programs
, not computations. It was however easy to see that in general ActorSystem
computations are naturally ObjectOriented
too, even if most ObjectOriented
languages are based on the procedural model of computation, and a few even on the logic model of computation.
Therefore the first few languages in the SmallTalk
family were not
procedural, and did not have procedure calls, but variants of message sending in the ActorSystem
sense. In particular this applied to Smalltalk-76, which is the language described in the first famous article about the Smalltalk family of languages in Scientific American.
With Smalltalk-80 any trace of ActorSystem
orientation were removed, in part because ActorSystem
computations are very expensive to simulate on conventional workstations, in part because AlanKay
's group were influenced by the Lisp research being performed on the same workstations at XeroxParc
Unfortunately even if Smalltalk-80 is a thoroughly conventional procedural language (and a fairly close variant of Lisp, even if with different syntax and details) AlanKay
and his group and the Smalltalk-80 community continued to use ActorSystem
terminology, retaining the message passing
nomenclature for what had become conventional procedure calls (there is a single, hard to spot, note in one of the Smalltalk-80 book where it is stated clearly that message passing
in that language really means the same as procedure calls
This unfortunate terminological issue has created endless confusion as to a large extent the mythical relevance of Smalltalk-80 and the conflation of ActorSystem
terminology with procedural semantics and ObjectOriented
concepts have muddle considerably the difference between these very different categories.
Many years after Smalltalk-80 was released AlanKay
seems to have come to regret the switch to procedural languages, arguing that the performance driven switch to a procedural computational model had been a mistake as increases in hardware performance would have made the simulation of ActorSystem
based computations on procedural hardware feasible, and that the ActorSystem
model of computation is preferable in his view to the procedural one.
However he has also stated that one of the most important recent books is The art of the metaobject protocol
which is entirely about advanced techniques related to procedural OO languages, which raises the possibility that he himself suffers from some confusion.
Most C programmers seem to be moving to ObjectOrientedProgramming
in the CeeLanguage
: They define structs and have functions for creating and destroying the structs. They implement some form of reference counting for garbage collection. However, they never seem to implement message passing. Is message passing an important part of object oriented programming or is it really not necessary?
- Do you mean the Smalltalk definition, or the concurrent-programming definition?
Message passing is really unrelated to ObjectOrientedProgramming
, although usually a "message" is created as an object.
I use the term "message passing" to mean "queuing of communication between a source (sender) and a destination (receiver)", without regard to technology used (usually asynchronous is implied however). JMS is one technology to do this, but I've also used a simple event queue/dispatcher to do message passing within a single JavaVirtualMachine
. Other examples of tools are given in the MessageBus
topic. The MultiCaster
pattern is the way to go if things are complex enough to need many processes. -- StanleyKnutson
A great definition
Jerry Smith on http://www.jguru.com/faq/view.jsp?EID=773
posted a nice summary:
- Message passing is a general term for a variety of strategies for high-level, structured interclient communication. For example, a mobile agent framework could provide classes and methods with which two agents (on two different computers) send each other messages. The steps required to send and receive messages are specific to the framework. JMS supports two common message passing strategies, namely, point-to-point and publish/subscribe. JMS can be utilized by any (Java-based) distributed software components; of course, the JMS middleware must be available.
Most C programmers seem to be moving to ObjectOrientedProgramming ... However, they never seem to implement message passing.
As a CeeLanguage
programmer, I don't quite understand the point. "message passing" seems to mean two very different things.
No, that's merely a commonly appropriate optimization of a more general mechanism. Activation records in Smalltalk and in Scheme need not follow a strict LIFO ordering, even though that is the most common in any language, and is why they are usually optimized as simple LIFO stack-based function calls. There was some strong communication between Parc and MIT in the 1970s that lead up to all this, but anyway, once you're doing non-LIFO function calls, you start getting things that instead could be viewed as messages between threads.
- In a object-oriented context, as far as I can tell, "message passing" is a fancy way of saying "function call". Say someone writes animal.talk("Hello!") or anAnimal talk:'Hello!' and says "I'm sending this animal the 'talk' message". But the computer acts just the same as if a CeeLanguage programmer writes "talk(animal,"Hello");" and says "I'm calling the talk() function with this 'animal' structure.". Not even close, the C implementation doesn't change its behavior based on the type of "animal".
Is this CeeLanguage
programmer implementing message passing ? If not, what do you mean by "message passing" ?
- In a networking application, "message passing" means "sending a message over the wire from a program on this computer to a program on that computer". For example, in X windows, sending a message from an application running on one of the campus Sun boxes "draw a white rectangle" to the Linux box on my desk at home. There's usually a buffer at both ends that can hold several messages. Occasionally the 2 programs run on the *same* computer -- then the OS simulates a "virtual wire" by directly copying from the out buffer into the in buffer.
I think of them as completely different things, because: What happens when a program is in the middle of handling one message, and then a second message come in ? In the OO case (a recursive call), the machine puts the first message on hold, takes care of the second message, then returns to processing the first message. In the networking case, the machine leaves the second message in the buffer until it's good and ready for it.
Common, but certainly not necessarily true. Input queues can be priority ordered, for instance.
I am implementing the "non-function call" kind of message passing between Objects in my language that are virtually all running independently of all others (green threads). Data is passed by a MAP that I call a "bag of variables" to "interface" functions on the Object that can accept only "MAP messages". My messages can be synchronous or asynchronous and they can be passed on (forwarded) to other Objects easily. All messages are queued and once an Object receives a message, any new messages have to wait until the current message has completed. One last thing, an Object can send and wait for messages that bypass the input message queue if it wants to.
The advantage of using a MAP (set of any group of variables or collections) is that input to interfaces can be drastically changed without invalidating (or re-compiling) other calls, as the MAP can contain any group of objects, unlike an object. Functions have a set number of parameters, in a specific order, with specific types. Maps on the other hand can contain any group of variables in no specific order, of any type. Maps aren't as efficient as functions but are significantly more flexible. In my system, messages are used at the higher level and functions are used at the local level.
See also: MessageOrientedProgramming