Warum wurden Null-Safe-Operatoren (z. B. „Elvis-Operator“) als Teil von Java 7s „Project Coin“ abgelehnt?

10

Eine der vorgeschlagenen Funktionen für Java 7s "Project Coin" war der "Elvis-Operator". In einem Bericht einer JavaOne-Präsentation 2009 zu Project Coin wurde dies als solches beschrieben:

Eine der "kleinen Funktionen", die in dieser Präsentation behandelt werden, ist der sogenannte "Elvis-Operator", eine präzisere Version des ternären Operators. Bei der Verwendung von traditionellem Java fehlen mir einige Funktionen von Groovy, und dies wäre ein Operator, den ich in beiden Sprachen verwenden könnte, wenn er hinzugefügt würde. Der Operator "Elvis" ist praktisch, um einen Standardwert anzugeben, der verwendet werden kann, wenn der ausgewertete Ausdruck null ist. Wie bei Groovys sicherem Navigationsoperator können Sie auf präzise Weise festlegen, wie unnötige Nullen vermieden werden sollen. Ich habe zuvor darüber gebloggt, wie ich die NullPointerException vermeiden möchte.

Während andere Aspekte von Project Coin letztendlich implementiert wurden, war dies nicht der Fall. Warum wurde der Elvis-Betreiber letztendlich abgelehnt, obwohl er auf JavaOne als wahrscheinlicher Kandidat für die Aufnahme vorgestellt wurde?

Um es klar auszudrücken, frage ich speziell nach diesem Operator und dem Grund, warum er als Teil von Java 7s "Project Coin" abgelehnt wurde, da er damals ernsthaft in Betracht gezogen wurde. Ich vermute, dass es Mailinglisten oder ähnliches gibt, in denen die Gründe für die Ablehnung besprochen wurden, aber ich konnte nichts finden. Wenn es allgemeinere Informationen darüber gibt, warum es in keiner Java-Version enthalten ist, ist dies akzeptabel, aber nicht bevorzugt.

Donnerschmiede
quelle
4
verdächtige Köpfe?
Ewan
1
Dies ist wahrscheinlich, weil es die Verwendung von Nullen als legitime Werte unterstützt und fördert und grundsätzlich den OO-Prinzipien widerspricht, da Sie den Typ eines Objekts überprüfen, bevor Sie eine Methode ausführen.
JacquesB
Solange jemand keine expliziten Dokumente (E-Mails, Memos, Transkripte) des Entscheidungsprozesses ausgräbt oder direkt an der Entscheidung beteiligt war, können wir die Antwort hier nicht wirklich kennen. Zum Beispiel ist Roberts Antwort nur Spekulation und allgemeine Überlegungen zum Sprachdesign, kein sachlicher und spezifischer Grund für die Ablehnung dieses Operators. Ich stimme daher dafür, diese Frage als meinungsbasiert abzuschließen.
Amon
1
@amon: Ich gab frei zu, dass meine Antwort zu Beginn meines Beitrags Spekulation war. Ich habe jedoch trotzdem eine Antwort gepostet, weil 1. ich unterrichte, wie man fischt, anstatt einen Fisch zu geben, und 2. dieser Beitrag als Ziel für enge Betrüger verwendet werden kann, wenn wir unsere Karten richtig spielen. Die Idee hinter einer Antwort, die eine allgemeine Analyse liefert, besteht darin, endlose Argumente über winzige Sprachentscheidungen zu entmutigen und anderen zu helfen, eine breitere Sicht auf die Gesamtprobleme zu sehen.
Robert Harvey
@RobertHarvey Ein kanonisches Dupe-Ziel „Warum hat Sprache X kein Merkmal Y?“ Wäre praktisch, aber die Frage in ihrer aktuellen Form scheint dafür nicht geeignet zu sein. Wenn es zu bearbeitende waren diese allgemeine Frage stellen (mit X = Java / Y = ?.als Beispiel ) ist es sicherlich zu weit gefasst als eine gewöhnliche Frage wäre, aber Sie würden eine gute Antwort haben.
Amon

Antworten:

15

Die beste Person, um diese Frage zu stellen, ist natürlich jemand im JCP-Exekutivkomitee, nicht wir. Das hindert mich jedoch nicht daran, mich auf müßige Spekulationen einzulassen.

Die Antwort auf jede Frage "Warum wurde diese Funktion nicht implementiert?" Lautet immer, dass der Nutzen die Kosten nicht überstieg.

