构造数据抽象
现在到了数学抽象中最关键的一步:让我们忘记这些符号所表示的对象。(数学家)不应该在这里止步,有许多操作可以应用于这些
符号,而根本不必考虑它们到底代表这什么。
————Hermann Weyl, 思维的数学方式
在第一章里,我们关注的是计算过程,以及过程在程序中所扮演的角色。在那里,我们学习到了:
- 使用基本数据和基本操作
- 通过复合、条件、参数的使用将一些过程组合起来,形成复合的过程
- 通过 define 做过程抽象
- 将过程看作一类计算演化的一个模式
- 对过程中蕴涵着的某些常见计算模式做了分类和推理
- 高阶过程能够提升语言的威力。
在这一章里,我们将进一步去考察更复杂的数据。第一章里处理的都是简单的数值数据,,而许多程序在设计的时候就是为了模拟复杂的现象,需要能够处理复杂的数据。和第一章相对应,这一章重点讨论复合数据:将数据对象组合起来,形成复合数据的方式。
为什么在程序设计语言里面需要复合数据呢?和我们需要复合过程的原因一样:
- 提升在设计程序时所位于的概念层次
- 提升设计的模块性
- 增强语言的表达能力
现在考虑设计一个系统,用来完成有理数的算术,即有理数的+-*/。从基本数据出发,我们需要将分子和分母两个整数“粘在一起”,形成一个对偶———一个复合数据对象。复合数据的使用能够使我们进一步提高程序的模块性。在程序中,我们能够将处理数据对象表示的部分和处理数据对象使用的部分相互隔离。这种技术称为:数据抽象。数据抽象能够使程序更容易设计、维护和修改。
在本章中,我们将首先实现上面所说的有理数算术系统,它将成为后面讨论复合数据和数据抽象的基础。我们也将看到,形成复合数据的关键在于,程序设计语言里应该提供了某种“粘合剂”,它们用于把一些数据对象组合起来,形成更加复杂的数据对象。粘合剂可能有很多不同的种类,我们还会发现怎样去构造出根本没有任何特定“数据”操作,只是由过程形成的复合数据。这将近一步模糊“过程”和“数据”之间的划分。我们还将探索:
- 表示序列和树的一些常规技术
- 闭包的概念——用于组合数据对象的粘合剂不但能用于基本的数据对象,同样也可用于复合的数据对象
- 符号表达式,进一步扩大语言的表述能力
- 实现通用型操作的需要,这种操作能够处理许多不同的数据类型
- 数据导向的程序设计——允许孤立的设计每一种数据表示,而后用添加的方式将它们组合进去