Lably
Skip to content

Modula-2

1970s-80s computer programming language

  • 12 min read
  • 9 chapters

Related on Lably

Through Operating system, Application software and Compiler

Wirth viewed Modula-2 as a successor to his earlier programming languages Pascal and Modula. The main concepts are:

  1. The module as a compiling unit for separate compiling
  2. The coroutine as the basic building block for concurrent processes
  3. Types and procedures that allow access to machine-specific data

The language design was influenced by the Mesa language and the Xerox Alto, both from Xerox PARC, that Wirth saw during his 1976 sabbatical year there. The computer magazine Byte devoted the August 1984 issue to the language and its surrounding environment.

Wirth created the Oberon series of languages as the successor to Modula-2, while others (particularly at Digital Equipment Corporation and Acorn Computers, later Olivetti) developed Modula-2 into Modula-2+ and later Modula-3.

Description

Modula-2 is a general purpose procedural language suitable for both systems programming and applications programming. The syntax is based on Wirth's earlier language, Pascal, with some elements and syntactic ambiguities removed. The module concept, designed to support separate compilation and data abstraction; and direct language support for multiprogramming were added.

The language allows the use of one-pass compilers. Such a compiler by Gutknecht and Wirth was about four times faster than earlier multi-pass compilers.

Here is an example of the source code for the "Hello world" program:

<span id="mwUA"></span><span class="kr" id="mwUQ">MODULE</span> <span class="n" id="mwUg">Hello</span><span class="p" id="mwUw">;</span> <span class="cm" id="mwVA">(* For GNU Modula-2 this would be</span> <span class="cm" id="mwVQ">FROM StrIO IMPORT WriteString *)</span> <span class="kr" id="mwVg">FROM</span> <span class="n" id="mwVw">STextIO</span> <span class="kr" id="mwWA">IMPORT</span> <span class="n" id="mwWQ">WriteString</span><span class="p" id="mwWg">;</span> <span class="kr" id="mwWw">BEGIN</span> <span class="n" id="mwXA">WriteString</span><span class="p" id="mwXQ">(</span><span class="s2" id="mwXg">"Hello World!"</span><span class="p" id="mwXw">)</span> <span class="kr" id="mwYA">END</span> <span class="n" id="mwYQ">Hello</span><span class="p" id="mwYg">.</span>

A Modula-2 module may be used to encapsulate a set of related subprograms and data structures, and restrict their visibility from other parts of the program. Modula-2 programs are composed of modules, each of which is made up of two parts: a definition module, the interface portion, which contains only those parts of the subsystem that are exported (visible to other modules), and an implementation module, which contains the working code that is internal to the module.

The language has strict scope control. Except for standard identifiers, no object from the outside is visible inside a module unless explicitly imported; no internal module object is visible from the outside unless explicitly exported.

Suppose module M1 exports objects a, b, c, and P by enumerating its identifiers in an explicit export list

<span id="mwcg"></span> <span class="kr" id="mwcw">DEFINITION</span> <span class="kr" id="mwdA">MODULE</span> <span class="n" id="mwdQ">M1</span><span class="p" id="mwdg">;</span> <span class="kr" id="mwdw">EXPORT</span> <span class="kr" id="mweA">QUALIFIED</span> <span class="n" id="mweQ">a</span><span class="p" id="mweg">,</span> <span class="n" id="mwew">b</span><span class="p" id="mwfA">,</span> <span class="n" id="mwfQ">c</span><span class="p" id="mwfg">,</span> <span class="n" id="mwfw">P</span><span class="p" id="mwgA">;</span> <span class="p" id="mwgQ">...</span>

Then the objects a, b, c, and P from module M1 are known outside module M1 as M1.a, M1.b, M1.c, and M1.P. They are exported in a qualified manner to the outside (assuming module M1 is global). The exporting module's name, i.e. M1, is used as a qualifier followed by the object's name.

Suppose module M2 contains the following IMPORT declaration

