Qual é a diferença entre uma corotina e uma continuação e um gerador?
generator
continuations
coroutine
Mehdi Asgari
fonte
fonte
Respostas:
Vou começar com os geradores, pois são o caso mais simples. Como @zvolkov mencionou, são funções / objetos que podem ser chamados repetidamente sem retornar, mas quando chamados retornarão (produzirão) um valor e suspenderão sua execução. Quando eles são chamados novamente, eles iniciam a partir do ponto em que suspenderam a execução e fazem suas ações novamente.
Um gerador é essencialmente uma corotina cortada (assimétrica). A diferença entre uma corotina e um gerador é que uma corotina pode aceitar argumentos depois de ter sido chamada inicialmente, enquanto um gerador não pode.
É um pouco difícil criar um exemplo trivial de onde você usaria corotinas, mas aqui está minha melhor tentativa. Tome esse código Python (composto) como exemplo.
Um exemplo de onde as corotinas são usadas é lexers e analisadores. Sem corotinas no idioma ou emuladas de alguma forma, o código lexing e de análise precisa ser misturado, mesmo que sejam realmente duas preocupações separadas. Mas, usando uma corotina, é possível separar o código lexing e de análise.
(Vou abordar a diferença entre corotinas simétricas e assimétricas. Basta dizer que elas são equivalentes, você pode converter de uma para a outra, e as corotinas assimétricas - que são as mais parecidas com geradores - são as Eu estava descrevendo como é possível implementar coroutines assimétricas em Python.)
Continuações são realmente bestas muito simples. São funções representando outro ponto do programa que, se você o chamar, fará com que a execução mude automaticamente para o ponto que a função representa. Você usa versões muito restritas deles todos os dias sem nem perceber. Exceções, por exemplo, podem ser pensadas como uma espécie de continuação de dentro para fora. Vou dar um exemplo de pseudocódigo baseado em Python de uma continuação.
Digamos que o Python tenha uma função chamada
callcc()
, e essa função tenha dois argumentos, o primeiro sendo uma função e o segundo uma lista de argumentos para chamá-lo. A única restrição a essa função seria que o último argumento necessário será uma função (que será nossa continuação atual).O que aconteceria é que
callcc()
, por sua vez, chamariafoo()
a continuação atual (cc
), isto é, uma referência ao ponto no programa em quecallcc()
foi chamado. Quandofoo()
chama a continuação atual, é essencialmente o mesmo que dizercallcc()
para retornar com o valor com o qual você está chamando a continuação atual e, quando faz isso, reverte a pilha para onde a continuação atual foi criada, ou seja, quando você chamoucallcc()
.O resultado de tudo isso seria que nossa hipotética variante Python seria impressa
'42'
.Espero que ajude, e tenho certeza que minha explicação pode melhorar um pouco!
fonte
A corotina é um dos vários procedimentos que se revezam no trabalho e depois param para dar controle às outras corotinas do grupo.
A continuação é um "ponteiro para uma função" que você passa para algum procedimento, a ser executado ("continuado com") quando esse procedimento é concluído.
Generator (no .NET) é uma construção de linguagem que pode cuspir um valor, "pausar" a execução do método e prosseguir a partir do mesmo ponto quando solicitado pelo próximo valor.
fonte
Na versão mais recente do Python, você pode enviar valores para os Geradores com
generator.send()
, o que faz com que os Geradores de python efetivamente sejam rotineiros.A principal diferença entre o python Generator e outro gerador, digamos greenlet, é que, em python, você
yield value
só pode retornar ao chamador. Enquanto estiver no greenlet,target.switch(value)
você pode levá-lo a uma corotina de destino específica e gerar um valor em que o valortarget
continuaria a ser executado.fonte
yield
chamadas devem estar na mesma função, chamada de "Gerador". Você não podeyield
de uma sub-função, e é por isso que os Python são chamados de semi-corotinas , enquanto Lua possui corotinas assimétricas . (Existem propostas para propagar os rendimentos, mas acho que só esses turvar as águas.)