Est. 1988 Intermediate

Modula-3

The safe systems programming language from DEC SRC and Olivetti that combined modules, objects, threads, exceptions, generics and garbage collection in a definition barely over 50 pages.

Created by Luca Cardelli, James Donahue, Lucille Glassman, Mick Jordan, Bill Kalsow, Greg Nelson

Paradigm Imperative, Procedural, Modular, Object-Oriented
Typing Static, Strong, Safe (unsafe code isolated in UNSAFE modules)
First Appeared 1988
Latest Version CM3 d5.12.0 (March 2026)

Modula-3 is a systems programming language designed in the late 1980s by a committee from Digital Equipment Corporation’s Systems Research Center (SRC) and the Olivetti Research Center. Its aim was to be safe and efficient enough for device drivers and compilers as well as applications. It combined interfaces, objects, generics, lightweight threads, exceptions, garbage collection and an explicit way to mark unsafe code, and it did this at a time when few languages offered all of these together, especially one that also allowed data outside the heap. The language never caught on in industry, but it had a large influence on later work. Python borrowed its explicit self and parts of its class model from Modula-3, Nim lists Modula-3 as its biggest influence, and Java RMI’s distributed garbage collector follows the Modula-3 Network Objects system.

History & Origins

From Mesa and Cedar to Modula-2+

Modula-3 has a long ancestry. In the early 1980s, researchers at Xerox PARC built the Mesa and Cedar languages and environments. When several of them moved to DEC’s Systems Research Center in Palo Alto, they extended Niklaus Wirth’s Modula-2 with ideas from Cedar: threads, garbage collection and exceptions. The result, Modula-2+, was developed at SRC from about 1984 to 1986. SRC used it to write the software for its Firefly multiprocessor workstation, and it was also used at the Acorn Research Center (later the Olivetti Research Center).

A New Modula

According to the Computer History Museum’s Modula-3 archive, Modula-3 began when Maurice Wilkes suggested to Wirth that Modula-2+ be revised and standardized as “Modula-3”. In December 1986, a joint SRC/Olivetti delegation visited Wirth at ETH Zurich. The design committee had five members:

DesignerAffiliation
Luca CardelliDEC SRC
Bill KalsowDEC SRC
Greg NelsonDEC SRC
James DonahueOlivetti Research California
Mick JordanOlivetti Research California

Lucille Glassman and Greg Nelson wrote the defining report, so all six names appear on it. James Donahue’s November 1989 lecture gives this schedule: early discussions on goals and scope from January to March 1987, serious design from April 1987, and a first complete draft in November 1987.

The Reports

The Modula-3 Report appeared on 25 August 1988 as DEC SRC Research Report 31, and also as Olivetti report ORC-1. Both labs started implementations right away. Writing Modula-3 compilers in Modula-3 showed where the design needed work. The January 1989 revisions introduced branded reference types, required opaque types to be branded, and made it more flexible to reveal information about opaque types. These changes went into the revised report (SRC Research Report 52), dated 1 November 1989. A paper on the type system appeared at POPL in January 1989.

The final revisions came on 19 December 1990, when Greg Nelson posted the “Twelve Changes” to the comp.lang.modula3 newsgroup. The biggest change was the addition of generics. The others included better IEEE 754 floating-point conformance, an empty RAISES set by default, and a clearer distinction between method declarations and overrides. The finished language was published in Systems Programming with Modula-3 (Prentice Hall, 1991), edited by Nelson. The designers had set themselves a 50-page budget for the language definition, and according to the CHM archive they went over it by only six lines plus the syntax summary.

Design Philosophy

Modula-3 tried to include the features that experience at PARC and SRC had shown to be essential for building large systems, each in its simplest form. Features thought dangerous or overly complicated, such as multiple inheritance and operator overloading, were left out.

  • Safety by default. A program written only with safe features always behaves according to the language semantics. Unchecked operations such as LOOPHOLE, address arithmetic and DISPOSE are only allowed in modules or interfaces marked UNSAFE. The usual pattern is to put a safe interface over an unsafe implementation.
  • Interfaces as the unit of design. Every compilation unit is either an INTERFACE or a MODULE. Clients see only the interface, and imported names must be qualified (Wr.PutText). There is no way to import every name from a module at once.
  • Opaque types and partial revelation. An interface can declare T <: Public, which says that T is some subtype of Public and nothing more. A REVEAL statement elsewhere can disclose more. Different clients can therefore see different amounts of a type’s implementation.
  • Structural type equivalence, with brands as the escape hatch. Two types are the same if they have the same structure. The BRANDED keyword makes a reference type distinct even if its structure matches another.
  • Practicality. Threads, mutexes, exceptions and a garbage-collected heap are part of the language because SRC’s systems programmers depended on them in Modula-2+.

Key Features

