2 Punkte von GN⁺ 2024-07-16 | 1 Kommentare | Auf WhatsApp teilen
  • Auf dem LSFMM+BPF Summit 2024 wurde diskutiert, wie sich Rust auf Linux-Dateisysteme anwenden lässt; im Mittelpunkt stand der zweite RFC-Patch nach dem RFC vom Dezember 2023
  • Die Rust-for-Linux-Seite will Anforderungen der Dateisystem-API im Rust-Typsystem abbilden, um Fehler zur Compile-Zeit zu erkennen, Ressourcenbereinigung zu automatisieren und speicherbezogene Schwachstellen zu verringern
  • Das Beispiel iget_locked() zeigt die Richtung: Prüfungen auf null, die Unterscheidung des inode-Status und die Fehlerbehandlung, die C-Aufrufer bisher selbst erledigen mussten, sollen durch get_or_create_inode() in Rust per Typen und automatischer Bereinigung erzwungen werden
  • Dave Chinner, Christian Brauner, James Bottomley, Ted Ts'o und andere äußerten Bedenken zu abweichenden Namen zwischen C- und Rust-APIs, API-Synchronisierung, Unterschieden bei Objektlebenszyklen und dem Wartungsaufwand mit Blick auf mehr als 50 Dateisysteme
  • Im Kern geht es weniger um die Vorteile der Rust-Abstraktion selbst als um die Frage, wer den Aufwand trägt, Rust-Bindings und Abstraktionen an laufende Änderungen im C-Code anzupassen

Die Rust-Session zu Dateisystemen auf dem LSFMM+BPF

  • Auf dem Linux Storage, Filesystem, Memory Management, and BPF Summit 2024 behandelten Wedson Almeida Filho und Kent Overstreet den Einsatz von Rust in Linux-Dateisystemen
  • Almeida hatte im Dezember 2023 ein RFC-Patchset für Rust-Abstraktionen für Dateisysteme eingereicht; rund um diesen Ansatz gab es unterschiedliche Auffassungen
  • Am Tag der Session Mitte Mai stellte Almeida die zweite Version des RFC-Patches ein, um sie zusammen mit anderen Rust-bezogenen Themen zu diskutieren

Ziele der Dateisystem-Abstraktionen in Rust-for-Linux

  • Die vorgeschlagenen Dateisystem-Abstraktionen spiegeln die Stoßrichtung des Rust-for-Linux project wider
  • Im Kern geht es darum, mehr Anforderungen der Dateisystem-API im Rust-Typsystem auszudrücken, damit Fehler bereits zur Compile-Zeit erkannt werden
  • Auch Aufgaben, die sich in C nur schwer elegant bereitstellen lassen, sollen automatisiert werden
    • Beispiel: Ressourcenbereinigung
  • Ziel ist es, die Entwicklung von Dateisystemen produktiver zu machen, Zeit beim Debuggen von Problemen zu sparen, die der Compiler finden kann, und speicherbezogene Schwachstellen zu reduzieren
  • Overstreet sagte, er habe in bcachefs zu viele zweiwöchige Bugjagden erlebt, und hält Rust für leistungsfähiger als C
    • Rust beseitigt undefiniertes Verhalten
    • Rust bietet Möglichkeiten, sichtbar zu machen, was im Code tatsächlich geschieht
    • Wenn sich die Korrektheit von Rust-Code nachweisen lasse, würden deutlich weniger Bugs die Entwicklung neuer Funktionen blockieren

