60 votes

Qu'est-ce que call / cc?

J'ai essayé plusieurs fois de saisir le concept de suites et de call/cc. Chaque tentative a été un échec. Quelqu'un peut-il svp m'expliquer ces concepts, idéalement avec plus réaliste des exemples de ces sur Wikipédia ou chez d'autres postes.

J'ai une formation en programmation web et de la programmation orientée objet. Je comprends aussi assembleur 6502 et eu un petit randez-vous avec Erlang. Cependant encore, je ne peut pas envelopper la tête autour de call/cc.

28voto

Kyle Cronin Points 35834

Pour le comparer à C, le courant de maintien est comme l'état actuel de la pile. Il dispose de toutes les fonctions en attendant le résultat de la fonction en cours de finition afin qu'ils puissent reprendre l'exécution. La variable capturée que le courant de maintien est utilisé comme une fonction, sauf qu'il prend la valeur fournie et le renvoie à l'attente de la pile. Ce comportement est similaire à la fonction C longjmp où vous pouvez retourner à la portion inférieure de la pile immédiatement.

(define x 0) ; dummy value - will be used to store continuation later

(+ 2 (call/cc (lambda (cc)
                (set! x cc)  ; set x to the continuation cc; namely, (+ 2 _)
                3)))         ; returns 5

(x 4) ; returns 6

Une des principales différences entre le C pile et une suite n'est qu'une continuation peut être utilisée à tout moment dans le programme, même si l'état de la pile a changé. Cela signifie que vous pouvez essentiellement de restaurer les versions antérieures de la pile et les utiliser encore et encore, conduisant ainsi à une unique flux de programme.

(* 123 (+ 345 (* 789 (x 5)))) ; returns 7

  reason: it is because (x 5) replaces the existing continuation,
          (* 123 (+ 345 (* 789 _))), with x, (+ 2 _), and returns
          5 to x, creating (+ 2 5), or 7.

La possibilité d'enregistrer et de restaurer l'état d'un programme a beaucoup en commun avec le multithreading. En fait, vous pouvez mettre en place votre propre planificateur de threads à l'aide de suites, que j'ai tenté d'illustrer ici.

24voto

temoto Points 1323

Regardez, j'ai trouvé la meilleure description de ce style de passage de continuation sur ce sujet.

10voto

vladr Points 34562

Un exemple trivial de l'utilisation de la continuation de la mise en œuvre d'un thread (fibre si vous le souhaitez) manager sur un ordinateur à processeur unique. Le planificateur pourrait interrompre le flux d'exécution périodiquement (ou, dans le cas de fibres, être invoquée à différents points stratégiques dans le code), enregistrer la continuation de l'état (correspondant au thread en cours), puis de passer à un autre de la continuation de l'état (correspondant à un autre thread dont l'état a été enregistré précédemment.)

Se référant à votre assemblée d'arrière-plan, la continuation de l'état de capturer des détails tels que les pointeur d'instruction, les registres, et du contexte de la pile (pointeur), pour être sauvé et restauré à volonté.

Une autre façon d'utiliser la continuation serait de penser à remplacer les appels de méthode avec plusieurs threads comme des entités qui co-existent en parallèle (soit en cours d'exécution ou suspendu) de contrôle de transmission pour chaque autre à l'aide de la poursuite des contextes au lieu de la 'classique' call paradigme. Ils fonctionnent sur le global (partagé) de données au lieu de s'appuyer sur des paramètres. C'est dans une certaine mesure plus souple qu' call dans le sens que la pile n'a pas à le vent vers le haut puis vers le bas (calls sont imbriquées), mais le contrôle de passer de manière arbitraire.

Essayer de visualiser ce concept dans une langue telle une C, imaginez-vous avoir une grande boucle avec un seul switch(continuation_point) { case point1: ... } déclaration, où chaque case correspond à une poursuite-point de sauvegarde, et où le code à l'intérieur de chaque case peut modifier la valeur de continuation_point et de renoncer à de contrôle pour qu' continuation_point par breaking de l' switch et la participation de la prochaine itération de la boucle.

Quel est le contexte de votre question? Tout les scénarios particuliers, vous êtes intéressé? Tout langage de programmation particulier? Est le fil/fibre exemple ci-dessus est-elle suffisante?

5voto

Dave Points 2554

La chose qui m'a aidé, c'est l'idée que, dans une langue traditionnelle, avec des appels de fonction vous implicitement passer une poursuite tout moment d'un appel de fonction.

Avant de sauter à un code de fonction vous économiser de l'état de la pile (c'est à dire que vous poussez votre adresse de retour et la pile contient déjà vos locaux). C'est essentiellement une continuation. Lorsque la fonction a terminé, il a pour déterminer où envoyer le flux d'exécution. Il utilise la poursuite stockées sur la pile, popping l'adresse de retour et le saut à elle.

D'autres langues généraliser cette idée de continuations, vous permettant de spécifier explicitement où continuer l'exécution du code, plutôt que de façon implicite continue sur d'où l'appel de la fonction a été faite.

EDIT basé sur les commentaires:

La suite est la complète exécution de l'état. À tout moment de l'exécution, vous pouvez diviser le programme en deux parties (dans le temps, pas d'espace) - ce qui a exécuté jusqu'à ce point, et tout ce qui va exécuter à partir d'ici. L'actuel "suite" est le "tout ce qui va exécuter à partir d'ici" (vous pouvez voir ça comme une sorte de fonction qui va faire tout le reste de votre programme aurais fait). Donc la fonction que vous fournissez call/cc est passée la poursuite qui était en vigueur lors de l' call/cc a été invoquée. La fonction peut utiliser la continuation de retour de l'exécution de l' call/cc déclaration (plus probable si ça va passer à la poursuite autour de quelque chose d'autre, parce que si elle est utilisée directement, il pourrait faire un retour pur et simple à la place).

5voto

SCFrench Points 4826

Lorsque j'essayais de comprendre call / cc, j'ai trouvé que cette page d' appel avec les programmeurs en cours de continuation pour C était utile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X