我们已经创建了函数定义的各个部分;现在需要将它们组合起来。
首先,while
表达式的内容:
(while (<= 行号 总行数) ; 真或假的测试 (setq 总和 (+ 总和 行号)) (setq 行号 (1+ 行号))) ; 增量器
连同 let
表达式的变量列表,这几乎完成了函数定义的主体。但是,还需要一个微妙的最后要素。
最后的一步是将变量 总和
单独放在 while
表达式之后的一行上。否则,整个函数返回的值将是在 let
主体中最后一个表达式的值,而这是由 while
评估得到的,其值始终为 nil
。
这一点乍一看可能不明显。它几乎看起来好像增量表达式是整个函数的最后一个表达式。但是该表达式是 while
主体的一部分;它是以符号 while
开始的列表的最后一个元素。此外,整个 while
循环是 let
主体内的列表。
概述来说,函数将如下所示:
(defun 函数名 (参数列表)
"文档…"
(let (变量列表)
(while (真或假的测试)
while的主体… )
… )) ; 这里需要最后的表达式。
评估 let
的结果将是由 defun
返回的结果,因为 let
不嵌套在任何包含列表中,除了整个 defun
。然而,如果 while
是 let
表达式的最后一个元素,函数将始终返回 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。