2.1 形式 (Form)

人可以通过实践来学习一件事,这对于 Lisp 来说特别有效,因为 Lisp 是一门交互式的语言。任何 Lisp 系统都含有一个交互式的前端,叫做顶层(toplevel)。你在顶层输入 Lisp 表达式,而系统会显示它们的值。

Lisp 通常会打印一个提示符告诉你,它正在等待你的输入。许多 Common Lisp 的实现用 > 作为顶层提示符。本书也沿用这个符号。

一个最简单的 Lisp 表达式是整数。如果我们在提示符后面输入 1

  1. > 1
  2. 1
  3. >

系统会打印出它的值,接着打印出另一个提示符,告诉你它在等待更多的输入。

在这个情况里,打印的值与输入的值相同。数字 1 称之为对自身求值。当我们输入需要做某些计算来求值的表达式时,生活变得更加有趣了。举例来说,如果我们想把两个数相加,我们输入像是:

  1. > (+ 2 3)
  2. 5

在表达式 (+ 2 3) 里, + 称为操作符,而数字 23 称为实参。

在日常生活中,我们会把表达式写作 2 + 3 ,但在 Lisp 里,我们把 + 操作符写在前面,接着写实参,再把整个表达式用一对括号包起来: (+ 2 3) 。这称为前序表达式。一开始可能觉得这样写表达式有点怪,但事实上这种表示法是 Lisp 最美妙的东西之一。

举例来说,我们想把三个数加起来,用日常生活的表示法,要写两次 + 号,

  1. 2 + 3 + 4

而在 Lisp 里,只需要增加一个实参:

  1. (+ 2 3 4)

日常生活中用 + 时,它必须有两个实参,一个在左,一个在右。前序表示法的灵活性代表着,在 Lisp 里, + 可以接受任意数量的实参,包含了没有实参:

  1. > (+)
  2. 0
  3. > (+ 2)
  4. 2
  5. > (+ 2 3)
  6. 5
  7. > (+ 2 3 4)
  8. 9
  9. > (+ 2 3 4 5)
  10. 14

由于操作符可接受不定数量的实参,我们需要用括号来标明表达式的开始与结束。

表达式可以嵌套。即表达式里的实参,可以是另一个复杂的表达式:

  1. > (/ (- 7 1) (- 4 2))
  2. 3

上面的表达式用中文来说是, (七减一) 除以 (四减二) 。

Lisp 表示法另一个美丽的地方是:它就是如此简单。所有的 Lisp 表达式,要么是 1 这样的数原子,要么是包在括号里,由零个或多个表达式所构成的列表。以下是合法的 Lisp 表达式:

  1. 2 (+ 2 3) (+ 2 3 4) (/ (- 7 1) (- 4 2))

稍后我们将理解到,所有的 Lisp 程序都采用这种形式。而像是 C 这种语言,有着更复杂的语法:算术表达式采用中序表示法;函数调用采用某种前序表示法,实参用逗号隔开;表达式用分号隔开;而一段程序用大括号隔开。

在 Lisp 里,我们用单一的表示法,来表达所有的概念。