2015-03-03 48 views
1
(define (decode bits tree) 
    (define (decode-1 bits current-branch) 
    (if (null? bits) 
     '() 
     (let ((next-branch (choose-branch (car bits) current-branch))) 
      (if (leaf? next-branch) 
       (cons (symbol-leaf next-branch) 
        (decode-1 (cdr bits) tree)) 
       (decode-1 (cdr bits) next-branch))))) 
    (decode-1 bits tree)) 

爲什麼我們甚至需要decode-1如果我們對decodedecode-1都使用相同的參數?爲什麼內部程序?

回答

1

decode-1實際上是指decode參數tree(在(decode-1 (cdr bits) tree)),而不僅僅是current-branch。所以他們不是「相同的論點」。 (在技術方面,decode-1closure。)

如果decode-1沒有提及tree(或任何外部變量,在一般情況),那麼,你可以遞歸到decode而不是直接需要的內部程序。

順便說一句,在「定義過程,並稱之爲」成語是如此普遍,方案更多好聽寫它提供了一個"named let" syntax

(define (decode bits tree) 
    (let decode-1 ((bits bits) (current-branch tree)) 
    (if (null? bits) 
     '() 
     (let ((next-branch (choose-branch (car bits) current-branch))) 
      (if (leaf? next-branch) 
       (cons (symbol-leaf next-branch) (decode-1 (cdr bits) tree)) 
       (decode-1 (cdr bits) next-branch)))))) 
0

的優勢,使這樣的內部過程是您可以簡單地修改它的實現而不改變參數數量。例如,添加一個額外的參數作爲過程的累加器,以便它可以是尾遞歸。 decode-1不是適當的尾遞歸所以如果太大,那麼實現可能會導致堆棧溢出。

下面是一個例子轉換您decode尾遞歸調用:

 
(define (decode bits tree) 
    (define (decode-1 bits current-branch acc) 
    (if (null? bits) 
     (reverse acc) 
     (let ((next-branch (choose-branch (car bits) current-branch))) 
      (if (leaf? next-branch) 
       (decode-1 (cdr bits) tree (cons (symbol-leaf next-branch) acc)) 
       (decode-1 (cdr bits) next-branch acc))))) 
    (decode-1 bits tree '())) 

修訂

上面這段代碼也可以命名讓寫。所以當你想用內部定義來編寫它時,情況如下。

  1. 如果內部程序有交叉引用,那麼它可以是您可以選擇的選項之一。這也可以通過letrec完成,但巢級會稍微更深。所以在你的情況下,choose-branch可以寫在decode程序中。
  2. 如果上層過程包含使用define-syntax的內部宏定義,那麼您只能使用內部定義進行編寫。 R7RS的let(rec)-syntax創建一個範圍,但內部define-syntaxdefine應被視爲在同一範圍內。

我不知道如果R7RS指定如何內部宏進行擴展(例如,第一擴展所有的宏像R6RS)。

+0

不,你不能「簡單地消除內部定義」。正如我的回答中所提到的,內部程序是一個閉包。事實上,即使你的尾遞歸定義仍然是一個閉包,所以你仍然無法將其提升到頂級過程,而無需添加額外的'tree'參數。 – 2015-03-04 15:21:52

+1

Opps,對不起,我沒有注意到'tree'參數。前兩句應該去。 – 2015-03-04 18:49:27

+0

你能解釋尾遞歸版本是如何工作的嗎?我似乎無法理解它在查看代碼......爲什麼如果比特是空的,就會反向acc? – user16655 2015-03-13 10:46:06