2 Punkte von GN⁺ 2023-11-27 | 1 Kommentare | Auf WhatsApp teilen
  • Der Rust-Port von fish-shell ist „größtenteils“ abgeschlossen; je nach Berechnungsweise liegt der Fortschritt bei 60 % nach entfernten C++-SLOC bis 74 % im Vergleich Rust-SLOC zu C++-SLOC
  • Die größte verbleibende Aufgabe ist die Portierung von Reader und Eingabesystem; Reader mit 3,5k Zeilen, Bildschirmbehandlung mit 1,3k Zeilen, Input mit 1k Zeilen und Pager mit 700 Zeilen sind stark miteinander gekoppelt
  • Sämtlicher C++-Code soll entfernt werden; es sind keine teilweisen Rust-Releases geplant, sondern ein Release wie fish 4.0 soll nur Rust enthalten und 0 C++
  • Ein Windows-Port war nie geplant; die Umstellung auf Rust ist keine Lösung für die Windows-Unterstützung, und Nutzer von MSYS2/cygwin befürchten, dass fehlende Rust-Targets für diese Umgebungen Updates blockieren könnten
  • Die Performance des fertigen Ports ist noch nicht endgültig geklärt; erste Ergebnisse sind ermutigend, aber in manchen Fällen sind rund 20 % weniger Leistung möglich, weshalb für das erste Rust-Release eine Beta als sinnvoll angesehen wird

Stand des Rust-Ports

  • Die Rust-Neuschreibung von fish-shell ist „größtenteils“ abgeschlossen
  • Der Fortschritt hängt davon ab, nach welchem Maßstab gezählt wird
    • Nach entfernten C++-SLOC: 60 %
    • Nach Rust-SLOC im Verhältnis zu C++-SLOC: 74 %
  • Ein Teil des Codes ist doppelte Übergangsinfrastruktur, die entfernt werden kann, sobald der letzte Aufrufer verschwunden ist
    • Zum Beispiel wurde wgetopt bereits nach Rust übersetzt, aber die C++-Version bleibt bestehen, bis der letzte C++-Aufrufer portiert ist
    • Das ist einfacher, als allen C++-Aufrufern Konvertierungscode hinzuzufügen
  • Wenn nach dem letzten Aufrufer doppelter Code entfernt wird, bereinigen sich manche Teile wie Domino-Steine

Noch verbleibende große Aufgaben

  • Die größte verbleibende Komponente sind Reader und Eingabesystem
  • Der zugehörige Code ist stark miteinander gekoppelt
    • Reader: 3,5k Zeilen
    • Bildschirmbehandlung: 1,3k Zeilen
    • Input: 1k Zeilen
    • Pager: 700 Zeilen
  • Danach bleiben noch etwas Restcode und die Ent-C++-isierung des Build-Systems
    • cmake entfernen
    • Auf cargo umstellen, damit es alles Nötige übernimmt
    • Auch Build und Installation von Dokumentation und Completion-Dateien müssen von cargo übernommen werden
  • Der fish-Build umfasst nicht nur das Kompilieren von Rust-Code, sondern auch verschiedene Hilfsartefakte, daher ist das keine einfache Umstellung
  • Diese Arbeit eignet sich nicht für die Art von „drive-by contribution“

Release-Plan und Versionsverlauf

  • fish-shell plant keine teilweisen Rust-Releases
  • Zum Beispiel soll fish 4.0 vollständig nur aus Rust bestehen, mit 0 C++
  • Beta-Versionen und Release Candidates wurden generell eingestellt, aber dieser Übergang wird als groß genug für eine Beta angesehen
    • Zuvor wurden Betas und Release Candidates eingestellt, weil sie nicht ausreichend getestet wurden
  • Vor dem Wechsel auf die Rust-Version ist auch ein C++-basiertes Zwischenrelease 3.7.0 gewünscht
    • Es soll als besserer Ausgangspunkt für Plattformen dienen, die die Rust-Version nicht verarbeiten können
    • 3.7.0 ist eine Form von 3.6.1 mit einigen zurückportierten Änderungen
  • An 3.7.0 wird im Branch Integration_3.7.0 branch gearbeitet
    • Es gibt auch ein vorläufiges CHANGELOG
    • Zu den wichtigsten Änderungen gehören Timeouts für Tastenkombinationen, Verbesserungen am History-Pager, behobene Rendering-Glitches und schnelleres Glob

Verbleibende Dateien und konkreter Umfang

  • Mit Stand vom 1. Dezember 2023 ist die Liste der verbleibenden Dateien wie folgt
