Erstellung einer effizienten und portierbaren Programmiersprache mit Zig | Fastly

Eine Programmiersprache von Grund auf neu zu entwickeln, ist alles andere als einfach. Neben dem Erstellen eines Compilers, dem Definieren der Standardbibliothek und der Unterstützung von Tools wie Editoren und Build-Systemen muss man auch die Sprache selbst entwickeln und sich fragen, ob sie imperativ oder funktional sein soll. Für welche Systeme ist die Sprache gedacht? Soll sie über Metaprogrammier-Fähigkeiten verfügen? 

Bei Zig, die Teil unseres Open-Source- und Non-Profit-Programms ist, handelt es sich um eine universelle Programmiersprache und Toolchain, mit der sich Software in einem optimalen und wiederverwendbaren Zustand halten lässt. Sie ist einfach und dennoch robust und verfügt über portierbare SIMD-Kapazitäten. Das Entwicklerteam von Zig hat sich die Entscheidung nicht leicht gemacht, eine Sprache zu entwickeln, die explizit auf seine besonderen Anforderungen ausgerichtet ist. Um mehr darüber zu erfahren, was ursprünglich den Denkanstoß gab, haben wir uns mit Loris Cro, einem Mitglied des Zig Teams, unterhalten.  

Hannah Aubry: Wie kam es zur Entwicklung von Zig und wie sind Sie dazugestoßen?

Loris Cro: Ich erzähle immer gerne eine Anekdote, wie es dazu kam. Andrew Kelley (der „Vater“ von Zig) wurde in seinem eigentlichen Job darum gebeten, eine C++ Code-Base zu bereinigen, die in einem so desolaten Zustand war, dass sich dies nur durch eine ganz neue Sprache bewerkstelligen ließ. Na ja, selbst wenn er tatsächlich für eine große C++ Code-Base zuständig war, sah die Wahrheit natürlich anders aus. Der Hauptgrund, warum er mit der Entwicklung von Zig begann, war, dass er sich für Audioverarbeitung in Echtzeit interessierte. Nachdem er einige Jahre lang seine Nächte und Wochenenden dafür geopfert hatte, bekam er letztlich genug Spenden aus der Zig Community zusammen, um seine Stelle bei OkCupid an den Nagel zu hängen. 

Zur gleichen Zeit arbeitete ich als unterstützender Entwickler bei Redis Labs und begann mich für Zig zu interessieren, weil es für Redis Extensions eine vielversprechende Alternative zu C war. Kurzum: Ich trat der Zig Community bei und begann, mich zu Beginn der Pandemie aus Frust und Langeweile mit Zig SHOWTIME, einer experimentellen Herangehensweise an Online-Events für Entwickler, zu befassen. Kurz darauf gründete Andrew die Zig Software Foundation, eine 501(c)(3) Non-Profit-Gesellschaft, und ich wurde Vice President of Community.

Hannah Aubry: Was ist das Besondere an Zig?

Loris Cro: Zig hat einen ganz einfachen Zweck: Es soll (mindestens) so effizient und portierbar wie C sein und dabei alle seine Probleme bei der Nutzerfreundlichkeit und seine Einschränkungen umgehen, die den eigenen (und auch den angrenzenden) Ökosystemen von C seit jeher zu schaffen machen. Wir haben den Vorteil, dass wir auf jahrzehntelange Arbeit bei der Systemprogrammierung zurückblicken können. Als es nun darum ging, einige Probleme zu beheben, kamen Andrew einige unglaubliche Ideen wie die Codeausführung schon während der Kompilierung. Die wesentlichen Grundzüge von Zig hat er vor einiger Zeit bei einem Vortrag mit dem Titel "The Road to Zig 1.0" beschrieben.

Auch aus gesellschaftlicher Sicht ist Zig ein echtes Greenfield-Projekt. Zig gehört zu keinem großen Konzern. Als Non-Profit-Stiftung steht es auf eigenen Beinen, nicht zuletzt wegen einer ausgewogenen Mischung aus Unternehmens- und Privatspenden. Bei uns im Vorstand sitzen keine großen Tech-Unternehmen, was uns ehrlich gesagt auch lieber ist. Wohin die Reise letztlich geht, wird sich zeigen. Ich erinnere mich aber noch, wie beeindruckt ich von Comptime und von Andrews Führungsqualitäten war, wodurch der Erfolg von Zig letztendlich nur eine Frage der Zeit zu sein schien. 

Mittlerweile haben wir einige bekannte Namen mit im Boot, beispielsweise Frank Denis, ein Softwareentwickler aus Fastlys OCTO Team und Autor von Libsodium, der für die Zig Standardbibliothek eine komplette Suite von Kryptotools beigetragen hat. Ich bin davon überzeugt, dass wir alle dieselbe Vision teilen. 

