乙個過程體中可以包含對其它過程的呼叫,特別的是也可以呼叫自己。
這個遞迴過程用來計算乙個數的階乘。如果這個數是0,則結果為1。對於任何其它的值n,這個過程會呼叫其自身來完成n-1階乘的計算,然後將這個子結果乘上n並返回最終產生的結果。(definefactorial(lambda(n)(if(=n0) 1
(*n (factorial (-
n1))))))
互遞迴過程也是可以的。下面判斷奇偶數的過程相互進行了呼叫。
這裡提供的兩個過程的定義僅作為簡單的互遞迴示例。scheme已經提供了簡單的判斷過程even? 和 odd?。(defineis-even?(lambda(n)(if(=n0) #t
(is-odd? (-n1)))))
(defineis-odd?(lambda(n)(if(=n0) #f
(is-even? (-n1)))))
6.1letrec
如果希望將上面的過程定義為區域性的,我們會嘗試使用let結構:
但這並不能成功,因為在初始化值過程中出現的local-even? 和 local-odd?指向的並不是這兩個過程本身。把let換成let*同樣也不能奏效,因為這時雖然local-odd?中出現的local-even?指向的是前面剛建立好的區域性的過程,但local-even? 中的local-odd?還是指向了別處。(let((local-even? (lambda(n)(if(=n0) #t
(local-odd? (-n1)))))
(local-odd? (lambda(n)(if(=n0) #f
(local-even? (-n1))))))
(list (local-even?23) (local-odd?
23)))
為解決這個問題,scheme提供了letrec結構。
用letrec建立的詞法變數不僅可以在letrec執行體中可見而且在初始化中也可見。letrec是專門為區域性的遞迴和互遞迴過程而設定的。(這裡也可以使用define來建立兩個子結構的方式來實現區域性遞迴)(letrec((local-even? (lambda(n)(if(=n0) #t
(local-odd? (-n1)))))
(local-odd? (lambda(n)(if(=n0) #f
(local-even? (-n1))))))
(list (local-even?23) (local-odd?
23)))
6.2已命名let
使用letrec定義遞迴過程可以實現迴圈。如果我們想顯示10到1的降數列,可以這樣寫:
這會在控制台上輸出10到1,並會返回結果liftoff。(letrec((countdown (lambda(i)(if(=i0)'liftoff
(begin(displayi)
(newline)(countdown (-i1)))))))
(countdown10))
scheme允許使用一種叫已命名let的let變體來更簡潔的寫出這樣的迴圈:
注意在let的後面立即宣告了乙個變數用來表示這個迴圈。這個程式和先前用letrec寫的程式是等價的。你可以將已命名let看成乙個對letrec結構進行擴充套件的巨集。(letcountdown ((i10))
(if(=i0)'liftoff
(begin(displayi)
(newline)(countdown (-i1)))))
譯 Scheme簡明教程6 條件語句
和其它的程式設計語句一樣,scheme 也包含條件語句。最基本的結構就是if 如果測試條件運算的結果是真 即,非 f的任何其它值 then 分支將會被執行 即滿足條件時的執行分支 否則,else 分支會被執行。else 分支是可選的。為了方便,scheme還提供了一些其它的條件結構語句。它們可以被定...
Visual Unit 簡明教程
visual unit,簡稱vu,是新一代單元測試工具,功能強大,使用簡單,完全視覺化,不需編寫測試 vu的測試結果使程式行為一目了然,有助於整理程式設計思路,提高程式設計效率和正確性,並能快速排錯 vu還增強偵錯程式功能 如自由後退 用例切換 提高除錯的效率 vu能達到空前的測試完整性,輕鬆完成語...
MYSQL簡明教程
dos進入mysql命令 c mysql h 127.0.0.1 u root p enter password mysql 進入完成 建立資料庫 create database databasename 使用指定資料庫進行操作 方法1 use database databasename 方法2 m...