Question

Quelle est la différence entre un coroutine et une continuation et un générateur?

Était-ce utile?

La solution

Je vais commencer par les générateurs, car ils sont le cas le plus simple. Comme mentionné @zvolkov, ils sont des fonctions / objets qui peuvent être appelés à plusieurs reprises sans revenir, mais quand appelé retournera (rendement) d'une valeur, puis suspendre leur exécution. Quand on les appelle à nouveau, ils vont commencer à partir leur dernier suspendu l'exécution et faire à nouveau leur chose.

Un générateur est essentiellement un coupé (asymétrique) coroutine. La différence entre un coroutine et le générateur est qu'un coroutine peut accepter des arguments après qu'il a été d'abord appelé, alors qu'un générateur ne peut pas.

Il est un peu difficile de trouver un exemple trivial où vous utiliseriez coroutines, mais voici mon meilleur essai. Prenez ce (composé) du code Python comme exemple.

def my_coroutine_body(*args):
    while True:
        # Do some funky stuff
        *args = yield value_im_returning
        # Do some more funky stuff

my_coro = make_coroutine(my_coroutine_body)

x = 0
while True:
   # The coroutine does some funky stuff to x, and returns a new value.
   x = my_coro(x)
   print x

Un exemple où coroutines sont utilisés est lexers et parseurs. Sans coroutines dans la langue ou émulé d'une certaine manière, lexing et le code d'analyse syntaxique doit être mélangé ensemble, même si elles sont vraiment deux préoccupations distinctes. Mais en utilisant un coroutine, vous pouvez séparer le code lexing et l'analyse syntaxique.

(je vais brosser sur la différence entre les coroutines symétriques et asymétriques Il suffit de dire qu'ils sont équivalents, vous pouvez convertir de l'un à l'autre, et coroutines asymétriques -. Qui ressemblent le plus generators- -Est-ce que le plus facile à comprendre. Je décrivais comment on pourrait mettre en œuvre coroutines asymétriques en Python.)

continuations sont en fait des bêtes assez simples. Tout ce qu'ils sont, sont des fonctions qui représentent un autre point du programme qui, si vous l'appelez, provoquera l'exécution de passer automatiquement au point que la fonction représente. Vous utilisez très restreintes versions de tous les jours sans même le réaliser. Les exceptions, par exemple, peuvent être considérés comme une sorte de continuation à l'envers. Je vais vous donner un exemple de pseudo-code à base de Python d'une continuation.

Dis Python a une fonction appelée callcc(), et cette fonction a deux arguments, la première étant une fonction, et le second étant une liste d'arguments pour appeler avec. La seule restriction à cette fonction serait que le dernier argument qu'il faut sera une fonction (qui sera notre suite actuelle).

def foo(x, y, cc):
   cc(max(x, y))

biggest = callcc(foo, [23, 42])
print biggest

Que se passerait-il que callcc() serait dans foo() d'appel à son tour avec la poursuite en cours (cc), qui est une référence au point dans le programme auquel callcc() a été appelé. Lorsque foo() appelle la poursuite actuelle, il est essentiellement la même chose que dire callcc() de revenir avec la valeur que vous appelez la poursuite en cours avec, et quand il le fait, il annule la pile à l'endroit où la poursuite actuelle a été créée, à savoir quand vous avez appelé callcc().

Le résultat de tout cela serait que notre hypothétique variante Python imprimerait '42'.

J'espère que cela, et je suis sûr que mon explication peut être améliorée un peu!

Autres conseils

Coroutine est l'une de plusieurs procédures qui se relaient font leur travail, puis une pause pour donner le contrôle aux autres coroutines du groupe.

Suite est un « pointeur vers une fonction » vous passez à une procédure, à exécuter ( « poursuivi ») lorsque cette procédure est faite.

Générateur (.NET) est une construction de langage qui peut cracher sur une valeur, « pause » exécution de la méthode et passer ensuite à partir du même point lorsqu'on lui a demandé de la valeur suivante.

Dans la version plus récente de Python, vous pouvez envoyer des valeurs aux générateurs avec generator.send(), ce qui rend python générateurs Coroutines efficacement.

La principale différence entre le générateur de python et autre générateur, dire Greenlet, est que, en python, votre yield value ne peut revenir à l'appelant. Alors que dans Greenlet, target.switch(value) peut vous emmener à un coroutine et donner une valeur cible spécifique où le target continuerait à fonctionner.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top