2009-07-23 15 views
49

Sto appena iniziando a lavorare su SICP (da solo, non è per una lezione), e ho sofferto con l'Esercizio 1.6 per un paio di giorni e non riesco a capirlo . Questo è quello in cui Alyssa ridefinisce if in termini di cond, in questo modo:Qual è la spiegazione dell'esercizio 1.6 in SICP?

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

Si verifica con successo in alcuni casi semplici, e quindi lo utilizza per riscrivere il programma radice quadrata (che funzionava 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 restituisce mai un valore, il che significa che il programma ricorre all'infinito. Non riesco proprio a spiegare perché questo accada. Qualunque sottile differenza esiste tra if e new-if mi sfugge. Qualsiasi aiuto è molto apprezzato.

+1

La forma del verbo "recursive" è "recurse", quindi "ricorre". –

+0

il titolo della tua domanda è sbagliato: ti riferisci all'esercizio 1.6, non 1.4. – systemovich

+1

@Geoffrey Van Wyk Hai ragione. All'epoca in cui ho scritto la domanda, stavo lavorando alla mia vecchia copia della prima edizione di SICP, in cui questo problema si presenta come esercizio 1.4. Nella 2a Edizione, è l'Esercizio 1.6. Farò il resto. –

risposta

62

new-if è una funzione. Quando viene chiamata una funzione, qual è la prima cosa che Scheme fa con la lista degli argomenti? Valuta tutti gli argomenti.

20

Prima di tutto è necessario understand the difference tra la valutazione di ordine applicativo e l'ordine normale. Lisp utilizza ordine applicativa, ma le espressioni condizionali vengono valutati non come normali funzioni (sicp chapter 1.1.6):

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

Per valutare se un'espressione, l'interprete inizia valutando la parte <predicate> dell'espressione. Se lo <predicate> restituisce un valore reale, l'interprete valuta lo <consequent> e restituisce il suo valore. Altrimenti valuta <alternative> e restituisce il suo valore.

28

new-if è un procedimento e sistema utilizza la valutazione applicativa-cassa (1.1.5), quindi anche prima new-if viene effettivamente eseguita, si deve valutare tutti gli argomenti prime, che sono guess e (sqrt-iter (improve guess x) x). Si può vedere che quest'ultimo argomento è una ricorsione, che chiama una nuova procedura new-if, questo è come avviene il ciclo infinito.

L'ordinario if non deve prima valutare i suoi argomenti, basta andare lungo la strada, questa è la differenza tra if e new-if. :)

+0

La procedura 'new-if' ha tre argomenti:' predicate', 'then-clause' e' else-clause'. Quindi quando 'new-if' è chiamato,' (abbastanza buono? Guess x) ',' guess', e '(sqrt-iter (migliora l'ipotesi x))' sono valutati. È giusto ? Questo non cambia il risultato perché solo la valutazione di 'sqrt-iter' causa il problema. Ma hai dimenticato un argomento ... –

Problemi correlati