刷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. (Assume that the evaluation rule for the special form if is the same whether the interpreter is using normal or applicative order: The predicate expression is evaluated first, and the result determines whether to evaluate the consequent or the alternative expression.)
意思就是,这段代码在正则序和应用序的解释器上会有不同的表现,为什么
先不考虑这道题是怎么做,来看看正则序是如何展开(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)
返回是什么呢