src/fish_indent_common.cpp
src/fish_indent.cpp
src/fish_key_reader.cpp
src/builtins/bind.cpp
src/builtins/commandline.cpp
src/fish_tests.cpp
src/pager.cpp
src/reader.cpp
  • Diese Liste zeigt den verbleibenden Umfang der C++-Portierung auf Dateiebene

Klarstellungen und Einschränkungen

  • Sämtlicher C++-Code soll entfernt werden
  • Ein Windows-Port ist nicht geplant und war auch früher nie geplant
    • C++ wird unter Windows ebenfalls gut unterstützt, daher löst Rust das Problem eines Windows-Ports nicht
    • Das Problem eines Windows-Ports liegt nicht an der Sprache, sondern daran, dass Windows kein Unix ist
  • Name und Maskottchen werden nicht geändert
  • Wahrscheinlich wird der Tagline nicht „written in Rust“ hinzugefügt
    • Auf fishshell.com könnte erwähnt werden, dass es in Rust geschrieben ist
    • In einer zusätzlichen Diskussion im September 2024 wurde die Haltung bekräftigt, „written in rust“ nicht in die Tagline aufzunehmen
  • Die Performance des fertigen Ports ist noch nicht bekannt
    • Erste Ergebnisse sind ermutigend
    • In manchen Fällen sind rund 20 % weniger Leistung möglich
    • Auch wenn der erste Port fertig ist, ist das Projekt damit nicht abgeschlossen; es bleibt noch viel zu tun

Bedenken von Windows- und MSYS2/cygwin-Nutzern

  • Ein Nutzer verwendet fish in einer MSYS2-Umgebung und erklärt, dass MSYS2 POSIX-Dienstprogramme bereitstellt, wodurch fish gut funktioniert
  • Da Rust keine Targets für cygwin oder MSYS2 bereitstellt, besteht die Sorge, dass fish nach der Rust-Neuschreibung nicht mehr für cygwin- oder MSYS2-Targets kompiliert werden kann
  • Dieser Nutzer sieht die Möglichkeit, dass die Umstellung auf Rust Updates für einige Windows-Fish-Nutzer blockieren könnte
  • Diese Sorge wurde nicht als Kritik an der Arbeit oder an der Sprache formuliert, sondern als Hinweis auf die Einschränkung, dass Windows kein Unix ist

