Zeitlose Programmiersprachen

Die Auswahl an Programmiersprachen wächst seit einigen Jahren wieder rasant. Wer sich abseits der tagtäglich genutzten weiterbilden und über den Tellerrand schauen möchte, steht vor der Frage, welche Sprache den größten Erkenntnisgewinn bringt. Vier Vorschläge.

In Pocket speichern vorlesen Druckansicht 65 Kommentare lesen
Lesezeit: 9 Min.
Von
  • Golo Roden
Inhaltsverzeichnis

Die Auswahl an Programmiersprachen wächst seit einigen Jahren wieder rasant. Wer sich abseits der tagtäglich genutzten weiterbilden und über den Tellerrand schauen möchte, steht vor der Frage, welche Sprache den größten Erkenntnisgewinn bringt. Vier Vorschläge.

Vor ungefähr einer Woche hat Damian Wolf einen Artikel mit einer Liste von "Zehn Programmiersprachen, die Entwickler 2017 lernen sollten" veröffentlicht. Das hat mir gut gefallen. Denn völlig unabhängig davon, ob man ihm bei der Auswahl der Sprachen zustimmt oder nicht, ist es sicherlich eine gute Idee, gelegentlich einen Blick über den Tellerrand zu werfen.

Dass es nicht möglich ist, in einem Jahr gleich zehn Sprachen auf einmal fundiert zu lernen und Erfahrung mit ihnen zu sammeln, liegt auf der Hand. Doch das ist nicht wichtig. Selbst wer nur alle drei Jahre eine neue Sprache lernt oder sich gelegentlich mit einer bislang unbekannten Sprache beschäftigt, lernt dazu. Das ist das einzige, was zählt.

Es zählt deshalb, weil nicht alle Programmiersprachen gleich sind. Natürlich gilt das im Allgemeinen im Hinblick auf die Turing-Vollständigkeit, aber es wird niemand ernsthaft bestreiten, dass manche Sprachen expressiver sind als andere, sodass sich Code besser, kürzer oder treffender ausdrücken und formulieren lässt. Wäre dem nicht so, würde jeder von uns heute noch mit der Sprache arbeiten, mit der das Programmieren ursprünglich gelernt wurde.

Wo ich persönlich anderer Meinung bin als Damian Wolf, ist die Auswahl der Sprachen. Das ist allerdings nicht als Vorwurf an ihn gemeint, denn es kann keine objektive Auswahl der besten Sprache geben. Dafür habe ich Anfang des Jahres bereits in "Programmiersprachen: Gleich und doch nicht dasselbe" plädiert. Mein Fazit war damals:

"Vielleicht wäre es daher am besten, gar nicht nach einer Sprache des Jahres zu suchen, sondern sich auf die allen Sprachen zugrunde liegenden Konzepte zu besinnen. Je mehr dieser Konzepte man kennt und je besser es einer Sprache gelingt, diese dem gewünschten Kontext entsprechend zu verpacken, desto besser ist die Sprache geeignet, die Herausforderungen des jeweiligen Jahres zu meistern."

Auf diesen Punkt kehre ich, beispielsweise auch in Diskussionen auf Konferenzen, immer wieder zurück: Die Konzepte sind weitaus wichtiger als die konkrete Implementierung.

Genau das ist der Grund, warum ich andere Sprachen als Damian Wolf gewählt hätte. Hinzu kommt, dass sich einige der Sprachen auf seiner Liste für meinen Geschmack schlicht zu ähnlich sind. So macht es meiner Meinung nach beispielsweise praktisch kaum einen Unterschied, ob man C# oder Java lernt oder ob man sich mit Python oder Ruby auseinandersetzt.

Spannend und mutig fand ich seine Empfehlung, Assembler zu lernen. Ich habe mir Gedanken gemacht, welche Sprachen ich ausgewählt hätte. Ich komme zwar nur auf vier Sprachen (was immer noch mehr als genug ist, wenn man die Sprachen fundiert lernen und Erfahrung mit ihnen sammeln will), aber Assembler hätte ich ebenfalls ausgewählt.

Warum? Weil moderne Hochsprachen die grundlegenden Konzepte zwar durch Abstraktion verbergen, aber deren Grenzen nicht sprengen können. In keiner Sprache wird so deutlich, wie effizient Algorithmen arbeiten, wie in Assembler. Wer weiß, wie ein Prozessor arbeitet, blickt mit anderen Augen auf jenen Code, den wir tagtäglich in Hochsprachen schreiben.

Joel Spolsky hat zu diesem Thema vor bereits 16 Jahren den Blogeintrag "Back to Basics" geschrieben, der bis heute nichts von seiner Relevanz und Aktualität eingebüßt hat. Sein Fazit lautet:

"If you want to teach somebody something well, you have to start at the very lowest level."

Dem ist aus meiner Sicht nichts hinzuzufügen.

Wer mein Blog bereits länger verfolgt, weiß, dass ich ein großer Anhänger von Lisp bin. Lisp ist für mich persönlich das Paradebeispiel einer Sprache, aus der ich immer wieder Neues lernen kann. Obwohl ich mich tagtäglich mit JavaScript und Node.js befasse, kehre ich alle paar Monate zu Lisp zurück und experimentiere für einige Tage mit der Sprache.

Ich halte es dort wie der US-amerikanische Entwickler Eric S. Raymond, der einmal gesagt hat, Lisp sei selbst dann eine lernenswerte Sprache, wenn man sie niemals verwenden werde. Der Erkenntnisgewinn führe dazu, ein allgemein besserer Entwickler zu werden. Es liegt daher nahe, sich die Sprache näher anzusehen.

