Radikalkur: Fortran soll grundlegend geändert werden

18.12.1987

Die genormte Programmiersprache Fortran macht zur Zeit die radikalste und weitreichendste Veränderung ihrer Existenz durch. Fortran-Experten aller Länder, insbesondere die Mitglieder der Arbeitsgruppe X3J3 des American National Standards Institute (ANSI) und der Working Group 5 der International Standardization Organisation (ISO), haben einen neuen Normentwurf erarbeitet, der unter dem Arbeitstitel "Fortran 8x" nun zur Kommentierung veröffentlicht wird.

Die Terminplanung sieht vor, daß der neue Entwurf in seiner endgültigen Form als nächste Fortran-Norm 1988 zur Verfügung steht. Seit der Publikation von "Fortran 77" (April 1978) wird an der Entwicklung eines neuen Entwurfes gearbeitet. Die zentrale Philosophie dabei war die Modernisierung von Fortran, so daß sie ihre historische Rolle als wichtigste Programmiersprache zur Lösung wissenschaftlich-technischer Aufgaben fortsetzen kann.

Der Unterschied zwischen dem alten und dem neuen Fortran wird auch im Namen zum Ausdruck gebracht: Künftig wird er auch offiziell unter Verwendung von Kleinbuchstaben geschrieben. Im Gegensatz dazu wird die zur Zeit noch gültige Norm ausschließlich unter Verwendung von Großbuchstaben geschrieben.

Aufwärtskompatibilität steht an erster Stelle

Eine Grundforderung an "Fortran 8x" war die Aufwärtskompatibilität zur gegenwärtigen Norm Fortran 77", was dadurch erreicht wurde, daß "Fortran 77" komplett in "Fortran 8x" enthalten ist. Darüber hinaus enthält "Fortran 8x" Konzepte und Strukturen, die sich in "modernen" Sprachen bewährt haben. Fortran hat sich im Laufe seiner Existenz zu seiner gegenwärtigen Gestalt als "Fortran 77" in einem stetigen Prozeß entwickelt, ist im Grunde aber dieselbe einfache und effiziente Formelsprache für wissenschaftlich-technische Anwendungen geblieben. In den zurückliegenden Jahren wurde ein erheblicher Aufwand an Arbeit und Geld in die Entwicklung von Fortran-Programmen investiert, die die Anwender heute und in Zukunft nutzen wollen. Eine solche Investition sind zum Beispiel die mathematischen Programm-Bibliotheken. Diese Tatsache, gepaart mit der Nutzung moderner Hardware, ist ein wichtiger Grund für das große Interesse an der Weiterentwicklung dieser Programmiersprache. So führte der Einsatz von Vektorrechnern zu der Forderung, Matrizen in Fortran verarbeiten zu können. Bei dieser Überarbeitung wird auch der Versuch unternommen, veraltete Strukturen durch Modernisierung der Sprache hinsichtlich der Datenstrukturen und der Konstrukte für die Strukturierung der Programme abzulösen. Die folgenden Sprachmerkmale verursachen die häufigsten Schwierigkeiten in Fortran-Programmen:

- Storage association: Darunter versteht man die direkte Verknüpfung von Datenobjekten mit dem physikalischen Speicher;

- Lochkarten-orientierter Quellcode;

- numerische Genauigkeit, die an die Wortlänge des Prozessors gebunden ist;

- fehlende Datenstrukturen.

Diese und weitere Mängel werden durch den Entwurf "Fortran 8x" abgestellt. Veraltete Sprachmerkmale zerfallen in zwei Kategorien und werden je nachdem als "obsolescent" oder "deprecated" gekennzeichnet. Sprachkonstrukte, die als obsolescent charakterisiert sind, sind bereits in "Fortran 77" redundant gewesen, werden jedoch immer noch häufig benutzt. Sprachkonstrukte, die als deprecated charakterisiert sind, werden in "Fortran 8x" durch die Einführung neuer Sprachmerkmale überflüssig.

Neue Fortran-Programme sollen nur solche Sprachmerkmale verwenden, die weder obsolescent noch deprecated sind. Zur Unterstützung wird der Fortran-8x-Compiler die Verwendung von Sprachkonstrukten kennzeichnen, die als obsolescent oder deprecated eingestuft sind, insoweit es syntaktisch ohne großen Aufwand feststellbar ist. "Fortran 77" ist zwar vollständig in "Fortran 8x" enthalten, seine Bestandteile sind jedoch teilweise als obsolescent und deprecated eingestuft.

Die wichtigsten Erweiterungen gegenüber "Fortran 77" sind:

- Matrixoperationen,

- Matrizen können zur Laufzeit eingerichtet werden,

- verbesserte arithmetische Genauigkeit,

- Datentypen können vom Benutzer definiert werden Patenstrukturen),

- Operatoren und Zuweisungen können vom Benutzer definiert werden,

- Modulkonzept für Daten und Prozeduren,

- rekursive Prozeduren,

- Ein- und Ausgabe mit Gruppennamen (NAMELIST).

