A escolha de uma sintaxe para a lista de geração de expressões [fechado]
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#.
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