Qual è la spiegazione per l'esercitazione 1.6 in SICP?
Domanda
Sto solo cominciando a lavorare attraverso SICP (per conto mio, questo non è per una classe), e sono stato alle prese con l'esercizio 1.6 per un paio di giorni e io non riesco a capirlo su. Questo è quello in cui Alyssa ridefinisce if
in termini di cond
, in questo modo:
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause))
Si mette alla prova con successo in alcuni casi semplici, e poi lo usa per ri-scrivere il programma radice quadrata (che ha lavorato bene con if
):
(define (sqrt-iter guess x)
(new-if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x)))
La domanda chiede quindi: "Cosa succede quando Alyssa tenta di usare questo per calcolare radici quadrate spiegare?". [Se necessario, sono felice di riprodurre le altre procedure (good-enough?
, improve
, ecc), fammelo sapere.]
Ora, so cosa succede: non si è mai restituisce un valore, il che significa che il programma recurses infinitamente. Non riesco a spiegare perché questo accade. esiste Qualunque sia la sottile differenza tra il if
e new-if
mi sta sfuggendo. C'è ne e tutto l'aiuto molto apprezzato.
Soluzione
new-if
è una funzione. Quando una funzione viene chiamata, qual è la prima cosa che fa Scheme con la lista degli argomenti? Esso valuta tutti gli argomenti.
Altri suggerimenti
new-if
è un procedimento e sistema utilizza la valutazione applicativa-cassa (1.1.5), quindi anche prima new-if
viene effettivamente eseguita, deve valutare tutti gli argomenti primo, che sono guess
e (sqrt-iter (improve guess x) x)
. Si può vedere che il secondo argomento è una ricorsione, che chiama una nuova procedura new-if
, questo è come si verifica il ciclo infinito.
Il if
normale non ha bisogno di valutare i suoi argomenti primo, basta andare lungo la strada, questa è la differenza tra if
e new-if
. :)
Prima di tutto è necessario capire la differenza tra valutazione ordine applicativa e l'ordine normale. Lisp utilizza ordine applicativa, ma le espressioni condizionali vengono valutati non come normali funzioni ( SICP capitolo 1.1.6 ):
(if <predicate> <consequent> <alternative>)
Per valutare se un'espressione, l'interprete inizia valutando la parte
<predicate>
dell'espressione. Se il<predicate>
restituisce un valore vero, l'interprete poi valuta la<consequent>
e restituisce il suo valore. In caso contrario, valuta la<alternative>
e restituisce il suo valore.
Ex1.6. new-se:
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))
La differenza con i ‘se-dichiarazioni’: se-dichiarazioni valutano uno ad uno dal predicato -> conseguente -> alternativa,
tuttavia la ‘nuova-se’ deve valutare tutti i parametri alias argomenti MOMENTO sua chiamata (che significa 'altra clausola' viene valutata alla partenza !!),
e quindi questo causa un ciclo infinito quando uno di questi parametri si definiscono un ciclo iterativo