Hannah Aubry: Wie ist es möglich, dass Zig Anwendungen schneller als C Code laufen und zugleich viel mehr Sicherheit bieten?

Loris Cro: Zig ist eine Sprache mit einem manuellen Speichermanagement, die im Gegensatz zu C ohne Runtime-Umgebung auskommt. In Sachen Performance sind Programme, die in Zig oder in C geschrieben werden, also in etwa vergleichbar. 

Der entscheidende Unterschied besteht darin, wie der Maschinencode genau generiert wird. Zig bietet dabei einige wesentliche Vorteile wie Comptime, das Zig generischen Code sowie die Möglichkeit bietet, Ergebnisse bereits während der Kompilierung vorauszuberechnen. Hier finden Sie eine genauere Erklärung, wie Sie mit Zig eine bessere Performance erzielen können. Müsste ich es aber in wenigen Worten zusammenfassen, würde ich sagen, dass das Schreiben von Code in Zig einfach bequemer ist als in C.

Aus Sicherheitsgründen besitzt Zig mehrere Build-Modi, über die optionale Laufzeitchecks für undefiniertes Verhalten (d. h. Bugs im Code, beispielsweise das Lesen über das Array Ende hinaus) möglich sind. Die Sicherheit in Zig ist aber nicht zuletzt auf eine ausdrucksstärkere Typisierung zurückzuführen, besonders bei Pointern. In C kommen viele Bugs (und deshalb auch Sicherheitslücken) von Fehlern mit Pointern, beispielsweise, dass die Prüfung eines Null-Pointers vergessen wurde, ein Leer-Pointer auf einen falschen Typ verweist, ein String oder ein Array nicht mit Null endet usw. Das alles sind Probleme, die in Zig durch die Typisierung bereits gelöst sind. Über die Sicherheitsvorteile von Zig ließe sich noch einiges sagen. Um es aber kurz zu machen: Sicherer Code lässt sich in Zig deutlich einfacher schreiben als in C.

Einfach nur zu sagen, dass Zig bequemer in der Anwendung ist, mag wenig überzeugend klingen. Wenn man aber bedenkt, dass die gesamte Entwickler-Community schließlich mit einem bestimmten Tool zurechtkommen muss, dann ist Bequemlichkeit ein wichtiger Faktor. Sie hat eine spürbare Auswirkung auf die Qualität jeder durchschnittlichen Bibliothek und ist der eigentliche Grund, warum Zig so hartnäckig auf Bequemlichkeit bedacht ist.

Hannah Aubry: Was bedeutet Portabilität im Zusammenhang mit Zig? Ich habe gelesen, dass man mit Zig eine Anwendung in Windows entwickeln und sofort auch eine Version für Mac, Linux und sogar für Compute@Edge – die (in WebAssembly entwickelte) Serverless-Compute-Umgebung von Fastly – erhalten kann, ohne auch nur eine einzige Codezeile zu ändern.

Loris Cro: Na klar! Zig funktioniert standardmäßig als Cross Compiler, sogar für C und C++ – eine elegante Lösung also, von der andere Programmiersprachen wie Go profitieren. So toll Cross Compiling auch ist, setzt es eine Menge Planung voraus, da man normalerweise Kompatibilität mit dem Zielbetriebssystem erreichen muss. Das Build-System von Zig und die Standardbibliothek sind so entwickelt, dass sie die gängigsten Plattformen abdecken. Sie bieten sogar einen „Bring-Your-Own-OS“-Mechanismus, mit dem man für Plattformen, die von Zig offiziell gar nicht unterstützt werden, die Wiederverwendung von Code aus der Standardbibliothek maximieren kann. 

Zig ist eine universelle Programmiersprache. Wenn man es also mit einer Turing-vollständigen Maschine zu tun hat, die ganz nach Von-Neumann-Architektur aussieht, sollte man mit Zig gut zurechtkommen. Gerade in letzter Zeit gab es viel Interesse an zwei derartigen (virtuellen) Maschinen: BPF und WebAssembly. Es versteht sich von selbst, dass wir beide unterstützen. Jakub Konka, der vor nicht allzu langer Zeit zum zentralen Zig Entwicklerteam gestoßen ist und sich massiv mit dem WebAssembly Ökosystem befasst, hat die Zig Standardbibliothek durch Unterstützung für WASI ergänzt (worüber er auch einen Vortrag gehalten hat).

Für Fastlys Compute@Edge sollten Sie einen Blick auf Zigly von Frank Denis werfen, das eine saubere Integration mit den für die Plattform spezifischen APIs bietet.

