Primeiramente, estamos falando de recursos de linguagens de programação, ou seja, este assunto é para arquitetos e coders.
Em segundo lugar, Generators e Iterators são a mesma coisa – por tanto, a partir daqui utilizarei somente a palavra Generators e você já sabe que estou falando dos dois!
Isto posto, vamos em frente.
Generator é uma espécie de função especial para controlar o comportamento de um looping numa coleção de itens. A grosso modo, é uma função que retorna uma lista (array ou vetores), como aquelas funções básicas que as vezes você cria para alimentar uma coleção de objetos.
A diferença está no comportamento: enquanto no modelo tradicional sua função de looping adiciona todos os itens numa coleção de uma única vez, e somente quando esta operação terminar a função retorna esta coleção completamente carrega, com o uso de generators os itens são entregues para a função chamadora (caller) um de cada vez através do yield, conforme a coleção for sendo utilizada por este caller.
Isto garante melhor utilização da memória e incrementa a performance em quase todas as situações, uma vez que os itens são processados em menor quantidade. Há cenários a qual os generators não são bem-vindos, como em situações de recursividade, ou quando é necessário retornar uma outra coleção de itens ou quando exceções são disparadas dentro do generator – mas estas são situações de exceção.
Em resumo, os generators lembram muito uma função, mas se comportam como iteradores.
Para exemplificar, segue o modelo tradicional:
FUNCAO Looping Tradicional
VARIÁVEL Coleção de Números
CONTAR DE 1 Até 5 NA VARIÁVEL Número
ADICIONAR Número NA Coleção de Números
LOGAR “Looping Tradicional” CONCATENADO COM Número
RETORNAR Coleção de Números
FUNCAO Imprimir Valor do Looping
VARIÁVEL Resultado IGUAL Á Looping Tradicional
PARA CADA Item NO Resultado
IMPRIMIR Item
LOGAR “Imprimir Valor” CONCATENADO COM Item
Quando a função caller “Imprimir Valor do Looping” for executada, será logado o seguinte:
Looping Tradicional 1
Looping Tradicional 2
Looping Tradicional 3
Looping Tradicional 4
Imprimir Valor 1
Imprimir Valor 2
Imprimir Valor 3
Imprimir Valor 4
Isto por que primeiro foi carregado toda a coleção da função “Looping Tradicional” de uma única vez. Depois ela voltou esta coleção para a função caller, que leu cada um dos resultados e imprimiu o valor de cada um dos números.
Vamos ver como ficaria o mesmo exemplo com Generator:
FUNCAO Looping Generator
VARIÁVEL Coleção de Números
CONTAR DE 1 Até 5 NA VARIÁVEL Número
YIELD ADICIONAR Número NA Coleção de Números
LOGAR “Looping Generator” CONCATENADO COM Número
RETORNAR Coleção de Números
FUNCAO Imprimir Valor do Looping
VARIÁVEL Resultado IGUAL Á Looping Generator
PARA CADA Item NO Resultado
IMPRIMIR Item
LOGAR “Imprimir Valor” CONCATENADO COM Item
O resultado ficará assim:
Looping Generator 1
Imprimir Valor 1
Looping Generator 2
Imprimir Valor 2
Looping Generator 3
Imprimir Valor 3
Looping Generator 4
Imprimir Valor 4
Ou seja, conforme os itens forem sendo solicitados na função caller, eles são retirados da função Generator, um à um, graças ao YIELD, que guarda a posição de retirada do item para voltar daquele ponto, assim que for solicitado pelo caller.
Este recurso não é novidade desde muito tempo para uma série de linguagens de programação. De fato, ele surgiu entre 1974 e 1975 na linguagem CLU. No C#, temos o recurso nativo disponível desde 2005, com o lançamento da .NET Framework 2.0. Em outras linguagens o lançamento é mais recente, como no caso do PHP 5.5. Temos ainda versões nativas no Python e no Ruby.
Uma coisa para deixar toda a comunidade bem empolgada é que o recurso entrou na especificação do ECMAScript 6 (conhecida como Harmony). Isto significa que o Javascript terá uma versão nativa em breve. Sendo assim, o pessoal da Vision Media não perdeu tempo e lançou o co para Node.js, módulo que também implementa os Generators, de acordo com a ECMAScript 6!
Curiosamente não temos o recurso nativo no Java – faço votos para que chegue muito em breve.
No próximo post, vamos ver alguns exemplos.
[…] que você aprendeu tudo sobre generators neste blog, temos uma surpresa bem […]