[
evaluation、computation、calculation,在第二章,是后两个计算放在一起,让人搞不清准确的含义;现在倒好,出现了三个计算,又该如何体会呢?
据说,从左到右,是从粗略到精确的过度,即,前面的强调估算,后面的强调演算。
能体会出来吗?语言不同,表达真的不同。
因此,计算机就选了一个中间值,既不强调粗,也不强调精;恰恰表明,既强调粗,也强调精。
前两天,听电视里的一个新闻讲,俄罗斯人(好像是)能分辨出雪的 1000 种白色。
听到这里,就让我想到中国人,不太喜欢精确,不是有一句话,叫什么“天下乌鸦一般黑”,根本不分各黑的区别。
但是,这样说,又有点以偏概全。看看古书上关于煮饭的锅、喝酒的杯、装菜的盘的字,我们能认识几个。
]
我们演示计算策略的不同,可以使用第二章描述的计算技术,展示程序一步一步的运行步骤,这样,就可以清楚地看出延迟计算和提前计算之间的差异。清单11.14 是一个表达式的计算,使用了两个函数:PlusTen(a) 返回a + 10,TimesTwo(a) 返回a*2。
[
这里的清单编号出了问题,从 11.14 一下变到 11.17。
好在这个不影响意思的表达。因此,译文也就译错如错吧。
]
清单11.14 延迟计算与提前计算
清单 11.17 延迟计算 |
清单 11.17 提前计算 |
PlusTen(TimesTwo(4)) // Start calculating PlusTen: TimesTwo(4) + 10 [1] // Calculate TimesTwo, because // we need its result now: 8 + 10 [2] // Calculate the result: 18 |
PlusTen(TimesTwo(4)) // To get values of all arguments, // calculate result of TimesTwo: PlusTen(8) [3] // Evaluate PlusTen next: 8 + 10 [4] // Calculate the result: 18 |
延迟计算策略首先计算PlusTen,而不先计算参数值。下一步,需要把10 与参数值相加[1],而参数值还没有计算。由于参数值是需要进一步处理,才执行对TimesTwo 的调用[2],这样,我们就得到了最终结果。
提前计算战略首先计算参数值,因此,在第一步就计算了TimesTwo(4),得到8 [3]。PlusTen 函数的所有参数值,现在就已经都计算了,因此,可以继续计算这个函数[4],计算出结果。
到目前为止,我们只看到使用延迟计算策略的一个原因,而这似乎已经很有用了。如果它只存在于Haskell 中,那为什么我们还把它提出来呢?因为在F# 和C# 3.0 中,可以实现类似的效果。