it-swarm.com.de

Java 8 Lambda-Ausdruck und erstklassige Werte

Sind Java 8-Verschlüsse wirklich erstklassige Werte oder handelt es sich nur um einen syntaktischen Zucker?

30
xdevel2000

Ich würde sagen, dass Java 8 Verschlüsse ("Lambdas") weder bloßer syntaktischer Zucker noch erstklassige Werte sind.

Ich habe das Problem des syntaktischen Zuckers in einer Antwort auf eine andere StackExchange-Frage angesprochen.

Ob Lambdas "erstklassig" sind, hängt wirklich von Ihrer Definition ab, aber ich werde ein Argument dafür anführen, dass Lambdas nicht wirklich erstklassig sind.

In gewissem Sinne möchte ein Lambda eine Funktion sein, aber Java 8 fügt keine Funktionstypen hinzu. Stattdessen wird ein Lambda-Ausdruck in eine Instanz einer funktionalen Schnittstelle konvertiert. Dadurch konnten Lambdas zu Java 8 hinzugefügt werden, wobei das Typsystem von Java nur geringfügig geändert wurde. Nach der Konvertierung ist das Ergebnis eine Referenz wie bei jedem anderen Referenztyp. Tatsächlich ist die Verwendung eines Lambda - beispielsweise in einer Methode, der ein Lambda-Ausdruck als Parameter übergeben wurde - nicht vom Aufrufen einer Methode über eine Schnittstelle zu unterscheiden. Eine Methode, die einen Parameter eines Funktionsschnittstellentyps empfängt, kann nicht feststellen, ob ihr ein Lambda-Ausdruck oder eine Instanz einer Klasse übergeben wurde, die diese Funktionsschnittstelle implementiert.

Weitere Informationen darüber, ob Lambdas Objekte sind, finden Sie in der Antwort Lambda FAQ auf diese Frage.

Da Lambdas in Objekte umgewandelt werden, erben sie (buchstäblich) alle Eigenschaften von Objekten. Insbesondere Objekte:

  • verschiedene Methoden wie equals, getClass, hashCode, notify, toString und wait
  • einen Identitäts-Hash-Code haben
  • kann durch einen synchronized Block gesperrt werden
  • kann mit den Operatoren == und != und instanceof verglichen werden

und so weiter. Tatsächlich ist all dies für die beabsichtigte Verwendung von Lambdas irrelevant . Ihr Verhalten ist im Wesentlichen undefiniert. Sie können ein Programm schreiben, das eines von diesen verwendet, und Sie werden ein Ergebnis erhalten, aber das Ergebnis kann von Release zu Release unterschiedlich sein (oder sogar von Run zu Run!).

Um es kurz zu machen: In Java haben Objekte eine Identität , aber Werte (insbesondere Funktionswerte, falls sie existieren sollten) sollten keine Identität haben. Java 8 hat keine Funktionstypen. Stattdessen werden Lambda-Ausdrücke in Objekte konvertiert, sodass sie viel Gepäck enthalten, das für Funktionen, insbesondere für die Identität, nicht relevant ist. Das kommt mir nicht "erstklassig" vor.

Update 24.10.2013

Ich habe über dieses Thema weiter nachgedacht, seit ich meine Antwort vor einigen Monaten veröffentlicht habe. Vom technischen Standpunkt aus ist alles, was ich oben geschrieben habe, richtig. Die Schlussfolgerung wird wahrscheinlich genauer ausgedrückt als Java 8 Lambda, die nicht rein sind (im Gegensatz zu erstklassigen )) Werte, weil sie viel Objektgepäck mit sich führen. Nur weil sie unrein sind, heißt das nicht, dass sie nicht erstklassig sind. Betrachten Sie die Wikipedia-Definition von erstklassiger Funktion. Kurz gesagt, die dort aufgeführten Kriterien für die Berücksichtigung von Funktionen erster Güte sind die folgenden:

  • übergeben Sie Funktionen als Argumente an andere Funktionen
  • funktionen von anderen Funktionen zurückgeben
  • zuweisen von Funktionen zu Variablen
  • funktionen in Datenstrukturen speichern
  • habe funktionen anonym sein

Java 8-Lambdas erfüllen alle dieser Kriterien. Das lässt sie erstklassig erscheinen.

Der Artikel erwähnt auch Funktionsnamen, die keinen speziellen Status haben, stattdessen ist der Name einer Funktion einfach eine Variable, deren Typ ein Funktionstyp ist. Java 8 Lambdas erfüllen dieses letzte Kriterium nicht. Java 8 hat keine Funktionstypen. es hat funktionale Schnittstellen. Diese werden effektiv wie Funktionstypen verwendet, sind jedoch überhaupt keine Funktionstypen. Wenn Sie eine Referenz haben, deren Typ eine funktionale Schnittstelle ist, wissen Sie nicht, ob es sich um ein Lambda, eine Instanz einer anonymen inneren Klasse oder eine Instanz einer konkreten Klasse handelt, die diese Schnittstelle implementiert.

Zusammenfassend sind Java 8 Lambdas mehr erstklassige Funktionen, als ich ursprünglich gedacht hatte. Sie sind einfach keine reinen erstklassigen Funktionen.

59
Stuart Marks

Ja , sie sind erstklassige Werte (oder werden es, sobald Java 8 veröffentlicht wird ...)

In dem Sinne, dass Sie sie als Argumente übergeben können, setzen Sie sie zu Funktionen höherer Ordnung zusammen, speichern Sie sie in Datenstrukturen usw. Sie können sie für eine Vielzahl funktionaler Programmiertechniken verwenden.

Siehe auch etwas mehr Definition dessen, was "erste Klasse" in diesem Zusammenhang bedeutet:

6
mikera

Wie ich es sehe, ist es syntaktischer Zucker, aber zusätzlich zu der Typinferenz, einem neuen Paket Java.util.functions und der Semantik innerer Klassen erscheint es als erstklassiger Wert.

2
kan

Eine echte Schließung mit variabler Bindung an den äußeren Kontext hat etwas Mehraufwand Ich würde die Implementierung von Java 8 als optimal genug betrachten.

Zumindest ist es nicht nur syntaktischer Zucker.

Und ich würde keine optimale Implementierung kennen.

1
Joop Eggen

Für mich ist Lambdas in Java 8 nur Syntax sugar , da Sie es nicht als First Class Citizen ( http://en.wikipedia.org/wiki/First-class_function ) jeder Funktion verwenden können sollte in ein Objekt eingebunden werden, da es im Vergleich zur Sprache mit reinen First-Class-Funktionen wie SCALA viele Einschränkungen auferlegt. Java 8-Closures können nur unveränderliche ("effektiv final") nichtlokale Variablen erfassen.

Hier ist eine bessere Erklärung, warum es sich um Syntaxzucker handelt. Java Lambdas and Closures

0
Lemberg