Frage

Einige Leute sagen, dass jede Programmiersprache ihr „Komplexität Budget“ hat, die es seinen Zweck zu erreichen, nutzen kann. Aber wenn die Komplexität Budget erschöpft ist, wird jede noch so kleine Veränderung zunehmend kompliziert und schwer in einer rückwärtskompatibel Weise zu implementieren.

Nach dem Lesen der aktuellen vorläufigen Syntax für Lambda (≙ Lambda-Ausdrücke, Ausnahme Transparenz, Verteidiger Methoden und Verfahren Referenzen) ab August 2010 ich frage mich, wenn die Leute bei Oracle vollständig Java Komplexität Budget ignoriert, wenn solche Änderungen berücksichtigen.

Das sind die Fragen, die ich bin über - einige von ihnen mehr über die Sprache Design im Allgemeinen:

  • Sind die vorgeschlagenen Ergänzungen vergleichbar Komplexität nähert sich anderen Sprachen gewählt haben?
  • Ist es generell möglich, solche Zusätze zu einer Sprache hinzuzufügen und Schutz der Entwickler von der Komplexität der Implementierung?
  • Ist diese Zusätze ein Zeichen Erreichen des Endes der Entwicklung von Java-as-a-Sprache oder dies zu erwarten, wenn eine Sprache mit einer großen Geschichte zu ändern?
  • Haben Sie andere Sprachen einen völlig anderen Ansatz an dieser Stelle der Sprachevolution genommen?

Danke!

War es hilfreich?

Lösung

Ich habe folgte nicht den Prozess und die Entwicklung des Lambda-Java 7 Vorschlag, ich bin nicht einmal sicher, was die neueste Vorschlag Formulierung ist. Betrachten Sie dies als eine Tirade / Meinung eher als Aussagen der Wahrheit. Ebenfalls, Ich habe nicht Java seit Jahren verwendet, so dass die Syntax möglicherweise rostig und falsch an Orten.

Erstens, was ist Lambda-Ausdrücke auf die Java-Sprache? Syntethischer Zucker. Während im allgemeinen lambda ermöglicht Code kleine Funktionsobjekte zu schaffen, in Ort wurde diese Unterstützung bereits --to einige extent-- in der Java voreingestellt Sprache durch die Verwendung von inneren Klassen.

Wie viel besser ist die Syntax von lambdas? Wo es gerade outperform vorherige Sprachkonstrukte? Wo könnte es besser sein?

