Domanda

C # ha funzioni di generatore che hanno sintassi come:

IEnumerable<int> GetNats(int max)
{
   for (int i=0; i < max; ++i)
      yield return i;
}

Una caratteristica che mi interessa per il mio linguaggio di programmazione (una semplice programmazione orientata agli oggetti simile a Java, Scala, ActionScript e C #) sono espressioni di generatori. Questi sono essenzialmente zuccheri sintattici per le funzioni del generatore.

Il mio attuale candidato preferito è la seguente sintassi:

IEnumerable<int> nats = 
  witheach (i in range(0, 42)) 
     yield i * 2; 

L'espressione range (0, 42) è una funzione del generatore integrata.

Quindi la mia domanda è quale sintassi preferiresti vedere per le espressioni del generatore, in un linguaggio di tipo C # / Java / Scala / ActionScript, e perché?

Alcuni fattori che possono influenzare le risposte sono che come Scala e ActionScript, i tipi nella mia lingua sono dichiarati dopo il tipo. Ad esempio:

var myVar : SomeType = initialValue;

Anche le funzioni anonime sono così:

var myFunc = function(int x) { 
  return x + 1; 
}

A parte questo, la sintassi del resto del mio linguaggio assomiglia a Java o C #. La mia lingua ha un'istruzione foreach che è molto simile a C #.

È stato utile?

Soluzione

C'è anche l'approccio di Python - nessuna sintassi speciale per i generatori; la presenza di un "rendimento" l'affermazione è tutto ciò che serve. Qualsiasi affermazione che richiede un blocco potrebbe essere utilizzata, anche se mi aspetto di trovare solo i loop utilizzati nella pratica:

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]

Qui presumo che l'endpoint giusto non sia incluso in un intervallo.

Ad essere sincero, quando l'ho visto in Python, mi sono chiesto: "a quale costo?"

Altri suggerimenti

Scopri cosa fa F #. Puoi farlo

seq { seq-expr }    // IEnumerable<T>, a.k.a. seq<T>
[ seq-expr ]        // list<T>
[| seq-expr |]      // array<T>

dove seq-expr è una forma che include la maggior parte dei costrutti del linguaggio insieme a 'yield'. Quindi ad es. puoi scrivere

seq {
    for i in 0..9 do
        for j in someColl do
            if i <> j then
                yield i*j
}

Il compilatore F # traduce questo codice in un'implementazione della macchina a stati di IEnumerable (come fa C # per i blocchi iteratori).

Mi piace questa sintassi perché significa ad es. puoi scrivere esattamente lo stesso codice con cui scriveresti " fai cose imperative ora " ;, ad esempio

    for i in 0..9 do
        for j in someColl do
            if i <> j then
                printfn "%d" i*j

ma racchiudi quel codice in seq {} e usa 'yield' e il codice diventa invece un IEnumerable pigro.

IEnumerable nats = 0...42

or for generators 

IEnumerable nats = yield 0...42
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top