刷SICP遇到的問題——深入學習理解正則序和應用序
仔細思考了SICP的練習1.5,對正則序和應用序產生了越來越多的問題,這篇部落格不提供解答,只記錄了一些自己的疑惑和思考
最常見的一種正則序應用序的定義方式是,正則序是先展開後規約,應用序是先求值再應用
對於這個定義,產生了幾個問題如下:
- 展開到什麼程度
- 什麼順序展開
- 什麼時候會求值
1 正則序展開到什麼程度
書上的正則序定義是這樣的"Instead it would first substitute operand expressions for parameters until it obtained an expression involving only primitive operators, and would then perform the evaluation."
因此,正則序會展開到只剩下primitive operators,就是Scheme裡面不需要自己define就可以呼叫的operators
2 正則序以什麼順序展開
來看練習1.5
Exercise 1.5. Ben Bitdiddle has invented a test to determine whether the interpreter he is faced with is using applicative-order evaluation or normal-order evaluation. He defines the following two procedures:
(define (p) (p))
(define (test x y)
(if (= x 0)
0
y))
Then he evaluates the expression
(test 0 (p))
What behavior will Ben observe with an interpreter that uses applicative-order evaluation? What behavior will he observe with an interpreter that uses normal-order evaluation? Explain your answer.
意思就是,這段程式碼在正則序和應用序的直譯器上會有不同的表現,為什麼
先不考慮這道題是怎麼做,來看看正則序是如何展開(test 0 (p))的,這裡有兩個combination,是先展開(p)還是(test)
看一下書上的正則序展開示例
所以是先展開最左側的括號,想想也是,如果先展開(p)那和應用序有什麼區別嘛
3 應用序什麼時候求值
這個問題來源於我不小心寫錯了題目中的程式碼, 寫成了如下的樣子
(define (p) (p))
(define (test x y)
(if (= x 0)
0
y))
(test 0 p)
直譯器完美執行,返回了0
為什麼這裡應用序不求解p了?
寫一個程式碼檢測
(define (p)
(display "yes\n"))
(define (testOrder x y)
(display "test\n")
(if (= x 0)
0
y))
(testOrder 0 p)
(testOrder 0 (p))
結果很明顯,沒有給p加括號,根本不會去呼叫p, 我想了一下,有了一個猜想(不一定對),p是作為一個類似函式指標一樣的東西傳給testOrder的,所以對p的求值只是獲取到了他的函式指標
一個佐證是,用lazyracket這個正則序直譯器執行如下程式
#lang lazy
(define (p)
(p))
(define (testOrder x y)
(if (= x 0)
0
y))
(testIOrder 1 p)
返回是什麼呢