2009-07-23 53 views
49

我剛開始工作通過SICP(我自己;這不是一個班級),並且我一直在努力練習1.6幾天,我似乎無法弄清楚。在cond而言這是一個地方賈靜雯重新定義if,像這樣:SICP練習1.6的解釋是什麼?

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

她成功地測試它在一些簡單的情況下,然後使用它來重新寫的平方根程序(這只是工作細跟if):

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

那麼接下來的問題問:「當阿麗莎試圖以此來計算平方根說明會發生什麼?」。 [如果有必要,我很高興能重現其他程序(good-enough?improve等),只是讓我知道。]

現在,我知道會發生什麼:它永遠不會返回一個值,這意味着程序無限遞歸。我無法解釋爲什麼會發生這種情況。無論ifnew-if之間存在什麼細微差別,都無法避免。任何和所有的幫助非常感謝。

+1

「遞歸」的動詞形式是「recurse」,所以它「遞歸」。 – 2009-07-23 11:57:29

+0

你的問題標題是錯誤的:你指的是練習1.6,而不是1.4。 – systemovich 2010-12-12 15:24:23

回答

62

new-if是一個函數。當一個函數被調用時,Scheme對參數列表做的第一件事是什麼?它評估全部的論點。

20

首先你必須understand the difference適用訂單評估和正常訂單之間。 Lisp的應用性使用順序,但條件表達式求值不象正常功能(sicp chapter 1.1.6):

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

爲了評估一個if語句,解釋器通過評估表達的<predicate>部分開始。如果<predicate>的計算結果爲真值,則解釋程序將評估<consequent>並返回其值。否則,它會評估<alternative>並返回其值。

28

new-if是一個過程,並計劃使用應用性,爲了評價(1.1.5),所以即使之前new-if被實際執行,它必須首先評估所有的參數,這是guess(sqrt-iter (improve guess x) x)。你可以看到後一個參數是一個遞歸,它調用了一個新的new-if過程,這是發生無限循環的方式。

普通的if不需要首先評估它的參數,只是一路走來,這是ifnew-if之間的區別。 :)