Programmiersprachen werden in 5 Generationen eingeteilt:
Laut Informatikduden[13, S. 300] lief die Einteilung der Generationen parallel mit den Generationen der Rechneranlagen.
Maschinensprache stellt die Grundlage für alle Programmiersprachen dar, denn es ist die einzige Sprache, die die real existierende Maschine versteht. Hierfür werden Bitmuster der Befehle und Zahlen direkt an die Maschine übergeben: durch Schalter, Lochkarten oder heutzutage durch das Lesen von ausführbaren Programme aus dem Arbeitsspeicher. Eine heutige Entsprechung wäre das ausführbare Programm in einem Editor mit hexadezimaler Darstellung einzugeben und ohne Kompilierung direkt zu starten.
Verfügbar sind die Befehle, die die Zielarchitektur unterstützt. Dabei besitzt jeder Prozessortyp unterschiedliche Befehle und mit jeder Prozessorgeneration kommen weitere Befehle hinzu. Die Befehle entsprechen einfachen mathematischen Anweisungen, wie Addition, Subtraktion oder Zuweisung. Dabei ist jede einzelne Operation ein einzelner Befehl, so dass selbst für einfache Rechnungen längere Programme erforderlich sind. Entsprechend der komplizierten Verwendung von Maschinensprache ist ihre inzwischen seltene Verwendung. Man kann mit guten Gewissen davon ausgehen, dass heutzutage auf den modernen Architekturen niemand mehr Maschinensprache direkt eingibt.
Maschinenspracheprogramme sind nicht auf andere Architekturen übertragbar und bedürfen - wie der Name bereits vermuten lässt - keinerlei Übersetzung.
Assemblersprachen sind eindeutige Entsprechungen der Maschinensprache. Anstelle von Bitmustern werden nun Schlüsselwörter verwendet, die direkt in das entsprechende Bitmuster übersetzt werden. Hier findet nahezu eine 1:1 Übersetzung statt, die Lesbarkeit der Maschinensprache wird durch die Schlüsselwörter und Labels lediglich (sehr deutlich) erhöht.
Unterschiede können sich ergeben, wenn zum Beispiel der Prozessor zwischen kurzen und weiten Sprüngen unterscheidet. So können Labels durch einen kurzen Sprung erreicht werden (beispielsweise ± 128Bytes), weiter entfernte Labels werden durch entsprechende Befehle für weite Sprünge umgesetzt.
Daher kann hier je nach Prozessor und Assemblerimplementierung bereits eine geringfügige Abstrahierung zwischen Maschine und Programmiersprache entstehen.
Modernere Varianten besitzen Makrofunktionen, die mehrere Befehle in einem Makro zusammenfassen und das Makro vor dem assemblieren für den Programmierer unbemerkt wieder durch die jeweiligen Befehle ersetzen.
Assembler spielt heutzutage nahezu keine wichtige Rolle mehr in der normalen Entwicklung von Programmen. Da Assemblercode lediglich die Übersetzung der Bitmuster in lesbare Texte darstellt, ist es ebenso abhängig von der Zielarchitektur wie die Maschinensprache selbst. Damit eignet sich Assembler nicht für portable Programme.
Assemblerprogramme müssen vor der Verwendung erst in Maschinensprache übersetzt werden. Assemblerübersetzer werden jedoch allgemein nicht als Kompiler bezeichnet, da sie den Sinn der Programms (zum Beispiel Schleifen oder Abfragen) nicht aus den Befehlswörtern in Maschinensprache übersetzen müssen, sondern die Befehle direkt durch das jeweilige Bitmuster austauschen können. Diese Übersetzer werden daher auch als „Assembler“ bezeichnet.
Zu dieser Generation zählen laut Informatikduden[13, S.301] ebenfalls frühe, unstrukturierte oder nur wenig strukturierte Sprachen, wie Algol 60, Fortran und Cobol. Die meisten Quellen, u.a. Wikipedia, Script an der FH Deggendorf[14], Uni-Bielefeld[15], Uni-München[16] ziehen den Schnitt jedoch scharf bei den Assemblersprachen. Ich müsste mich sehr täuschen, wenn die Vorlesung „Einführung in Informatik“ von Herrn Ertelt den Schnitt nicht ebenfalls dort gezogen hätte.
Sprachen wie Fortran und Cobol werden dort der 3. Generation zugeordnet hat, zumal Algol als erste strukturierte Programmiersprache gilt und der strukturierte Aufbau als Eigenschaft von Algol 60 ebenfalls im Informatikduden genannt wird.
Lässt man die Grenze, die der Informatikduden zieht mal außen vor und bezieht sich auf die Mehrzahl der gefundenen Quellen, so verbindet man mit Sprachen ab der 3. Generation erst den Begriff „Programmiersprache“, ebenfalls wird erst ab diesem Abstraktionslevel von „kompilieren“ gesprochen.
Da das Programm nicht mehr in Abhängigkeit zur Architektur geschrieben werden muss, können Programme auch erstmals unverändert auf anderen Architekturen kompiliert werden, wenn für diese Sprache dort ein entsprechender Kompiler existiert. Damit werden Programme erstmals portabel und können auch weiterbenutzt und -entwickelt werden, wenn auf neuere Architekturen gewechselt wurde.
Mit der dritten Generation werden vorrangig imperative (prozedurale) Programmiersprachen bezeichnet, wie Basic, Pascal oder C.
Anwendungsbezogene Sprachen erweitern die Sprachen der dritten Generation zusätzlich um spezialisierte Mittel, die die Entwicklung einer Anwendung gestatten. Hierzu gehören Dateiein- und -ausgabe, Datenbankzugriffe oder die Interaktion mit dem Benutzer, zum Beispiel durch die graphische Benutzeroberfläche oder Datei Ein- und Ausgaben.
Das Ziel von anwendungsbezogenen Sprachen ist es, mit möglichst wenig Aufwand ein spezielles Problem zu lösen. Zu diesen Sprachen zählen zum Beispiel die Visual-Basic und Visual-C++ von Microsoft. Hier werden Formulardaten geklickt und Steuerungsinformationen zum Beispiel in Kommentaren und Resource-Dateien gespeichert und durch den Compiler verarbeitet. Für den Entwickler bedeutet dies weniger Programmieraufwand, aber auch schlechter lesbaren Code. Neuere Varianten, wie Visual C# oder Delphi beschreiben Formulare als gültigen Quelltext. Die Compiler besitzen selber keine spezialisierten Fähigkeiten mehr, der GUI-Designer dient somit lediglich als Codegenerator.
Ein bekanntes Beispiel für eine anwendungsbezogene Sprache ist SQL. Hier lassen sich Informationen aus dem Datenbestand auslesen und speichern, ohne dass der Programmierer hierfür von Hand Dateien öffnen und durchsuchen muss, oder im Falle eines Datenbankservers beschreiben muss, wie die Verbindung zum Datenbankserver erstellt wird. Anwendungsorientierte Sprachen können also im Vergleich zusätzliche zu Sprachen der dritten Generation spezielle Probleme einfacher und mit weniger Quelltext lösen.
Der Informatikduden verweist hier zusätzlich auf bessere Programmierumgebungen, objektorientierte Programmierung und Programmgeneratoren. Programmierumgebungen und Programmgeneratoren sind jedoch keine Eigenschaften einer Sprache und die objektorientierte Programmierung lässt sich auch mit Sprachen der 3. Generation bewerkstelligen.
In Sprachen der 5. Generation wird nicht mehr die Lösung beschrieben, sondern das eigentliche Problem, dass mit Hilfe der Programmiersprache zu lösen ist. Den Lösungsweg herauszufinden wird der Sprache selbst überlassen. Problembeschreibende Sprachen finden in Bereichen der künstlichen Intelligenz Verwendung, zu den bekanntesten Vertreter problembeschreibender Sprache zählen Prolog und LISP.
Zusätzlich zu den genannten Eigenschaften von Sprachen der 5. Generation, zählt der Informatikduden Komponenten und Middleware (Softwareschnittstellen oder Dienste, die eine Verbindung zwischen zwei Komponenten herstellt, um Daten auszutauschen).
Objektorientierte Sprachen werden üblicherweise nicht in das Generationen-Modell eingefügt, sondern in einer „OO-Generation“ gesondert aufgezählt. Da man in einer prozeduralen Sprache, ein Programm ebenfalls objektorientiert aufbauen kann, zerfließt die Grenze zwischen prozeduralen und objektorientierten Sprachen. Es wird offensichtlich, dass objektoriente Programmiersprachen die objektorientierte Programmierung unterstützen, vereinfachen und damit die Lesbarkeit des Programmquelltextes erhöhen. Von ihrer Arbeitsweise und ihrer Ausdrucksmächtigkeit sind sie jedoch durchaus den Sprachen der dritten Generation zuzuordnen.