6
votes

Y a-t-il un moyen dans un langage de messages uniquement pour définir un message WhileTetrue sans tours de récursion ou de compilateur?

SmallTalk a la base: -Message mis en œuvre par récursivité (dans Visualworks) ou par l'inflexion de compilateur (dans Squeak / Pharo). Existe-t-il un moyen de définir une telle méthode sans utiliser l'un d'entre eux? Sinon, y a-t-il une preuve pour cette aviable quelque part?


0 commentaires

4 Réponses :


5
votes

Je propose la solution suivante: xxx

au lieu d'utiliser des tours de récursivité et de compilateur, le code ci-dessus utilise la réflexion sur la pile d'exécution. Avant que la boucle ne commence la méthode stocke le compteur de programme actuel dans une variable temporaire et la réinitialise à la fin pour revenir au début de la méthode. Dans certaines implémentations de SmallTalk, une telle approche pourrait être lente car certaines dialectes de SmallTalk réindiquent la pile à la demande uniquement, mais à Pharo / Squeak, cette astuce est assez pratique.

Remarque, le code ci-dessus ne répond pas au résultat de La dernière activation du bloc en tant que mise en œuvre initiale de #Quitre: fait. Il devrait être assez facile de résoudre ce problème.


2 commentaires

Dans ce cas, la restauration du contexte est fondamentalement l'équivalent de goto


Sans récursivité infinie, sans nombre infini de déclaration et sans la capacité de reprendre un contexte, il semble impossible.



1
votes

Vous pouvez également utiliser un gestionnaire d'exception pour le faire revenir au début, mais cela pourrait compter comme tricher si le code de manipulation des exceptions utilisait un élément essentiel: ou une autre construction de boucle quelque part. Ainsi, fondamentalement, la question se résume si vous pouvez mettre en œuvre une boucle sans aller à l'emploi ni à la récursivité, et je pense que la réponse est non. Donc, si la récursion est interdite, vous êtes laissé à essayer de gaver un goto de techniques telles que définir la méthode PC ou en utilisant une exception.


0 commentaires

4
votes

WhileRue: & Tandurlied: retournez toujours nul. par exemple. S'il y a une définition récursive normale:

ContextPart methods for controlling
label
    ^{ pc. stackp }

goto: aLabel
    "N.B. we *must* answer label so that the
     top of stack is aLabel as it is when we send label"
    pc := aLabel at: 1.
    self stackp: (aLabel at: 2).
    ^aLabel

BlockContext>>myWhileTrue: aBlock 
    | label |
    label := thisContext label.
    self value ifFalse: [^nil].
    aBlock value.
    thisContext goto: label

BlockClosure>>myWhileTrue: aBlock 
    | label |
    label := thisContext label.
    ^self value ifTrue:
        [aBlock value.
         thisContext goto: label]


0 commentaires

1
votes

juste faire:

Blockclousure >> WhileRue: Ablock

Valeur de soi Iftrue: [ Valeur Ablock. CeciContext Redémarrer. "Redémarrez sur Pharo, réinitialiser sur VW"]


0 commentaires