复合过程

介绍如何定义复合过程:过程定义的标准形式、名字、形参、过程体等概念,以及多形参、零形参过程和用已有过程定义新过程。

定义过程

你已经知道如何定义像 square 这样的简单过程了。定义过程的标准形式是 (define (name formal-parameters) body),即 (define (过程名 形参表) 过程体)。

先来熟悉几个术语:

  • 复合过程(compound procedure):由 Racket 基本过程(primitive procedure)组合定义而成的过程。
  • 名字(name):过程的名字是一个符号(symbol),用来引用该过程。
  • 形参(formal parameters):过程的形参是过程体内部用来指代实参(argument)的名字。
  • 过程体(body):过程体是过程的”肉”,是整个过程的核心。它的正式定义是”当形参被替换为过程应用的实际实参时,将产生过程应用值的表达式”,不过你可以把它理解为让计算机遵照执行的指令。

在过程定义 (define (square x) (* x x)) 中,名字是 square,形参是 x,过程体是 (* x x)。

假设我这样定义一个过程:(define (foo x y) (+ (* 3 x) (* 4 y)))。请回答以下问题。

上面这个过程的名字是什么?

它的两个形参是什么?

它的过程体是什么?

多形参过程

过程不一定只有一个形参,比如 square。它也可以有多个形参。创建多实参过程的方法相当直接,写法类似这样:(define (foo x y z) (* x y z))。

我们也可以创建完全没有实参的过程!代码写法类似这样:(define (foo) 3)。这样,每次调用 (foo),它都会返回 3。

过程之中还有过程

编程中最有用(也最酷!)的一点是:一旦定义了一个过程,你不仅可以反复使用它,还可以用它来定义其他过程。

你现在大概已经看腻了 square 了,我们换个例子。先定义一个谓词(predicate)vowel?,再用它来定义另一个过程:

(define (vowel? letter) (member? letter '(a e i o u)))

有了 vowel?,我们就可以在不同的过程中使用它。例如,0.3 中的一道题就涉及 Pig Latin(儿童黑话)。如果一个单词以元音开头,把它翻译成 Pig Latin 只需在词尾加上 “ay”。我们现在先不操心怎么把单词翻译成 Pig Latin,只是再定义一个谓词,检查一个单词是否以元音开头:

(define (pig-complete? wd) (vowel? (first wd)))

如你所见,我们用一个用户自定义的过程(vowel?),定义了另一个过程。