Die Geschichte der Programmiersprachen wird meistens als Zeitleiste erzählt. Das ist falsch herum. Keine dieser Sprachen ist verschwunden — sie sind übereinandergestapelt, und jede läuft noch.
Was du gleich nach unten scrollst, ist deshalb keine Zeitleiste, sondern ein Bohrkern. Oben liegt der Satz, den du heute an einen Agenten schreibst. Ganz unten liegen die Zahlen, die 1947 ein Register gefüllt haben. Dazwischen liegt alles, was seither niemand mehr sagen muss.
Jede Schicht zeigt dieselbe Aufgabe: zähle die Zahlen von 1 bis 10 zusammen und gib das Ergebnis aus. Und daneben die einzige Frage, die zählt — wie viel von dem Geschriebenen ist eigentlich Absicht, und wie viel ist bloß Buchhaltung für die Maschine?
Der Schalter unten schaltet die Buchhaltung ab. Lass ihn an, während du fällst.
Der Bruch: Das Programm wird nicht mehr geschrieben, sondern beauftragt. Der Quelltext ist Zwischenprodukt.
Zwischen 2023 und 2025 verschiebt sich etwas Grundsätzliches: Das Modell antwortet nicht mehr nur, es handelt. Es liest Dateien, führt Kommandos aus, sieht das Ergebnis und korrigiert sich. Mit dem Model Context Protocol (Anthropic, November 2024) bekommt diese Schicht eine Steckdosennorm — Werkzeuge und Datenquellen lassen sich anschließen, ohne für jedes Modell neu gebaut zu werden.
Damit ändert sich, was ein Programm überhaupt ist. Die dauerhafte Sache ist nicht mehr die Datei mit dem Code, sondern die formulierte Absicht. Der Code darunter kann jederzeit neu entstehen.
Zähl die Zahlen von 1 bis 10 zusammen,
schreib das Ergebnis in report.md
und commit es mit einer sinnvollen Message.
Der Preis: Der Auftrag wird länger als der Code, den er ersetzt. Absicht präzise zu formulieren ist eine eigene Disziplin — und die einzige, die auf dieser Schicht noch zählt.
Der Bruch: Natürliche Sprache wird zur Eingabeschicht. Zum ersten Mal muss der Mensch keine Notation mehr lernen.
2017 beschreibt ein Paper mit dem Titel „Attention Is All You Need" die Transformer-Architektur. 2020 zeigt GPT-3, dass ein hinreichend großes Sprachmodell Aufgaben löst, für die es nie ausdrücklich trainiert wurde. 2021 kommt Codex und mit ihm GitHub Copilot; im November 2022 macht ChatGPT die Sache für alle sichtbar.
Der Bruch ist subtiler, als er wirkt. Alle Schichten davor haben die Notation vereinfacht — Register wurden zu Namen, Sprünge zu Schleifen, Zeiger zu Objekten. Hier fällt die Notation ganz weg. Was bleibt, ist Sprache, und Sprache ist mehrdeutig. Das ist Feature und Fehler in einem.
Zähl die Zahlen von 1 bis 10 zusammen
und sag mir das Ergebnis.
Der Bruch: Statt Regeln zu schreiben, zeigt der Mensch Beispiele. Das Programm entsteht durch Optimierung, nicht durch Autorschaft.
2012 gewinnt AlexNet den ImageNet-Wettbewerb mit einem Abstand, der die Sache entscheidet. Die Bausteine sind alt — Backpropagation ist seit 1986 beschrieben — aber jetzt treffen sie auf genug Daten und auf GPUs. Mit TensorFlow (2015) und PyTorch (2016) wird das Verfahren zum Handwerk. Andrej Karpathy nennt es 2017 „Software 2.0".
Das ist der radikalste Bruch dieser ganzen Seite, und er wird oft übersehen, weil er nach Statistik aussieht und nicht nach Programmieren. Zum ersten Mal gibt es kein Artefakt mehr, das ein Mensch gelesen und geschrieben hat. Der Quelltext ist eine Zahlenmatrix. Man kann sie ausführen, aber nicht lesen.
# Für diese Aufgabe existiert kein geschriebenes Programm.
# Es existieren Beispiele:
[1, 2, 3] -> 6
[4, 5] -> 9
[2, 2, 2, 2] -> 8
# und ein Optimierer, der 3,7 Millionen Zahlen so lange
# verschiebt, bis die Beispiele stimmen.
#
# Das Ergebnis ist das Programm. Lesbar ist es nicht.
Ohne diese Schicht gäbe es die beiden darüber nicht. Der Prompt ist kein Nachfolger des trainierten Programms, sondern seine Bedienoberfläche.
Der Bruch: Der Compiler prüft nicht mehr nur Formen, er führt einen Beweis. Ganze Fehlerklassen werden unmöglich statt unwahrscheinlich.
Graydon Hoare beginnt 2006 an Rust, Mozilla steigt 2009 ein, Version 1.0 erscheint im Mai 2015. Die Idee dahinter ist unbequem und deshalb wirkungsvoll: Wer eine Referenz besitzt, wer sie ausleihen darf und wie lange, wird vom Compiler nachgehalten. Speichersicherheit ohne Garbage Collector — dafür ein Übersetzer, der Programme ablehnt, die vielleicht funktioniert hätten.
Parallel läuft dieselbe Bewegung in der anderen Richtung: TypeScript legt ab 2012 ein Typsystem über eine Sprache, die keines hatte. Beides gehört zusammen. Nach dreißig Jahren, in denen Abstraktion vor allem hieß, dem Menschen Arbeit abzunehmen, nimmt hier jemand dem Menschen wieder Arbeit auf — damit die Maschine mehr garantieren kann.
fn main() {
println!("{}", (1..=10).sum::<i32>());
}
Die erste Schicht dieses Abstiegs, die den Absichtsanteil wieder senkt. Das ::<i32> ist keine Buchhaltung für die Maschine — es ist Buchhaltung für den Beweis. Abstraktion steigt nicht monoton.
Der Bruch: Speicher ist nicht mehr das Problem des Programmierers. Und das Programm ist nicht mehr an eine Maschine gebunden.
Ein enges Fenster mit außergewöhnlicher Dichte. Guido van Rossum veröffentlicht Python 1991. 1995 erscheinen innerhalb von Monaten Java, JavaScript und Ruby — Java mit einer virtuellen Maschine und dem Versprechen, überall zu laufen; JavaScript in zehn Tagen für den Netscape-Browser geschrieben; Ruby aus der Überzeugung, dass die Freude des Programmierers ein Entwurfskriterium ist.
Das Gemeinsame ist die Laufzeitumgebung: Garbage Collection als Normalfall, dynamische Typen als Normalfall, Portabilität als Normalfall. Was ab hier verschwindet, ist der ganze Themenkomplex „Wo liegt das eigentlich im Speicher, und wer räumt es weg?" — jahrzehntelang die häufigste Fehlerquelle überhaupt.
print(sum(range(1, 11)))
Man sieht hier gut, warum die Zeichenzahl allein nichts taugt: Die eine Zeile ist kurz, aber unter ihr läuft ein Interpreter, ein Speicherverwalter und ein Betriebssystem. Kurz heißt nicht wenig.
Der Bruch: Der Mensch modelliert nicht mehr die Maschine, sondern die Welt. Zustand und Verhalten wandern zusammen.
Ole-Johan Dahl und Kristen Nygaard bauen am Norwegischen Rechenzentrum eine Sprache für Simulationen — Simula 67 — und erfinden dabei Klassen und Objekte, weil man Schiffe und Warteschlangen nun einmal so beschreibt. Am Xerox PARC treiben Alan Kay, Dan Ingalls und Adele Goldberg die Idee bis an ihr Ende: In Smalltalk ist alles ein Objekt, und Programmieren heißt, Nachrichten zu verschicken. 1985 bringt C++ dieselbe Idee zu den Leuten, die Performance zählen.
Kays eigentliche Pointe war nie die Vererbung, sondern die Kapselung: Ein Objekt gibt nichts über sein Inneres preis. Man darf es nur fragen. Das ist die erste Schicht, auf der der Programmierer bewusst weniger wissen darf, als er könnte.
Transcript showln: (1 to: 10) sum
Der Bruch: Der Mensch sagt, was er will. Die Maschine entscheidet selbst, wie.
1970 beschreibt Edgar F. Codd das relationale Modell. 1974 bauen Donald Chamberlin und Raymond Boyce bei IBM darauf eine Abfragesprache, zunächst SEQUEL genannt. Ihr Ziel ist ausdrücklich, dass auch Nicht-Programmierer sie schreiben können.
Aus heutiger Sicht ist SQL der eigentliche Vorgriff auf alles, was oben in diesem Stapel liegt. Der Mensch beschreibt das gewünschte Ergebnis; ein Optimierer sucht sich den Weg dorthin und wählt ihn je nach Datenlage jedes Mal neu. Genau diese Arbeitsteilung — Absicht hier, Ausführungsplan dort — kehrt fünfzig Jahre später als Prompt wieder.
SELECT SUM(n) FROM generate_series(1, 10) AS n;
Diese Schicht liegt zeitlich unter dem Objekt, aber vom Abstraktionsgrad her weit darüber. Der Stapel ist keine Treppe. Manche Ideen kamen zu früh und mussten fünfzig Jahre warten.
Der Bruch: Der Kontrollfluss bekommt eine Form. Und die Systemsprache wird portabel.
1968 erscheint in den Communications of the ACM ein kurzer Brief von Edsger Dijkstra über den Sprungbefehl. Die These: Wer springen darf, wohin er will, kann über sein eigenes Programm nicht mehr nachdenken, weil kein Zusammenhang zwischen Textstelle und Programmzustand mehr besteht. Was folgt, sind Schleifen und Bedingungen als benannte, verschachtelte Konstrukte — Wirths Pascal 1970, davor ALGOL 60 mit Blockstruktur und Rekursion.
1972 schreibt Dennis Ritchie bei Bell Labs C, und 1973 wird Unix darin neu geschrieben. Das ist der zweite, praktischere Bruch dieser Schicht: Ein Betriebssystem muss nicht mehr für jede Maschine neu in deren Assembler entstehen. C ist nah genug am Blech, um Systeme zu bauen, und abstrakt genug, um umzuziehen.
#include <stdio.h>
int main(void) {
int sum = 0;
for (int i = 1; i <= 10; i++) sum += i;
printf("%d\n", sum);
return 0;
}
Der Bruch: Zwei Antworten auf dieselbe Frage — soll die Sprache dem Denken folgen oder der Sprache des Fachs?
John McCarthy beschreibt 1958 LISP, gedacht als Notation für symbolische Berechnung. Steve Russell bemerkt, dass sich die theoretische Funktion eval tatsächlich implementieren lässt — und damit ist ein Interpreter da, in dem Programme dieselbe Gestalt haben wie Daten. Rekursion, Garbage Collection, Funktionen höherer Ordnung: alles hier, alles 1958.
Ein Jahr später entsteht COBOL, aus einer ganz anderen Richtung. Vorbild ist Grace Hoppers FLOW-MATIC, das erste System, in dem Programmanweisungen wie englische Sätze aussehen. Das Ziel ist nicht mathematische Eleganz, sondern Lesbarkeit für Menschen, die keine Mathematiker sind — Verwaltung, Buchhaltung, Versicherung.
Beide Zweige laufen bis heute. Der eine mündet in funktionale Sprachen und letztlich in das map deines Lieblingsframeworks. Der andere in die Idee, dass ein Programm etwas ist, das man lesen können sollte — und damit, sehr weit oben, in den Prompt.
(defun sum (n) (if (= n 0) 0 (+ n (sum (- n 1)))))
(print (sum 10))
DATA DIVISION.
WORKING-STORAGE SECTION.
01 I PIC 9(2) VALUE 1.
01 TOTAL PIC 9(4) VALUE 0.
PROCEDURE DIVISION.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10
ADD I TO TOTAL
END-PERFORM
DISPLAY TOTAL
STOP RUN.
Der Bruch: Ein Programm übersetzt Programme. Der Mensch schreibt nicht mehr für die Maschine, sondern für einen Übersetzer.
John Backus' Team bei IBM liefert im April 1957 den ersten FORTRAN-Compiler aus. Der Widerstand vorher war erheblich, und er war fachlich begründet: Niemand glaubte, dass eine Maschine Code erzeugen könne, der es mit handgeschriebenem Assembler aufnimmt. Ein großer Teil der Entwicklungszeit floss deshalb in Optimierung — es ging um Glaubwürdigkeit.
Der Name sagt, worum es ging: Formula Translation. Zum ersten Mal darf im Quelltext stehen, was der Mathematiker meint, statt was das Rechenwerk tut. Alles, was auf dieser Seite darüber liegt, ist eine Fortsetzung dieses einen Gedankens.
ISUM = 0
DO 10 I = 1, 10
10 ISUM = ISUM + I
WRITE (6, 20) ISUM
20 FORMAT (I5)
STOP
END
Die Spaltenregeln, die Anweisungsnummern, das FORMAT in einer eigenen Zeile — das sind Spuren der Lochkarte. Jede Schicht trägt die Form ihres Eingabegeräts.
Der Bruch: Die Zahl bekommt einen Namen. Das ist die gesamte Erfindung — und die größte auf dieser Seite.
Am Anfang steht kein Text, sondern eine Zahlenfolge. Ein Befehl ist ein Zahlenwert, seine Argumente sind Zahlenwerte, das Sprungziel ist eine Adresse, die man von Hand nachrechnet, wenn man eine Zeile einfügt.
Kathleen Booth entwickelt zwischen 1947 und 1950 an der Universität London für die ARC-Maschine eine Notation, in der Befehle Kürzel und Adressen Namen tragen — und ein Programm, das diese Kürzel in Zahlen zurückübersetzt. 1949 fährt in Cambridge der EDSAC mit David Wheelers „Initial Orders" an, die eingegebene Symbole beim Laden auflösen.
Alles Weitere ist Wiederholung dieses einen Schrittes auf immer höherer Ebene. Ein Name steht für etwas Umständliches. Ein Prompt ist nichts anderes: ein Name für ein Programm, das noch nicht existiert.
MOV CX, 10 ; Zähler
XOR AX, AX ; Summe = 0
NEXT: ADD AX, CX ; aufaddieren
DEC CX
JNZ NEXT ; solange CX != 0
; Ausgabe: Zahl durch 10 teilen, Rest merken,
; Reste umdrehen, jeden in ASCII wandeln,
; Puffer aufbauen, INT 21h / AH=09h rufen.
; — 30 weitere Zeilen, kein Wort davon
; hat mit "zusammenzählen" zu tun.
Darunter liegt nur noch Spannung an Transistoren. Das ist der Grund des Bohrkerns.
Das ist die Pointe des Querschnitts. Keine dieser Schichten wurde abgelöst. Sie wurden begraben — und laufen weiter, unter dir, jedes Mal.
Wenn du oben einen Satz an einen Agenten schreibst, passiert Folgendes. Drück den Knopf und sieh zu.
Gezählt an den oben gezeigten Fassungen — eine Illustration, keine Messung. Interessant ist nicht, dass die Zahl fällt, sondern dass sie zweimal wieder steigt.
Rust steigt, weil Beweise Platz brauchen. Der Agent-Auftrag steigt, weil er mehr will als eine Rechnung — er will ein Ergebnis, eine Datei und einen Commit. Der Preis der Abstraktion ist nicht Länge. Er ist Kontrolle.
Jeder Bruch auf dieser Seite folgt demselben Handel. Der Mensch gibt etwas ab, das er bisher selbst bestimmt hat, und bekommt dafür Reichweite. Backus gab die Registerzuteilung ab und bekam Formeln. Die Laufzeitschicht gab die Speicherkontrolle ab und bekam Portabilität. Die Deklaration gab die Reihenfolge ab und bekam einen Optimierer.
Auf den obersten beiden Schichten wird derselbe Handel gemacht, nur ist der Einsatz höher: Abgegeben wird die Gewissheit, dass zweimal dasselbe herauskommt. Bekommen wird eine Ausdrucksform, die niemand mehr lernen muss.
Ob das ein guter Handel war, entscheidet sich nicht an der Technik, sondern daran, ob man weiß, was man abgegeben hat. Genau deshalb ist der Weg nach unten interessanter als der nach oben.