<span id="mwhw"></span> <span class="kr" id="mwiA">MODULE</span> <span class="n" id="mwiQ">M2</span><span class="p" id="mwig">;</span> <span class="kr" id="mwiw">IMPORT</span> <span class="n" id="mwjA">M1</span><span class="p" id="mwjQ">;</span> <span class="p" id="mwjg">...</span>

Then this means that the objects exported by module M1 to the outside of its enclosing program can now be used inside module M2. They are referenced in a qualified manner: M1.a, M1.b, M1.c, and M1.P. Example:

<span id="mwkw"></span> <span class="p" id="mwlA">...</span> <span class="n" id="mwlQ">M1</span><span class="p" id="mwlg">.</span><span class="n" id="mwlw">a</span> <span class="o" id="mwmA">:=</span> <span class="mi" id="mwmQ">0</span><span class="p" id="mwmg">;</span> <span class="n" id="mwmw">M1</span><span class="p" id="mwnA">.</span><span class="n" id="mwnQ">c</span> <span class="o" id="mwng">:=</span> <span class="n" id="mwnw">M1</span><span class="p" id="mwoA">.</span><span class="n" id="mwoQ">P</span><span class="p" id="mwog">(</span><span class="n" id="mwow">M1</span><span class="p" id="mwpA">.</span><span class="n" id="mwpQ">a</span> <span class="o" id="mwpg">+</span> <span class="n" id="mwpw">M1</span><span class="p" id="mwqA">.</span><span class="n" id="mwqQ">b</span><span class="p" id="mwqg">);</span> <span class="p" id="mwqw">...</span>

Qualified export avoids name clashes. For example, if another module M3 exports an object called P, then the two objects can be distinguished since M1.P differs from M3.P. It does not matter that both objects are called P inside their exporting modules M1 and M3.

An alternative method exists. Suppose module M4 is formulated as this:

<span id="mwsA"></span> <span class="kr" id="mwsQ">MODULE</span> <span class="n" id="mwsg">M4</span><span class="p" id="mwsw">;</span> <span class="kr" id="mwtA">FROM</span> <span class="n" id="mwtQ">M1</span> <span class="kr" id="mwtg">IMPORT</span> <span class="n" id="mwtw">a</span><span class="p" id="mwuA">,</span> <span class="n" id="mwuQ">b</span><span class="p" id="mwug">,</span> <span class="n" id="mwuw">c</span><span class="p" id="mwvA">,</span> <span class="n" id="mwvQ">P</span><span class="p" id="mwvg">;</span>

This means that objects exported by module M1 to the outside can again be used inside module M4, but now by mere references to the exported identifiers in an unqualified manner as: a, b, c, and P. Example:

<span id="mwww"></span> <span class="p" id="mwxA">...</span> <span class="n" id="mwxQ">a</span> <span class="o" id="mwxg">:=</span> <span class="mi" id="mwxw">0</span><span class="p" id="mwyA">;</span> <span class="n" id="mwyQ">c</span> <span class="o" id="mwyg">:=</span> <span class="n" id="mwyw">P</span><span class="p" id="mwzA">(</span><span class="n" id="mwzQ">a</span> <span class="o" id="mwzg">+</span> <span class="n" id="mwzw">b</span><span class="p" id="mw0A">);</span> <span class="p" id="mw0Q">...</span>

This method of import is usable if there are no name clashes. It allows variables and other objects to be used outside their exporting module in the same unqualified manner as inside the exporting module.

The export and import rules not only safeguard objects against unwanted access, but also allow a cross-reference of the definition of every identifier in a program to be created. This property helps with the maintenance of large programs containing many modules.

The language provides for single-processor concurrency (monitors, coroutines and explicit transfer of control) and for hardware access (absolute addresses, bit manipulation, and interrupts). It uses a nominal type system.

Sign in to keep reading

8 more chapters are free with a Lably account.

More in Computing and communication