Interfaces and Modules

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
INTERFACE Counter;
TYPE
  T <: Public;
  Public = OBJECT
  METHODS
    init(): T;
    inc();
    value(): INTEGER;
  END;
END Counter.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
MODULE Counter;

REVEAL
  T = Public BRANDED OBJECT
    n: INTEGER := 0;
  OVERRIDES
    init  := Init;
    inc   := Inc;
    value := Value;
  END;

PROCEDURE Init(self: T): T =
  BEGIN self.n := 0; RETURN self END Init;

PROCEDURE Inc(self: T) =
  BEGIN INC(self.n) END Inc;

PROCEDURE Value(self: T): INTEGER =
  BEGIN RETURN self.n END Value;

BEGIN
END Counter.

Clients of Counter can call NEW(Counter.T).init() and use its methods, but they cannot see the field n. The concrete representation exists only in the REVEAL inside the implementation module.

Hello World

1
2
3
4
5
MODULE Main;
IMPORT IO;
BEGIN
  IO.Put("Hello, World!\n")
END Main.

Objects

Objects are reference types that support single inheritance, methods, and overrides. The syntax is close to that of records. When an object is allocated with NEW, methods can be overridden for that one instance, which gives a simple form of prototype-style specialization without defining a new named subclass.

Exceptions

Procedures list the exceptions they can raise in a RAISES clause. Handlers use TRY ... EXCEPT, with one branch per exception, a little like a CASE statement:

1
2
3
4
5
6
7
8
9
EXCEPTION Empty;

PROCEDURE Pop(s: Stack): INTEGER RAISES {Empty} = ...

TRY
  x := Pop(s)
EXCEPT
| Empty => IO.Put("stack is empty\n")
END;

TRY ... FINALLY runs cleanup code however a block exits.

Threads

Threads are part of the language and its required interfaces. MUTEX is a predeclared type, and the LOCK statement acquires and releases a mutex around a block. Andrew Birrell’s An Introduction to Programming with Threads was originally an SRC report and later a chapter of the Nelson book.

Generics

Generics came with the 1990 changes and work at the module level. A GENERIC INTERFACE and GENERIC MODULE take other interfaces as parameters, and an instantiation such as INTERFACE IntStack = Stack(IntElem) END IntStack. produces concrete code. Because the parameters are interfaces, built-in types like INTEGER have to be wrapped in a small interface before they can be used.

Garbage Collection and Untraced References

REF types are traced by the garbage collector. UNTRACED REF types point into a separate heap that the collector does not manage; freeing such memory with DISPOSE is only allowed in UNSAFE modules.

Implementations and Evolution

ImplementationOriginNotes
Olivetti Modula-3Olivetti Research CaliforniaAST-based toolkit (M3AST), generated C; first released October 1989; ended when ORC closed in February 1991
SRC Modula-3DEC SRC (Bill Kalsow, Eric Muller)First released December 1989; generated C until version 3.0, then moved to an intermediate language with a GCC-based backend; last release 3.6 (September 1996)
GNU / Persistent Modula-3UMass Amherst, later PurdueGCC-based front end used for research on persistence and precise garbage collection
CM3Critical Mass, Inc.Commercial successor to SRC M3 with the Reactor web-based IDE; added Unicode WIDECHAR and runtime-loadable modules
PM3Polytechnique Montréal (Michel Dagenais)SRC 3.6 plus community patches, a Linux ELF code generator and a simpler build
EZM3John PolstraMinimal subset of PM3, made to build CVSup
CM3 (open source)Elego Software Solutions, now GitHubOpen-sourced around 2000–2001; 5.8.6 in July 2010; still developed at github.com/modula3/cm3

According to Kalsow, the first SRC compiler was written in Modula-2+ and emitted C. He then used the Vulcan programming environment’s AST builder to translate it into Modula-3; by his account at least 90% of the translation was automatic, and the result made the compiler self-hosting. Later versions used a pluggable code-generator interface, and the most widely used backend was a small GPL’d C program that called GCC’s code-generation libraries. Kalsow left SRC in July 1995, and SRC’s compiler work moved into maintenance mode. Early in 1996 he joined Critical Mass, a Cambridge, Massachusetts company founded by Farshad Nayeri and Lauren Schmitt, and continued the work there using the SRC release as its base.

According to the CHM archive, Critical Mass had stopped active Modula-3 development by 1998 and later released its code as open source (the archive gives both 2000 and 2001 for this). Elego Software Solutions in Berlin then ran the infrastructure for CM3, and from March 2002 for PM3 as well. When Elego wound down its Modula-3 work after more than a decade, development moved to GitHub. During the Elego years, Antony Hosking converted CM3’s thread library to native threads on POSIX platforms (the Win32 version had always used native threads) and added a mostly-concurrent, mostly-copying garbage collector, which he presented at ISMM 2006.

Current Relevance

