Johannes Seitz

Voraussichtliche Lesedauer: 6 Minuten

Techblog

Fünf Dinge, die ich an Rust bemerkenswert finde

Wir leben wahrlich in einem goldenen Zeitalter der Programmiersprachen, denn gefühlt alle paar Wochen drängt sich eine neue Programmiersprache auf den Markt. Sie verspricht mit den Versäumnissen ihrer Vorgänger aufzuräumen oder eine innovative Idee umzusetzen, die alles für immer verändern wird.Als ich mein nächstes privates Nebenprojekt – ein Tool für Softwareentwickler – plante, fiel mir…

Techblog

Wir leben wahrlich in einem goldenen Zeitalter der Programmiersprachen, denn gefühlt alle paar Wochen drängt sich eine neue Programmiersprache auf den Markt. Sie verspricht mit den Versäumnissen ihrer Vorgänger aufzuräumen oder eine innovative Idee umzusetzen, die alles für immer verändern wird.

Als ich mein nächstes privates Nebenprojekt – ein Tool für Softwareentwickler – plante, fiel mir die Wahl der Programmiersprache deshalb wirklich nicht einfach. Warum habe ich mich also gerade für die von Mozilla Research entwickelte Programmiersprache “Rust” entschieden? “Rust” – das klingt erst mal alles andere als modern und sexy. Aber von dem Namen darf man sich nicht täuschen lassen.

Rust bezeichnet sich selbst als Programmiersprache zur Systemprogrammierung, ist aber als “General-Purpose”-Sprache für jeden Einsatzzweck denkbar. Oft wird Rust mit C und C++ verglichen, aber dieser Vergleich ist nicht wirklich angemessen. Denn obwohl Rust einen ähnlichen Grad an Kontrolle über die Hardware erlaubt wie C und C++, strotzt die Sprache nur so vor modernen Features und Abstraktionen, die leidige Aufgaben aus der Systemprogrammierung einfacher machen. 

Mir gefällt vor allem, wie Rust mit Memory Safety, Zero Cost Abstractions, Performance, Cross Platform Binaries und Interoperabilität umgeht: Fünf Dinge, die ich an Rust bemerkenswert finde: 

Memory Safety

Eine dieser leidigen Aufgaben ist das manuelle Memory-Management. Die Art, wie Rust mit Hauptspeicher (Memory) umgeht, erinnert auf den ersten Blick ein wenig an Automatic Reference Counting (ARC), wie es zum Beispiel bei Objective-C und Swift üblich ist. Bei genauerem Hinschauen fällt auf, dass der Ansatz noch wesentlich mächtiger, aber auch komplexer ist.

In Rust ist die Eigentumsbeziehung (ownership) und der Lebenszyklus (lifecycle) eines Objekts eine explizit zu definierende Programmeigenschaft. Was bedeutet das genau? Es läuft darauf hinaus: Wo andere Programmiersprachen dem Entwickler die Freiheit geben, Fehler zu machen – etwa Memory Leaks oder Race Conditions – kann das Typsystem von Rust diese Fehler mit Hilfe von Zusatzinformationen im Programm bereits zur Compile Time finden. Kann man den Compiler davon überzeugen, dass ein Programm korrekt ist (eine Arbeit die gerade am Anfang ziemlich frustrieren kann), ist das Programm auch garantiert ohne Buffer Overruns, ohne Memory Leaks und ohne “use after free”-Fehler.

Zero Cost Abstractions

“Na und?” denken sich jetzt bestimmt manche. Memory Management kann mein Java/C# Garbage Collector auch und der nervt mich nicht. Stimmt. Aber das geniale an Rust ist: Sämtliche dieser Garantien werden bereits zur Compile-Zeit forciert und kommen ohne zusätzlichen Aufwand zur Laufzeit. Damit ist Rust auch für Einsatzzwecke eine gute Wahl, in denen eine Garbage Collection unerwünscht ist (stark interaktive GUIs, Embedded- und Realtime Systeme).

Performance

Gerade durch den niedrigen Laufzeit-Overhead der beschriebenen Abstraktionen ist Rust verdammt schnell. Das ist gerade bei Programmen, die sehr, sehr oft ausgeführt werden, beispielsweise Tools für Softwareentwickler, ein bedeutender Unterschied. Eine Minute Laufzeit mehr bei einer langsameren Programmiersprache kann man vielleicht vernachlässigen, wenn sie nur einmal im Monat aufgerufen wird. Wird das Tool über 60 Mal am Tag aufgerufen, macht die Performance einen deutlichen Unterschied.

Cross Platform Binaries

Und wo wir gerade über Entwicklertools reden… Als Nutzer von Entwicklertools kennt man das folgende Problem: Jedes Tool bringt seine eigene Laufzeitumgebung mit, seine eigenen Libraries und oft auch seinen eigenen Package Manager. Wäre es nicht schöner, eine kleine Binärdatei für *nix und Windows zu haben? Wenn sie klein genug ist, könnte man sie vielleicht sogar in das SCM einchecken und das Setup der Entwicklungsumgebung deutlich erleichtern.

Mit Rust ist genau das möglich, ohne dabei auf die Bequemlichkeit einer modernen Programmiersprache zu verzichten. Der Cargo Package Manager macht es einfach, Libraries in das eigene Projekt einzubinden und in die generierte Binärdatei zu packen. Und das vor wenigen Tagen veröffentlichte Tool “Rustup” (http://blog.rust-lang.org/2016/05/13/rustup.html) macht die Cross-Kompilierung für beliebige Prozessorarchitekturen und Betriebssysteme erstaunlich einfach.

Interoperabilität

Früher oder später muss jede Programmiersprache mit einer C-API integrieren. Deshalb ist es verdammt praktisch, dass Rust und Cargo mit wenig Aufwand C-kompatible Libraries erzeugen können. Diese lassen sich nicht nur verwenden, um zum Beispiel performance-kritischen Code in ein Java-Projekt zu integrieren, sondern auch um Cross-Platform-Mobile-Applikationen zu schreiben (einen ähnlichen Ansatz hat Skyscanner übrigens mit C++ gewählt: http://www.skyscanner.net/blogs/developing-mobile-cross-platform-library-part-1-exploring).

Fazit

Bisher bin ich mit meiner Wahl sehr zufrieden und begeistert von der Qualität der Sprache, der Libraries und der Dokumentation. Außerdem bildet sich um die junge Sprache eine lebendige und freundliche Community. Rust schafft den Brückenschlag zwischen der bequemen Welt moderner funktionaler Programmierung (Immutable Objects, Pattern Matching, …) und der Mächtigkeit, Kontrolle und Performance von klassischer Systemprogrammierung.

Die eigentliche Innovation von Rust sehe ich darin, dass es implizite Konzepte wie “ownership” und “lifecycle” von Objekten explizit macht und damit das Auftreten von Race Conditions bereits zur Compile-Zeit verhindert. In diesem Punkt ist der Compiler anderen Sprachen um eine Generation voraus.

Leider sind die Entwicklertools noch weit von dem Funktionsumfang entfernt, den man von modernen Java- oder C/C++ IDEs gewohnt ist. Auch ist die Lernkurve vor allem wegen dem neuartigen Memory Management recht steil und manchmal frustrierend.

Wer Interesse bekommen hat, tiefer in die Sprache einzusteigen, findet das offizielle Buch zu Rust hier: https://doc.rust-lang.org/book/.


Über den Autor

Johannes Seitz