We have identified in Lisp some of the elements that must appear in any
powerful programming language:
我们已经在 Lisp 中识别出了任何强大编程语言所必须具备的若干要素:
Numbers and arithmetic operations are primitive data and procedures.
数和算术运算是基本的数据和过程。
Nesting of combinations provides a means of combining operations.
组合式的嵌套提供了一种组合操作的方法。
Definitions that associate names with values provide a limited means of
abstraction.
将名字与值关联起来的定义提供了一种有限的抽象手段。
Now we will learn about
procedure definitions, a much more powerful
abstraction technique by which a compound operation can be given a name and
then referred to as a unit.
现在我们将学习过程定义 (procedure definitions)——一种更为强大的抽象技术,通过它可以给一个复合操作命名,并将其作为一个整体来引用。
We begin by examining how to express the idea of “squaring.” We might say,
“To square something, multiply it by itself.” This is expressed in our
language as
我们从考察如何表达"求平方"这一概念开始。我们可以说:"对某个东西求平方,就是将它与自身相乘。"在我们的语言中,这可以表达为
We can understand this in the following way:
我们可以这样来理解这个定义:
We have here a
compound procedure, which has been given the name
square. The procedure represents the operation of multiplying something
by itself. The thing to be multiplied is given a local name, x, which
plays the same role that a pronoun plays in natural language. Evaluating the
definition creates this compound procedure and associates it with the name
square.
The general form of a procedure definition is
这里我们有了一个复合过程 (compound procedure),它被命名为 square。该过程表示将某个东西与自身相乘的操作。被乘的那个东西有一个局部名字 x,它在这里所起的作用与自然语言中代词的作用相同。对这个定义求值,会创建该复合过程并将其与名字 square 关联起来。过程定义的一般形式为
The ⟨name⟩ is a symbol to be associated with the procedure definition in
the environment. The ⟨formal parameters⟩
are the names used within the body of the procedure to refer to
the corresponding arguments of the procedure. The ⟨body⟩ is an
expression that will yield the value of the procedure application when the
formal parameters are replaced by the actual arguments to which the procedure
is applied. The ⟨name⟩ and
the ⟨formal parameters⟩ are grouped within parentheses, just as they
would be in an actual call to the procedure being defined.
Having defined square, we can now use it:
其中,⟨name⟩ 是一个符号,将在环境中与该过程定义关联;⟨formal parameters⟩ 是在过程体中使用的名字,用于指代过程的相应实际参数;⟨body⟩ 是一个表达式,当形式参数被过程所接受的实际参数替换后,它将产生过程应用的值。⟨name⟩ 和 ⟨formal parameters⟩ 被括号括在一起,就像实际调用被定义的过程时那样。定义了 square 之后,我们就可以使用它了:
We can also use square as a building block in defining other procedures.
For example, x
2
我们也可以将 square 用作定义其他过程的构建块。例如,x²
+
y
2 can be expressed as
y² 可以表达为
We can easily define a procedure sum-of-squares that, given any two
numbers as arguments, produces the sum of their squares:
我们可以很容易地定义一个过程 sum-of-squares,它以任意两个数为参数,求出它们的平方和:
Now we can use sum-of-squares as a building block in constructing
further procedures:
现在我们可以将 sum-of-squares 用作构建更多过程的构建块:
Compound procedures are used in exactly the same way as primitive procedures.
Indeed, one could not tell by looking at the definition of
sum-of-squares given above whether square was built into the
interpreter, like + and *, or defined as a compound procedure.
复合过程的使用方式与基本过程完全相同。事实上,仅凭上面 sum-of-squares 的定义,是无法判断 square 究竟是像 + 和 * 那样内置于解释器中,还是被定义为一个复合过程的。
(define (square x) (* x x)) (define (square x) (* x x))
| | | | | |
To square something, multiply it by itself. (define (⟨name⟩ ⟨formal parameters⟩) ⟨body⟩) (square 21)
441
(square (+ 2 5))
49
(square (square 3))
81 (+ (square x) (square y)) (define (sum-of-squares x y)
(+ (square x) (square y)))
(sum-of-squares 3 4)
25 (define (f a)
(sum-of-squares (+ a 1) (* a 2)))
(f 5)
136