复合过程
介绍如何定义复合过程:过程定义的标准形式、名字、形参、过程体等概念,以及多形参、零形参过程和用已有过程定义新过程。
定义过程
你已经知道如何定义像 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?),定义了另一个过程。