The encyclopedia lists Modula-3 as historical, and in industry it is. Its textbooks are out of print, and the original SRC, Olivetti and Critical Mass groups are gone. The implementation is still alive, though. The CM3 repository on GitHub had commits in October 2026, and release d5.12.0 (27 March 2026) made EXTENDED a true 128-bit floating-point type, so far only on AMD64_LINUX (other targets still treat it as LONGREAL). The release ships boot archives for Linux, macOS (Intel and ARM) and Windows. The Computer History Museum’s Software Preservation Group keeps a detailed Modula-3 archive, edited by Paul McJones and last updated in July 2026. It includes the original reports, the SRC releases from 1.5 to 3.6, and source code for many of the applications.

No official or maintained Docker image exists. The practical way to run Modula-3 today is to install a CM3 release from GitHub.

Why It Matters

Modula-3 showed that one compact language could provide strong static safety, garbage collection, objects, threads and exceptions together, and still be fit for writing kernels and compilers. Its influence can be traced directly:

  • Python. The Python tutorial calls its class mechanism “a mixture of the class mechanisms found in C++ and Modula-3”, and the Python design FAQ says the explicit self parameter “was borrowed from Modula-3”.
  • Java. Oracle’s RMI specification says RMI’s distributed garbage collection uses “a reference-counting garbage collection algorithm similar to Modula-3’s Network Objects”, and Harbison’s Modula-3 is reportedly listed in the bibliography of the first edition of the Java Language Specification.
  • Nim. The Nim FAQ lists Modula-3 first among the languages it “borrows heavily from”.
  • Research. Network Objects, Obliq (whose POPL ‘95 paper won the 2005 Most Influential POPL Paper award), the Extended Static Checker, and the SPIN kernel’s language-based protection were all built in Modula-3 and shaped later work on distributed objects, program verification and safe operating systems.

The combination it introduced, with safe code by default, unsafe code marked explicitly, and interfaces as the unit of abstraction, has since become common in mainstream languages. C#’s unsafe blocks and Rust’s unsafe keyword use the same split, although neither project cites Modula-3 as the source.

Timeline

1986
Following Maurice Wilkes's suggestion that Modula-2+ be revised and standardized as Modula-3, a joint DEC SRC / Olivetti delegation visits Niklaus Wirth at ETH Zurich in December
1987
Serious design work begins in April; the committee produces a first complete draft in November
1988
The Modula-3 Report is published on 25 August as DEC SRC Research Report 31 (also Olivetti report ORC-1), and implementation begins at both labs
1989
Revised Modula-3 Report (SRC Research Report 52) published in November; Olivetti Modula-3 is first released publicly in October and SRC Modula-3 in December
1990
The "Twelve Changes" (posted to comp.lang.modula3 on 19 December) add generics and finalize the language
1991
Greg Nelson's Systems Programming with Modula-3 (Prentice Hall) publishes the final language definition; Olivetti Research California closes in February
1992
Samuel P. Harbison's textbook Modula-3 appears in February; the language definition is reprinted in ACM SIGPLAN Notices in August
1993
Network Objects, the distributed-object system written in Modula-3, is presented at SOSP '93
1995
The SPIN extensible operating system, written in Modula-3, is presented at SOSP '95
1996
DEC SRC ships Modula-3 3.6 in September, its last release; Critical Mass releases the Reactor environment late in the year
2010
Elego Software Solutions releases CM3 5.8.6 in July
2026
CM3 d5.12.0 is released on GitHub in March, making EXTENDED a 128-bit floating-point type on AMD64_LINUX

Notable Uses & Legacy

SPIN Operating System

The University of Washington's extensible research kernel. It was written in a modified SRC Modula-3, and it relied on the language's type safety to let applications link extensions safely into the running kernel.

CVSup

John Polstra wrote this CVS repository mirroring tool for the FreeBSD Project in Modula-3, and maintained the cut-down EZM3 compiler distribution so that CVSup could be built easily.

DEC SRC Network Objects

A distributed-object system by Birrell, Nelson, Owicki and Wobber. Oracle's Java RMI documentation says RMI's distributed garbage collector uses an algorithm similar to the one in Network Objects.

Trestle, Zeus and Obliq

DEC SRC built its research software in Modula-3, including the Trestle window system, the Zeus algorithm-animation system, the Juno-2 constraint drawing editor, the Postcard mail reader and Luca Cardelli's distributed scripting language Obliq.

Extended Static Checker (ESC/Modula-3)

A DEC SRC checker that used an automatic theorem prover to find array-bounds, nil-dereference and locking errors in Modula-3 programs at compile time.

Positron Industries Power911

A next-generation 911 emergency call system built in Modula-3. Michel Dagenais directed software development on it from 1995 to 1996.

Language Influence

Influenced By

Modula-2 Modula-2+ Mesa Cedar Object Pascal Oberon Euclid

Influenced

Running Today

Run examples using the official Docker image:

docker pull
Last updated: