[英]SICP example doesn't work on Racket
我正在嘗試SICP第4章中的示例(編寫LISP解釋器的一部分)
(define (definition-value exp)
(if (symbol? (cadr exp))
(caddr exp)
(make-lambda
(cdadr exp) ; formal parameters
(cddr exp) ; body
)
)
)
(define (make-lambda parameters body)
(cons 'lambda (cons parameters body))
)
我測試了它,'(define(double x)(+ xx)))上的定義值應該返回一個lambda函數
( (definition-value '(define (double x) (+ x x))) 10)
球拍輸出
procedure application: expected procedure, given: (lambda (x) (+ x x)); arguments were: 10
“(lambda(x)(+ xx))”不是程序嗎? 還是參考? 如果是引用,有什么方法可以“取消引用”嗎?
definition-value
返回定義表達式中的值作為參數:
(definition-value '(define x 42))
=> 42
(definition-value '(define (qq x) (+ x y 42)))
=> (make-lambda '(x) '((+ x y 42)))
=> '(lambda (x) (+ x y 42))
您不能像這樣調用帶引號的列表: ( '(lambda (x) (+ xy 42)) 10)
無效。 它不是一個函數,它只是一個s表達式 。
definition-value
是解釋器的一部分。 該解釋器是“解除引用”的方法,即解釋函數定義。 不同的解釋器可以使用不同的方式來解釋相同的函數定義,從而為所得語言提供不同的語義。
表達式的求值必須在上下文中進行-它們出現在某些詞法范圍內 (代碼中可見變量的區域),這會引起環境 (也就是this )。 在上面的示例中, y
在正在解釋的程序的某些封閉范圍內定義。 試圖解釋通過調用REPL那表情球拍的eval
,將什么樣的價值y
有哪些?
我想出了答案,如果在文件中執行Racket腳本,球拍解釋器將不知道名稱空間,但是REPL知道。 解決方法是在文件開頭添加此行
(define ns (make-base-namespace))
然后在使用時將ns傳遞給eval
(eval <what ever code reference here> ns)
這將使我上面提到的示例起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.