【翻訳属性】另一个Scheme入门_03_使用list
commonlisp吧
全部回复
仅看楼主
level 13
nadesico19 楼主
1. 前言
Scheme是Lisp系语言,因此操作list自然不在话下。为了能够充分发挥Scheme的能力,理解list是必要的。list在这之后会接触到的递归函数、高阶函数中将起到非常重要的作用。
在这里笔者将对 cons、car、cdr、list以及quote,以上基本函数进行解说。
2012年09月25日 15点09分 1
level 13
nadesico19 楼主
2. Cons Cell与list
2.1. Cons Cell
首先,从list的构成要素Cons Cell开始说明。Cons Cell是指存放有两个地址的内存空间。Cons Cell可以由cons函数建立。请尝试向解释器输入 (cons 1 2)。
-------------------
> (cons 1 2)
(1 . 2)
-------------------
得到 (1 . 2) 。cons会如图1所示,取得包含两个地址大小的内存空间,一个指向1,另二个指向2。保存着1的地址的一方称为car部,保存着2的地址的一方称为cdr部。car是Contents of the Address part of the Register的缩写,而cdr则是Contents of the Decrement part of the Register的缩写。这两个是,早期Lisp机内存里的部位名称。由此可以看出Cons Cell实际是内存空间。顺带,cons是“构成”的英文construct的缩写。
图1:Cons Cell
Cons Cell可以串连。
-------------------
> (cons 3 (cons 1 2))
(3 1 . 2)
-------------------
(3 1 . 2) 是 (3 . (1 . 2)) 的省略形式。此时,内存上的情景如图2所示。
图2:串连后的Cons Cell
此外,可以将不同种类的数据组合使用,以及嵌套。
-------------------
> (cons #\a (cons 3 "hello"))
(#\a 3 . "hello")
> (cons (cons 0 1) (cons 2 3))
((0 . 1) 2 . 3)
-------------------
之所以能够实现这种组合与嵌套,是由于Scheme对所有数据一律以地址进行管理。顺带,
#\c代表c字符。又如#
\a则代表a字符。

2012年09月25日 16点09分 2
level 13
nadesico19 楼主
2.2. list
当一连串Cons Cell中的最后一个,其cdr部指向 '() 时,则称这一连串Cons Cell为list。单纯的 '() 被称为空list,也属于list。即使只有一个Cons Cell,如果其cdr指向 '() 的话则成为list。list (1 2 3) 的内存构造如图3所示。
图3:list
事实上list是如下的递归所定义的。
1. '()是list。
2. 若假定ls为list,obj为任意对象,则(cons obj ls)为list。
像这样,由于list是递归定义的数据结构,因此在后面将会接触到的递归函数以及高阶函数中经常会被使用。
2.3. atom
没有使用Cons Cell的数据被称为atom。数值、字符、字符串、数组即是atom。
习题1
利用cons在解释器上得到如以下表示的输出。
(1) ("hi" . "everybody")
(2) (0)
(3) (1 10 . 100)
(4) (1 10 100)
(5) (#\I "saw" 3 "girls")
(6) ("Sum of" (1 2 3 4) "is" 10)
答案

2012年09月28日 15点09分 3
level 13
nadesico19 楼主
3. quote
在Scheme中,括号求值是按先内侧后外侧的顺序进行的,最外侧括号的求值结果将作为表达式的返回值。然而,有时并不希望表达式中的Token(编程语言中的“最小有意义单位”,几乎和“单词”同义)被求值。像符号或list这类被求值后不再具有原本意义的数据,当需要保持其原本意义时可以使用quote命令。
例如,(+ 2 3) 被求值后变为 5,而写为(quote (+ 2 3)) 的话就可以让 (+ 2 3) 保持不被求值的状态。由于quote很常用,所以可以使用 ' (单引号)来代替。于是 (quote (+ 2 3)) 可以写为 '(+ 2 3),表示 (+ 2 3) 这个list。像这样,要将list作为Literal(直接写入代码的数据)时使用quote。
quote不仅对list适用,对符号的求值也有效。例如 '+ 就表示 + 这个符号本身,而不代表加法运算程序。
实际上,'() 就是对 () (空list)使用了quote的产物。因此,在解释器上输入时使用 '() ,而表示出的空list为 ()。
3.1. 特殊形式(special form)
Scheme是由“对括号内所有Token求值后将结果返回括号外”的函数,以及起其他作用的特殊形式所构成的。特殊形式除了有刚刚接触到的quote以外,还有lambda、define、if、setq等。

2012年09月30日 17点09分 5
level 13
nadesico19 楼主
4. 函数 car 和 cdr
car函数会返回Cons Cell的car部,而cdr函数会返回cdr部。如果cdr的返回值是list等Cons Cell的队列,那么队列里所有Cons Cell的car部的值将会被显示出来。最后的Cons Cell的cdr部如果不是'()(即该队列不是list),则由 . 分隔后,该值也会被表示出来。
--------------------
> (car '(1 2 3 4))
1
> (cdr '(1 2 3 4))
(2 3 4)
--------------------
习题2
求以下表达式的值
(1) (car '(0))
(2) (cdr '(0))
(3) (car '((1 2 3) (4 5 6)))
(4) (cdr '(1 2 3 . 4))
(5) (cdr (cons 3 (cons 2 (cons 1 '()))))
答案
(1) 0
(2) ()
(3) (1 2 3)
(4) (2 3 . 4)
(5) (2 1)
5. 函数 list
制作由复数个元素组成的list时使用 list 函数较为便利。list函数可以接受任意个数的参数,并返回一个由参数所组成的list。
------------------------
> (list)
()
> (list 1)
(1)
> (list '(1 2) '(3 4))
((1 2) (3 4))
> (list 0)
(0)
> (list 1 2)
(1 2)
------------------------
6. 结束
在本节中笔者讲解了关于list的基本操作。虽然目前为止的内容可能略显无聊,不过下一节开始将会正式进入编程环节。笔者首先会对从编写代码到执行程序的流程进行解说,其后将是关于如何定义函数。

2012年10月05日 16点10分 10
1