2010-09-14 55 views
3

的循環順序以下步驟是在這兩個方案R6RS有效和球拍:方案/球拍:不做評價

;; create a list of all the numbers from 1 to n 
(define (make-nums n) 
    (do [(x n (- x 1)) (lst (list) (cons x lst))] 
    ((= x 0) 
    lst))) 

我測試過這兩個R6RS和球拍和它正常工作,但我只知道確實爲DrRacket。

我的問題是如果它是保證該步驟表達式(在這種情況下(- x 1)(cons x lst))將按順序進行評價。如果不能保證,那麼我的程序不是很穩定。

我沒有在任何一種語言的標準中看到任何特定的內容,但我在這裏問,因爲當我測試它時,它是按順序排除的。

回答

7

他們通常不保證按順序評估,但結果仍然是一樣的。這是因爲這裏沒有副作用 - 循環不改變xlst,它只是將它們重新綁定到新值,所以兩個步驟表達式的評估順序是不相關的。

看到這一點,與您的代碼更清潔的看着版本開始:

(define (make-nums n) 
    (do ([x n (- x 1)] [lst null (cons x lst)]) 
     [(zero? x) lst])) 

翻譯爲named- let

(define (make-nums n) 
    (let loop ([x n] [lst null]) 
    (if (zero? x) 
     lst 
     (loop (- x 1) (cons x lst))))) 

,並進一步轉化,爲一個輔助功能(該功能是什麼 - let真的是):

(define (make-nums n) 
    (define (loop x lst) 
    (if (zero? x) 
     lst 
     (loop (- x 1) (cons x lst)))) 
    (loop n null)) 

它現在應該清楚,在遞歸調用loop時評估這兩個表達式的順序並沒有使它做任何不同的事情。

最後,請注意,在球拍評估保證是從左到右。當存在副作用時這很重要--Rocket喜歡可預測的行爲,而其他人反對,聲稱這會讓人們隱含地依賴於此。示出的差的一個常見小的例子是:

(list (read-line) (read-line)) 

這在球拍保證返回的第一行讀出的列表,然後第二個。其他實現可能會以不同的順序返回這兩行。

+0

編輯:謝謝!這很有趣,我沒有意識到「做」是這樣工作的。 – Cam 2010-09-15 12:21:33