32 votes

Je n'ai tout simplement pas de suite!

Qu'est-ce qu'ils sont et à quoi servent-ils?

Je n'ai pas de diplôme de CS et je suis issu de VB6 -> ASP -> ASP.NET/C#. Quelqu'un peut-il l'expliquer de manière claire et concise?

42voto

John Millikin Points 86775

Imaginez si chaque ligne de votre programme constituait une fonction distincte. Chacun accepte, en tant que paramètre, la ligne / fonction suivante à exécuter.

En utilisant ce modèle, vous pouvez "suspendre" l'exécution de n'importe quelle ligne et la poursuivre plus tard. Vous pouvez également faire des choses inventives telles que sauter temporairement la pile d'exécution pour récupérer une valeur ou enregistrer l'état d'exécution actuel dans une base de données pour le récupérer ultérieurement.

11voto

Dustin Points 35205

Vous comprenez sans doute mieux que vous le pensez.

Les Exceptions sont un exemple de "la hausse" uniquement " les suites. Ils permettent au code de profondeur vers le bas de la pile pour en appeler à un gestionnaire d'exception pour indiquer un problème.

Exemple Python:

try:
    broken_function()
except SomeException:
    # jump to here
    pass

def broken_function():
    raise SomeException() # go back up the stack
    # stuff that won't be evaluated

Les générateurs sont des exemples de "à la baisse" uniquement " les suites. Ils permettent de code à entrer de nouveau une boucle, par exemple, pour créer de nouvelles valeurs.

Exemple Python:

def sequence_generator(i=1):
    while True:
        yield i  # "return" this value, and come back here for the next
        i = i + 1

g = sequence_generator()
while True:
    print g.next()

Dans les deux cas, ils devaient être ajoutés à la langue spécifiquement tandis que dans une langue avec les continuations, le programmeur peut créer ces choses là où ils ne sont pas disponibles.

9voto

Kyle Cronin Points 35834

Un heads-up, cet exemple n'est pas concis, ni exceptionnellement claire. C'est une démonstration d'une application puissante de continuations. Une VB/ASP/C#, programmeur, vous pouvez ne pas être familiers avec le concept d'un système de pile ou de l'enregistrement de l'état, de sorte que le but de cette réponse, c'est une démonstration et non une explication.

Les suites sont extrêmement polyvalents et sont un moyen d'économiser de l'état d'exécution et le reprendre plus tard. Voici un petit exemple d'une coopérative de multithreading environnement à l'aide de suites dans le Schéma:

(À supposer que les opérations de mise en file et file d'attente de travail comme prévu sur un mondial de la file d'attente pas défini ici)

(define (fork)
  (display "forking\n")
  (call-with-current-continuation
   (lambda (cc)
     (enqueue (lambda ()
                (cc #f)))
     (cc #t))))

(define (context-switch)
  (display "context switching\n")
  (call-with-current-continuation
   (lambda (cc)
     (enqueue
      (lambda ()
        (cc 'nothing)))
     ((dequeue)))))

(define (end-process)
  (display "ending process\n")
  (let ((proc (dequeue)))
    (if (eq? proc 'queue-empty)
        (display "all processes terminated\n")
        (proc))))

Cette offre trois verbes qui permet à une fonction de l'utilisation - de la fourche, du contexte de l'interrupteur, et en fin de processus. La fourche opération de fourches le fil et renvoie #t dans un cas et #f dans un autre. Le contexte-le fonctionnement du commutateur commutateurs entre les threads, et en fin de processus se termine, un thread.

Voici un exemple de leur utilisation:

(define (test-cs)
  (display "entering test\n")
  (cond
    ((fork) (cond
              ((fork) (display "process 1\n")
                      (context-switch)
                      (display "process 1 again\n"))
              (else (display "process 2\n")
                    (end-process)
                    (display "you shouldn't see this (2)"))))
    (else (cond ((fork) (display "process 3\n")
                        (display "process 3 again\n")
                        (context-switch))
                (else (display "process 4\n")))))
  (context-switch)
  (display "ending process\n")
  (end-process)
  (display "process ended (should only see this once)\n"))

La sortie doit être

entering test
forking
forking
process 1
context switching
forking
process 3
process 3 again
context switching
process 2
ending process
process 1 again
context switching
process 4
context switching
context switching
ending process
ending process
ending process
ending process
ending process
ending process
all processes terminated
process ended (should only see this once)

Ceux qui ont étudié la fourche et le filetage dans une classe sont souvent donné des exemples similaires à ce. Le but de ce post est de montrer qu'avec les continuations vous pouvez obtenir des résultats similaires dans un seul thread par la sauvegarde et la restauration de l'etat de sa continuation manuellement.

P. S. - je pense que je me souviens de quelque chose de semblable Sur Lisp, donc si vous voulez voir le code des professions, vous devriez vérifier le livre.

8voto

Paul Johnson Points 8604

Une façon de penser d'une poursuite est un processeur de la pile. Lorsque vous "call-with-current-poursuite c" il appelle votre fonction "c", et le paramètre passé à "c" est votre pile avec toutes vos variables automatiques sur elle (représenté encore une autre fonction, de l'appeler "k"). Pendant ce temps, le processeur commence la création d'une nouvelle pile. Lorsque vous appelez "k", il exécute un "retour de sous-routine" (RTS) l'instruction sur l'origine de la pile, le saut, vous de retour dans le cadre du "call-with-current-poursuite" ("call-cc" à partir de maintenant) et en permettant à votre programme de continuer comme avant. Si vous avez passé un paramètre "k", puis cela devient la valeur de retour de l'appel "cc".

Du point de vue de votre tapis de départ, le "call-cc" ressemble à un appel de fonction. Du point de vue de "c", l'original de votre pile ressemble à une fonction qui ne retourne jamais.

Il y a une vieille blague sur un mathématicien qui a capturé un lion dans une cage par l'escalade dans la cage, le verrouillage, et se déclarant lui-même en dehors de la cage tandis que tout le reste (y compris le lion) était à l'intérieur. Les suites sont un peu comme de la cage, et "c" est un peu comme le mathématicien. Votre programme principal pense que "c" est à l'intérieur, tout en "c", estime que votre programme principal est à l'intérieur "k".

Vous pouvez créer arbitraire flux de structures de contrôle à l'aide de suites. Par exemple, vous pouvez créer un enfilage de la bibliothèque. "rendement" utilise des "cc" pour mettre l'continuation sur une file d'attente, puis saute dans à la une sur la tête de la file d'attente. Un sémaphore aussi a sa propre file d'attente de suspension des poursuites, et qu'un thread est reporté par le prendre sur le sémaphore de la file d'attente et de le mettre sur la file d'attente principale.

4voto

Jason Baker Points 56682

Fondamentalement, une continuation est la possibilité pour une fonction d’arrêter l’exécution, puis de reprendre là où elle s’est arrêtée ultérieurement. En C #, vous pouvez le faire en utilisant le mot-clé rendement. Je peux entrer plus en détail si vous le souhaitez, mais vous vouliez une explication concise. ;-)

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