参数为3或4的情况

假设调用 triangle-recursively 时参数为3。

步骤 1    评估再次执行测试。

首先评估 if 表达式。这是再次执行测试,并返回false,因此 if 表达式的else部分将被评估。(请注意,在此示例中,再次执行测试在测试false时导致函数调用自身,而不是在测试true时。)

步骤 2    评估else部分的最内层表达式。

评估else部分的最内层表达式,将3减少到2。这是下一步表达式。

步骤 3    评估 triangle-recursively 函数。

将数字2传递给 triangle-recursively 函数。

我们已经知道当Emacs使用参数2评估 triangle-recursively 时会发生什么。在经历了前面描述的一系列动作后,它将返回值3。因此,在这里也将发生这种情况。

步骤 4    评估加法。

3将作为参数传递给加法,并将被添加到调用函数的数字中,该数字为3。

函数整体返回的值将为6。

现在我们知道当 triangle-recursively 使用参数3调用时会发生什么,那么如果使用参数4调用它会发生什么就显而易见了:

在递归调用中,评估

(triangle-recursively (1- 4))

将返回评估的值

(triangle-recursively 3)

这是6,此值将通过第三行的加法添加到4中。

函数整体返回的值将为10。

每次评估 triangle-recursively 时,它都会评估它自己的版本—一个具有较小参数的不同实例,直到参数足够小以使其不再评估自身。

请注意,这种递归函数的特定设计要求推迟操作。

(triangle-recursively 7) 可以计算其答案之前,它必须调用 (triangle-recursively 6);在 (triangle-recursively 6) 可以计算其答案之前,它必须调用 (triangle-recursively 5);依此类推。也就是说,(triangle-recursively 7) 进行的计算必须推迟,直到 (triangle-recursively 6) 进行其计算为止;而 (triangle-recursively 6) 必须推迟,直到 (triangle-recursively 5) 完成为止;依此类推。

如果将 triangle-recursively 的每个实例都视为不同的机器人,第一个机器人必须等待第二个完成其工作,第二个必须等待第三个完成,依此类推。

有一种绕过这种等待的方法,我们将在 无推迟的递归 中讨论。