Putting the function definition together

我们已经创建了函数定义的各个部分;现在需要将它们组合起来。

首先,while 表达式的内容:

(while (<= 行号 总行数)   ; 真或假的测试
  (setq 总和 (+ 总和 行号))
  (setq 行号 (1+ 行号)))    ; 增量器

连同 let 表达式的变量列表,这几乎完成了函数定义的主体。但是,还需要一个微妙的最后要素。

最后的一步是将变量 总和 单独放在 while 表达式之后的一行上。否则,整个函数返回的值将是在 let 主体中最后一个表达式的值,而这是由 while 评估得到的,其值始终为 nil

这一点乍一看可能不明显。它几乎看起来好像增量表达式是整个函数的最后一个表达式。但是该表达式是 while 主体的一部分;它是以符号 while 开始的列表的最后一个元素。此外,整个 while 循环是 let 主体内的列表。

概述来说,函数将如下所示:

(defun 函数名 (参数列表)
  "文档…"
  (let (变量列表)
    (while (真或假的测试)
      while的主体… )
    … ))                    ; 这里需要最后的表达式。

评估 let 的结果将是由 defun 返回的结果,因为 let 不嵌套在任何包含列表中,除了整个 defun。然而,如果 whilelet 表达式的最后一个元素,函数将始终返回 nil。这不是我们想要的!相反,我们想要的是变量 总和 的值。通过简单地将该符号作为以 let 开始的列表的最后一个元素放置在列表中,它将在之前的元素被评估之后被评估,这意味着在为总和赋予正确值之后才被评估。

通过将以 let 开始的列表打印在一行上,可能更容易看到这一点。这种格式使得显而易见,变量列表while 表达式是以 let 开始的列表的第二和第三个元素,而 总和 是最后一个元素:

(let (变量列表) (while (真或假的测试) while的主体… ) 总和)

将所有内容放在一起,triangle 函数定义如下:

(defun triangle (总行数)    ; 带有
                                    ;   增量计数器的版本。
  "将三角形中的鹅卵石数量相加。
第一行有一个鹅卵石,第二行有两个鹅卵石,
第三行有三个鹅卵石,依此类推。
参数为总行数。"
  (let ((总和 0)
        (行号 1))
    (while (<= 行号 总行数)
      (setq 总和 (+ 总和 行号))
      (setq 行号 (1+ 行号)))
    总和))

安装 triangle 后,您可以尝试它。以下是两个示例:

(triangle 4)

(triangle 7)

前四个数字的总和是10,前七个数字的总和是28。