2009-07-23 6 views
49

Estoy empezando a trabajar a través de SICP (por mi cuenta, esto no es para una clase), y he estado luchando con el ejercicio 1.6 durante un par de días y parece que no puedo entenderlo . Esto es en la que Alyssa redefine if en términos de cond, así:¿Cuál es la explicación para el ejercicio 1.6 en el SICP?

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

Ella pone a prueba con éxito en algunos casos sencillos, y luego lo utiliza para re-escribir el programa de la raíz cuadrada (que funcionaba bien con if):

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

La pregunta entonces se pregunta: "¿Qué pasa cuando Alyssa intenta usar esto para calcular raíces cuadradas Explicar?". [Si es necesario, me complace reproducir los otros procedimientos (good-enough?, improve, etc.), házmelo saber.]

Ahora, sé lo que sucede: nunca devuelve un valor, lo que significa que el programa recurses infinitamente Simplemente no puedo explicar por qué sucede esto. Cualquier diferencia sutil existente entre if y new-if me está eludiendo. Cualquier y toda ayuda muy apreciada.

+1

La forma verbal de "recursivo" es "recurrir", por lo que "recurses". –

+0

el título de su pregunta es incorrecto: se refiere al ejercicio 1.6, no al 1.4. – systemovich

+1

@Geoffrey Van Wyk Tienes razón. En el momento en que escribí la pregunta, estaba trabajando en mi copia anterior de la 1ra Edición del SICP, en la que este problema aparece como el Ejercicio 1.4. En la 2da Edición, es Ejercicio 1.6. Haré el cambio. –

Respuesta

62

new-if es una función. Cuando se llama a una función, ¿qué es lo primero que hace Scheme con la lista de argumentos? Evalúa todos los argumentos.

20

En primer lugar tiene que understand the difference entre la evaluación de la orden aplicativa y la orden normal. Lisp utiliza el orden aplicativo, pero las expresiones condicionales se evalúan no como funciones normales (sicp chapter 1.1.6):

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

para evaluar una expresión if, el intérprete se inicia mediante la evaluación de la parte <predicate> de la expresión. Si el <predicate> evalúa a un valor verdadero, el intérprete luego evalúa el <consequent> y devuelve su valor. De lo contrario, evalúa el <alternative> y devuelve su valor.

28

new-if es un procedimiento, y el Esquema utiliza evaluación aplicativo orden (1.1.5), por lo que incluso antes de new-if se realiza realmente, se tiene que evaluar todos los argumentos primeros, que son guess y (sqrt-iter (improve guess x) x). Puede ver que el último argumento es una recursión, que llama a un nuevo procedimiento new-if, así es como ocurre el ciclo infinito.

El ordinario if no necesita evaluar primero sus argumentos, solo siga el camino, esta es la diferencia entre if y new-if. :)

+0

El procedimiento 'new-if' tiene tres argumentos:' predicate', 'then-clause' y' else-clause'. Entonces cuando se llama 'new-if',' (lo suficientemente bueno? Guess x) ',' guess', y '(sqrt-iter (improve guess x))' son evaluados. Está bien ? Esto no cambia el resultado porque solo la evaluación de 'sqrt-iter' causa el problema. Pero tú has olvidado un argumento ... –

Cuestiones relacionadas