Für den Anfang, mag ich die Tatsache, dass es zwei verfügbare Syntax für Lambda-Funktionen (aber das geht in der Linie von C #, so dass ich mein erraten Meinung ist nicht weit verbreitet. Ich denke, wenn wir zu Zucker Mantel wollen, dann #(int x)(x*x) ist süßer als #(int x){ return x*x; } selbst wenn die Doppel Syntax fügt nichts anderes. Ich hätte es vorgezogen die zweite Syntax, allgemeinere auf die zusätzlichen Kosten von Schriftfelter return und ; in den kurzen Versionen.

Um wirklich nützlich, lambda Variablen aus dem Anwendungsbereich nimmt in wo sie definiert und von einer Schließung . Konsequent mit Innere Klassen, Lambda-Ausdrücke sind auf beschränkt Capturing ‚effektiv final‘Variablen. Übereinstimmung mit den bisherigen Funktionen der Sprache ist ein nettes Feature, aber für die Süße, wäre es schön, zu sein können Variablen erfassen, die neu zugeordnet werden können. Zu diesem Zweck, sie erwägen, dass Variablen im Kontext präsentieren und kommentierte mit @Shared werden gefangen durch Verweis , so dass Zuordnungen. Mir scheint dies seltsam, wie wie eine Lambda eine Variable verwenden können wird am Ort der Deklaration der Variablen eher bestimmt als wobei das Lambda ist definiert. Eine einzelne Variable könnte in mehr verwendet werden als eine Lambda und diese Kräfte das gleiche Verhalten in allen von ihnen.

Lambdas versuchen tatsächliche Funktionsobjekte zu simulieren, aber der Vorschlag tut nicht vollständig dort: die Parser einfach zu halten, jetzt, da bis zu Bezeichnet eine Kennung entweder einen Gegenstand oder ein Verfahren, das gehalten wurde, konsistent und ein Lambda-Aufruf erfordert eine ! nach dem Lambda mit Name: #(int x)(x*x)!(5) 25 zurück. Dies bringt eine neue Syntax für Lambdas zu verwenden, die von dem Rest der Sprache unterscheiden, wobei ! steht irgendwie als synonim für .execute auf einem virtuellen generic Schnittstelle Lambda<Result,Args...> aber, warum nicht machen es vollständig?

Eine neue generische (virtuelle) Schnittstelle Lambda erstellt werden kann. Es würde müssen virtuell sein als die Schnittstelle nicht eine reale Schnittstelle, sondern ein Familie solcher: Lambda<Return>, Lambda<Return,Arg1>, Lambda<Return,Arg1,Arg2> ... Sie könnten eine einzige Ausführung definieren Verfahren, das Ich mag würde wie C ++ operator() sein, aber wenn es das ist eine Belastung dann wäre ein anderer Name in Ordnung sein, die ! als umarmend Abkürzung für die Ausführung der Methode:

 interface Lambda<R> {
    R exec();
 }
 interface Lambda<R,A> {
    R exec( A a );
 }

Dann muss der Compiler übersetzt nur identifier!(args) zu identifier.exec( args ), die einfach ist. Die Übersetzung der Lambda-Syntax erfordern würde die Compiler die richtigen zu identifizieren Schnittstelle implementiert werden und könnte als abgestimmt werden:

 #( int x )(x *x)
 // translated to
 new Lambda<int,int>{ int exec( int x ) { return x*x; } }

Dies würde auch Benutzer erlauben, Innere Klassen zu definieren, die verwendet werden können, wie Lambda-Ausdrücke, in komplexeren Situationen. Zum Beispiel, wenn Lambda Funktion benötigt eine Variable als @Shared in einer kommentierten einzufangen Nur-Lese-Weise oder aufrechtzuerhalten, die den Zustand des erfassten Objekts an der Ort der Erfassung, würde manuelle Umsetzung des Lambdas sein zur Verfügung:

 new Lambda<int,int>{ int value = context_value;
     int exec( int x ) { return x * context_value; }
 };

In einer Weise, ähnlich dem, was die aktuelle Innere Klassen-Definition ist, und damit natürlich sein, um aktuelle Java-Nutzer. Dies könnte be verwendet, beispielsweise in einer Schleife Multiplizierer Lambdas zu erzeugen:

 Lambda<int,int> array[10] = new Lambda<int,int>[10]();
 for (int i = 0; i < 10; ++i ) {
    array[i] = new Lambda<int,int>{ final int multiplier = i;
       int exec( int x ) { return x * multiplier; }
    };
 }
 // note this is disallowed in the current proposal, as `i` is
 // not effectively final and as such cannot be 'captured'. Also
 // if `i` was marked @Shared, then all the lambdas would share
 // the same `i` as the loop and thus would produce the same
 // result: multiply by 10 --probably quite unexpectedly.
 //
 // I am aware that this can be rewritten as:
 // for (int ii = 0; ii < 10; ++ii ) { final int i = ii; ...
 //
 // but that is not simplifying the system, just pushing the
 // complexity outside of the lambda.

Dies würde Verwendung von Lambda-Ausdrücke und Methoden ermöglichen, die Lambda-Ausdrücke akzeptieren beide mit der neuen einfachen Syntax: #(int x){ return x*x; } oder mit dem mehr komplexer manueller Ansatz für bestimmte Fälle, in denen die Zuckerschicht interferiert mit der beabsichtigten Semantik.

Insgesamt glaube ich, dass der Lambda-Vorschlag verbessert werden kann verschiedene Richtungen, dass die Art und Weise fügt sie syntaktischer Zucker a Abstraktion undicht (Sie müssen extern mit Fragen befassen, die insbesondere das Lambda), und dass durch kein niedrigeres Niveau bereitstellt Schnittstelle macht es Benutzercode weniger lesbar in Anwendungsfällen, die nicht tun perfekt mit dem einfachen Anwendungsfall. :

Andere Tipps

Modulo einige Rahmen-Begriffsklärung Konstrukte, die fast alle dieser Methoden ergeben sich aus der tatsächlichen Definition einer Lambda-Abstraktion:

λx.E

Um Ihre Fragen zu beantworten, um:

Ich glaube nicht, gibt es keine besonderen Dinge, die die Vorschläge der Java-Community besser oder schlechter als irgendetwas anderes zu machen. Wie gesagt, es aus der mathematischen Definition folgt, und damit alle Gläubigen Implementierungen gehen fast genau die gleiche Form haben.

Anonymous erstklassige Funktionen auf imperativen Sprachen verschraubt sind in der Regel als ein Merkmal, um am Ende, dass einige Programmierer lieben und häufig verwenden, und dass andere ignorieren vollständig - deshalb ist es wahrscheinlich eine vernünftige Wahl ihm einig Syntax zu geben, die nicht verwirren Arten von Menschen, die das Vorhandensein dieser besonderen Sprache-Funktion zu ignorieren wählen. Ich denke, die Komplexität und die Einzelheiten der Umsetzung versteckt ist, was sie unter Verwendung von Syntax, dass Mischungen gut mit Java zu tun versucht haben, aber das hat keine wirkliche Konnotation für Java-Programmierer.

Es ist wahrscheinlich wünschenswert, dass sie einige Bits der Syntax zu verwenden, die bestehenden Definitionen nicht erschweren werden, und so dass sie leicht in den Symbolen eingeschränkt sind, können sie wählen, als Betreiber und solche verwenden. Sicherlich Java Beharren auf verbleibenden rückwärtskompatibel Grenzen die Sprachentwicklung leicht, aber ich glaube nicht, das ist unbedingt eine schlechte Sache. Der PHP-Ansatz ist am anderen Ende des Spektrums (das heißt: „Hey Jungs, mal Pause alles jedes Mal gibt es eine neue Point-Release!“). Ich glaube nicht, dass Java die Entwicklung von Natur aus mit Ausnahme von einigen der grundlegenden Lehren des Designs beschränkt ist - z.B. Einhaltung der OOP-Prinzipien, VM-basiert.

Ich denke, dass es sehr schwierig ist, starke Aussagen über die Sprache Entwicklung von Java-Perspektive zu machen. Es ist in einer ziemlich einzigartigen Position. Zum einen ist es sehr, sehr beliebt, aber es ist relativ alt. Microsoft hatte den Vorteil von mindestens 10 Jahren im Wert von Java Vermächtnis, bevor sie beschlossen, selbst zu starten, eine Sprache „C #“ genannt zu entwerfen. Die Programmiersprache C gestoppt grundsätzlich überhaupt entwickelt. C ++ hat einige bedeutende Änderungen hatte, die jede allgemeine Akzeptanz gefunden. Java hat sich weiter durch eine langsame, aber konsistenten Prozess entwickeln -. Wenn alles, was ich denke, es ist besser, ausgestattet mit ähnlich großen installierten Code-Basen auf sich entwickelnden als alle anderen Sprachen zu halten

Es ist nicht viel komplizierter als Lambda-Ausdrücke in anderen Sprachen.

Consider ...

int square(x) {
    return x*x;
}

Java:

#(x){x*x}

Python:

lambda x:x*x

C #:

x => x*x

ich glaube, der C # Ansatz etwas intuitiver ist. Persönlich würde ich lieber ...

x#x*x

Vielleicht ist das nicht wirklich eine Antwort auf Ihre Frage, aber das kann auf die Art und Weise Objective-c vergleichbar sein (was natürlich eine sehr enge Benutzerbasis im Gegensatz zu Java hat) wurde durch Blöcke erweitert (examples ). Während die Syntax nicht den Rest der Sprache (IMHO) passen, ist es eine sinnvolle Ergänzung und und die zusätzliche Komplexität in Bezug auf die Sprachfunktionen zum Beispiel mit einer geringeren Komplexität der gleichzeitigen Programmierung (einfache Dinge wie die gleichzeitige Iteration über ein Array wird belohnt oder komplizierte Techniken wie Grand Central Dispatch ).

Darüber hinaus sind viele gemeinsame Aufgaben einfacher, wenn Blöcke mit, zb ein Objekt ein Delegierter (oder - in Java-Jargon - „Listener“) für mehrere Instanzen der gleichen Klasse. In Java können bereits anonyme Klassen für diese Ursache verwendet werden, so dass Programmierer das Konzept kennen und kann sich nur ein paar Zeilen Quellcode verschonen Lambda-Ausdrücke verwenden.

In Objective-C (oder die Cocoa / Cocoa Touch-Frameworks), sind neue Funktionen jetzt oft nur zugänglich Blöcke verwenden, und es scheint, wie Programmierer sind sie schnell zur Annahme (vorausgesetzt, dass sie die Abwärtskompatibilität mit alten OS-Versionen aufgeben ).

Das ist wirklich ganz in der Nähe Lambda-Funktionen in der neuen Generation der C vorgeschlagen ++ (C ++ 0x) so glaube ich, haben Oracle Jungs bei den anderen Implementierungen sieht vor ihre eigenen kochen.

http://en.wikipedia.org/wiki/C%2B%2B0x

[](int x, int y) { return x + y; }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top