Pergunta

C# tem gerador de funções que possuem sintaxe:

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

Um recurso que eu estou interessado em por minha linguagem de programação (uma simples programação orientada a objetos semelhante ao Java, Scala, ActionScript, C#) são gerador de expressões.Estes são, essencialmente, um açúcar sintático para o gerador de funções.

Meu candidato favorito é a seguinte sintaxe:

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

A expressão range(0, 42) é um built-in função do gerador.

Então, minha pergunta é o que a sintaxe prefere ver para o gerador de expressões, em um C#/Java/Scala/ActionScript tipo de linguagem, e por quê?

Alguns fatores que podem influenciar as respostas são de que, como Scala e ActionScript, tipos de minha linguagem são declarados após o tipo.Por exemplo:

var myVar : SomeType = initialValue;

Também funções anônimas parecido com este:

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

Diferente do que o resto da minha língua sintaxe semelhante a do Java ou C#.Meu idioma tem um foreach declaração de que é muito semelhante ao C#.

Foi útil?

Solução

Há também Python abordagem--nenhuma sintaxe especial para geradores;a presença de um "rendimento" declaração é tudo o que preciso.Quaisquer instruções que leva um bloco pode ser usado, embora eu esperaria encontrar apenas loops utilizado na prática:

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]

Aqui eu estou supondo que o direito de ponto de extremidade não está incluído em um intervalo.

Para ser completamente honesto, quando eu vi isso em Python, eu tive que perguntar:"a que custo?"

Outras dicas

Confira o que F# faz. Você pode fazer

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

onde o SEQ-EXPR é um formulário que inclui a maioria das construções de idiomas juntamente com o 'rendimento'. Então, por exemplo, você pode escrever

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

O compilador F# traduz esse código em uma implementação de máquina de estado de Ienumerable (como C# faz para blocos de iterador).

Eu gosto dessa sintaxe porque significa, por exemplo, você pode escrever exatamente o mesmo código que escreveria para "fazer coisas imperativas agora", por exemplo,

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

Mas embrulhe esse código no SEQ {} e use 'rendimento' e o código se torna um Ienumerable preguiçoso.

IEnumerable nats = 0...42

or for generators 

IEnumerable nats = yield 0...42
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top