Hi
könntest du mal kurz schreiben (für die, die jetzt die Doku noch nicht gelesen haben), was das mit dem "yield" auf sich hat? Für mich sieht das wie eine Endlosschleife aus.
Warum hast du die Doku nicht gelesen? :)
Einstein wurde mal von nem Reporter gefragt ob er die Relativitätstheorie in 10 min erklären könne. Natürlich könne er das, aber ob der andere es verstünde sei ne andere Frage... ;-)
OK, das Konzept ist fast 1 zu 1 von Python abgekupfert und in JS eigentlich nur theoretisch interessant, weil es nicht zum ECMA Standard gehört. wenn du nach Generator/Iterator/Python googelst wirst du zig deutschsprachige Quellen mit ausführlichen Beispielen dazu finden.
Nun die Kurzerklärung: Indem du in einer Funktion das "return" durch ein (oder mehrere) "yield" ersetzt wandelt es sich magisch in eine(n) Generator(funktion), (was im Grunde ein funktionaler Konstruktor ist)
Diese liefert bei jedem Aufruf ein Iterator-Objekt zurück, statt den Body auszuführen. Dieser Funktionskörper beschreibt nämlich den Code der next-methode des Objekts.
Bei jedem Aufruf dieser next()-Methode wird genau an der Stelle weitergemacht wo sie das letztemal durch yield verlassen wurde (bei einem return würde wieder von vorne angefangen). Da alle lokalen Variablenzustände zwischen den Aufrufen erhalten bleiben statt reinitialisiert zu werden, wird die Methode nicht davon beeinflusst, ob sie jemals verlassen wurde (solche vars kennt man glaub ich auch als "static" in C und PHP)
Das ganze ist also ein Spezialfall von Ko-Routinen, die wiederum als eine Sonderform des Multitasking verstanden werden kann.
Um dir die Vorteile klar zu machen, könntest du versuchen ein Iterator-Objekt klassisch zu erzeugen. Dann müssten alle Zustandsvariablen ins Closure von next() verschoben werden, um statisch zu bleiben, außerdem müsstest du dafür sorgen dass sie nur einmal initialisiert werden.
Alle Klarheiten beseitigt? :)
Ich finde ehrlich gesagt Guido's Design etwas fragwürdig, weil ein Anfänger intuitiv davon ausgehen muss, dass ein Aufruf eines Generators gen() auch dessen Code ausführt (schließlich steht "function" bzw "def" davor).
Die Gründe werden auch in in einer [href:http://www.python.org/dev/peps/pep-0255/@title=PEP] erläutert, ich persönlich finde Larry's Vorschlag für gather/take in Perl6 klarer, weil "gather" eben kein "sub" ist.
Product Placement:
Wie man gather/take pragmatisch in Perl5 implementieren kann ist Inhalt eines Talks dass ich auf der nächsten YAPC::EU in Riga und auf dem Deutschen Perl Workshop im Oktober in Frankfurt halten werde.
Cheers
Rolf