If we can form compound data using symbols, we can have lists such as
如果我们能用符号 (symbols) 构造复合数据,便可以拥有如下这样的表:
Lists containing symbols can look just like the expressions of our
language:
包含符号的表看起来可能与我们语言中的表达式毫无二致:
In order to manipulate symbols we need a new element in our language: the
ability to
quote a data object. Suppose we want to construct the
list (a b). We can’t accomplish this with (list a b), because
this expression constructs a list of the
values of a and
b rather than the symbols themselves. This issue is well known in the
context of natural languages, where words and sentences may be regarded either
as semantic entities or as character strings (syntactic entities). The common
practice in natural languages is to use quotation marks to indicate that a word
or a sentence is to be treated literally as a string of characters. For
instance, the first letter of “John” is clearly “J.” If we tell somebody
“say your name aloud,” we expect to hear that person’s name. However, if we
tell somebody “say ‘your name’ aloud,” we expect to hear the words “your
name.” Note that we are forced to nest quotation marks to describe what
somebody else might say.
为了操作符号,我们需要在语言中引入一种新元素:对数据对象进行引用 (quote) 的能力。假设我们希望构造表 (a b),但无法用 (list a b) 来实现,因为这个表达式构造的是 a 和 b 的值所组成的表,而非符号本身。这一问题在自然语言中早已为人熟知——词语和句子可以被视为语义实体,也可以被视为字符串(句法实体)。自然语言中的惯常做法是用引号来表示某个词或句子应被当作字面字符串来处理。例如,"John"的第一个字母显然是"J"。如果我们告诉某人"大声说出你的名字",我们期待听到此人的名字;但如果我们说"大声说出'你的名字'这几个字",我们期待听到的则是"你的名字"这几个词。请注意,为了描述某人可能说的话,我们不得不嵌套使用引号。
We can follow this same practice to identify lists and symbols that are to be
treated as data objects rather than as expressions to be evaluated. However,
our format for quoting differs from that of natural languages in that we place
a quotation mark (traditionally, the single quote symbol ') only at the
beginning of the object to be quoted. We can get away with this in Scheme
syntax because we rely on blanks and parentheses to delimit objects. Thus, the
meaning of the single quote character is to quote the next object.
Now we can distinguish between symbols and their values:
我们可以沿用同样的做法,将表和符号标记为应被视为数据对象而非待求值的表达式。不过,我们的引用格式与自然语言有所不同:我们只在被引用对象的开头放置一个引号标记(按惯例,使用单引号符号 ')。在 Scheme 语法中这样做行得通,因为我们依靠空白和括号来划定对象的边界。因此,单引号字符的含义就是引用其后的下一个对象。这样,我们便能区分符号与其值:
Quotation also allows us to type in compound objects, using the conventional
printed representation for lists:
引用还使我们能够直接键入复合对象,使用表的常规打印表示形式:
In keeping with this, we can obtain the empty list by evaluating '(),
and thus dispense with the variable nil.
与此相一致,我们可以通过对 '() 求值来得到空表 (nil),从而无需再使用变量 nil。
One additional primitive used in manipulating symbols is eq?, which
takes two symbols as arguments and tests whether they are the same.
Using eq?, we can implement a useful procedure called memq. This
takes two arguments, a symbol and a list. If the symbol is not contained in
the list (i.e., is not eq? to any item in the list), then memq
returns false. Otherwise, it returns the sublist of the list beginning with
the first occurrence of the symbol:
在操作符号时还会用到另一个基本过程 eq?,它以两个符号为参数,检验它们是否相同。利用 eq?,我们可以实现一个有用的过程 memq。该过程接受两个参数——一个符号和一个表。若该符号不包含在表中(即与表中任何元素都不 eq?),则 memq 返回假;否则,返回以该符号第一次出现为起点的子表:
For example, the value of
例如,以下表达式的值
is false, whereas the value of
为假,而以下表达式的值
is (apple pear).
为 (apple pear)。
(a b c d)
(23 45 17)
((Norah 12)
(Molly 9)
(Anna 7)
(Lauren 6)
(Charlotte 4)) (* (+ 23 45) (+ x 9))
(define (fact n)
(if (= n 1)
1
(* n (fact (- n 1))))) (define a 1)
(define b 2)
(list a b)
(1 2)
(list 'a 'b)
(a b)
(list 'a b)
(a 2) (car '(a b c))
a
(cdr '(a b c))
(b c) (define (memq item x)
(cond ((null? x) false)
((eq? item (car x)) x)
(else (memq item (cdr x))))) (memq 'apple '(pear banana prune)) (memq 'apple '(x (apple sauce) y apple pear))