Das Typsystem-Beispiel rund um iget_locked()

  • Almeida führte in seinen Folien das aktuelle Kernel-[iget_locked()](https://elixir.bootlin.com/linux/v6.9.5/source/fs/inode.c#L1248) als Beispiel für komplexe Anforderungen an
  • C-Aufrufer müssen mehrere Bedingungen selbst behandeln
    • Sie müssen prüfen, ob der Rückgabewert null ist
    • Sie müssen feststellen, ob das zurückgegebene struct inode ein neues oder ein bestehendes inode ist
    • Falls es ein neues inode ist, muss es vor der Verwendung initialisiert werden
    • Falls die Initialisierung fehlschlägt, muss iget_failed() aufgerufen werden
  • Al Viro widersprach einem Teil von Almeidas Darstellung der Anforderungen an Aufrufer von iget_locked(), und die Diskussion über das genaue Verhalten setzte sich fort
  • Overstreet meinte, dass der Compiler die korrekte Behandlung erzwingen könne, wenn man solche Regeln in Rust-Typen und -Abstraktionen kapselt
  • Die von Almeida gezeigte Rust-Entsprechung hieß get_or_create_inode()
    • Wie in C muss weiterhin auf Fehler geprüft werden
    • Bei Erfolg erhält der Aufrufer entweder ein inode mit normaler Referenzzählung oder ein neues inode
    • Bei einem normalen inode wird die Referenzzählung automatisch verringert, wenn das Objekt nicht mehr referenziert wird
    • Bei einem neuen inode wird automatisch eine Behandlung entsprechend iget_failed() aufgerufen, wenn es nicht initialisiert wird
    • Sobald ein neues inode einmal initialisiert wurde, wird es zu einem normalen inode, und die automatische Verringerung der Referenzzählung greift danach
    • Dieses Verhalten wird durch das Typsystem erzwungen
  • Viro stellte infrage, wo diese Einschränkungen im realen Quellcode überhaupt definiert würden
  • Almeida antwortete, er wolle die Einschränkungen aus Gesprächen mit Viro und anderen Dateisystementwicklern herausarbeiten und dann Typen und Abstraktionen bauen, die sie erzwingen

Der Bruch zwischen C-API und Rust-API

  • Dave Chinner meinte, dass Entwickler bei unterschiedlichen Namen in C-API und Rust-API aus vorhandenem C-Code nur schwer auf den entsprechenden Rust-Aufruf schließen könnten
  • Es wurde auch die Sorge geäußert, dass bei anderen Namen eine API entstünde, die der bestehenden Entwicklergemeinschaft völlig fremd vorkommt
  • Wenn sich C-Code ändert, muss Rust-Code nachziehen; offen bleibt damit, wer diese Arbeit übernimmt
  • Almeida räumte ein, dass dies diskutiert werden müsse
    • Er sei nicht gegen Umbenennungen
    • Er halte iget_locked() allerdings nicht für einen guten Namen und sehe darin auch eine Chance auf bessere Bezeichnungen
  • Viro meinte, iget_locked() sei ein schlechtes Beispiel, weil es keine Member-Funktion eines superblock-Objekts, sondern eine Bibliotheksfunktion sei
  • Almeida entgegnete, get_or_create_inode() könne ebenfalls zu einer Bibliotheksfunktion gemacht werden; das Beispiel solle zeigen, wie sich Einschränkungen in Typen kodieren lassen

Wahl zwischen allgemeiner Abstraktion und Fokus auf einfachere Dateisysteme

  • Christian Brauner meinte, man müsse zuerst entscheiden, ob die Rust-Abstraktionen eine allgemeine Abstraktion für alle Kernel-Dateisysteme sein sollen oder eher auf die für einfachere, in Rust geschriebene Dateisysteme nötigen Funktionen zielen
  • Langfristig könne es problematisch werden, wenn eine Funktion wie get_or_create_inode() sehr viel mehr Einschränkungen enthält als iget_locked()
  • C-Code könne sich insbesondere anfangs schneller entwickeln als Rust-Code, sodass beide APIs fortlaufend synchronisiert werden müssten
  • Overstreet sagte, entscheidend sei, ob man mit den Rust-Abstraktionen zugleich Refactoring und Aufräumarbeiten angehen wolle; aus seiner Sicht sei das nötig
  • James Bottomley meinte, dass Objektlebenszyklen in der Rust-API kodiert seien, während es in C keine entsprechende Darstellung gebe
    • Wenn sich der Objektlebenszyklus auf einer Seite ändere, könnten auf der anderen Seite Bugs entstehen
  • Chinner sagte, der Lebenszyklus von inode-Objekten unterscheide sich teils je nach Dateisystem
    • Wenn die API ein einheitliches Lebenszyklusmodell voraussetzt, könnten diese Funktionen in manchen Dateisystemen nicht funktionieren
  • Almeida antwortete, das Beispiel sei nur für Dateisysteme gedacht, die derzeit iget_locked() aufrufen und davon profitieren würden
    • Rust-Entwickler wollten Dateisysteme nicht dazu zwingen, ihre heutige Arbeitsweise zu ändern

„Wer trägt den Schmerz?“

  • Ted Ts'o sagte, es wirke, als wolle man alle zu der „Religion“ Rust bekehren, doch Linux habe mehr als 50 Dateisysteme, und eine sofortige Umstellung werde es nicht geben
  • Der C-Code werde weiter verbessert; wenn diese Änderungen Rust-Bindings brechen, könnten auch Dateisysteme brechen, die von diesen Bindings abhängen
  • Ts'o sieht Rust-Bindings auf absehbare Zeit als Bürger zweiter Klasse; kaputte Rust-Bindings seien nicht das Problem der gesamten Dateisystem-Community, sondern der Rust-for-Linux-Entwickler
  • Er meinte, innerhalb von ein bis zwei Jahren werde sich zeigen, ob es gut oder schlecht ist, gleichzeitig Rust-Bindings zu entwickeln, C-Code weiterzuentwickeln und dabei große Mengen an Semantik ins Typsystem zu verlagern
  • Für Ts'o läuft eine große Veränderung letztlich auf die Verteilung des Schmerzes hinaus
    • Ein Entwickler, der die C-API ändert, kann sagen, dass er den betroffenen C-Code zwar repariert, aber die Rust-Bindings nicht, weil er kein Rust kann
  • Almeida entgegnete, es gehe nicht darum, die C-API einzufrieren, sondern darum, dass Dateisystementwickler die Bedeutung der API erklären, damit sie in Rust kodiert werden kann
  • Bottomley meinte, je mehr Semantik in Bindings kodiert werde, desto anfälliger könnten sie unter Synchronisierungsaspekten werden
  • Almeida antwortete, dass bei API-Änderungen wie bei anderen Nutzern eben auch die API-Nutzer aktualisiert werden müssten

Methoden, Funktionen und Typen: Was wohin gehört

  • Viro kritisierte erneut, dass der Ersatz für iget_locked() auf Methoden setzt
    • Bei Methoden würden Argumente seiner Ansicht nach nicht explizit angegeben
  • Overstreet sagte, die Abneigung gegen Methoden stamme aus Sprachen wie C++, die sich zu stark auf Vererbung stützten
    • Rust tue das nicht, und Methoden in Rust seien größtenteils ein syntaktisches Element
  • Jan Kara unterschied zwischen Verhalten, das dem inode selbst folgt, und Verhalten, das der Funktion iget_locked() inhärent ist
    • Mit dem inode verbunden sind etwa Referenzzählung und deren Behandlung
    • In der Funktion iget_locked() steckt zusätzlich eigenes Verhalten
  • Overstreet und Almeida antworteten, dass beide Teile zwar in Typen kodiert, aber getrennt seien; andere Funktionen, die den inode-Typ verwenden, könnten Rückgabewerte mit anderen Eigenschaften haben
  • Viro erklärte, warum inode im VFS derzeit so funktioniert, und stimmte zu, klein anzufangen und dann die weitere Richtung zu prüfen
  • Overstreet sagte, dieses Beispiel sei womöglich zu komplex und daher kein guter Ausgangspunkt gewesen; Viro antwortete „Nein, war es nicht“, womit die Session endete

1 Kommentare

 
GN⁺ 2024-07-16
Hacker-News-Kommentare
  • Ich verstehe nicht, dass jedes Dateisystem zwar einen eigenen inode-Lebenszyklus haben soll, aber dieselben Funktionen zur Verwaltung des Lebenszyklus verwendet werden und sich nur die Semantik unterscheidet.
    Wenn dieselbe Funktion je nach Implementierungsdetails unterschiedlich verwendet werden muss, klingt das eher nach dem Gegenteil einer Abstraktionsschicht.
    Wenn der inode-Lebenszyklus dateisystemspezifisch ist, sollte er mit dateisystemspezifischen Funktionen verwaltet werden.

    • Ich hatte dieselbe Frage, und es sieht so aus, als wolle man für die Rust-Arbeit alle C-APIs verstehen oder dokumentieren.
      Wenn man solche Informationen zusammenträgt, können Stellen sichtbar werden, die sich so refaktorisieren lassen, dass solche Fragen gar nicht erst aufkommen; das ist eine gute Sache.
    • Falls das Material neu für dich ist, kann https://www.kernel.org/doc/html/latest/filesystems/vfs.html hilfreich sein.
      Es ist ein Überblick über die VFS-Schicht, die dateisystemspezifisches Verhalten behandelt und zugleich eine konsistente Schnittstelle zur Kernel-Seite aufrechterhält.
    • Ich verstehe es so, dass alles, was sich allgemein abbilden lässt, in der VFS-Schicht so weit wie möglich abstrahiert wird, während nicht passende Ausnahmen in der dateisystemspezifischen Schicht behandelt werden.
      Der inode-Lebenszyklus war möglicherweise nur ein erstes Beispiel, um die Diskussion anzustoßen.
    • Offenbar soll es so funktionieren, dass der Compiler die inode-Lebensdauer nachverfolgt.
      Der Compiler hilft bei temporären Referenzen, aber das Dateisystem muss die Link-Anzahl weiterhin auf der Festplatte speichern.
    • Es gibt mehrere Funktionen, mit denen man einen inode erstellen und in den Cache legen kann; iget_locked(), auf das hier der Fokus liegt, ist dabei ein bestimmtes Muster.
      Nicht alle Dateisysteme verwenden diesen Ansatz, und je nach Situation wird er auch nicht genutzt.
      FAT zum Beispiel verwendet ihn nicht, weil es inode-Nummern erzeugt und ein eigenes Mapping von FAT-Positionen auf inodes pflegt.
      Es gibt auch Dateisysteme wie proc, die inode-Objekte nicht cachen.
      Da der Zustandsfluss des inode-Objekts selbst unabhängig von seiner Herkunft gleich zu sein scheint, ändert sich aus Sicht der Consumer die Verwendung von inode nicht.
      Was sich unterscheidet, ist die Art, wie die Dateisystemschicht inode-Objekte erstellt und intern behandelt.
  • Ich frage mich, ob hier nicht die falsche Frage gestellt wird.
    Muss Rust wirklich so geändert werden, dass es C einfacher aufrufen kann?
    Ich habe ein wenig Rust ausprobiert, aber aus Sicht eines Hobbyentwicklers ist mir noch nicht klar, wie man mit C interoperieren soll.
    In C++ oder Objective-C hingegen bindet man den richtigen Header ein und ruft die Funktion auf.
    Swift kann Objective-C-Dateien einbinden, und von dort aus kann man C aufrufen.
    In diesem Fall frage ich mich, ob nicht eher die Sprache Rust etwas flexibler werden sollte, statt zu erwarten, dass sich Kernel-Entwickler an die Sprache anpassen.

    • C aus Rust aufzurufen ist ziemlich einfach.
      Man deklariert eine externe Funktion und ruft sie auf.
      Zum Beispiel kann man sie, wie im Rust-Buch unter https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#usin... gezeigt, mit extern "C" deklarieren.
      Wenn man bei komplexen Bibliotheken nicht alle Deklarationen von Hand schreiben möchte, kann man ein Tool wie bindgen verwenden, das aus C-Header-Dateien automatisch extern-Deklarationen erzeugt: https://github.com/rust-lang/rust-bindgen
      Man kann argumentieren, dass etwas wie bindgen in Rust enthalten sein sollte, damit man es ohne Drittanbieter-Abhängigkeit oder build.rs-Konfiguration nutzen kann, aber das ist nicht der Kern dieses Artikels.
      Das Problem sind nicht Low-Level-Bindings, sondern Rust-typische High-Level-Wrapper; und es kann kein allgemeines Tool geben, das solche Wrapper automatisch aus beliebigem C-Code erzeugt.
    • Das ist weder eine wichtige Schwierigkeit in Rust noch hat es mit dem Thema des Artikels zu tun.
      Der Artikel sucht nach Wegen, Kernel-Dateisystemtreiber und Ähnliches tatsächlich in Rust zu implementieren.
      Wichtig ist auch, dass Rust-Code im Kernel zwangsläufig C-Interfaces konsumiert.
      Für den Anwendungsfall, an den du denkst, passt bindgen ziemlich gut: https://github.com/rust-lang/rust-bindgen
    • In der Praxis ist es ziemlich einfach.
      Um aus Rust aufzurufen, deklariert man extern "C" fn foo() -> T und übergibt die Linker-Flags per #[link]-Attribut oder über build.rs.
      Mit der Crate bindgen kann man Bindings vorab generieren oder sie in build.rs erzeugen und per include!() einbinden.
      Üblicherweise erstellt man eine -sys-Crate, die nur die generierten Bindings enthält, und der eigentliche Code verwendet die Bindings dieser sys-Crate ganz normal mit use.
      Auch in C++ und Objective-C muss man nicht nur den richtigen Header einbinden, sondern auch gegen die Bibliothek linken.
    • Der Kernpunkt ist, dass Rust Invarianten modellieren kann, die sich in C nicht ausdrücken lassen.
      Aufrufe in beide Richtungen sind möglich, aber wenn C nicht ausdrücken kann, was Rust ausdrücken kann, hat das erhebliche Auswirkungen auf das Design einer API, die beide Seiten gemeinsam verwenden müssen.
    • C-Aufrufe sind bereits sehr einfach, daher muss Rust dafür nicht einfacher werden.
      Man deklariert eine C-Funktion mit extern "C" und ruft sie auf.
      Meist braucht man unsafe und muss Referenzen in Raw Pointer umwandeln oder casten, aber die Syntax selbst ist einfach.
      Es gibt auch Tools, die C-Header-Dateien scannen und daraus Deklarationen erzeugen; bindgen ist das am häufigsten verwendete.
      Der Streitpunkt in diesem Artikel ist weniger die Sprache selbst als vielmehr die Frage, wie man Rust verwendet.
      Die Rust-for-Linux-Entwickler möchten mit Rusts Features und Typsystem die Semantik von API-Aufrufen kodieren, um sie sicherer und weniger fehleranfällig zu machen.
      Die C-Seite fürchtet, dass es dadurch schwieriger werden könnte, Verhalten und Semantik der C-API weiterzuentwickeln.
      Wenn sich die C-API ändert, muss auch die Rust-API angepasst werden, und diese Arbeit möchte man nicht übernehmen.
      Eine leichter akzeptierbare Alternative wäre, Rust-Features und das Typsystem weniger stark zu nutzen, um Semantik in der Rust-API zu kodieren.
      Dann wäre die Aktualisierung der Rust-API bei Änderungen an der C-API mechanisch und einfach, aber wenn Rust-for-Linux Rusts Fähigkeiten nicht nutzen kann, um bessere und sicherere APIs zu bauen, stellt sich die Frage, welchen Sinn diese Arbeit überhaupt hat.
      Es ist allerdings etwas merkwürdig, sich zu diesem Thema so definitiv zu äußern, während man zugleich einräumt, die Sprache nicht ausreichend zu verstehen.
  • Da ich Linux-Dateisysteme nicht gut kenne, war mir nicht klar, ob diese Rust-API die C-API umhüllt oder sie neu implementiert.
    Wenn es eine Neuimplementierung oder eine separate API ist, dürfte es mit der Zeit nur noch mehr Verwirrung stiften, die Namen der C-API unverändert beizubehalten.
    Auch wenn es anfangs vertrauten Entwicklern hilft, schneller hineinzufinden, sehe ich das so.

    • Almeida hat gezeigt, was in Rust iget_locked() entspricht, und der Name war get_or_create_inode().
      Die Antwort scheint zu sein: Es ist eine Neuimplementierung, und man verwendet offenbar nicht dieselben Namen.
  • Wenn man bedenkt, wie solche Diskussionen normalerweise verlaufen und wie groß die Änderung ist, ist diese Diskussion überraschend höflich.
    Ich teile die negative Stimmung in diesem Thread nicht.
    Ich bin ziemlich optimistisch, weil die Beteiligten die zentralen Schmerzpunkte klar und ohne Unsinn vermittelt haben.

    • Mehr noch als wegen des Inhalts habe ich wegen der hervorragenden Aufbereitung der Aufzeichnungen weitergelesen.
      Die eigentliche Diskussion dürfte, wie es sich für eine Programmiersprachen-Debatte unter eigenwilligen Leuten mit starken Meinungen gehört, hitzig, sprunghaft und voller Haarspalterei gewesen sein.
      Jake Edge, der diese Zusammenfassung geschrieben hat, scheint sehr gut darin zu sein, solche Teile herauszufiltern und nur den Kern festzuhalten.
  • Einige Kommentare unten auf der lwn.net-Seite sind ziemlich unhöflich.
    Man stelle sich nur vor, man bekäme bei einem Open-Source-Projekt, zu dem man beiträgt, einen Kommentar wie Science advances one funeral at a time.

  • Mehr Auswahl im Linux-Kernel ist immer von Vorteil
    Aber Rust ist möglicherweise nicht die Antwort auf alles
    Rust tut sein Bestes, um ein sicheres Programmiermodell zu garantieren, aber auch dieses Modell hat Grenzen
    Es mag so wirken, als solle man bei Speicherproblemen Rust verwenden und bei Nebenläufigkeitsproblemen auf Rust umstellen, aber ohne unsafe-Blöcke kann man nicht alles tun, was C tut
    Rust kann auf solche Probleme eine neue Perspektive eröffnen, ist aber keine vollständige Lösung

    • Der große Vorteil von Rust bei dieser Arbeit ist, dass es solche Sicherheitsprobleme aktiv in Typen kapselt, und genau darum geht es auch in diesem Artikel
      C, insbesondere das im Kernel verwendete C, schiebt jedem Einzelnen die Verantwortung zu, alle impliziten Regeln vollständig zu kennen
      Das skaliert nicht
      Kernel-Entwickler, die dieselben Datenstrukturen verwenden, konnten sich nicht einmal in einem Raum vollständig auf diese Regeln einigen
      Rust ist stark darin, die Regeln, die man kennen muss, sichtbar zu machen und, wenn jemand anderes die Einhaltung der Regeln garantieren kann, daraus nicht mehr mein Problem zu machen
      Manchmal kann das Ergebnis weniger optimal sein, aber auch im Linux-Kernel sind weniger optimale Defaults oft richtig; und wer für bessere Performance noch sechs seltsame Regeln lernen kann, dem kann man den unsafe-Ausweg anbieten
    • unsafe-Blöcke kann man verwenden
      Man sollte sie nur dann verwenden, wenn sie nötig sind
      Ein unsafe-Block mit sehr eng begrenztem Wirkungsbereich lässt nicht alle Garantien verschwinden, die man im restlichen Code erhält
    • Es stimmt, dass Low-Level-Arbeiten unsafe-Code erfordern
      Aber daraus zu schließen, Rust sei ungeeignet, weil man unsafe verwenden muss, ist ein Missverständnis
      Die Unterscheidung zwischen sicher und unsicher in Rust soll klar markieren, welche Teile des Codes unsicher sind, damit man das Audit auf kleine Bereiche konzentrieren und darauf vertrauen kann, dass der Rest funktioniert, wenn diese Teile korrekt sind
    • Ich frage mich, wie viel davon tatsächlich zu 100 % eindeutig notwendig ist
      Gibt es im Dateisystem-Code gute Gründe, warum etwas zwingend unsafe sein muss?
      Vermutlich ist es nur eine sehr kleine Teilmenge, die an ein paar Stellen nötig ist
    • Ich mag Rust, weil das Verständnis manchmal sehr gut zusammenpasst, aber im Async-Bereich fühlt es sich für mich noch ziemlich rau an
      Es ist nicht intuitiv, was intern passiert
  • Wenn man die Sitzungsnotizen liest, wirkt Rust im Kernel wie zusätzliche Komplexitätskosten
    Würde man ein Betriebssystem von Grund auf neu schreiben, könnte man die Stärken der Sprache voll ausschöpfen
    Aber wenn man es an eine bereits riesige Codebasis anfügt, entstehen, wie hier zu sehen, zusätzliche Probleme

    • Stimmt, aber diese Kosten sollten durch einfachere Treiberentwicklung aufgewogen werden
      Man muss nur den Blogbeitrag lesen, in dem steht, dass der Rust-GPU-Treiber von Asahi Linux in einem Monat entstanden ist
      Sucht bei Google nach tales of the m1 gpu; der Autor hat eine sehr negative Meinung von Hacker News
      Wer möchte, kann ihn über den Link lesen: https://asahilinux.org/2022/11/tales-of-the-m1-gpu/
      Ob das allgemein gilt, wird man in den nächsten Jahren sehen müssen
    • Es fühlt sich stark danach an, als würde man auf der Suche nach Perfektion das Gute verpassen
    • Ich stimme den Vorteilen von Rust zu, glaube aber, dass Vernunft nur schwer gegen Hype ankommt
      Diese Kosten werden als notwendig angesehen werden, um Zukunft und Fortschritt anzunehmen
      Ich frage mich, warum man sich nicht auf eine sichere Teilmenge beschränkt, statt sich in eine riesige Strömung voller unbekannter Bugs und Kompromisse zu stürzen
    • Man könnte auch sagen, dass jeder zusätzliche Code, nicht nur Rust, Komplexität einführt
      Dass die Codebasis bereits zu groß ist, heißt nicht, dass man Innovation einstellen und auf unbestimmte Zeit in den Wartungsmodus gehen sollte
      Wenn wie bei realen Steuern die Kosten auf der einen Seite dazu dienen, andere Probleme auszugleichen, muss es kein Nettoverlust sein
      Aus einer einzelnen, noch nicht abgeschlossenen Diskussion zu schließen, dass gar keine Probleme ausgeglichen werden, wirkt wie eine zu kurze Argumentation
  • Der Punkt, dass die Namen der C-API und der Rust-API auseinanderlaufen und man beim Blick auf C-Code nicht erkennen kann, welcher Rust-Aufruf äquivalent ist, wirkt wie ein Kampf gegen alte Namenskonventionen
    Es hat schon gut funktioniert, denselben Namen beizubehalten und, wenn ein alternativer Name gewünscht ist, den neuen Namen den alten umschließen zu lassen
    Trotzdem ist Namensgebung schwierig

    • Eines der zwei großen Probleme der Informatik
      Die anderen beiden sind Nebenläufigkeit und Off-by-one-Fehler