1. 定义函数的名字 输入数据的定义 函数合约、头部和用途
  2. 构造使用函数的例子
  3. 设计与数据定义相符的函数模板

设计自引用数据定义的函数

要使递归的数据定义有意义,必须满足两个条件:

  1. 该定义必须至少含有两条子句;
  2. 其中至少一条子句不能引用定义自身;

(define (fun-for-los a-list-of-symbol)
(cond
[(empty? a-list-of-symbols) ...]
[else ... (first a-list-of-symbol) ...
... (fun-for-los (rest a-list-of-symbols)) ...]))

主体 : 设计主体从不包含自然递归的那些cond子句开始. 对应的答案一般已由例子给出 然后再来处理那些包含自引用的情况 首先,考虑模板中每个表达式计算什么 eg:

(define (how-many a-list-of-symbols)
(cond
[(empty? a-list-of-symbols) 0]
[else (+ (how-many (cdr a-list-of-symbols)) 1)]))

阶段 目标 活动
数据分析和设计 阐数定 设计数据定义
合约,用途说明和函数头部    
例子    
模版    
主体    
测试    

一个函数表示一种依赖关系

应该从严格分析输入输出之间的关系,根据数据分析结果,先设计一个模板,然后进一步完善,最后得到完整的函数定义

  1. 如果问题的解答需要对某个变量的值进行分析,那么使用cond表达式
  2. 如果用到特定领域的知识,使用辅助函数
    1. 如果某个计算必须处理表,自然数或是其他任意大的数据,使用辅助函数
  3. 如果函数的自然形态不是我们所期望的表达式,它很可能就是程序目标的一般形式

函数清单的原则

维护一张函数清单,其中放置程序所有的函数。按照设计诀窍开发每一个函数

把函数加入函数清单前,先要检查是否已经存在相似的函数,或是清单中已经有了类似的函数说明。 我们应该尽量利用已有的 如果所设计的函数不依赖于清单中的其他函数,就可以进行测试,一旦完成了基本的函数测试,就可以测试其他的(调用基本函数的)函数, 直到清单中的所有函数都测试完成为止。我们应该在测试一个函数之前严格测试被他调用的其他函数,这样可以 减少此后逻辑错误的定位时间

范化函数的使用是简化问题的最好方法