Aufgrund dieser gelegentlichen, aber regelmäßigen Beschäftigung mit Lisp habe ich vor etwas über einem Jahr zwei Blogeinträge zu dem Thema geschrieben: "Lisp lernen, Teil 1: Primzahlen berechnen" und "Lisp lernen, Teil 2: Quicksort implementieren".

Die Sprache hat mich bisher nicht enttäuscht – im Gegenteil. Obwohl ich aufgrund fehlender Erfahrung weit davon entfernt bin, ein guter Lisp-Entwickler zu sein, kann ich die Aussage von Eric S. Raymond nur unterstreichen. Insbesondere für mein Verständnis von JavaScript war die Beschäftigung mit Lisp sehr zuträglich.

Wer einen kurzweiligen, aber fundierten Einstieg in die Sprache sucht, dem sei das Buch "Common Lisp: A Gentle Introduction to Symbolic Computation" empfohlen.

Die dritte Sprache, die ich auswählen würde, ist Haskell. Im Gegensatz zu Lisp verwendet Haskell ein statisches Typsystem, geht damit aber ganz anders um als beispielsweise C# oder Java.

Eine häufig anzutreffende Diskussion unter Entwicklern ist die Frage nach Sinn oder Unsinn eines statischen beziehungsweise dynamischen Typsystems. Häufig ist den Beteiligten jedoch gar nicht bewusst, dass ein statisches Typsystem auch eine andere Form haben kann als in den zuvor genannten Sprachen. Haskell kann in dieser Hinsicht durchaus als Referenz gelten, mit der sich andere statisch typisierte Sprachen vergleichen lassen müssen.

Hinzu kommt, dass es sich bei Haskell um eine rein funktionale Sprache handelt, die ohne imperative Sprachkonstrukte auskommt und funktionale Aspekte wie die Unveränderlichkeit von Datentypen erzwingt. Haskell-Code liest sich daher – genau wie Lisp-Code – zunächst äußerst ungewohnt.

Wie bei Lisp gilt aber auch hier, dass Haskell gerade dadurch, dass es grundlegend anders als die gängigen C-Sprachen ist, dazu zwingt, sich gedanklich auf neue Ideen einzulassen. Davon profitiert man spätestens bei der Rückkehr zur gewohnten Alltagssprache.

Die vielleicht am wenigsten ausgefallene Sprache in meiner Liste ist Go. Irgendwo habe ich einmal den Satz aufgeschnappt, dass Go das moderne C sei und dass C wie Go aussähe, wäre es im 21. Jahrhundert entwickelt worden. Das ist an vielen Stellen richtig.

Go ist näher an C als die zuvor genannten Sprachen, lässt sich auf ähnliche Art nutzen, bietet aber weitaus modernere Konstrukte an, beispielsweise für Nebenläufigkeit. Außerdem ist die Sprache im Vergleich zu C deutlich vereinfacht worden, was das Nachdenken über Code erleichtert. Aus meiner Sicht ist Go eine gute Basissprache für systemnahe Programme und Werkzeuge, die als statisch gelinkte, ausführbare Dateien für die jeweilige Zielplattform kompiliert werden müssen.

Gerade weil Go die am wenigsten ausgefallene Sprache in dieser Liste ist, gilt zugleich, dass man im Zweifelsfall auf Go am ehesten verzichten kann. Wer nur drei Sprachen lernen will oder kann, der kann am ehesten auf Go verzichten. Der Erkenntnisgewinn bei den drei zuvor genannten Sprachen dürfte weitaus höher ausfallen.

Auffällig ist, dass ich keine einzige objektorientierte Sprache im Stil von C# oder Java für meine Liste ausgewählt habe. Der Grund dafür ist, dass diese Sprachen ohnehin sehr verbreitet sind, sodass die meisten Entwickler mit deren Konzepten vertraut sein dürften. Daher ergibt es wenig Sinn, für einen Blick über den Tellerrand eine solche Sprache zu empfehlen.

Hinzu kommt, dass die funktionale Programmierung im Kontext der Parallelisierung von Code wieder an Zulauf gewinnt. Auch diesem Aspekt trage ich mit meiner Liste Rechnung, obgleich nicht alle der genannten Sprachen in diese Richtung gehen.

Ein wichtiger Aspekt soll zum Schluss aber noch genannt sein. Damian Wolf erwähnt ausdrücklich die Zielgruppe für seinen Artikel:

"Insbesondere für Anfänger mögen die Hinweise von Interesse sein. Die aufgeführten Sprachen können beim Start einer neuen Karriere oder bei der Neuorientierung helfen."

Das gilt in meinem Fall nicht. Ich würde keinem Einsteiger dazu raten, mit Assembler, Lisp oder Haskell zu beginnen. Nicht, weil diese Sprachen zu schwierig oder zu komplex wären. Im Gegenteil: Würden mehr Entwickler ihre ersten Schritte mit einer dieser Sprachen wagen, würde das dem Grundlagenwissen förderlich sein.

Der Grund dafür ist lediglich, dass es sehr schwierig wird, einen Job zu finden, wenn man ausschließlich eine dieser drei Sprachen beherrscht. Die Brücke zu Wolf versuche ich daher mit Go zu schlagen, was aus meiner Sicht eine durchaus geeignete Sprache für den Einstieg in die Programmierung ist.

Die übrigen Sprachen – Assembler, Lisp und Haskell – sehe ich dann eher als Ergänzung, wie eingangs erwähnt, als Blick über den Tellerrand.

tl;dr: Wer bei der Wahl einer Programmiersprache einen Blick über den Tellerrand wagen will und Erkenntnis anstrebt, der sollte eine Sprache abseits des Mainstreams wählen. Dazu eignen sich beispielsweise Assembler, Lisp, Haskell und Go. ()