Zum Hauptinhalt springen

Ein merkwürdiger Fall der Ternäroperatoren

· 5 Min. Lesezeit
Inoffizielle Beta-Übersetzung

Diese Seite wurde von PageTurner AI übersetzt (Beta). Nicht offiziell vom Projekt unterstützt. Fehler gefunden? Problem melden →

Die Formatierung von Ternäroperatoren war schon immer eine Herausforderung, und in Version 3.1.0 gehen wir dieses Problem endlich an – mit einem neuartigen Formatierungsstil.

Erfahren Sie mehr über unsere Reise und die Motivation hinter dieser Änderung, inklusive frühem Feedback von Entwicklern und einem Überblick über den "merkwürdigen Ternäroperatoren"-Stil.

Probieren Sie bitte die Option --experimental-ternaries aus und teilen Sie uns Ihre Meinung mit!

Für eine kurze Zusammenfassung sehen Sie sich den Release-Post an.

Einführung

Verschachtelte Ternäroperatoren in verschiedensten Szenarien ansprechend zu formatieren, ist eine überraschend knifflige Aufgabe.

Entwickler fanden sie schon lange so verwirrend zu lesen, dass sie ihren Code oft in eine unschöne Serie von if-else-Anweisungen umwandeln, häufig mit einer let-Deklaration, einem IIFE oder einer separaten Funktion.

Laut Beta-Testern erfordert der neue Formatierungsstil zwar etwas Gewöhnung, ermöglicht aber letztendlich den praktischen Einsatz von Ternäroperatoren als prägnante Form von if-else-Ausdrücken in modernen Codebasen.

Historischer Hintergrund

Prettiers ursprünglicher, naiver Ansatz – einfach Einrückungen für jede Ebene eines verschachtelten Ternäroperators hinzuzufügen – funktionierte in einfachen Fällen gut, skaliert aber offensichtlich nicht für lange Ketten verschachtelter Ternäroperatoren und hatte andere Probleme.

Daher ersetzten wir diesen 2018 durch flache Ternäroperatoren, was damals wie eine gute Idee erschien, aber schlecht aufgenommen wurde – das Issue zur Rückgängigmachung erhielt über 500 Upvotes.

Obwohl wir schließlich zu eingerückten Ternäroperatoren zurückkehrten, wollten wir eine bessere Lösung finden.

In den letzten Jahren haben wir zahlreiche Ansätze untersucht und mit vielen möglichen Lösungen experimentiert, die in Standardfällen ebenso lesbar wie eingerückte Ternäroperatoren sein, aber auch in vielfältigeren Situationen gut funktionieren sollten.

Anspruchsvolle Kriterien

Idealerweise würden wir ein Schema finden, das folgende Kriterien erfüllt:

  1. In allen Fällen sollte leicht erkennbar sein: "Was ist die if-Bedingung?", "Was ist das then-Ergebnis?" und "Was ist das else-Ergebnis?" – und welcher Teil wozu gehört.

  2. Der Code sollte flüssig von einem einzelnen Ternäroperator über eine Kette von zweien bis hin zu langen Ketten einfacher Fälle und komplexeren Strukturen mit einigen verschachtelten Bedingungen übergehen. (Die meisten Alternativen scheiterten hier).

  3. Die Syntax in JSX, TypeScript-Bedingungsausdrücken (die nicht mit if ausgedrückt werden können) und normalem JavaScript sollte einheitlich aussehen und sich konsistent anfühlen.

  4. Es sollte für verschachtelte Ternärketten beliebiger Länge skalieren (stellen Sie sich einen TypeScript-Bedingungstyp mit Dutzenden Alternativfällen vor).

Eingerückte Ternäroperatoren scheiterten offensichtlich an (4), wohl auch an (1) und sogar an (3) – wir haben JSX-Ternäroperatoren fast immer in einem flachen, aber lesbaren Format formatiert, das leider außerhalb von JSX unnatürlich wirkte.