- Ein Konzept für die Evolution der Programmiersprache:

- lochkartenunabhängige Quellform,

- neue Typ-Deklarationsanweisung,

- neue Steuerkonstrukte,

- veraltete Sprachmerkmale sollen später wegfallen.

Die Typ-Deklarationsanweisung

Jedes Datenobjekt in Fortran besitzt einen Typ und zahlreiche weitere Eigenschaften (Attribute). Explizit vereinbart wird der Typ eines Datenobjektes mit der Typ-Deklarationsanweisung, deren Gestalt wie folgt geändert wurde:

Typ, Attribute:: Liste der Deklarationen

Als Typ sind alle bisherigen Typvereinbarungen zugelassen: INTEGER, REAL, DOUBLE PRECISION, COMPLEX, CHARACTER und LOGICAL. Darüber hinaus kann mit dem Schlüsselwort TYPE eine Datenstruktur vereinbart werden (siehe Kapitel "Datenstrukturen").

Für den Typ REAL und COMPLEX kann zusätzlich eine dezimale Genauigkeit und ein zulässiger Exponentenbereich angegeben werden (siehe Kapitel Verbesserte arithmetische Genauigkeit").

Für den Typ CHARACTER wurde darüber hinaus das Schlüsselwort LEN (Abkürzung für LENGTH) zur Längenangabe eingeführt:

REAL:: A, B, C

CHARACTER (LEN = 1 0) :: TEXT, ANHANG

Die REAL-Variablen A, B und C erhalten voreingestellte Werte für Genauigkeit und Exponentenbereich, weil die expliziten Angaben fehlen; die Zeichenvariablen TEXT und ANHANG können zehn Zeichen aufnehmen. Die Zeichenfolge "::" kann entfallen, wodurch die in "Fortran 77" üblichen Typvereinbarungen zulässig werden.

Als Attribute sind erlaubt:

PARAMETER für die Vereinbarung von Konstanten, DATA für die Initialisierung der Variablen, ARRAY für die Vereinbarung von Matrizen, SAVE für die Sicherstellung der Werte, weitere Angaben werden in den entsprechenden Kapiteln erläutert: REAL, PARAMETER :: EINS = 1.0, ZWEI = 2.0

INTEGER, ARRAY (1: 1 0):: VEKTOR

Die erste Zeile definiert zwei reelle Konstanten, die zweite eine Matrix VEKTOR für ganzzahlige Werte mit den Indices 1 bis 10.

Zeichensatz

Das Zeichen Unterstrich "-" darf in Namen verwendet werden. Kleinbuchstaben sind erlaubt und sind äquivalent zu den entsprechenden Großbuchstaben, ausgenommen in Zeichenkonstanten.

Neue Sonderzeichen sind:

! " % & ; < > ? [ ]

Diese Sonderzeichen gehören zur Syntax und werden als Operationssymbole, zur Klammerung und für verschiedene Formen der Separierung und Begrenzung anderer lexikalischer Einheiten verwendet (ausgenommen"?"). Für die Zeichen [ und ] kann in Programmen alternativ die Folge "(/" beziehungsweise "/)" verwendet werden.

Beispiel für einen Namen, der maximal aus 31 Zeichen bestehen darf: TABULATOR-POSITION.

Matrixoperationen

Die Matrixoperationen wurden für den Einsatz auf modernen Vektor- und Parallelrechnern entworfen. Eine Matrix kann in "Fortran 8x" als eine Einheit angesprochen werden. Operationen können sowohl mit kompletten Matrizen als auch mit Teilmatrizen (Abschnitten) ausgeführt werden. Sie führen zu kürzeren Programmen und ermöglichen die Programmierung auf einer höheren Ebene, da die bisherige Auflösung in Schleifen entfällt. Dadurch können Anwendungsprogramme schneller und zuverlässiger entwickelt und gewartet werden. Die neuen Operationen ermöglichen auf vielen Rechnerarchitekturen eine Optimierung der Matrixverknüpfungen.

Die in "Fortran 77" enthaltenen arithmetischen, booleschen und Zeichenoperationen können auch auf Matrixoperanden angewendet werden. Zuweisungen von kompletten Matrizen und Teilmatrizen, maskierte Matrixzuweisungen, Konstante und Ausdrücke in Form von Matrizen und die Definition von Matrixfunktionen durch den Benutzer sind ebenfalls möglich. Neue innere Funktionen (intrinsic functions) für die Erzeugung und Manipulation von Matrizen, für die Zusammenfassung und Zerlegung von Matrizen und für die Unterstützung weiterer Rechenmöglichkeiten mit Matrizen wurden hinzugefügt (zum Beispiel MATMUL für die Matrixmultiplikation).

Beispiel für die Addition der zweidimensionalen Matrizen A und B und der Zuweisung des Ergebnisses nach C:

REAL, ARRAY (10, 10):: A, B, C

. . .

C = A + B

Speicherklassen von Matrizen

- Matrizen können statisch angelegt werden, dabei sind nur konstante Indexgrenzen möglich (SAVE-Attribut erlaubt).

- Matrizen können als lokale Variable mit dem Prozeduraufruf als Lebensdauer vereinbart werden, dabei sind variable Indexgrenzen, abhängig von aktuellen Prozedurparametern, möglich (kein SAVE-Attribut erlaubt).

- Matrizen kann mit der ALLOCATE-Anweisung dynamisch Speicher zugewiesen beziehungsweise mit der DEALLOCATE-Anweisung freigegeben werden. Solche Matrizen dürfen variable Indexgrenzen besitzen.

- Matrizen dürfen formale Prozedurparameter sein: Ihre innerhalb der Prozedur nicht veränderbaren, aber als variabel betrachteten Indexgrenzen werden vom Aufrufer bestimmt.

- Matrizen können Alias-Variable sein: In diesem Fall besitzen sie keinen eigenen Speicher, sondern werden dynamisch zu einem beliebigen Zeitpunkt mit variablen Indexgrenzen über die IDENTIFY-Anweisung mit anderen Matrizen assoziiert (dynamisches EQUVALENCE).

Matrix-Konstruktor

Durch eine Folge von skalaren Werten kann eine Matrix gebildet werden; so zum Beispiel:

REAL, ARRAY(2,2):: X

X = [3.2, 4.01, 6.5, 2.3]

oder X = (/3.2, 4.01, 6.5, 2.3/)

In diesem Beispiel wird der Matrix X ein konstanter Ausdruck zugewiesen (Ergebnis: X(1,1) = 3.2, X(2, 1) =4.01, X(1,2)=6.5, X(2,2)=2.3). Jeder Matrix-Ausdruck vom Rang eins kann als Konstruktor verwendet werden. Wenn ganzzahlige Ausdrücke zur Bildung eines Konstruktors herangezogen werden, gibt es eine vereinfachte Schreibweise.

Beispiel 1:

INTEGER I(51)

I = (/0: 100: 2/)

Hier werden der Matrix I alle geraden Zahlen von 0 bis 100 (Schrittweite ist 2) zugewiesen.

Beispiel 2:

REAL Y(30)

Y = (/10(/0.0, 1.0, 2.0/)/)

Hier werden der Matrix Y durch den Wiederholungsfaktor 10 die

Zahlen 0.0, 1.0, 2.0 insgesamt zehnmal zugewiesen.

Matrix-Abschnitte

Durch Triplex-Notation kann jederzeit ein rechteckiger Ausschnitt aus einer Matrix ausgewählt werden. Beispiel:

A(1 : 10 : 2, 10 : 1 : 3-3)

Der erste Parameter der Indexliste legt den Anfangswert, der zweite den Endwert und der dritte die Schrittweite fest. Fehlt der erste Parameter, wird die Untergrenze angenommen, fehlt der zweite Parameter, wird die Obergrenze angenommen, und fehlt der dritte Parameter, wird als Schrittweite eins genommen.

Beispiel:

REAL, ARRAY (5,4,3) :: D

. . .

D(3:5, 2, 1:2) = (/1.0, 2.0, 3.0, 4.0, 5.0, 6.0/)

Die Ergebnisvariable ist ein Matrix-Abschnitt, der den Rang 2 mit den Dimensionen 3 und 2 besitzt und aus folgenden Elementen besteht:

D(3,2,l), D(4,2,1), D(5,2,1), D(3,2,2), D(4,2,2), D(5,2,2).

RANGE-Anweisung

Matrizen, die sich im Typ unterscheiden, aber denselben Rang und dieselben unteren und oberen Grenzen haben, können mit der RANGE-Anweisung zusammengefaßt werden:

INTEGER, ARRAY (10, 10):: IA

RANGE /LISTE1 / A, B, C, IA

Die effektive Form aller Matrizen A, B, C, IA kann dann durch Ausführung der SET-RANGE-Anweisung, die den Namen der Liste enthält, geändert werden. Dabei ist keine Angabe einer Schrittweite erlaubt. Durch Ausführung der SET-RANGE-Anweisung werden neue Grenzen für alle Matrizen der Liste festgelegt; dieser Matrix-Ausschnitt wird mit demselben Matrix-Namen identifiziert:

N = 3

SET RANGE (N:2*N, N:2*N) / LISTE1 /

Nach Ausführung dieser Anweisung beträgt die untere Grenze für alle Matrizen in LISTE1 in beiden Dimensionen 3 und die obere Grenze beträgt 6 in beiden Dimensionen. Danach ausgeführte Operationen benutzen nur diese effektiven Grenzen, es sei denn, sie werden durch eine weitere SET-RANGE-Anweisung erneut verändert.

Wenn nur unterschiedliche Matrizen mit der SET-RANGE-Anweisung verändert werden sollen, kann man alle Matrizen in einer RANGE-Anweisung ohne Listennamen aufführen.

Beispiel:

DIMENSION RA(10), JA(5, 6)

RANGE RA, JA

Die Matrizen RA und JA können nur unabhängig voneinander in verschiedenen SET-RANGE-Anweisungen erscheinen.