2011-04-24 22 views
1

例如,在遞歸調用Scheme期間`let`創建的局部變量的狀態是否改變?

我想檢查一個元素是否在列表中。該算法很簡單,讓我們做它在C++

bool element_of(const std::vector<int>& lst, int elem) { 
    for(int i(0), ie = lst.size(); i < ie; ++i) 
     if(elem == lst[i]) 
      return true; 
    return false; 
} 

由於計劃不要讓我使用單if聲明,我不能做類似於上面的C++代碼的東西。然後我想出了一個臨時變量,即resultresult將有初始值#f,接下來我遞歸調用該函數來檢查列表中的下一項,即cdr lst ...因此,我的問題是,每當它進入一個新函數時,用let創建的變量是否恢復其初始值呼叫或其值保持不變直到最後一次呼叫?

在另一方面,使用fold,我的解決辦法是,

(define (element-of x lst) 
    (fold (lambda (elem result) 
      (if (eq? elem x) (or result #t) result)) 
     #f 
     lst)) 

感謝,

回答

2

每個Let調用創建環境的新的變量集的Let的主體是評估英寸Let語法是一個「語法糖」的lambda正在評估參數傳遞給它已被評估。例如

(let ((a (func object)) 
     (b (func object2))) 
    (cons a b)) 

是一樣的書寫

((lambda (a b) (cons a b)) (func object) (func object2)) 

所以你可以看到,在Let語法,參數先進行計算,然後身體評估,並a的定義和在本地環境範圍內使用b。因此,如果遞歸調用Let,則每次輸入Let調用的主體時,都會在新環境中評估主體(因爲主體位於新定義的lambda中),並且在本地定義的參數定義爲Let範圍將是不同的(它們實際上是新lambda嵌套環境設置中的新變量,而不是簡單的變量,這些變量就像您在C++循環中找到的那樣被突變或「重新定義」)。

另一種說法是,你的變量將像C++遞歸函數中的本地作用域變量一樣......對於每個函數的棧幀,局部作用域變量將有自己的定義,並且它們自己的定義內存位置......它們不是像在循環中可能看到的變異變量,它在本地範圍內重用相同的內存變量。

希望這有助於

傑森

+0

謝謝。所以我猜想Scheme的局部變量的機制就像命令式語言一樣。 – Chan 2011-04-24 05:11:33

+0

Sort of ... Scheme的環境模型是必需的,因爲Scheme不是一種「純粹的」功能語言,因爲它確實允許變量的可變性。基本上所有的變量都是在「環境」中保存的符號,它基本上是一個符號表。 '(define a b)'關鍵字爲本地環境(符號表)添加符號「a」,並將其綁定到「b」的計算值。再次在'a'上調用'define'會將'a'重新綁定到別的東西,除非您在新環境中調用它,在這種情況下,它會在符號表中添加一個新的'a',掩蓋舊的可用性值。 – Jason 2011-04-24 05:26:33

+0

有關計劃環境模型的更多信息,請查看以下鏈接:http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer- programs-spring-2005/lecture-notes/lecture15webhan.pdf – Jason 2011-04-24 05:27:56

1

let總是重新初始化變量;很明顯,因爲您必須始終提供新的綁定值。例如,

(let ((a 42)) 
    ...) 

...內部,a開始作爲42,始終。它不會「保留」以前調用的值。


順便說一句,我想你的意思是寫(or result (equal? elem x))而非(if (eq? elem x) (or result #t) result)。 :-)

(or result (equal? elem x))轉換爲下面的C++代碼:

return result || elem == x; 

(假設==操作者已被重載執行什麼equal?確實,當然。)這樣做的好處是,如果result是已經如此,沒有進一步的比較。

+0

是的,你是對的。當試圖傳遞我的C++想法時,我被困住了。謝謝。 – Chan 2011-04-24 05:10:52

相關問題