Eric Lippert (ehemaliges Mitglied des C # -Teams) sagt, dass ein Produkt eine Funktion haben muss, damit es eine Funktion hat:

  • an erster Stelle gedacht
  • erwünscht
  • entworfen
  • angegebenen
  • implementiert
  • geprüft
  • dokumentiert
  • Versand an Kunden

Mit anderen Worten, es müssen viele wichtige Dinge geschehen, bevor eine neue Programmiersprachenfunktion realisiert werden kann. Die Kosten sind höher als Sie denken.

Im C # -Team beginnt jede neue Funktionsanforderung mit einer Punktzahl von minus 100. Anschließend bewertet das Team die Vorteile und Kosten, addiert Punkte für die Vorteile und subtrahiert Punkte für die Kosten. Wenn die Punktzahl nicht über Null liegt, wird die vorgeschlagene Funktion zusammenfassend verworfen. Mit anderen Worten, die neue Funktion muss einen überzeugenden Vorteil bieten.

Aber der Elvis-Operator hat es in C # geschafft. Warum hat es es nicht nach Java geschafft?

Trotz ihrer offensichtlichen Ähnlichkeiten haben Java und C # signifikant unterschiedliche Sprachphilosophien. Dies wird durch die Tatsache belegt, dass Java-Unternehmensprogramme in der Regel große strukturelle Architekturkollektionen sind. Kürze und Ausdruckskraft der Sprache werden auf dem Altar der Zeremonie und der einfachen Codierung geopfert. Bekannte Software-Architekturmuster, die jeder im Entwicklungsteam erkennen kann, werden gegenüber Sprachkomfort bevorzugt.

Betrachten Sie diesen Reddit-Austausch :

Der Elvis-Operator wurde seit 7 für jede Java-Version vorgeschlagen und jedes Mal abgelehnt. Verschiedene Sprachen fallen auf verschiedene Punkte entlang des Spektrums von "rein" bis "pragmatisch", und Sprachen, die den Elvis-Operator implementieren, tendieren dazu, weiter am pragmatischen Ende des Spektrums zu sein als Java.

Wenn Sie ein Team von mehr als 15-jährigen Java-Profis haben, die ein hochverteiltes, gleichzeitig ablaufendes Backend-Verarbeitungssystem schreiben, dann möchten Sie wahrscheinlich ein hohes Maß an architektonischer Genauigkeit.

Wenn Sie jedoch ein Junior- bis Mid-Level-Team haben, von dem die Hälfte von Visual Basic migriert ist, und eine ASP.NET-Webanwendung schreiben, die meistens nur CRUD-Operationen ausführt, ist es möglicherweise übertrieben, eine Reihe zu entwerfen von AbstractFactoryFactoryKlassen, um die Tatsache zu abstrahieren, dass Sie keine Kontrolle darüber haben, welche Spalten in der beschissenen Legacy-Datenbank, die Sie verwenden müssen, nullwertfähig sind.

Diese tiefgreifenden Unterschiede in der Sprachphilosophie erstrecken sich nicht nur auf die Art und Weise, wie die Sprachen verwendet werden, sondern auch auf die Art und Weise, wie der Sprachentwurfsprozess selbst durchgeführt wird. C # ist eine wohlwollende Diktatorsprache . Um eine neue Funktion in C # zu integrieren, müssen Sie nur eine Person überzeugen: Anders Hejlsberg .

Java verfolgt einen konservativeren Ansatz. Um eine neue Funktion in Java zu integrieren, muss ein Konsortium großer Anbieter wie Oracle, IBM, HP, Fujitsu und Red Hat einen Konsens erzielen. Offensichtlich wird dieser Prozess langsamer sein und einen höheren Balken für neue Sprachfunktionen darstellen.

Die Frage "Warum wurde die x-Funktion nicht implementiert ..." enthält immer implizit die Worte "... wenn es offensichtlich eine so gute Idee ist?" Wie ich hier hinreichend demonstriert habe, ist die Wahl nie so einfach.

Robert Harvey
quelle
8
Sarkasmus: Weil AbstractFactoryFactory-Klassen ein guter Indikator für architektonische Genauigkeit sind und kein Aufblähen von Code. /Sarkasmus.
Machado
2
@RobertHarvey Ihre Schlussfolgerungen zur Rolle von Komitees bei der Gestaltung der Java-Sprache sind viel zu einfach. Während es tatsächlich eine Zusammenarbeit mit der Community und mit Industriepartnern gibt, ist die Aussage, dass die Java-Sprache "Design by Committee" ist, ziemlich völlig falsch und eine schreckliche (wenn auch leider oberflächlich glaubwürdige) Erklärung für die Frage dieses Posters.
Brian Goetz
5
Die meisten der zuvor aufgeführten Gründe - jedes Sprachmerkmal ist größer als irgendjemand denkt, begrenzte Budgets (für Aufwand, für Änderungen, für Komplexität) - sind korrekt. Und ich würde hinzufügen: Wir machen kein Feature X, weil wir denken, dass andere Features Y und Z die bessere Wahl sind. Darüber hinaus verfolgen wir einen konservativeren Ansatz als andere Sprachen, da wir wissen, dass jedes Feature in Zukunft mit anderen möglichen Features interagiert oder diese in einigen Fällen ausschließt. Wir möchten, dass Java in 20 Jahren lebendig und relevant bleibt, was zwangsläufig bedeutet, nicht alle Funktionen zu nutzen, die jetzt cool erscheinen könnten.
Brian Goetz
1
@BrianGoetz: Da das Problem in der abwertenden Natur des Begriffs "Design by Committee" zu liegen scheint (Sie werden feststellen, dass ich Java auf keine andere Weise herabgesetzt habe), habe ich meine Antwort leicht geändert, um den Begriff zu entfernen.
Robert Harvey
1
Früher gab es einige Rivalitäten zwischen den C # - und Java-Designern. C # wurde von Java-Designern (und das zu Recht) als Abzocke angesehen. C # -Delegierte wurden abgelehnt, weil sie "nicht objektorientiert" waren, aber der wahre Grund war, dass sie zuerst in C # erschienen. Es ist schön zu denken, dass nur aus rationalen Gründen einige Funktionen hinzugefügt oder weggelassen werden ... Ich bezweifle es.
Frank Hileman