Auswählen einer Syntax für Ausdrücke zur Listengenerierung [geschlossen]
Frage
C# verfügt über Generatorfunktionen mit folgender Syntax:
IEnumerable<int> GetNats(int max)
{
for (int i=0; i < max; ++i)
yield return i;
}
Eine Funktion, die mich für meine Programmiersprache (eine einfache objektorientierte Programmierung ähnlich Java, Scala, ActionScript und C#) interessiert, sind Generatorausdrücke.Dabei handelt es sich im Wesentlichen um syntaktischen Zucker für Generatorfunktionen.
Mein aktueller Lieblingskandidat ist die folgende Syntax:
IEnumerable<int> nats =
witheach (i in range(0, 42))
yield i * 2;
Der Ausdruck range(0, 42)
ist eine eingebaute Generatorfunktion.
Meine Frage ist also, welche Syntax würden Sie für Generatorausdrücke in einer Sprache vom Typ C#/Java/Scala/ActionScript bevorzugen und warum?
Einige Faktoren, die Antworten beeinflussen können, sind, dass Typen in meiner Sprache wie Scala und ActionScript nach dem Typ deklariert werden.Zum Beispiel:
var myVar : SomeType = initialValue;
Auch anonyme Funktionen sehen so aus:
var myFunc = function(int x) {
return x + 1;
}
Ansonsten ähnelt der Rest meiner Sprachsyntax Java oder C#.Meine Sprache hat eine foreach
Anweisung, die C# sehr ähnlich ist.
Lösung
Es gibt auch Pythons Ansatz – keine spezielle Syntax für Generatoren;Das Vorhandensein einer „Yield“-Anweisung genügt.Alle Anweisungen, die einen Block benötigen, könnten verwendet werden, obwohl ich erwarte, dass in der Praxis nur Schleifen verwendet werden:
IEnumerable<int> nats =
for (i in range(0,42))
yield i*2
String phrase = "I want to buy some cheese.";
IEnumerable<int> substrs =
for (i in 0 .. phrase.length)
for (j in i .. phrase.length+1)
yield phrase[i..j]
Hier gehe ich davon aus, dass der richtige Endpunkt nicht in einem Bereich enthalten ist.
Um ganz ehrlich zu sein, als ich das in Python sah, musste ich mich fragen:"Zu welchem Preis?"
Andere Tipps
Schauen Sie sich an, was F# tut. Du kannst tun
seq { seq-expr } // IEnumerable<T>, a.k.a. seq<T>
[ seq-expr ] // list<T>
[| seq-expr |] // array<T>
wobei SEQ-EXPR ein Formular ist, das die meisten Sprachkonstrukte zusammen mit "Ertrag" enthält. Also zB du kannst schreiben
seq {
for i in 0..9 do
for j in someColl do
if i <> j then
yield i*j
}
Der F# Compiler übersetzt diesen Code in eine Implementierung von IEnumerable (wie C# für Iteratorblöcke).
Ich mag diese Syntax, weil es bedeutet, dass Sie genau denselben Code schreiben können, den Sie schreiben würden, um "jetzt imperativen Zeug zu tun", z. B.
for i in 0..9 do
for j in someColl do
if i <> j then
printfn "%d" i*j
Wickeln Sie diesen Code jedoch in SEQ {} ein und verwenden Sie stattdessen 'Ertrag' und der Code wird zu einer faulen Ienumerable.
IEnumerable nats = 0...42 or for generators IEnumerable nats = yield 0...42