1 Kommentare

 
GN⁺ 2023-11-27
Hacker-News-Kommentare
  • Wenn ich es richtig verstanden habe, ist es beeindruckend, dass sie eine schrittweise Neuschreibung von C++ nach Rust durchführen und dabei die ganze Zeit ein funktionierendes System behalten
    Das Tempo ist ebenfalls sehr hoch, und wer fish noch nicht ausprobiert hat, sollte das unbedingt tun. Es ist eine Shell, die schon mit den Standardeinstellungen sehr gut ist und sich auch ohne Anpassungen angenehm nutzen lässt; ich bin vor ein paar Jahren von bash umgestiegen und habe nicht vor, zurückzugehen
    Als Bonus muss man nicht jedes Mal die selten genutzte und wenig intuitive for-Loop-Syntax von bash googeln

    • Es scheint nicht wirklich schrittweise zu sein
      Sie planen angeblich keine Releases mit einer teilweise in Rust geschriebenen Version und wollen zum Beispiel fish 4.0 als vollständig Rust, 0 % C++ veröffentlichen. Dazwischen soll es offenbar auch noch eine rein auf C++ basierende 3.7.0 geben, um Plattformen, die die Rust-Version nicht verkraften, einen besseren Ausgangspunkt zu bieten
      https://github.com/fish-shell/fish-shell/discussions/10123#d...
    • Für Skripte nutze ich weiterhin lieber Bash oder greife einfach zu Python/Perl, aber für die Nutzung im Terminal ist Fish eindeutig besser
    • Als leicht zu merkendes Beispiel für Bash-Schleifen kann man einen inkrementierenden Index so schreiben: for ((i = 0; i < 10; i++)); do echo $i; done
      Über ein Array kann man iterieren, indem man foo[0]=a, foo[1]=b setzt und dann for i in ${foo[@]}; do echo $i; done verwendet
  • Die Motivation für die Neuschreibung wird ausführlicher erläutert
    https://github.com/fish-shell/fish-shell/pull/9512#issuecomm...

    • Der Beitrag des Maintainers ist reif und logisch, mit genau dem richtigen Maß an Humor und Entschlossenheit, sodass sich mein bisheriges „Sollte ich Fish mal ausprobieren?“ in ich habe wohl ein großartiges Projekt verpasst verwandelt hat
    • Dass ein Port auf C++17 als „zu mühsam“ angesehen wird, während ein komplettes Umschreiben in einer neuen Sprache akzeptabel erscheint, sagt ziemlich viel aus
      Letztlich ist die Erzählung vom allgemeinen Hinterherlaufen hinter neuen, glänzenden Dingen in der Entwicklerwelt wohl schwer zu schlagen. Ich nutze Fish zwar nicht, wünsche dem Projekt aber Erfolg
  • Als jemand, der Fish täglich auf etwa vier Betriebssystemen nutzt und mag, freue ich mich sehr auf diese Neuschreibung, und angesichts der Größe und Komplexität der Codebasis ist das Tempo erstaunlich
    Ich denke auch, dass es dadurch für viele Leute, mich eingeschlossen, leichter wird, beizutragen. Weniger beachtet, aber für mich noch spannender, ist der Plan, dass fish künftig UTF-8 statt wchar_t verwenden soll. UCS2 und UTF-16 waren für Software problematisch, und Rust macht den Umgang mit UTF-8 deutlich angenehmer

    • Wenn man mehrere Compiler für dieselbe Codebasis unterstützen muss, wird es noch komplizierter
      sizeof(wchar_t) ist bei MSVC 2 Byte, also UTF-16, und bei gcc 4 Byte, also UTF-32
  • Fish ist eine unterschätzte Shell
    Es trifft starke Entscheidungen wie den Verzicht auf POSIX-Kompatibilität und ist dadurch am Ende eine sehr gute Shell. Ich nutze sie seit über 10 Jahren und mag sie immer noch
    Auch das Shell-Scripting in Fish ist sehr angenehm; es wirkt wie ein ergonomisches bash. Jedes Projekt hat Schwächen, aber Fish hat mich nie wirklich daran gehindert, das zu tun, was ich tun wollte

  • Ich nutze zsh + spaceship und frage mich, welche Vorteile ein Umstieg auf Fish als Haupt-Shell hätte
    Ich schreibe nicht viele bash-Skripte, daher ist mir der Skripting-Aspekt weniger wichtig

    • Wenn du zsh bereits so eingerichtet hast, wie du es möchtest, gibt es wahrscheinlich nicht viele große Vorteile
      Die große Stärke von Fish ist, dass es ohne Konfiguration sofort nahe an der idealen Shell ist. Autovervollständigung funktioniert direkt, der Verlauf lässt sich leicht durchsuchen, es gibt befehlsbasierte Vervollständigung aus dem Verlauf, und selbst die Auswahl eines Prompts ist so einfach wie das Öffnen eines Browsers. Man kann es wie zsh tiefgreifend anpassen, aber auch mit den Standardwerten ist es schon eine ziemlich gute Shell
    • Ich habe mich 2017 statt für zsh für Fish entschieden, weil die gewünschten Funktionen bereits eingebaut waren und es sich deutlich schneller anfühlte
      Seitdem finde ich es angenehm, dass ich fast keine Zeit mehr auf die Wartung der Shell-Konfiguration verwende
    • Wegen der Geschwindigkeit
      Fish bringt vieles von Haus aus mit, wofür man bei zsh Plugins brauchte. Die zsh-Plugins waren langsam und die Shell brauchte über 3 Sekunden zum Starten, während Fish selbst mit Plugins deutlich schneller startet
    • Als ich zum ersten Mal im richtigen Verzeichnis eine fish_prompt.fish-Datei angelegt, darin die Funktion fish_prompt geschrieben und einfach einen String auf stdout ausgegeben habe, um meinen eigenen Shell-Prompt zu bauen, war ich kurz davor, zsh zu löschen
      Danach fällt es schwer, zu einer Methode zurückzukehren, bei der man allerlei Dinge in $PS1 hineinstopft und hofft, dass es funktioniert. Ich würde empfehlen, es wenigstens ein paar Tage auszuprobieren. Dann sieht man, welche Dinge, die man für selbstverständlich hält, eigentlich shellspezifische Features sind. Im schlimmsten Fall sagt man einfach: „Ist nicht mein Geschmack“ und geht zurück zu bash, zsh oder einer anderen bevorzugten Shell
    • Ich bin vor ein paar Jahren von zsh zu Fish gewechselt, und die Funktionen sind fast gleich, aber die Fish-Konfigurationsdatei ist nur etwa 10 % so groß wie meine zsh-Konfiguration
      Das meiste, was ich will, ist bereits eingebaut, und inzwischen nutze ich nur noch das Plugin fzf.fish
  • Eine der schnellsten Shells könnte noch schneller werden
    Seit meinem Wechsel von zsh zu Fish ist meine Produktivität im Terminal deutlich gestiegen

    • Darauf würde ich nicht wetten
      Laut dem Link weiß man in Wirklichkeit nicht, wie die Performance des fertigen Ports ausfallen wird. Die ersten Ergebnisse sind ermutigend, aber in manchen Fällen könnte es durchaus etwa 20 % langsamer werden
    • Ich glaube nicht, dass der Performance-Unterschied zwischen C++ und Rust so groß ist
      Sie liegen ziemlich dicht beieinander, und es gibt wahrscheinlich keinen klaren Sieger
    • Ich frage mich, bei welchen Workflows die Shell-Performance überhaupt zum Flaschenhals wird
      Ich habe sie eher als Klebecode gesehen, der Arbeit an andere Stellen weiterreicht. Vielleicht geht es um ineffiziente Pipes oder um Sonderlinge, die ganze Programme in bash schreiben, aber es wirkt etwas ungewöhnlich, Geschwindigkeit als Hauptvorteil hervorzuheben, wo Fish doch so viele Verbesserungen bei der Lebensqualität bietet
    • Ich tippe und organisiere meine Arbeit sicher nicht schnell genug, dass Unterschiede zwischen C, C++, Rust oder anderen Sprachen eine Rolle spielen würden; ich frage mich also, ob Fish noch etwas anderes bietet
  • Ich nutze Fish seit einem Jahr
    Mir gefällt zwar nicht, dass es die Standardkompatibilität bricht, sodass einige Skripte wie gvm oder nvm nicht laufen, aber dafür bringt es alle Funktionen mit, die man sich bei zsh normalerweise selbst einrichtet. Nachdem ich versucht hatte, mein zsh-Setup auf mehreren Rechnern nachzubauen, habe ich aufgegeben und überall zum Standard-Fish gewechselt.
    Ich bin mir nicht sicher, was ein Port nach Rust bringt, wenn es doch bereits gut funktioniert. Wenn es um Sicherheit geht, denke ich eher, dass dann ohnehin schon irgendetwas auf dem System läuft, das Fish böswillig manipulieren kann

    • Wie schon in der ursprünglichen Rust-Diskussion erwähnt, gibt es mehrere Gründe für den Umstieg auf Rust
      Es geht vor allem darum, Mitwirkende zu gewinnen und asynchrone/parallele Modi hinzufügen zu können, bei denen sich die Maintainer sicher fühlen.
      [1] https://github.com/fish-shell/fish-shell/pull/9512
  • Fish ist gut
    Ich bin von ZSH+Prezto auf reines Fish umgestiegen, vermisse nichts und es ist deutlich schneller. Auf Servern ist zwar überall bash im Einsatz und ich nutze weiterhin bash-Skripte, aber für alltägliche Terminal-Arbeit reicht Fish völlig aus

  • Fish hat mich immer interessiert, aber ich habe wegen der POSIX-Inkompatibilität gezögert
    Mich würde interessieren, ob jemand Probleme aus diesem Bereich und mögliche Workarounds teilen kann

    • Fish ist nicht als Ersatz für bash/shell-Skripte gedacht, sondern als interaktive Shell, daher ist POSIX-Konformität in der Praxis kein großes Problem.
      Der Nachteil ist, dass ein wenig Kontextwechsel nötig ist. Besonders dann, wenn man sein Leben lang bash/zsh genutzt hat. Für mich ist die Unterscheidung zwischen der Shell als Benutzeroberfläche und bash/sh als Interpreter einfach, aber für alle ist das vielleicht nicht intuitiv.
      Außerdem habe ich, seit ich keine POSIX-kompatible Shell mehr als Alltagsshell nutze, Skripte, die ich früher in bash gelöst hätte, schneller in eine allgemeine Programmiersprache hochgezogen
    • Bash-/zsh-Skripte startet man einfach mit Bash bzw. zsh: bash script.sh
      Als ich anfing, Fish zu nutzen, hat mich die POSIX-Inkompatibilität auch gestört, aber nachdem ich etwas andere Syntax gelernt und mich davon gelöst hatte, fand ich, dass sich die vernünftigere Syntax von Fish gelohnt hat. Heute macht mir die Arbeit im Terminal viel mehr Spaß.
      Außerdem muss man in 90 % der Fälle keine POSIX-Kompatibilität einhalten, und inzwischen unterstützen viele Skripte und Erweiterungen auch Fish. In Unternehmensumgebungen bleibe ich bei dem Standard Bash/zsh
  • Ich frage mich, warum auf Rust umgestellt wird
    Ist die C++-Codebasis zu schwer beherrschbar geworden?