Adapted from: Wirth N: Programming in Modula-2, 3rd ed. Springer Verlag, Berlin, 1985.
Modula-2 grew out of a practical need for a general, efficiently implementable systems programming language for minicomputers. Its ancestors are Pascal and Modula. From the latter it has inherited the name, the important module concept, and a systematic, modem syntax, from Pascal most of the rest. This includes in particular the data structures, i.e. arrays, records, variant records, sets, and pointers. Structured statements include the familiar if, case, repeat, while, for, and with statements. Their syntax is such that every structure ends with an explicit termination symbol.
The language is essentially machine-independent, with the exception of limitations due to wordsize. This appears to be in contradiction to the notion of a system-programming language, in which it must be possible to express all operations inherent in the underlying computer. The dilemma is resolved with the aid of the module concept. Machine-dependent items can be introduced in specific modules, and their use can thereby effectively be confined and isolated. In particular, the language provides the possibility to relax rules about data type compatibility in these cases. In a capable system-programming language it is possible to express inpuut/output conversion procedures, file handling routines, storage allocators, process schedulers etc. Such facilities must therefore not be included as elements of the language itself, but appear as (so-called low-level) modules which are components of most programs written. Such a collection of standard modules is therefore an essential part of a Modula-2 implementation.
The concept of processes and their synchronization with signals as included in Modula is replaced by the lower-level notion of coroutines in Modula-2. It is, however, possible to formulate a (standard) module that implements such processes and signals. The advantage of not including them in the language itself is that the programmer may select a process scheduling algorithm tailored to his particular needs by programming that module on his own. Such a scheduler can even be entirely omitted in simple (but frequent) cases, e.g. when concurrent processes occur as device drivers only.
A modern system programming language should in particular also facilitate the construction of large programs, possibly designed by several people. The modules written by individuals should have well-specified interfaces that can be declared independently of their actual implementations. Modula-2 supports this idea by providing separatet definition and implementation modules. The former define all objects exported from the corresponding implementation module; in some cases, such as procedures and types, the definition module specifies only those parts that are relevant to the interface, i.e. to the user or client of the module.