Question

Je suis juste commencer à travailler sur SICP (moi-même, ce n'est pas pour une classe), et je l'ai été aux prises avec l'exercice 1.6 pour quelques jours et je ne peux pas sembler comprendre en dehors. C'est celui où Alyssa re-définit if en termes de cond, comme suit:

(define (new-if predicate then-clause else-clause)
    (cond (predicate then-clause)
          (else else-clause))

Elle teste avec succès sur certains cas simples, et utilise ensuite pour réécrire le programme de racine carrée (qui fonctionnait très bien avec if):

(define (sqrt-iter guess x)
    (new-if (good-enough? guess x)
            guess
            (sqrt-iter (improve guess x)
                       x)))

La question demande alors: « Qu'est-ce qui se passe quand Alyssa tente d'utiliser pour calculer des racines carrées? Expliquez. » [Si nécessaire, je suis heureux de reproduire les autres procédures (good-enough?, improve, etc.), vient de me faire savoir.]

Maintenant, je sais ce qui se passe: il ne retourne une valeur, ce qui signifie que le programme récursif infini. Je ne peux pas expliquer pourquoi cela se produit. Quelle que soit la différence subtile existe entre if et new-if qui me éludant. Toute aide très appréciée.

Était-ce utile?

La solution

new-if est une fonction. Lorsqu'une fonction est appelée, quelle est la première chose que le schéma fait avec la liste des arguments? Il évalue tous les arguments.

Autres conseils

new-if est une procédure, et utilise le schéma d'évaluation d'ordre applicatif (1.1.5), donc avant même new-if est effectivement réalisé, il doit évaluer tous les arguments d'abord, qui sont guess et (sqrt-iter (improve guess x) x). Vous pouvez voir que ce dernier argument est une récursion, qui appelle une nouvelle procédure de new-if, voici comment se produit la boucle infinie.

Le if ordinaire n'a pas besoin d'évaluer d'abord ses arguments, il suffit d'aller sur le chemin, c'est la différence entre if et new-if. :)

Tout d'abord, vous devez comprendre la différence entre l'évaluation de commande applicative ordre normal. Lisp utilise l'ordre applicatif, mais les expressions conditionnelles ne sont pas évaluées comme des fonctions normales ( chapitre SICP 1.1.6 ):

(if <predicate> <consequent> <alternative>)
  

Pour évaluer une expression si, l'interprète commence par l'évaluation de la partie <predicate> de l'expression. Si le <predicate> évalue à une valeur réelle, l'interprète évalue ensuite la <consequent> et retourne sa valeur. Sinon, il évalue la <alternative> et retourne sa valeur.

Ex1.6. nouveau si:

(define (new-if predicate then-clause else-clause)
     (cond (predicate then-clause)
                (else else-clause)))

Différence avec « si-déclarations »: si-déclarations évaluent un par un à partir prédicat -> conséquente -> alternatif,

mais la « nouvelle si » doit évaluer tous les paramètres aka arguments du INSTANT son appelé (qui signifie « autre article » est évaluée au début !!),

et donc cela provoque une boucle infinie lorsque l'un de ces paramètres se remettent en une boucle itérative

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