Hannah Aubry: Wie ist es möglich, dass Anwendungen bei Zig selbst mit begrenztem Speicher nie abstürzen?

Loris Cro: Alle dynamischen Speicherzuteilungen in Zig sind explizit. Es gibt keinen globalen oder impliziten Allokator wie Malloc in C, und jede Funktion, die dynamischen Speicher zuweisen will, muss einen Allokator beim Input akzeptieren. Die Vorteile dieser einfachen Vorgehensweise sind erstaunlich: Wenn man eine Plattform ansteuern will, wo es kein Heap-Konzept gibt oder wo die Allokation eine spezielle Semantik verwendet (wie es beispielsweise bei WebAssembly der Fall ist), muss man lediglich einen geeigneten Allokator weitergeben. Damit wird dann der gesamte Code kompiliert, einschließlich der Bibliotheken! Das bedeutet zugleich, dass Zig Bibliotheken bereitwillig kooperieren, wenn man ganz bestimmte Allokationsschemata wie Arenen braucht. 

Trifft man auf eine Out-of-Memory-Situation, wird dies von allen Bibliotheken so gemeldet, dass eine Wiederherstellung möglich ist (d. h. ohne in Panik zu verfallen). Wenn man in dieser Situation eine geeignete Strategie hat, kann die Anwendung wiederhergestellt werden und weiterhin gut funktionieren. Die Umsetzung ist nicht immer einfach, aber dank dieses expliziten Paradigmas kann man beispielsweise im Webserver einen allokationsfreien Pfad einarbeiten, der mit einem 503-Fehlercode reagiert, statt unter der Belastung zusammenzubrechen.

Hannah Aubry: Ist Zig auch für Leute interessant, die keine Systemprogrammierer sind?

Loris Cro: Gut möglich! Das hängt wohl davon ab, wie viel Kontrolle man über den eigenen Code haben will. Ich war schon daran interessiert, meine Programmierkenntnisse aufzubessern, aber in Anbetracht meiner Vorgeschichte schien es nie sonderlich sinnvoll, sich mit all der zufallsbedingten Komplexität von Build-Systemen, seltsamen C/C++ Footguns und Eigenarten älterer Systeme zu befassen. Für mich schien Zig der einfachste Weg, um ein vielseitiger Softwareentwickler zu werden, und für andere könnte das ähnlich aussehen.

Hannah Aubry: Ist Zig schwer zu erlernen? Wo findet man gute Ressourcen für den Einstieg in Zig? 

Loris Cro: Zig ist eine einfache Sprache, deren Grundzüge man innerhalb eines Wochenendes erlernen kann, sofern man sich mit einigen grundlegenden Konzepten der Systemprogrammierung (wie Pointern und den Unterschieden zwischen einem Stack und einem Heap) auskennt. Unser Projekt steht noch ziemlich am Anfang, weshalb wir leider noch keine lange Liste an Lernmaterialien vorweisen können. Meine Empfehlung wäre es daher, dem Kapitel „Getting Started“ auf der offiziellen Website zu folgen und dann zu Zig Learn zu wechseln, wo die meisten wichtigen Themen behandelt werden. Außerdem ist es empfehlenswert, einer bestehenden Zig Community beizutreten, um sich gegebenenfalls von anderen Zig Programmierern weiterhelfen zu lassen … Ach ja, und wenn man sich für Vorträge über Zig interessiert, sollte man sich unbedingt bei Zig SHOWTIME vorbeischauen!

Hannah Aubry
Senior Community Manager
Veröffentlicht am

Lesedauer: 7 Min.

Sie möchten sich mit einem Experten austauschen?
Sprechen Sie mit einem Experten
Diesen Beitrag teilen
Hannah Aubry
Senior Community Manager

Hannah Aubry ist eine Community Managerin, die sich auf Communities im Bereich der Open-Source-Entwicklung spezialisiert hat und auf die Entwicklung offener Systeme konzentriert, die eine positive Zusammenarbeit und ein freundliches Klima fördern. In ihrer Funktion betreut sie auch Fastlys Open-Source-Initiative Fast Forward und arbeitet ehrenamtlich als Hauptorganisatorin für CHIditarod, eine gemeinnützige Organisation, die sich für Hungerleidende in Chicago einsetzt. Die Frage, was sie als Vogel wäre, beantwortete sie mit „ein Rosalöffler“. Auf Mastodon finden Sie sie unter @haubles@fosstodon.org und auf Bluesky unter [@haub.les].(https://staging.bsky.app/profile/haubl.es).

Sie möchten loslegen?

Setzen Sie sich mit uns in Verbindung oder erstellen Sie einen Account.