Was sind "Zucker", "Desugar" im Zusammenhang mit Java 8?

107

Ich höre in Java 8 häufiger von "Zuckern" und "Desugarieren". Was bedeuten diese Begriffe? sind sie konzeptionell oder syntaktisch?

Einige Beispiele:

Standardmäßig iterierte Schleife, die in Java resugariert

Beobachtungen zu syntaktischem Zucker bei der Zusammenstellung.

Xelian
quelle

Antworten:

136

Zucker bezieht sich in der Programmierung normalerweise auf die süßen Zusätze, meistens Abkürzungen, die das Schreiben und Lesen einiger Konstrukte erleichtern (letzteres ist in der Praxis das wichtigste während des Lebenszyklus Ihres Programms).

Wikipedia hat eine Definition von syntaktischem Zucker, aber Sie sollten beachten, dass nicht jeder Zucker im Wesentlichen syntaktisch ist (nicht alle jüngsten süßen Ergänzungen waren nur Änderungen am Compiler).

Hier einige Beispiele:

  • die Postfix- und Präfix-Inkrementoperatoren ( i++und ++i). Ihr einziger Zweck ist es, das Schreiben einer zusätzlichen Erklärung zu vermeiden. Sie sind reiner Zucker.
  • +=, |=, &=Usw. sind von der gleichen Art von Zucker.
  • Die implizite Umwandlung zwischen primitiven Typen und Objekten ist auch Zucker.
  • Typinferenz ist auch Zucker.
  • Der mit Java 8 gelieferte Lambda-Ausdruck ist eine andere Art von Zucker (dieser ist nicht nur syntaktisch ).

Java wird allgemein als nicht präzise genug angesehen, insbesondere im Vergleich zu modernen Sprachen. Aus diesem Grund sind Ergänzungen willkommen, die das Lesen des Codes beschleunigen.

Abschließend möchte ich nur darauf hinweisen, dass ein Mangel an Zucker Ihr Programm zwar fett machen kann, ein Überschuss an Zucker, der zu vielen verschiedenen Möglichkeiten führt, die gleichen Dinge zu schreiben, Ihre Sprache jedoch unruhig und Ihr Programm weniger kohärent und schwieriger zu pflegen machen kann . Eine andere Art von Zucker, API-Zucker, ist meistens eine Seuche, die es schwieriger macht, die API zu erfassen, insbesondere wenn sie aus Zusätzen besteht (z. B. Überladung).

Dies wird gesagt, Entzuckern bezieht sich entweder auf

  • Der Prozess, mit dem Sie alles entfernen, was in einer Sprache redundant ist
  • der Prozess, durch den ein Codeprozessor herausfindet, was hinter einer gezuckerten Anweisung steckt (dies kann beispielsweise eine Typinferenz beinhalten)
Denys Séguret
quelle
6
+1 Sie können auch den Desugar-Teil erwähnen, da dies die Antwort vervollständigen würde, die OP gefragt hat! :)
Rahul Tripathi
6
@justhalf Überlegen Sie, wie viel dünner Ihre Programme sein werden, wenn Sie alle von Ihnen erstellten Schnittstellen entfernen können, um eine Funktion übergeben zu können.
Denys Séguret
42
"Syntaktischer Zucker verursacht Krebs des Semikolons." - Alan Perlis
Stuart Marks
12
Postfix- und Präfixoperatoren waren in den frühen Tagen von C einmal kein syntaktischer Zucker. Frühe Compiler waren nach heutigen Maßstäben dumm, und diese Operatoren konnten mit einer Maschinencode-Anweisung implementiert werden, die entsprechende Zuweisungsanweisung jedoch nicht. So konnten effizientere Programme geschrieben werden.
Raedwald
3
@justhalf Diese Frage hat viel Aufmerksamkeit bekommen. In solchen Fällen ist es nicht selten, dass Administratoren Kommentare löschen, die nicht konstruktiv erscheinen. Ich glaube nicht, dass Ihr Kommentar gelöscht werden musste, aber er brachte nicht viel.
Denys Séguret
17

"Desugaring" scheint in Java 8 eine sehr spezifische Bedeutung zu haben. Es scheint ein Sammelbegriff zu sein, um die verschiedenen Arten auszudrücken, wie ein Lambda-Ausdruck an einen tatsächlichen konkreten Methodenaufruf gebunden sein kann.

Dieses Dokument über "Übersetzung von Lambda-Ausdrücken" scheint die wirklichen Details darüber zu enthalten, was passiert, wenn Sie an Einzelheiten interessiert sind.

Ein Schlüsselbegriff aus dem Dokument:

Der erste Schritt bei der Übersetzung von Lambdas in Bytecode besteht darin, den Lambda-Körper in eine Methode umzuwandeln.

Geschoren
quelle
6

Im Allgemeinen ermöglicht "Desugaring" in Javac die Darstellung einiger Sprachfunktionen mit bereits vorhandenen. Auf diese Weise können sie im Bytecode dargestellt werden, ohne dass große Änderungen am Klassendateiformat vorgenommen werden müssen. Auch aus diesem Grund ist das Backend des Compilers stabiler als das Frontend. Dies bedeutet nicht, dass jedes neue Sprachmerkmal nur syntaktischer Zucker ist, wie dies bei Lambdas und Methodenreferenzen definitiv nicht der Fall ist. Es gibt weitere Beispiele für "Desugaring" im Compiler:

  • für jede Schleife werden für Schleifen im C-Stil "desugariert"
  • Behauptungen werden zu einem if-Satz "entgiftet"
  • innere Klassen werden als eigenständige Klasse dargestellt

Sie können auch untersuchen, was mit dem String-Schalter passiert, Löschen eingeben, ...

Vicente Romero
quelle