Melden Sie sich hier an, um auf Kommentare und die Whitepaper-Datenbank zugreifen zu können.

Kein Log-In? Dann jetzt kostenlos registrieren.

Falls Sie Ihr Passwort vergessen haben, können Sie es hier per E-Mail anfordern.

Der Zugang zur Reseller Only!-Community ist registrierten Fachhändlern, Systemhäusern und Dienstleistern vorbehalten.

Registrieren Sie sich hier, um Zugang zu diesem Bereich zu beantragen. Die Freigabe Ihres Zugangs erfolgt nach Prüfung Ihrer Anmeldung durch die Redaktion.

25.03.1988 - 

Modula II trotz einiger Schwächen wesentlich eleganter:

Alte Cobol-Zöpfe besser radikal abschneiden

Ein bestehendes Programm in einer neuen Sprache zu codieren, ist oft billiger, als ein altes, unübersichtliches System weiterzupflegen. Manfred Gahr* beschreibt eine Programmumstellung von Cobol auf Modula II, die im Kundenauftrag durchgeführt wurde. Die Erfahrungen des Projekt-Teams mit Modula Il waren allerdings zwiespältig.

Zweieinhalb Jahre Verspätung bei der Softwarelieferung hatten das Unternehmen, mit dem das Projekt begonnen worden war, aus dem Rennen geworfen. Zu diesem Zeitpunkt waren die Weichen schon gestellt: Die Hardware (VAX/VMS) stand seit Monaten nutzlos herum, das Pflichtenheft und die Spezifikationen waren abgezeichnet, als Programmiersprache sollte Cobol verwendet werden, und eine Datenbank hatte der ursprüngliche Anbieter bereits installiert.

Kommandosatz wenig griffig und kaum leistungsfähig

Die Forderung des Kunden: ein universell einsetzbares, datenbankgestütztes Administrationspaket für verteilte Datenbanken mit aktiven Dictionaries und einer mehrsprachigen Benutzeroberfläche. Ein rudimentäres Programm stand bereit - codiert in Cobol. Da bereits eine beträchtliche Summe in diese Software investiert worden war, bestand der Anwender zunächst darauf, das System in derselben Programmiersprache weiterzuentwickeln.

Dabei geriet die Software aus den Fugen wie ein Hefeteig. Hier zeigt der wenig griffige und nicht sehr leistungsfähige Kommandosatz von Cobol seine Nachteile: Der Programmierer schreibt und schreibt, aber es geschieht nicht viel.

Nach Stand des Jahres 1986 fehlt Cobol eigentlich alles, was von einer zeitgemäßen Programmiersprache zu erwarten wäre: Datenkapselung, Loops, vernünftige Blockungen, dynamische Dateizuordnungen, Prozeduren mit Parametern, Rekursion etc. Ein Problem stellt auch der Versuch dar, Datenstruktur und Ausgabeformat zu vermischen. Der Muff der Batch-orientierten Lochkarten ist bei Cobol ständig zu spüren.

Mit zunehmender Komplexität des Systems, traten immer mehr Wechselwirkungseffekte auf, so daß schließlich ein Punkt erreicht war, wo das Debugging neu installierter Features mehr Zeit in Anspruch nahm als die Entwicklung selber. Um den mangelhaften Sprachschatz von Cobol auszugleichen, mußten zahlreiche Hilfskonstruktionen eingebaut werden, die häufiges MOVE erforderten. Das aufgeblähte System und der aufgrund statischer Array-Deklarierungen immense Speicherbedarf führten schließlich zu massiven Laufzeitproblemen.

In dieser verfahrenen Situation gelang es, den entnervten Kunden davon zu überzeugen, daß man einen Sportwagen nicht mit Speichenrädern aus Holz bauen, also ein modernes DV-System auch nicht in einer antiquierten Sprache realisieren kann. Daher gab es schließlich grünes Licht für den Erwerb eines Compilers und die Recodierung des Systems in einer neuen Sprache.

Auf diese Weise konnten zahlreiche Ideen und Wünsche des Kunden, die während der Entwicklung des Pilotsystems entstanden waren, integriert werden, was diese enorm kostenintensive und riskante Entscheidung erleichterte. Allerdings machte der Anwender den Anbieter für Konsequenzen einer Fehlentscheidung voll haftbar.

Die Auswahl einer geeigneten Sprache gestaltete sich schwierig. Folgende Kriterien mußten - in dieser Rangfolge der Wichtigkeit - berücksichtigt werden: Portabilität, gute Integration in VMS, leistungsfähiger Kommandosatz, Modularisierbarkeit, prozeduraler Aufbau mit ausreichenden Flow-Control-Möglichkeiten, Strong-Data-Typing, dynamische Arrays sowie gutes String-Handling.

Fortran schied aus, da Flow-Control unzureichend und Datenstrukturen nicht Standard; für Ada reichte das Budget nicht; PL/1 ist offensichtlich veraltet. Pascal wird in VMS sehr gut unterstützt, viele notwendige Features wie Modularisierbarkeit, String-, File- und IO-Handling sind aber standardmäßig nicht vorhanden, so daß diese Sprache an der Portabilität scheiterte. Mit der unübersichtlichen Syntax von "C" kann sich nicht jeder Programmierer anfreunden; außerdem fehlen hier Strong-Data-Typing und gute Strukturierungsmöglichkeiten. Die anderen auf VMS verfügbaren Sprachen weisen ebenfalls zuwenig Portabilität auf.

Schließlich fiel die Wahl auf Modula II. Hier fehlt zwar das String-Handling, und dynamische Arrays sind nur über einen Trick realisierbar. Alle anderen Punkte schienen aber erfüllt. Ein Risiko war allerdings die Tatsache, daß der Compiler von einem Fremdhersteller geliefert wurde, so daß ungünstiges Laufzeitverhalten des erzeugten Code oder mangelnde Systemintegration zu befürchten waren.

Nach Abschluß des Projektes läßt sich sagen, daß die Entscheidung richtig war und die Sprachwahl wesentlich zum Durchbruch in dem Projekt verholfen hat. Die anfängliche Begeisterung wurde allerdings durch Nachteile der Sprache getrübt. Zunächst jedoch die positiven Seiten von Modula II: Es ist erstaunlich, was man mit den wenigen Kommandos alles machen kann. Die Programme werden übersichtlich, gut lesbar und sind dennoch kompakt. Gegenüber Cobol dürfte sich der Code-Umfang auf etwa 30 bis 40 Prozent reduziert haben.

Sehr hilfreich sind die vielfältigen Möglichkeiten, Datentypen zu beschreiben, und die damit verknüpften Kontrollen des Compilers und des Runtime-Systems. Typdeklarierungen können auch exportiert werden. Das erlaubt übersichtliche Programmstrukturen. Die Verwendung von Definitionsmodulen mit expliziten Import- und Exportlisten ist sehr übersichtlich und führt zu guten Schnittstellendefinitionen und einer klaren Gliederung.

Obwohl die Programmiereffizienz schwierig zu schätzen ist, dürfte hier etwa eine Verdoppelung gegenüber Cobol eingetreten sein. Modula-II-Code leistet nicht nur mehr, er schreibt auch schneller, ist transparenter und erfordert viel weniger Debugging als Cobol-Code. Aufgrund der guten Modularisierbarkeit ist kaum mit Wechselwirkungsfehlern zu kämpfen. Ebensowenig gibt es Integrationsprobleme mit neuen Modulen. Die Entwicklungsgeschwindigkeit blieb während des Projekts deshalb auch weitgehend konstant.

Die Datentypen BITSET, BYTE, WORD, LONGWORD und OPEN ARRAY ermöglichen darüber hinaus problemlose Aufrufe von Systemfunktionen. Die Hoffnung, alle offensichtlichen Schwächen von Pascal seien in Modula II ausgemerzt, wird jedoch gründlich enttäuscht. Durch eine in manchen Punkten eigenartige Systemphilosophie sind sogar einige Schwächen hinzugekommen:

Eine Datei als eine lange Wurst von Zeichen aufzufassen, bei der man buchstabenweise vorwärts und rückwärts lesen kann, ist in der Praxis absolut unbrauchbar. War die Dateischnittstelle in Pascal schon dürftig, in Modula II ist sie eine Katastrophe. Wenigstens sollte dann schon der Minimalstandard unterstützt werden: sequentielle Dateien mit variablen Satzlängen, strukturierte Dateien mit indexsequentiellem oder Direktzugriff und Ausgabe-Files für den Line-Printer, die automatisch gespoolt werden.

Simple Bildschirmaktionen unter Modula II ein Problem

