7
votes

Spécificités d'appel / cc

Ceci est lié à Qu'est-ce que Call / CC? , mais je ne voulais pas Pour détourner cette question à mes propres fins, et certains de ses arguments comme l'analogie à SetJMP / Longjmp Evontez-moi.

Je pense avoir une idée suffisante sur la poursuite de la poursuite, j'y pense comme un instantané de la pile d'appels actuelle. Je ne veux pas aller dans la discussion pour laquelle cela pourrait être intéressant ou ce que vous pouvez faire avec les continuations. Ma question est plus spécifiquement, pourquoi dois-je fournir un argument de fonction à appeler / cc? Pourquoi n'appelle-t-il pas / cc vient de retourner la continuation actuelle, alors je pouvais faire tout ce que je veux avec elle (stockez-le, appelez-le, vous le nommez)? Dans un lien de cette autre question ( http: // communauté .schemewiki.org /? Call-with-courriel-continuation-for-c-programmeurs ), il parle "essentiellement, c'est juste un moyen propre pour obtenir la continuation avec vous et garder hors de la manière des sauts ultérieurs retour au point sauvé. ", mais je ne l'obtiens pas. Cela semble inutilement compliqué.


3 commentaires

Regardant sur ce fil, il est parfaitement incertain pour moi ce que vous étiez après, et pourquoi vous avez trouvé le poste LTU illuminant. Peut-être que vous pourriez éditer cette question pour expliquer ces choses mieux?


Je pense que la question reflète toujours exactement le point que je me luttais avec, et c'était probablement le terme "test" de l'affiche de la LTU qui a frappé avec moi, car cela m'a fait penser aux conséquences de simplement retourner la continuation, lorsque vous invoquez ce. La citation de l'URL Schemewiki.org dans la question a essentiellement capturé tout cela, mais comme je l'ai dit, je ne l'ai pas eu. C'était juste dans mon visage, mais je n'ai pas "vu". La compréhension n'est pas liée de manière linéaire de l'information et, parfois, il a besoin d'une torsion.


Ok, je l'ai eu! Le point sur le chemin torsadé à la compréhension est juste, mais c'est un peu frustrant d'essayer de répondre à une question et de ne pas pouvoir comprendre pourquoi le questionneur l'a rejeté.


4 Réponses :


2
votes

Ce serait moins polyvalent. Si vous voulez ce comportement, vous pouvez simplement faire:

(call/cc (lambda (x) x))


1 commentaires

Merci d'avoir montré comment je pourrais dégrader à ce cas d'angle. Mais je voulais une explication, pas une solution.



9
votes

Si vous utilisez une construction comme des émissions de Jay, vous pouvez saisir la suite, mais d'une certaine manière, la valeur qui est saisie est déjà gâtée car vous êtes déjà à l'intérieur de cette continuation. En revanche, appel / cc peut être utilisé pour saisir la suite qui est toujours en attente de l'expression actuelle. Par exemple, l'une des utilisations les plus simples de la continuation consiste à mettre en place une sorte de Abort : xxx

Vous ne pouvez pas le faire avec l'opération que vous décrivez. Si vous essayez: xxx

alors vous obtenez une erreur concernant l'application de 9 comme procédure. Cela se produit car abandon retourne au let avec la nouvelle valeur de 9 - ce qui signifie que vous faites maintenant un deuxième tour de La même expression d'addition, sauf que maintenant abandon est liée à 9 ...

deux notes connexes supplémentaires:

  1. Pour une belle introduction pratique à la poursuite, voir Pla .
  2. appel / cc est un peu complexe en ce que cela prend une fonction - une construction conceptuellement plus facile à utiliser est let / cc que vous pouvez trouver dans certaines implémentations telles que PLT Schéma. L'exemple ci-dessus devient (let / cc Abort (+ 1 2 (Abort 9))) .

3 commentaires

Donc, ce que vous dites en termes de ma question, est a) si la suite est immédiatement renvoyée, il est "gâté" parce que je suis à l'intérieur de la continuation. Mais je ne peux pas être dans une continuation à moins que je n'appelle ça. Si les continuations sont des valeurs de première classe, elles ne peuvent pas être gâtées en les transmettant, peuvent-ils ?! Ensuite, vous dites (b) Call / CC attraperait une continuation "en attente". Comment une valeur peut-elle être en attente? Vous dites également que la suite est «à l'extérieur» de l'expression actuelle. Je ne comprends pas vraiment ça. Combien la continuation capture-t-elle? Tout jusqu'à mais non inclure l'appel à appeler / cc ?!


