譯 Scheme簡明教程8 遞迴

2021-08-30 09:24:25 字數 3038 閱讀 2289

乙個過程體中可以包含對其它過程的呼叫,特別的是也可以呼叫自己。

(definefactorial
(lambda(n)
(if(=

n0) 1

(*

n (factorial (-

n1))))))

這個遞迴過程用來計算乙個數的階乘。如果這個數是0,則結果為1。對於任何其它的值n,這個過程會呼叫其自身來完成n-1階乘的計算,然後將這個子結果乘上n並返回最終產生的結果。

互遞迴過程也是可以的。下面判斷奇偶數的過程相互進行了呼叫。

(defineis-even?
(lambda(n)
(if(=

n0) #t

(is-odd? (-

n1)))))

(defineis-odd?
(lambda(n)
(if(=

n0) #f

(is-even? (-

n1)))))

這裡提供的兩個過程的定義僅作為簡單的互遞迴示例。scheme已經提供了簡單的判斷過程even? 和 odd?。

6.1letrec

如果希望將上面的過程定義為區域性的,我們會嘗試使用let結構:

(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)))

但這並不能成功,因為在初始化值過程中出現的local-even? 和 local-odd?指向的並不是這兩個過程本身。把let換成let*同樣也不能奏效,因為這時雖然local-odd?中出現的local-even?指向的是前面剛建立好的區域性的過程,但local-even? 中的local-odd?還是指向了別處。

為解決這個問題,scheme提供了letrec結構。

(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)))

letrec建立的詞法變數不僅可以在letrec執行體中可見而且在初始化中也可見。letrec是專門為區域性的遞迴和互遞迴過程而設定的。(這裡也可以使用define來建立兩個子結構的方式來實現區域性遞迴)

6.2已命名let

使用letrec定義遞迴過程可以實現迴圈。如果我們想顯示10到1的降數列,可以這樣寫:

(letrec((countdown (lambda(i)
(if(=

i0)'liftoff

(begin
(display

i)

(newline)
(countdown (-

i1)))))))

(countdown

10))

這會在控制台上輸出10到1,並會返回結果liftoff。

scheme允許使用一種叫已命名letlet變體來更簡潔的寫出這樣的迴圈:

(letcountdown ((i

10))

(if(=

i0)'liftoff

(begin
(display

i)

(newline)
(countdown (-

i1)))))

注意在let的後面立即宣告了乙個變數用來表示這個迴圈。這個程式和先前用letrec寫的程式是等價的。你可以將已命名let看成乙個對letrec結構進行擴充套件的巨集。

譯 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...