将函数定义组合在一起

我们可以将这些表达式组合在一起以创建一个有效的函数定义。然而,在检查时,我们发现其中一个局部变量是不必要的!

函数定义如下:

;;; 第一个减法版本。
(defun triangle (number-of-rows)
  "将三角形中小石子的数量相加。"
  (let ((total 0)
        (number-of-pebbles-in-row number-of-rows))
    (while (> number-of-pebbles-in-row 0)
      (setq total (+ total number-of-pebbles-in-row))
      (setq number-of-pebbles-in-row
            (1- number-of-pebbles-in-row)))
    total))

按照写法,这个函数是有效的。

然而,我们不需要 number-of-pebbles-in-row

当评估 triangle 函数时,符号 number-of-rows 将绑定到一个数字,给它一个初始值。该数字可以在函数体内部像局部变量一样更改,而无需担心这样的更改会影响函数外部的变量值。这是 Lisp 的一个非常有用的特性;这意味着变量 number-of-rows 可以在函数中任何使用 number-of-pebbles-in-row 的地方使用。

以下是稍微更清晰地编写的函数的第二个版本:

(defun triangle (number)                ; 第二个版本。
  "返回 1 到 NUMBER(包括)的数字的总和。"
  (let ((total 0))
    (while (> number 0)
      (setq total (+ total number))
      (setq number (1- number)))
    total))

简而言之,一个正确编写的 while 循环将包含三个部分:

  1. 一个测试,循环重复正确次数后将返回 false。
  2. 一个表达式,其评估在重复评估后将返回所需值。
  3. 一个表达式,用于更改传递给真假测试的值,以便在循环重复正确次数后测试返回 false。