Entendendo Generators, Iterators e Yield

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.

Etiquetado , , , , , , , , , , ,

Um pensamento sobre “Entendendo Generators, Iterators e Yield

  1. […] que você aprendeu tudo sobre generators neste blog, temos uma surpresa bem […]

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: