Erlang and the Decision to Make Fault-Tolerant Concurrency a Language Property
Erlang combined lightweight isolated processes, asynchronous messages and supervisory recovery into a programming model designed for long-lived telecom systems.
Erlang began as a telecom programming experiment rather than a language manifesto
During the 1980s, Ericsson’s Computer Science Laboratory was investigating how to program telecommunications systems that had to handle many simultaneous activities, remain available for long periods, and recover from faults. Erlang emerged from experiments led initially by Joe Armstrong, Robert Virding, and Mike Williams.[1][3]
Armstrong’s historical account is careful about the timeline: work began in 1986, the language evolved through prototypes, and many of the ideas stabilized over the following years rather than appearing fully formed on one launch date.
Lightweight processes made concurrency the normal unit of structure
Erlang programs are built from lightweight processes rather than a small number of heavyweight operating-system threads. The runtime is designed to support large numbers of such processes, which have small memory footprints and are inexpensive to create relative to OS processes.[2]
This made it practical to model telecom activities as many independent conversations. Instead of centralizing all state and events in one large control loop, programmers could represent separate logical activities as separate processes.
Processes are isolated by default
Erlang processes do not share ordinary mutable memory in the way threads in a shared address space do. That isolation reduces one source of data races and pushes coordination toward explicit messages.[1]
Asynchronous messages replaced shared-state coordination
Erlang processes send messages and use pattern matching in receive expressions to select messages they are prepared to handle. The model makes asynchronous signaling a basic mechanism of the language and runtime.[2]
The historical significance is not that Erlang invented message passing. It combined lightweight isolated processes, asynchronous messages, pattern matching, and a runtime designed for long-lived concurrent systems into one coherent programming environment.
The first implementation in Prolog made language evolution cheap
The official BEAM compiler history records that the first Erlang version was implemented in Prolog in 1986. That choice let the researchers add or remove language features quickly while they learned what worked for telecom programming.[4]
Performance eventually became a constraint. The JAM abstract machine followed in 1989, with a C runtime, compiler, and libraries built by members of the original team. The implementation history shows a language moving from experiment toward deployable engineering.
Experimentation preceded optimization
The sequence matters historically. Erlang’s concurrency model was not derived from the fastest runtime mechanism available; the team first explored programming properties, then built faster machinery once the model proved useful.
Links and failure signals made faults part of normal process interaction
Erlang processes can be linked so termination generates signals to related processes. Armstrong’s work on reliable systems emphasized designing for software errors rather than pretending long-running systems would never fail.[1][2]
This changed the programming stance. A process crash could be treated as information to be handled by another process, supporting architectures where damaged components are restarted instead of forcing an entire system to stop.
OTP turned recurring fault-tolerance patterns into reusable structure
Erlang/OTP formalized patterns for structuring applications. Its supervision-tree model distinguishes workers that perform application work from supervisors that monitor workers and can restart them when something goes wrong.[5]
Supervision trees made fault recovery an architectural relationship rather than an improvised exception path. They also encouraged systems to define restart boundaries deliberately.
Let it crash is a design discipline, not indifference to errors
The phrase often associated with Erlang is easy to misunderstand. The useful idea is not to ignore failures; it is to isolate components, detect termination, preserve enough state externally, and let a supervisory strategy restore service when that is safer than continuing with corrupted local state.
Telecom requirements shaped the language’s idea of reliability
Armstrong’s historical and doctoral accounts repeatedly connect Erlang to systems expected to run for very long periods while evolving and recovering from faults.[1][2] This is why hot code loading, distribution, process isolation, and supervision belong to one historical story rather than to a random feature list.
The language’s reputation for concurrency came from an operational problem: many simultaneous users and services had to coexist without one fault bringing down everything.
Distribution extended the same process model across nodes
Erlang’s process and message concepts were extended to distributed nodes, making remote interaction resemble local process messaging at the language level. Network failure still matters, but the programming vocabulary remains process-oriented.
Why Erlang changed expectations for concurrent software
Erlang demonstrated that concurrency could be the ordinary structure of an application rather than an advanced library technique added around a sequential core. Its lightweight processes, asynchronous messages, linked failures, and OTP supervision patterns formed a system for building software expected to keep running.[1][3][5]
Its legacy reaches far beyond telecom. The deeper historical contribution is the integration of concurrency and fault handling: failures are events among processes, and recovery can be designed as part of the process topology.
Works Cited
- 01
- 02
- 03
- 04
- 05
CodeHistory is a living archive. Citations document the evidence used for this edition; later evidence may refine the account.
Submit a research lead