Oui, vous êtes déjà à l'intérieur de la continuation. La chose à propos de la continuation est qu'elles représentent le calcul «futur» après l'expression de Call / CC actuel. Ainsi, après que vous ayez fini de (appeler / cc (Lambda (k) K)), vous passez immédiatement à la suite que Vous venez de capturer.


Remarque, BTW, que la vue de «une continuation représente la pile actuelle» est utile de la mettre en œuvre, mais de ne pas le comprendre. Une meilleure façon de le regarder si vous voulez comprendre qu'il est de le considérer comme le contexte. Par exemple, la suite qui devient liée à K dans (liste 1 2 (appel / cc (Lambda (k) k)) 3 4) est le contexte qui attend une réponse et procédera ensuite à évaluer 3 et 4, Ensuite, appliquez une liste sur les 5 valeurs. En d'autres termes, vous le considérez comme suit: (Liste 1 2 [...] 3 4). Cela peut être difficile à faire, car dans la plupart des cas, ce contexte est global. Voir ces références que j'ai signalées à.



2
votes

Je suggère de commencer en vous demandant: Que signifie être une continuation de première classe?

La poursuite d'une expression est essentiellement constituée de deux pièces de données: première, la fermeture (c'est-à-dire l'environnement) de cette expression ; et deuxièmement, une représentation de ce qui devrait être fait avec le résultat de l'expression. Une langue avec des continuations de première classe, est donc celle qui comporte des structures de données qui encapsulent ces pièces et traite ces structures de données tout comme elles le feraient d'autres. P>

Call / CC est un moyen particulièrement élégant de réaliser Cette idée: la poursuite actuelle est emballée en tant que procédure qui encapsule ce qui est-à-faire - avec l'expression de l'expression comme quelle est la procédure lorsqu'elle est appliquée à l'expression; Pour représenter la suite de cette façon signifie simplement que la fermeture de cette procédure contient l'environnement sur le site, il a été invoqué. P>

Vous pouvez imaginer réaliser l'idée de continuations de première classe d'une autre manière. Ils ne seraient pas appelés / cc, et il est difficile pour moi d'imaginer comment une telle représentation pourrait être plus simple. P>

sur une note de séparation, envisagez la mise en œuvre de Let / CC que Eli mentionné, que je préfère Appeler BIND / CC: P>

(define-syntax bind/cc
    (syntax-rules ()
        ((bind/cc var . body)
             (call/cc (lambda (var) . body)))))


1 commentaires

Merci pour le poste, mais c'est encore une fois, trop loin de ma question à me laisser une réponse.



2
votes

contre commun alors nesiquette Je réponds à ma propre question, mais plus comme éditeur que le fournisseur de la réponse.

Après un moment, j'ai commencé à une question similaire sur LTU . Après tout, ce sont les gars qui réfléchissent à la conception de la langue toute la journée, ne sont-ils pas, et l'un des réponses enfin frappé avec moi. Maintenant, les choses mentionnées ici, par ex. par Eli ou dans la question initiale, rendez-vous beaucoup plus de sens pour moi. Il s'agit de ce qui est inclus dans la continuation et où la suite appliquée s'installe.

Un de l'un des affiches chez LTU a écrit:

"Vous pouvez voir exactement comment Call / CC vous permet de" garder à l'écart ". Avec EM ou GET / CC, vous devez faire une sorte de test pour déterminer si vous avez un saut arrière ou juste la première appel. Fondamentalement, Call / CC conserve l'utilisation de la continuation de la continuation, alors qu'avec GET / CC ou EM, la suite contient son utilisation et (généralement), vous devez ajouter un test au début de la suite (c.-à-d. immédiatement après GET / CC / EM) pour séparer "Utilisation des pièces de continuation" à partir du "reste des pièces de continuation". "

qui l'a conduit à la maison pour moi.

Merci de toute façon!


1 commentaires

Je pense que le prestataire de continuation EM (exclu du milieu) de Derek peut être mis en œuvre à l'aide de GET / CC. Si je trouve le temps, je vérifierai cela.