1.2 函数与它们产生的计算
至此我们已经考虑了程序设计中的一些要素。我们用过各种基本算术操作,知道如何组合使用这些运算,还考虑了通过把组合运算声明为复合函数,实现对复合运算的抽象。但是,即使知道了这些,我们还不能说自己已经理解了如何去编写程序。我们现在的状况很像初学象棋的人,他们已经知道了移动棋子的规则,但还不知道典型的开局、战术和策略。与之类似,我们现在还不知道本领域中有用的常见模式,缺少有关棋步价值的知识(哪些函数值得声明),缺少对所走棋步(执行一个函数)的后果做出预期的经验。
能看清所考虑的动作的后果,这种能力对于成为程序设计专家是至关重要的,就像类似能力在所有综合性的创造性活动中的作用一样。举个例子,要成为专业摄影师,就必须学会如何去观察景象,知道在各种可能的曝光和显影选择下,景象中的各个区域在影像中的明暗情况。只有在具有了这些能力后,我们才能去做反向推理,对得到所需效果应该做的取景、亮度、曝光和显影等做出规划。同样,在程序设计领域,我们需要对计算过程中各种动作的进行情况做出规划,用一个程序去控制这种过程的进展。要想成为专家,我们必须学习如何看清各种不同类型的函数产生的计算过程。只有掌握了这种技能,我们才能学会如何可靠地构造出程序,使之能表现出我们期望的行为。
一个函数就是一个计算过程的局部演化的模式,它描述了这个过程中的每个步骤如何在前面步骤的基础上进行。在用函数描述了一个计算过程的局部演化过程之后,我们当然希望能做出一些有关该计算过程的整体或全局行为的论断。一般而言这是非常困难的,但我们至少还是可以试着去描述这种过程演化的一些典型模式。
在这一节,我们要考察由一些简单函数产生的计算过程的“形状”,还要研究这些计算过程消耗各种重要计算资源(时间和空间)的速率。这里考察的函数都很简单,它们的用途就像摄影术中的测试模式,都是极度简化的,并不是很实际的例子。