- Modula 2
-
Modula-2 ist eine 1978 entstandene Weiterentwicklung der Programmiersprache Pascal und wurde wie diese von Niklaus Wirth entwickelt. Hauptkennzeichen von Modula-2 sind die Sprachmerkmale zur Modularisierung von Programmen. Modula-2 diente selbst später als Vorlage für die Programmiersprache Oberon.
Inhaltsverzeichnis
Entstehung
Wirth hatte 1977/78 am Forschungszentrum Palo Alto Research Institute von Xerox die zukunftsweisende Architektur der Alto-Workstations kennengelernt, die bereits über Maus, Grafikbildschirm und Fenstertechnik verfügten. Programmiert wurde der Alto in der Pascal-ähnlichen Programmiersprache Mesa. Nach seiner Rückkehr an die ETH Zürich begann Wirth mit seiner Gruppe die Eigenentwicklung einer solchen Workstation, der später so genannten Lilith, wobei Hardware und Software im Zusammenhang entwickelt wurden.
Standard-Pascal, das als Sprache für den Programmierunterricht entwickelt worden war, eignete sich nicht für die Programmierung eines Betriebssystems für die Lilith, und zwar vor allem aus zwei Gründen:
- es fehlen Vorrichtungen für die nebenläufige Programmierung
- die Aufteilung eines großen Programms in zahlreiche Module mit sauber definierten Schnittstellen nach den Lehren der Softwaretechnik ist nicht möglich.
Die neue Sprache, die den Namen „Modula“ erhielt, enthielt gegenüber Pascal deshalb (neben etlichen Änderungen in der Syntax) zwei neue Konzepte:
- Prozeduren
NEWPROCESS,TRANSFERundIOTRANSFERzur Behandlung nebenläufiger Prozesse (threads) im Sinne eines kooperativen Multitasking und - das
MODULEals Einheit für die separate Übersetzung von Programmteilen.
Modula wurde ausserhalb der ETHZ erst in der Version Modula-2 bekannt. Die klare Trennung von Definition und Implementierung in getrennten Dateien (in der Regel mit Extension DEF bzw. MOD) war richtungsweisend und wurde von späteren Programmiersprachen zwar kopiert, aber in ihrer Klarheit nicht erreicht. Modula-2 hatte später von Wirth unabhängige Nachfolger wie Modula-2 plus und Modula-3. Seit 1996 gibt es eine internationale Norm ISO/IEC 10514-1 für Modula-2.
Eigenschaften
Da Modula-2 eine Fortentwicklung von Pascal ist, genügt es, auf die wesentlichen Unterschiede zu dieser Sprache einzugehen.
Module
Die prominenteste Neuerung in Modula-2 sind die Module als Vorrichtung für das modulare Programmieren nach den Vorstellungen der Softwaretechnik, zuerst geäußert von David Parnas. Auch das Hauptprogramm heißt deswegen
MODULEstattPROGRAMwie in Pascal. Alle separat vom Hauptprogramm übersetzten Teile müssen in zwei Dateien aufgespalten werden: EinDEFINITION MODULEenthält nur die Beschreibung der Schnittstelle des Moduls, das heißt: es listet die Konstanten, Typen, Variablen und Prozeduren auf, die für andere Module zur Verfügung gestellt („exportiert“) werden sollen. Ein getrenntesIMPLEMENTATION MODULEgibt dann die Implementierung an.Es ist im Sinne der strikten Modularisierung folgerichtig, dass Konzepte wie die Ein-/Ausgabe und mathematische Funktionen, die in Pascal zum normalen Sprachumfang gehörten, in der Sprache Modula-2 nicht enthalten sind. Sie müssen im Bedarfsfall aus dafür vorgesehenen Modulen (in der Regel
InOutfür Ein-/Ausgabe undMathLibfür die mathematischen Funktionen) importiert werden.Datentypen
Die Lilith sollte eine Wortbreite von 16 bit bekommen. Ganze Zahlen hätten somit einen Bereich von -32.768 bis +32.767 gehabt, was Wirth als zu große Einschränkung empfand. Zusätzlich zum Datentyp
INTEGERbekam Modula-2 daher einen DatentypCARDINALfür die nicht-negativen Zahlen zwischen 0 und 65.535. Gemischte Ausdrücke, die sowohlINTEGER- als auchCARDINAL-Teilausdrücke enthalten, waren verboten. Deshalb gibt es allgemeine Möglichkeiten, Typen zu verwandeln:- Typkonversionsfunktionen
VAL(Typ,Ausdruck)rechnen einen Ausdruck so um, dass er zu dem neuen Typ gehört, während - Typtransferfunktionen („type casts“, bei Wirth: „type cheats“) der Form Typ
(Ausdruck)ein Bitmuster unverändert lassen und lediglich für den Compiler den Datentyp verändern.
Beispielsweise ergibt
VAL(CARDINAL,-1)eine Fehlermeldung, währendCARDINAL(-1) = 65.535gilt.Eine Innovation gegenüber Pascal stellt auch der Datentyp
PROCEDUREdar, mit dem eine Schwäche von Pascal behoben werden sollte: In Pascal war es möglich, einer Prozedur eine Funktion als Argument zu übergeben, gekennzeichnet durch das SchlüsselwortFUNCTION. Dabei konnte jedoch nicht überprüft werden, ob die später aktuell übergebene Funktion in Anzahl und Typ ihrer Parameter überhaupt passend war. Deklariert man jedoch in Modula-2 beispielshalberTYPE myFunction = PROCEDURE (INTEGER): REAL;
so kann beim Aufruf einer Prozedur (das Schlüsselwort
FUNCTIONgibt es in Modula-2 nicht)PROCEDURE myProcedure (f: myFunction; n: INTEGER): REAL;
der Compiler bei jedem Aufruf von
myProcedurefeststellen, ob die aktuell fürfübergebene Funktion den richtigen Typ hat. Da Prozeduren damit ganz normale Datentypen sind, ist es auch möglich, sie in anderen Datenstrukturen wie etwaARRAYs undRECORDs einzubauen.Kontrollstrukturen
Zur Vermeidung zahlreicher
BEGIN−END-Klammern wird in Modula-2 dieIF- undWHILE-Anweisung jeweils mit einemENDabgeschlossen. Das von Pascal vertrauteGOTOgibt es nicht, dafür aber einLOOP–EXIT-Konstrukt.Das Pseudomodul SYSTEM
Als Sprache für die Betriebssystemprogrammierung musste Modula-2 über Vorrichtungen verfügen, auf Details der zugrundeliegenden Maschine zuzugreifen. Dafür gab es ein eigenes Modul
SYSTEM, aus dem sich die DatentypenWORDfür ein unspezifisches Speicherwort undADDRESSfür eine Speicheradresse importieren ließen, ebenso wie eine FunktionADRzur Ermittlung der Speicheradresse eines Konstrukts undTSIZEzur Ermittlung der Speichergröße für einen bestimmten Datentyp. Hinzu kommen die bereits erwähnten Funktionen für die nebenläufige Programmierung.SYSTEMheißt Pseudomodul, weil es dazu weder Definitions- noch Implementierungsteil gibt, sondern alle Kenntnis über dieses Modul direkt in den Compiler eingebaut ist.Implementierungen
Modula-2 erreichte in den späten 1980er Jahren eine verhältnismäßig große Popularität, insbesondere in der Version von Jensen und Partners International (JPI), die einen 10-Fenster-Editor in ihrer Entwicklungsumgebung für MS-DOS und einen sehr schnellen Compiler mit gut optimiertem Objektcode auf den Markt brachten. Spätere Versionen davon hießen TopSpeed Modula-2; in die Entwicklungsumgebung wurden auch C und C++ aufgenommen.
Kritik
Wirth selbst[1] listet im Zusammenhang mit der Entwicklung von Oberon folgende Probleme von Modula-2 auf:
Qualifizierende Importe
Die empfohlene Methode zur Verwendung von Bestandteilen fremder Module ist
IMPORT M;
Dadurch werden alle von
Mexportierten Bezeichner durch sogenannte qualifizierte Bezeichner, etwaM.A,M.Bverfügbar. Alternativ dazu kennt Modula-2 den qualifizierenden ImportFROM M IMPORT A,B;
Bei diesem Import sind die Bezeichner dann einfach in der Form
Abzw.Bverfügbar; die Herkunft aus dem ModulMist an der Verwendungsstelle dann nicht mehr direkt sichtbar. Dadurch können Programmierer Irrtümer begehen. In Oberon gibt es den qualifizierenden Import deshalb nicht mehr.Export von Aufzählungstypen
Enthält ein Modul den exportierten Typ
TYPE Ampel = (rot, gelb, gruen);
so bezieht sich nach der Logik der Sprache ein Import dieses Typs nur auf den Typnamen (
Ampel), in Wirklichkeit werden aber heimlich die Namenrot,gelbundgruenmitimportiert, was im Falle von Bezeichnerkonflikten an der Verwendungsstelle den Programmierer verwirren kann. In Oberon gibt es Aufzählungstypen deshalb gar nicht mehr, weil man sonst auch ihren Export nicht verhindern könnte.Datentyp CARDINAL
Vorzeichenlose Arithmetik funktioniert ganz anders als vorzeichenbehaftete Arithmetik; deshalb sind Ausdrücke, in denen vorzeichenlose und vorzeichenbehaftete Werte gleichzeitig vorkommen, problematisch. Modula-2 hat deshalb solche Mischungen grundsätzlich verboten, was bei den Programmierern auf Protest stieß, weil die Programme durch die Verwendung von Typkonversionsfunktionen unnötig verkompliziert wurden. Darüber hinaus entstehen häßliche Unsymmetrien in der Behandlung bestimmter Programmstrukturen und bei der mathematischen Modulo-Funktion (
MOD).Typtransferfunktionen und andere low level-Vorrichtungen
Mit den Typtransferfunktionen (type casts) wird es möglich, Eigenschaften der zugrundeliegenden Maschine zu entdecken, die dem Programmierer einer höheren Programmiersprache eigentlich verborgen bleiben sollten, wie etwa die Endianness, das heißt die Frage, in welcher Ordnung die einzelnen Bits eines Maschinenworts abgespeichert sind. Je nachdem ist nämlich
BITSET(65520) = {4 .. 15}oder
BITSET(65520) = {0 .. 11}für eine 16-bit-Architektur.
Literatur
- Niklaus Wirth: Programming in Modula-2. Gebundene Ausgabe, Springer Verlag, 4. Auflage, 1989, ISBN 0-387-50150-9.
- ↑ A Brief History of Modula and Lilith. In: Advances in Modular Languages – Proceedings of the Joint Modular Languages Conference, Ulm 1994
Wikimedia Foundation.