Auch bei der Terminal-Ein-/-Ausgabe kann man sich nur wundern. Die elementarsten Funktionen werden aus Bibliotheksmodulen zusammengeklaut. Und hier gibt es nichts, was vernünftig zu gebrauchen ist: keine Formatanweisungen, keine Cursor-Positionierung, keine Bildschirmattribute, keine Tabulatoren, keine Ausgabebefehle, die eine Argumentenliste erlauben.

Selbst simple Bildschirminteraktionen werden zu einem Problem, von den Listing-Generatoren ganz zu schweigen. Also fängt man an, Escape-Sequenzen für Inversdarstellung zu Fuß zu programmieren oder Betriebssystemfunktionen aufzurufen. . .

Double-Precision wird nicht unterstützt. Hier ist man auf herstellerabhängige Datenformate angewiesen. Real-Zahlen werden nur auf sechs Stellen genau dargestellt, was in der Praxis unbrauchbar ist. Außerdem müssen selbst für triviale arithmetische Operationen Betriebssystemfunktionen aufgerufen werden.

Das fehlende String-Handling war ein großes Problem, das viel Zeit gekostet hat. Variable Strings sind nicht implementiert. Für String-Operationen müssen entweder Betriebssystemfunktionen aufgerufen werden, oder alles muß selbst programmiert werden. String-Zuweisungen funktionieren nur unter Umgehung des Strong-Data-Typing.

Eine Anweisung wie "String: = "ABC";" ist nicht möglich, ebensowenig eine Anweisung: "IF StringA = StringB THEN...". Wenn Strings vom Typ "complex type" sind, können sie auch nicht als Funktionswerte zurückgeliefert werden. Definiert man Strings als opake Typen, so muß man sich um das Allokieren und Deallokieren selbst kümmern. Daß komplexe String-Funktionen nicht verfügbar sind, versteht sich da fast schon von selbst. String-Operationen sind in kommerziellen Programmen jedoch genauso wichtig wie mathematische Funktionen - eine Erkenntnis, von der sich Sprachentwickler wohl nur schwer überzeugen lassen.

Eine Initialisierung von Records ist nicht implementiert und läßt sich nur durch einen Trick bewerkstelligen, der auf Kosten der Laufzeit geht. Ebensowenig ist eine Möglichkeit für dynamische Arrays vorhanden, vielmehr müssen sie im Sourcecode fix dimensioniert werden. Wer dynamisch dimensionierte Arrays benötigt, muß sie selbst allokieren. Mit OPEN ARRAYS können nur bereits definierte Datenstrukturen in Unterprogrammaufrufen geklont werden.

Spätestens jetzt wird deutlich, daß die Chance, eine leistungsfähige, portierbare Sprache verfügbar zu machen, vertan wurde. Quer durch das Programm ziehen sich Aufrufe für Betriebssystemroutinen - leider für völlig triviale Funktionen, so daß von Herstellerunabhängigkeit nicht die Rede sein kann.

Diese Aufrufe lassen sich natürlich wiederum über eigene Module bündeln, doch viel weiter als bei unzureichend genormten Sprachen ist man dann nicht mehr. Das Problem wurde vom Hersteller des Compilers dadurch etwas entschärft, daß umfangreiche Module mitgeliefert wurden, die alle wesentlichen Betriebssystemaufrufe enthalten; genormt ist hier aber nichts mehr.

Wer mit Modula II anfängt zu arbeiten, muß sehr viel Zeit darauf verwenden, Supportpakete zu schreiben oder zu beschaffen, die eigentlich zum Sprachschatz gehören sollten, zum Beispiel Module für String-Handling, Terminal-IO, Listinggenerierung und File-IO. Das bedeutet aber eine zeitraubende und völlig überflüssige Arbeit. Kommen bei diesen Supportpakten neue Funktionen hinzu, so müssen die Definitionsmodule geändert und als Folge davon das gesamte System rekompiliert werden.

Grundsätzlich erfordert es Mut, eine bereits vorhandene Software in einer neuen Sprache zu rekodieren. In einigen Fällen ist diese Lösung jedoch billiger und besser, als mit einem total verfilzten Programm weiterzuarbeiten - auch wenn die Systementwickler umschulen müssen. Wer auf VAX/VMS entwickelt und keine opaken Typen braucht, ist allerdings mit dem erweiterten DEC-Pascal sicher besser bedient als mit Modula II.