2012-07-13 148 views
3

我不明白的區別是什麼之間(遺憾的人爲的例子):創建本地綁定的'let'或'letrec'和'define'之間有什麼區別?

(define average 
    (lambda (elems) 

    (define length 
    (lambda (xs) 
     (if (null? xs) 
      0 
      (+ 1 (length (cdr xs)))))) 

    (define sum 
    (lambda (xs) 
     (if (null? xs) 
      0 
      (+ (car xs) (sum (cdr xs)))))) 

    (define total (sum elems)) 

    (define count (length elems)) 

    (/ total count))) 

(define average 
    (lambda (elems) 
    (letrec ((length 
       (lambda (xs) 
       (if (null? xs) 
        0 
        (+ 1 (length (cdr xs)))))) 

      (sum 
       (lambda (xs) 
       (if (null? xs) 
        0 
        (+ (car xs) (sum (cdr xs)))))) 

      (total (sum elems)) 

      (count (length elems))) 

    (/ total count)))) 

據我所知,他們都創造了新的範圍,在那個範圍內創建4個局部變量,這些變量是相互引用的,並且是自己的,並且評估並返回一個主體。

我在這裏丟失了些什麼,或者是letrec與作用域define s同義嗎?

我知道這可能取決於實施;我試圖理解Lisps的基本原理。

回答

6

你是對的,你的代碼的defineletrec版本之間有相似之處。然而,魔鬼在細節中。在R5RS中,internal define has letrec semantics。在R6RS中,internal define has letrec* semantics

有什麼區別?你的代碼實際上只是強調了這種差異。至於哲浩的回答中提到,您同樣letrec作爲lengthsum內的totalcount定義是不正確的:lengthsum不能保證被你正在評估的(length elems)(sum elems)值的時間的約束,因爲結合這些變量不保證是從左到右。

letrec*letrec類似,但具有從左到右的保證。所以,如果您將letrec更改爲letrec*,那就沒問題。

現在,回到我的初步意見:由於R5RS內部define使用letrec語義,甚至你define版本的代碼將是一個R5RS實施中的不正確,但它的R6RS的實現,它letrec*語義下好起來的。

+0

嚴格地說,'length'和'sum'保證是* bound *(到位置);不能保證的是他們還沒有被賦予它們的初始值*。即使他們已經被分配了他們,Scheme報告R5RS - R7RS表示,它仍然是一個「錯誤」,就像你在「total」和「count」的初始化子句中那樣引用這些值。 (但是,我不認爲需要實現來檢測和抱怨這個錯誤。)一些更多的差異btw'letrec' /'letrec *':http://stackoverflow.com/q/13078165/272427 – dubiousjim 2012-11-04 17:37:01

4

這兩個let/letrec和define都會創建本地作用域定義。但是,當你不在裏面並且隱式的開始語句時,讓/ letrec更方便。例如,以下代碼使用let宏。

(define (test) (let ((x 1)) x)) 

使用局部範圍定義了相同的代碼將

(define test (lambda() (define x 1) x)) 

這是那種一個人爲的例子,但一般都採用讓宏做本地綁定被認爲是更多的功能。

此外,您的示例代碼不正確使用letrec。您不需要letrec聲明中的定義(實際上它們實際上不應該在那裏)。

+0

很好的回答!正如我的回答中所提到的,在R5RS下,甚至OP代碼的'define'版本都不正確,而不僅僅是'letrec'版本。 – 2012-07-13 02:52:41

+0

關於'letrec'裏的'define'的好處...當我寫這些時肯定很累。+1 – 2012-07-13 11:29:23

相關問題