2.6 函数 (Functions)

你可以用 defun 来定义新函数。通常接受三个以上的实参:一个名字,一组用列表表示的实参,以及一个或多个组成函数体的表达式。我们可能会这样定义 third

  1. > (defun our-third (x)
  2. (car (cdr (cdr x))))
  3. OUR-THIRD

第一个实参说明此函数的名称将是 our-third 。第二个实参,一个列表 (x) ,说明这个函数会接受一个形参: x 。这样使用的占位符符号叫做变量。当变量代表了传入函数的实参时,如这里的 x ,又被叫做形参

定义的剩余部分, (car (cdr (cdr x))) ,即所谓的函数主体。它告诉 Lisp 该怎么计算此函数的返回值。所以调用一个 our-third 函数,对于我们作为实参传入的任何 x ,会返回 (car (cdr (cdr x)))

  1. > (our-third '(a b c d))
  2. C

既然我们已经讨论过了变量,理解符号是什么就更简单了。符号是变量的名字,符号本身就是以对象的方式存在。这也是为什么符号,必须像列表一样被引用。列表必须被引用,不然会被视为代码。符号必须要被引用,不然会被当作变量。

你可以把函数定义想成广义版的 Lisp 表达式。下面的表达式测试 14 的和是否大于 3

  1. > (> (+ 1 4) 3)
  2. T

通过将这些数字替换为变量,我们可以写个函数,测试任两数之和是否大于第三个数:

  1. > (defun sum-greater (x y z)
  2. (> (+ x y) z))
  3. SUM-GREATER
  4. > (sum-greater 1 4 3)
  5. T

Lisp 不对程序、过程以及函数作区别。函数做了所有的事情(事实上,函数是语言的主要部分)。如果你想要把你的函数之一作为主函数(main function),可以这么做,但平常你就能在顶层中调用任何函数。这表示当你编程时,你可以把程序拆分成一小块一小块地来做调试。