4.2.1 正常次序与应用次序

 4.2.1 正常次序与应用次序
在1.1部分,我们开始讨论解释模型的地方,我们注意到,SCHEME是一种应用次序的语言。
如其名,当程序被应用时,SCHEME程序的所有的实际参数,已经被执行过了。相反,
正常次序的语言推迟了程序的实际参数的执行,直到实际参数的值被需要时。程序的实际参数的
推迟执行,直到可能的最后一刻 ,(例如直到它们被一个原生的操作需要时) 这叫做
推迟解释。
考虑如下的程序:
(define (try a b)
   (if (= a 0) 1 b))
在scheme中执行  (try 0 (/ 1 0)) 生成一个错误。有推迟执行的话,就没有报错。
执行表达式返回1,因为 实际参数 (/ 1 0) 根本就没有被执行。
探索推迟执行的一个例子是 程序unless 的定义:

(define (unless condition usual-value exceptional-value)
     if condition exceptional-value usual-value))

上述的定义在如下的表达式中被使用:

(unless (= b 0)
         (/ a b)
         (begin (display "exception: returning 0")
          0))

在程序序语言中,这是无效的,因为正常值和异常值都在unless被调用之前时被解释。
推迟解释的一个优点是一些程序,例如程序unless能做有用的计算,即使
它的参数一些的解释出错或者是没有停止。

如果在一个参数被解释完成前,就能进入程序体,我们说这个程序的参数是不严格限制的。
如果在进入程序体之前,参数被解释了,我们说这个程序的参数是严格限制的。
在一个纯粹的程序序语言中,我们的所有的程序在任何一个参数上都是严格限制的。
在一个纯粹的自然序语言中,我们的所有的复合程序在任何一个参数上都是不严格限制的。
原生程序可能是严格限制也可能是不严格限制。见练习4.31,也有语言给程序员们具体地控制
他们定义的程序的限制性。

一个程序的显而易见的例子是做成非严格限制性是很有用的,是cons函数。(或者更通用的说,
几乎所有的数据结构组装子) 。即使元素的值还不知道,它能做有用的计算,组合元素形成数据结构
和在结果的数据结构上操作。它提供了完美的智能,例如,计算列表的长度却不知道在列表中的元素的值。
我们将在4.2.3部分中,探索这个思想,来实现第三章中的流,作为由非限制性的数对所组成的列表。

练习4.25
假定(在普通的应用程序序的scheme)我们定义了unless 如上的显示的,然后
用unless来定义factorial阶乘。

(define   (factorial  n)
  (unless  (=  n  1)
              (*  n (factorial (- n 1)))
              1
  )
)

如果我们试图解释(factorial 5)?   我们的定义能在正常序的语言中工作吗?

练习4.26
苯和丽莎对于实现的东西例如unless ,不认为延迟解释有什么重要的。
苯指出在应用序以一个关键字实现unless是可能的。丽莎指出如果那么做,
Unless 仅是语法,没有程序能用在与高阶程序的组合了。在实际参数的两边
填写上细节。显示如何实现unless作为一个可推导的表达式(像 cond 或者let)
给了这个情况的例子,它是可能有用的,让unless作为一个程序可用,而不是一个关键字。

猜你喜欢

转载自blog.csdn.net/gggwfn1982/article/details/82500580