Ziglang

Vergesst RUST!

Die Programmiersprache ZIG (auch als ZIGlang bekannt) wäre die einzige Sprache, die vielleicht mal C ersetzen könnte … weil sie C beinhaltet.


Seit meiner ersten Bekanntschaft mit RUST, stelle ich mir häufiger die Frage, welche Techniken eine Sprache besser oder schlechter für Betriebssysteme geeignet sind.

C++ stellt für mich nach wie vor ein Optimum dar, da es vollständig auf C aufsetzt. Dennoch stehen Exceptions und RTTI als genutzte Features in der STL dem Ziel OSDev leider sehr im Wege.

An RUST hingegen stört mich sehr, dass es C als Fremdkörper behandelt und den zentralen Fehler vieler Sprachen wiederholt: Es bildet kein stabiles ABI ab und integriert das C-ABI nicht direkt sondern nur über foreign-function-calls.

Und dann entdeckte ich ZIG`.

Als Sprache ist ZIG für mich “leider” ähnlich wie RUST zur Visual-Basic Syntax zurückgerutscht und liest sich neben C Code schwer, weil alles verkehrt deklariert wird. Eine C Funktion wie

1int32_t foo(int32_t x, int32_t y) {
2  return x + y;
3}

sieht in ZIG so aus:

1pub fn foo(x: i32, y: i32) i32 {
2  return x + y;
3}

Konkret fehlt eigentlich nur der -> Pfeil zwischen Funktionsparameter und Return-Type, um aus der ZIG-Funktion eine RUST-Funktion zu machen.

In Summe kann ZIG auch um einiges weniger als RUST, es unterstützt keine Klassen, keine Traits und keine Polymorphismen für Objekte.

Doch ZIG kann etwas, woran andere Sprachen scheitern:

Es integriert einen C Compiler, kann selbst als C-Compiler auftreten und C-Code zusammen mit dem eigenen ZIG-Format in einem Programm zusammenfassen.

Diese Eigenschaft hatte bisher nur C++, ab nun gibt es Konkurrenz.

Hochsprache ohne Exceptions

Fehlerbehandlung ist ein großes Thema und Exception sind häufig der Grund warum C++ im Embedded, OS und Hardwarebereich verworfen wird. (Dabei vergisst man leider, dass man C++ auch ohne Exceptions nutzen kann!).

ZIG bietet mit seinen integrierten Optionals und Error-Typen ein Feature auf unterster Sprachebene an, was C++ erst mit C++17 durch std::optional und std::variant nachliefert und dort leider nicht so elegant geschrieben werden kann.

Zusätzlich dürfen ZIG-Pointer nicht NULL werden, an diese Stellen treten leere Optionals oder Error-Types. Man kann dann auf den Inhalt des Pointers gar nicht zugreifen, wenn man ihn nicht prüft oder den Error-Type per try oder catch behandelt.
Der Compiler lässt daher unsicheren Code (ähnlich wie in RUST) erst gar nicht entstehen.

Comptime vs. Makros

ZIG unterstützt keine Makros (außer man kompiliert reinen C Code). Als Alternative erlaubt einem die Sprache aber jede Funktion, Variable oder jeden Parameter als comptime zu markieren.
Das bedeutet, dass das Element schon zur Übersetzungszeit bekannt sein muss und der Code teilweise oder vollständig vom Compiler ausgeführt wird, womit eine neue Form der dynamischen Code-Generierung entstehen kann.

Vergleichbar ist dieses Feature noch am ehesten mit C++ constexpr, welches mit jedem neuen Sprachstandard tiefer in die Sprache vordringt.

Durch comptime lassen sich Typen auswerten und Generics-Features entwerfen, wie auch ganze Datenstrukturen während des Kompilierens zusammengesetzt werden können.

Kurz gesagt: Voll geil!

Fazit

ZIG ist für mich Neuland, jedoch eine Gegend, die ich gerne betrete. Ich weiß nicht, wie lange es dauern wird, bis ich ausreichend darüber weiß, doch jetzt muss ein Schritt nach dem anderen gesetzt werden.

Fall es möglich ist, würde ich gerne ZIG als weitere Anbindung neben C++ in mein GATE Projekt aufnehmen.
… aber ob das so leicht umsetzbar sein wird, das steht noch in den Sternen.