SICP 1.1节是这样描述数据和过程的:数据是一种我们希望去操作的东西,而过程就是有关操作这些数据的规则的描述。也就是说,数据是被动的,而过程是主动的。
这只是对数据和过程的一种表面上的理解,实际上,数据本身就是由过程构造出来的(参见SICP 2.1.3的有理数,序对,以及本节练习2.6中非负整数),本质上过程和数据就是一个东西。从最底层的角度来看,无论是数据还是过程,对于计算机来说都是0和1的序列,存储时也是以0和1来保存的。
举个例子,windows的系统光盘,从系统安装者的角度去看,里面既有过程也有数据,从光盘复制者的角度去看,里面所有的内容都是数据。
这说明数据和过程的区分是由于观察的角度不同,从这个角度观察是一个数据,换个角度观察是一个过程。
具体来说,数据是从整体的角度去观察,过程是从如何构造这个整体的角度去观察,这一点从SICP 2.1.3节就可以看出来。
即使是所谓的基本数据,例如数值数据和符号数据(参见P96),继续往下分解,你就会发现它们仍是用过程来构造的。拿浮点数来说,对于不同的指令集,解释器的实现也是不同的。像8051指令集,压根没有浮点指令,如果你想在8051上弄个lisp解释器,就必须自己用过程去构造浮点数。而像x86指令集,自带浮点运算指令,但你再往下分解,你会发现它的浮点运算指令是靠硬件层面的浮点运算器来实现的。硬件层面的东西和过程有关系吗,当然有,硬件实际上可以看成是把过程固化到物理电路中的产物,比如用硬件描述语言生成的硬件,当然,即使是纯手工设计的电路,其实也是过程的固化。
还能继续往下分解吗?可以,如果把数字电路里的基本门电路看成数据,那么这些数据就是由晶体管的组合过程构造出来的。如果把晶体管看成数据,那么这些数据就是由半导体的加工过程构造出来的。如果把半导体材料看成数据,那么这些数据就是由分子的组合过程构造出来的。再往下,就是原子,有人说,原子往下该没有了吧,不好意思,还有,原子是由电子,中子,质子构成的。这种分解也许永远都没有尽头。所以,平常编程里面说的原子对象不可分解,其实也是一种相对的说法。
再引申一下,宇宙的一切都可以看成是数据,这些数据就是由许许多多的过程构造出来的,宇宙的发展就是不断的由过程去构造新的数据。
再联想一下,数据其实就是信息,也就是说,信息也是由过程构造出来的(参见宇宙的发展历程这篇帖子)
最后,用一句话来总结,数据就是过程的抽象。抽象的好处在于它能使你忽略无关的细节(参见【代码大全】第二版 5.3节 形成一致的抽象),这正是降低软件设计复杂性的关键所在。SICP致谢部分的第五段是这样说的:在大型系统的构造中,应该避免控制中的复杂性(也就是避免太过复杂的过程),将精力集中到数据的组织上,以反映所模拟世界的真实结构。
上面的这种说法其实指的就是以数据为中心来进行编程,或者说数据驱动编程。把关注点放在数据上有什么好处呢,正如前面一段提到的,数据是过程的抽象,抽象的东西能让你忽略细节,从而降低复杂度。举个例子,设计数字电路就是去组织各个门电路(这里的各个门电路就是数据),把门电路看成数据,那么设计数字电路实际上就是在组织数据。