Question

Je suis en train de savoir comment je peux faire un « retour rapide » dans une procédure de système sans à l'aide d'un if haut niveau ou cond comme construction.

(define (win b)
 (let* ((test (first (first b)))
        (result (every (lambda (i) (= (list-ref (list-ref b i) i) test))
                       (enumerate (length b)))))
  (when (and (not (= test 0)) result) test))
 0)

Par exemple, dans le code ci-dessus, je veux win revenir test si la condition de when est atteint, sinon revenir 0. Cependant, ce qui se passe est que la procédure toujours return 0, quel que soit le résultat de la condition de when.

La raison pour laquelle je Structurer mon code de cette façon est parce que dans cette procédure que je dois faire de nombreux contrôles complexes (plusieurs blocs semblables à la let* dans l'exemple) et tout mettre dans un grand cond serait très difficile à manier.

Était-ce utile?

La solution

Voici comment utiliser l'appel / cc pour construire vous-même return.

(define (example x)
  (call/cc (lambda (return)
    (when (< x 0) (return #f))
    ; more code, including possible more calls to return
    0)))

Certains systèmes définissent une macro appelée let / cc qui vous permet de déposer une partie du bruit du lambda:

(define (example x)
  (let/cc return
    (when (< x 0) (return #f))
    0))

Bien sûr, si votre régime ne pas laisser / cc est trivial d'écrire.


Cela fonctionne parce que l'appel / cc enregistre le point où il a été appelé comme une continuation. Il passe que la poursuite de son argument de la fonction. Lorsque la fonction appelle que la poursuite, le schéma abandonne tout pile appel, il avait construit jusqu'à présent et continue de la fin de l'appel appel / cc. Bien sûr, si la fonction appelle jamais la poursuite, il retourne juste normalement.

continuations ne reçoivent pas vraiment hallucinant jusqu'à ce que vous commencez à les retour de cette fonction, ou de les stocker peut-être dans une structure de données globales et les appeler plus tard. Dans le cas contraire, ils sont comme tous les autres déclarations structurées-goto de langue (alors que / pour / pause / retour / continuer / exceptions / conditions).


Je ne sais pas ce que votre code complet ressemble, mais il pourrait être préférable d'aller avec le facteur et cond les contrôles complexes dans des fonctions distinctes. Ayant besoin return et let* est habituellement un symptôme d'un code trop impératif. Cependant, la méthode d'appel / cc devrait obtenir votre code de travail pour l'instant.

Autres conseils

Une façon serait d'utiliser la récursivité au lieu de boucle, puis une sortie précoce est obtenue en ne récursion plus.

Vous pouvez utiliser le support « appel à la poursuite en cours » pour simuler un retour. Il y a un exemple sur wikipedia . La fonction est appelée call-with-courant continuation , bien qu'il y ait souvent un alias appeler / cc qui est exactement la même chose. Il y a aussi un exemple un peu plus propre

Note: Ceci est tout à fait une technique de programmation Scheme avancée et peut être un esprit peu de flexion au premier ... !!!!

Dans ce cas, vous ne voulez pas quand, vous voulez un si, mais pas de haut niveau.

(define (win b)
  (let* ((test (first (first b)))
         (result (every (lambda (i) (= (list-ref (list-ref b i) i) test))
                        (enumerate (length b)))))
    (if (and (not (= test 0)) result) 
        test
        0)))

La raison pour laquelle il a toujours été de retour à zéro est que si oui ou non le corps de l'exécution lorsque se est, le résultat serait tombé sur le sol. Vous voyez, le lambda implicite dans la fonction crée la forme définit un bloc implicite commencent aussi, donc

(define foo 
  (lambda (b)
     (begin
       (let ...)
       0)))

et les travaux façon de commencer est qu'il renvoie le résultat de la dernière forme à l'intérieur, tout en laissant tomber tous les résultats intermédiaires sur le sol. Ces résultats intermédiaires sont destinés à avoir des effets secondaires. Vous n'utilisez pas de ce qui est grand (!), Mais vous devez faire attention à n'avoir une forme (dont le résultat que vous voulez vraiment) dans la définition de la fonction.

Grem

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