Viele in der Community waren von einem "Case-Stil" begeistert, inspiriert von der match-Syntax aus Sprachen wie Rust oder OCaml, aber dieser Ansatz erfüllte nicht (2) und andere Ziele.

Eine überraschende Lösung

Die gute Nachricht: Wir fanden einen Formatierungsalgorithmus, der unsere Kriterien erfüllt. Die schlechte: Er ist neuartig und daher den meisten Entwicklern unbekannt.

Beim Beta-Testing stellten wir fest, dass Entwickler zunächst skeptisch reagierten:

"Ich bin nicht überzeugt, dass die neue Version hier leserlicher ist."

Doch nach kurzer Nutzungszeit wollten sie nicht mehr zurück:

"Ich mag die Ternaries! Diese Formatierung ergibt Sinn. Ich habe mich auch sehr schnell daran gewöhnt. \nStimme zu, die Eingewöhnung dauert nur sehr kurz."

Ein weiterer Entwickler äußerte sich so:

In der ersten Stunde mit der Regel fühlte es sich etwas seltsam an. Aber nach zwei Stunden hatte ich sie mehrmals genutzt, um Probleme zu lösen, die sonst hässliche Refaktorierungen zu if-Anweisungen erfordert hätten. Ich werde nicht zurückwechseln.

Früher hasste ich verschachtelte Ternaries, aber ich hasse es auch, elegante Codezeilen in if-else-Statements umzubauen. Die neue Regel fügt der Sprache einen verständlichen, linearen if-else, if-else Ausdruck hinzu und ist viel angenehmer als mehrfach verschachtelte Ternaries.

Wir waren vom Erfolg überzeugt, wussten aber, dass die Einführung für die Community gewöhnungsbedürftig sein könnte.

Daher haben wir diese neue Formatierung vorerst hinter die Option --experimental-ternaries gestellt und gleichzeitig die lang erwartete Einrückung von Ternaries ausgeliefert.

Formatierungsüberblick

Wie sieht dieser neue Stil eigentlich aus?

Ein konstruiertes Beispiel veranschaulicht die Logik hinter "curious" Ternaries:

const animalName =
pet.canBark() ?
pet.isScary() ?
'wolf'
: 'dog'
: pet.canMeow() ? 'cat'
: 'probably a bunny';
  1. Jede Zeile, die mit einem Fragezeichen endet, ist ein "if".

    • foo ? fragt quasi nach foo – "wenn foo? dann, …".
  2. Jede Zeile, die mit : beginnt, ist ein "else".

    • : foo bedeutet "ansonsten foo".
    • : foo ? heißt "ansonsten, wenn foo?".
  3. Zeilen ohne : oder ? sind "then"-Anweisungen.

    • Ein einfaches foo bedeutet "dann foo".

So sieht der Code im "Case-Stil" aus:

const animalName =
pet.isScary() ? 'wolf'
: pet.canBark() ? 'dog'
: pet.canMeow() ? 'cat'
: 'probably a bunny';

Dies ermöglicht eine prägnante, match-ähnliche Syntax in JavaScript – wenn auch mit Einschränkungen.

Unser neues Format verbindet fließend "curious" Ternaries (Fragezeichen am Zeilenende) und "Case-Style"-Ternaries (Fragezeichen in Zeilenmitte).

Beispiel:

const animalName =
pet.canSqueak() ? 'mouse'
: pet.canBark() ?
pet.isScary() ?
'wolf'
: 'dog'
: pet.canMeow() ? 'cat'
: pet.canSqueak() ? 'mouse'
: 'probably a bunny';

Gebt uns Feedback!

Wir hoffen, dass Ihnen die lesbarere neue Standardeinstellung gefällt, und wir hoffen wirklich, dass Sie die neue Option --experimental-ternaries einige Wochen lang ausprobieren und uns Ihre Meinung dazu mitteilen.

Bitte geben Sie uns Ihr Feedback über Google Forms: https://forms.gle/vwEuboCobTVhEkt66