Die Programmiersprache Crystal
Ein interessantes Nischenprodukt.
Vorab: Es geht mir enorm auf den Keks, wenn ständig irgendwer irgendwelche Phantasieprogrammiersprachen erfindet und ständig neue Programmiersprachen aus dem Boden schießen. ich halte das für eine Katastrophe, weil viel zu viel Aufwand getrieben und Arbeitsleistung vergeudet wird – wichtige Bibliotheken muss man mehrfach schreiben und pflegen – und deshalb die einzelnen Sprachen dann auch zu wenig Wartung abbekommen, zu schlecht gepflegt werden. Außerdem blickt da auch keine Sau mehr durch, findet man kein Personal mehr, wenn jeder in diesem Sprachbabylon eine andere Sprache spricht. Ich weiß von einem Fall, in dem ein firmeninternes Security-Team, das eigentlich den produzierten Code überprüfen sollte, bevor die Software produktiv geht, die Waffen gestreckt und kapituliert hat, weil jedes Programmierteam nach Lust und Laune eine andere Modesprache einsetzte, die man dann irgendwie – soweit sie auf der Java-Plattform basierten – zusammengeflickt hat oder – man verwendet ja heute Micro-Services – als getrennte Dienste laufen ließ. Das Security-Team gab auf, weil sie einfach gar nicht die Kapazitäten und die Sachkunde hatten, Quelltexte in einer ständig wachsenden Zahl von verschiedenen Sprachen zu prüfen.
Und es gibt ja schon seit Jahrzehnten die Informatiker-Erkenntnis, dass immer dann, wenn sich einer darüber aufregt, dass es viel zu viele Sprachen gibt, die auch noch alle Mängel haben, einer daherkommt, meint, die Supersprache entwickeln zu müssen – und zu können – die geeignet und erkoren ist, die bisherigen Sprachen zu ersetzen, und das Ergebnis dann einfach nur ist, dass der Misthaufen gewachsen ist, weil man nun n+1 Sprachen hat.
Eigentlich also sollte man keine neuen Sprachen bewerben, sondern nur das Absterben von Sprachen bejubeln. Der Sprachendschungel ist viel zu groß.
Allerdings hatte ich erwähnt, dass ich bisher gerne in Ruby programmiert habe, weil eine sehr elegante, ausdrucksstark-prägnante Sprache ist, in der man sich sehr kurz ausdrücken kann und kaum „Boilerplate-Code“ braucht, und die nicht nur trotzdem, sondern gerade deshalb leicht lesbar ist. Ich hatte mal einen Verriss der Sprache Scala geschrieben, unter anderem weil Scala als „funktionale Sprache“ entworfen ist, aber das eigentlich nicht funktional konzipierte Ruby aufgrund seiner eleganten und logischen Struktur und exzellenten Lambda-Ausdrücke viel besser, kürzer, eleganter in funktionaler Programmierung ist als Scala, und die quasi so als Sprachselbstverständlichkeit hat, ohne groß Aufhebens darum zu machen, und Ruby von diesem Konzept weit mehr profitiert, als das explizit auf funktional getrimmte Scala.
Diese Woche hat mich ein Leser auf die Sprache Crystal hingewiesen. Die ich seltsamerweise noch gar nicht kannte, obwohl es sie seit 10 Jahren gibt und obwohl sie ziemlich genau das ist, was ich gesucht habe. Was aber wohl daran lag, dass man sie viele Jahre still entwickelt hat und sie erst seit kurzer Zeit Einsatzreife hat.
Crystal ist nämlich so etwas wie ein Ruby-Compiler mit Sprachverbesserungen wie der Möglichkeit einer Typbindung von Parametern und Optimierungen und Prüfungen zur Übersetzungszeit statt erst zur Laufzeit. Es entspricht nicht exakt Ruby, ein paar Compiler-bedingte Unterschiede gibt es schon (die ich noch nicht alle überblicke), aber genau das behebt die wesentlichen Probleme, die ich an Ruby sehe.
Es gibt noch nicht so viele Bibliotheken, und sicherlich hat die Sprache auch noch einige Entwicklung und Verbesserung vor sich, aber gerade weil es keine neue Sprache ist, sondern sich eng an Ruby orientiert, daraus aber ein kompiliertes – und erheblich schnelleres – Programm macht, ist jedenfalls für Ruby-Leute eine sehr interessante Neuerung. C und C++ würde ich wegen der Sicherheitsprobleme nicht mehr verwenden (und bei C++, was vor 25 Jahren meine absolute Lieblingssprache war, blicke ich auch nicht mehr durch, was denn der aktuelle Sprachstandard ist und was denn jetzt eigentlich die Laufzeitbibliothek und wo sie dokumentiert ist, das hat man in vielen Schritten verschlimmbessert), während die heute bevorzugte Sprachen Go und Rust sind, beide auch deutlich sicherer und gegen eine Reihe typischer Programmierfehler resistent, aber beide kein objektorientiertes Konzept im eigentlichen Sinne haben, und man das durch Interfaces bzw. Traits ersetzt hat (zu Assembler- und frühen C-Zeiten nannte man es profan, aber treffend „Sprungtabellen“). Auch eine sehr interessante Sache, mit der man wirklich gut Ordnung in die Software bekommt und gut abstrahieren kann, aber ein vollwertiger Ersatz für Objektorientierung ist sie nicht – und umgekehrt auch nicht. Es sind zwar ähnliche, aber eben nicht gleiche Dinge.
Ich muss mir das jetzt auch erste einmal ansehen und testen, und würde das jetzt auch nicht für sehr große Projekte nehmen.
Aber:
Es hat enorme Vorteile.
Rube hat zwar ein exzellentes System, um Bibliotheken und Abhängigkeiten zu verwalten (die „Gems“, Gemfile, Gemfile.lock) und kann auch von jeder Bibliothek mehrere Versionen gleichzeitig halten. Trotzdem ist das nicht immer unproblematisch, weil manche Gems Code enthalten, der in C oder C++ geschrieben ist und compiliert werden muss, und dann braucht man auf dem Zielsystem wieder den Compiler, includes, und so weiter, was das alles aufbläht. Ruby ist sehr gut, solange man damit auf seinem Arbeitsplatz bleibt, auf dem man sowieso alles Gerümpel installiert hat, aber wenn man den Code auf ein Zielsystem installieren will („deploy“, „ausrollen“), oder auch nur in einem Docker-Container packen will, kann das zu unerwünschtem Overhead führen, wenn man noch C++-compiler usw. installieren muss, und viele C-/C++-Bibliotheken benötigt werden. Und das hat man hier nicht oder deutlich weniger, weil ziemlich viel einkompiliert wird, und nur ganz wenige dynamische Bibliotheken dynamisch dazugebunden werden. Weil aber manche Crystal-Bibliotheken („shards“) ihrerseits Anbindungen an C-Bibliotheken sind, könnte das im Einzelfall auch mehrere werden, aber das macht das alles deutlich einfacher, wenn man das Programm auf anderen Rechnern installieren will.
Ruby-Programme in Go oder Rust umzuschreiben, bedeutet erheblichen Aufwand und oft erhebliche Änderungen an der Programmstruktur, weil die typische Struktur von Ruby-Programmen mit den vielen Lambda-Ausdrücken nicht ohne weiteres abzubilden ist. Für Crystal braucht man kaum Änderungen.
Es ist jetzt sicherlich nicht die Brüllersprache für alle Zwecke und Projekte. Aber sie bringt Syntax und weitgehend auch die Eleganz von Ruby in eine Compilersprache.