业余编程爱好者
分类: 敏捷开发
2013-01-24 13:54:05
《SICP》2.1.3节讲述了数据的本质。文中用过程构造数据,从而抛出了数据到底是什么的问题。整理下有趣的思想:
“一般而言,我们总可以将数据定义为一组适当的选择函数和构造函数,以及为使这些过程成为一套合法表示,它们就必须满足一套特定的条件。”
这意味着什么?lisp系统中的复合数据,可以通过一组构造函数描述如何将“基本数据”粘合在一起而形成。通过一组选择函数来实现提取组成这种复合数据的“基本数据”。这里并没有提到必须要有一种数据结构来存放这种复合数据,也就是可以不用数据结构,而只用函数来实现这种复合数据。
比如以下通过过程来实现lisp中的序对结构:
(define (cons-new x y) (lambda (m) (m x y))) (define (car-new z) (z (lambda (p q) p))) (define (cdr-new z) (z (lambda (p q) q))) ; (car-new (cons-new a b)) ;-> ; (car-new (lambda (m) (m a b))) ;-> ; ((lambda (m) (m a b)) (lambda (p q) p)) ;-> ; ((lambda (p q) p) a b) ;-> ; a ; (cdr-new (cons-new a b)) ;-> ; (cdr-new (lambda (m) (m a b))) ;-> ; ((lambda (m) (m a b)) (lambda (p q) q)) ;-> ; ((lambda (p q) q) a b) ;-> ; b
在序对的实现中,并没有一种数据类型来存放“序对”这种复合数据,而是把作为参数的基本数据在构造和选择函数中传来传去,用以实现对复合数据的操作。
在lisp系统中,是直接实现了“序对”这种数据类型,主要是为了效率。在我理解中,可以通过C语言中链表结构的概念来实现“序对”,这样“序对”就作为了一种数据结构,真实的把数据存放在内存中。而在上文用过程实现对“序对”中,“序对”并不是做为一种数据类型存在,只是通过一组函数来模拟出对“序对”的操作。这很违背直觉,但确实可以这么做。这也从另一个方面表达了,数据可以作为一个黑箱存在,只要是提供它的接口函数,并能返回正确的结果,就不用管实现它的具体细节。
仔细想一下,《SICP》在这一节讲出了数据的本质。在外部看,复合数据做为了一个可以赋值,可以操作的对象存在。而在内部,复合数据可以是一种实现好的数据类型,也可以用过程来构造。在后面的情况下,复合数据不是真正的存在,只有在对它操作时,才会表现出一个对象的样子。
从哲学上看,这跟物质的组成很相似。以前一直认为物质是用最小的基本单位“原子”组成,“原子”作为一个真实的对象存在。“原子”则是由另一些基本粒子组成,这些基本粒子互相作用,表现出“原子”的特性。在物理学家的猜想“弦理论”中,组成“原子”的基本粒子并不是真实的存在,只是由很小很小的线状“弦”的不同振动而表现出不同的基本粒子的样子。
从《SICP》用过程也能实现数据的情况联想到:数据的存在,只能通过数据在外部环境的表现中来判定。如果数据可以被正确的操作和构成,满足特定的条件,那它就可以被理解成真正的存在。以便于我们想象和理解,用来构造更加高级的数据。