2012-03-16 60 views
3

我試圖根據Harold Abelson和Gerald Jay Sussman着名的書籍「結構和計算機程序的解釋」在計劃中實現Metacircular Evaluator。Metacircular evaluation,implementation the environment

http://mitpress.mit.edu/sicp/full-text/sicp/book/node79.htmlhttp://mitpress.mit.edu/sicp/full-text/sicp/book/node80.html

作者建議安裝環境是這樣的:

(define (define-variable! var val env) 
    (let ((frame (first-frame env))) 
    (define (scan vars vals) 
     (cond ((null? vars) 
      (add-binding-to-frame! var val frame)) 
      ((eq? var (car vars)) 
      (set-car! vals val)) 
      (else (scan (cdr vars) (cdr vals))))) 
    (scan (frame-variables frame) 
      (frame-values frame)))) 

(define (setup-environment) 
    (let ((initial-env 
     (extend-environment (primitive-procedure-names) 
          (primitive-procedure-objects) 
          the-empty-environment))) 
    (define-variable! 'true true initial-env) 
    (define-variable! 'false false initial-env) 
    initial-env)) 

不過,我不明白爲什麼我們在方案預計

(define myenv (setup-environment)) 

應該工作,因爲,正如我所知,Scheme默認將變量傳遞給函數,因此在兩次將「define-variable!」應用於initial之後-env,initial-env不會每次都被更改,並且setup-environment函數將在extend-environment返回值時返回值。

我的理解錯誤在哪裏,請問您能提供意見嗎?

預先感謝您!

回答

5

您的問題可能是一個teensy位更具體,但我相信我理解它。

具體來說,您的問題似乎是這樣的:

「我通過

(define myenv (setup-environment)) 
(define-variable! 'a 13 myenv) 
(lookup myenv 'a) 

具體的行爲感到驚訝,我希望它失敗,因爲計劃是調用 - 值「。這是你的問題嗎?

如果是這樣,那麼我想我可以回答它。撥打電話不是表示值不能更改。這只是意味着函數調用涉及將來自調用者的值傳遞給被調用者。事實上,幾乎所有的語言都是按價值劃分的;這個詞被廣泛誤解。例如,Java也是一種按價值調用的語言。

沒有什麼關於Scheme的,那麼,這可以防止你改變或「變異」一個值。在這個例子中,set-car!調用突變了它所指的列表。這個改變對於任何能夠「看見」這個值的代碼都是可見的。

我認爲你的根本問題確實與「按價值劃撥」的含義有關,我希望我已經闡明瞭一些看法。

+0

是的,很多人認爲語言不是「按價值傳遞」,當他們真的是時,他們只是「按價值傳遞參考」。 – 2012-03-16 22:36:38

+0

非常感謝!你說得對,我的問題不是很準確,請原諒,請原諒。下一次會更清楚。 – 2012-03-17 11:07:19

2

要理解它是如何工作的,首先你要明白,變量initial-env將指向環境第一幀,而這個參考的是從未修改。環境本身是一個框架列表,每個框架是一對列表,第一個框架的car是變量列表的頭部,第一個框架的cdr是值列表的頭部。

一旦明確,您需要了解程序scanadd-binding-to-frame!的工作方式。 Scan將在當前幀的變量列表中查找與var同名的變量;如果找到它將替換值列表中的對應值。如果未找到該變量,add-binding-to-frame!將在相應列表的開頭添加一個新變量和一個新值,更新框架以指向這個新的標題。請注意,initial-environment仍然指向第一幀,第一幀仍指向其變量和值列表的首部(但帶有新的綁定)。

所以你現在看到,即使initial-env從未被改變過,它包含的列表也被修改了,因此增加了新的變量和它們各自的值。我相信理解整個過程的最好方法是抓住一支筆和一張紙,逐步繪製修改所涉及的cons單元格的結果。

+0

非常感謝! – 2012-03-17 04:02:48

+0

@Alfucio如果這個答案在任何方面對你有幫助,upvote會很好:) – 2012-03-17 13:04:30

+0

是的,我非常抱歉有兩件事:首先,我不能將你的答案標記爲已接受(tttt ,這對我來說很奇怪,我不能在這裏,因爲我相信經常有很多被接受的答案,例如,對於我目前的問題),儘管我認爲你的答案和第一個答案一樣有幫助(和我決定只標記第一個,因爲它是第一個:));其次,我現在無法提出你的答案,因爲我的聲望點只有13。我一定會盡快上傳你的帖子,我將會收到15頁。再一次,非常感謝你,這真的很有幫助! – 2012-03-17 16:17:44