Concurrent Components With Message Passing
In our experience, the right default for structuring programs is
as concurrent components that communicate through asynchronous message passing.
Components should be sequential or communicate synchronously only if necessary.
This is not a new idea; Carl Hewitt anticipated it thirty years ago in the Actor model.
But today we have many strong reasons for accepting it.
For example:
- As explained in our
programming textbook,
the simplest paradigms for concurrent programming are
declarative concurrency and message-passing concurrency.
The simplest paradigm that has no limitations in expressive
power is message-passing concurrency.
Practice shows that it is much simpler to program in and
reason with than shared-state concurrency.
- The Erlang language
is designed and used successfully for
building highly available systems (systems that rarely go down)
in the presence of both software and hardware failures.
For fundamental reasons that are explained by Erlang's designers,
Erlang's computation model is essentially based on asynchronous message passing
between independent entities.
- The E language
is designed and used successfully for building highly secure
distributed systems in the presence of malicious attackers.
For fundamental reasons that are explained by E's designers,
E's computation model is essentially based on asynchronous message passing
between independent entities.
Unfortunately,
these reasons and their conclusion are almost completely ignored
by mainstream languages and by books on program design.
In both, object-oriented programming and shared-state concurrency are
given priority, even though they are the wrong default.
In the Erlang and E designs,
the use of message-passing concurrency
gives a fundamental simplification that is not possible using
shared-state concurrency.
This fundamental simplification is studied
by theoretical computer science in the area
of concurrent process calculi.
Two of the important insights are first
that components should be independent by default,
and second that components that are
independent must also be concurrent.
Components that live in a sequential context are
not independent, because there is a single global order of
instruction execution.
For more information, see the following talk and article:
Back to the book