形而上学和面向对象
如果有人问我,哲学研究什么?我会告诉他三个问题:
1、世界是什么?
2、我如何认识世界?
3、我该如何生活?
这三个问题基本概括了哲学最主要的三个分支:本体论、认知论和伦理学。
如果有人问我,计算机科学研究什么?我也会告诉他三个问题:
1、计算机能解决哪些问题?
2、计算机如何描述问题?
3、计算机如何解决问题?
分别是计算机的数学模型、计算机对物理世界的模拟和计算机的架构及实现。
邱奇-图灵论题认为:任何在算法上可计算的问题同样可由图灵机计算。尽管尚未被公式证明,但它仍然已经被广泛接受。图灵机本身是人类逻辑的产物,我们有理由假定,任何人类逻辑产生的可计算的问题,均可用图灵机进行形式化描述。但是,由于图灵机本身被限定为具有开始和结束状态,“开始”、“结束”的概念本身,已经包含了比图灵机本身更高阶的条件。有开始,便意味着存在“开始之前”,有结束,便意味着有“结束之后”。当任何问题包含了图灵机的开始之前和结束之后的条件,其问题便无法靠图灵机本身解决了。停机问题判断任意一个程序是否会在有限的时间之内结束运行,问题本身包含结束条件,所以超出了图灵机解决问题的范围。这就好比坚持宇宙起源论的人,总要面对诸如“大爆炸之前是什么”这样的问题;认同创世说的人,也难回避“造物主由谁创造”的问题一样。
人类自称高等生物的一大原因是善用身体以外的工具。既然图灵机已经有如此明确的数学形式,如果使用机械装置实现它用以作为人脑的工具,那么许多只有算法而由于人脑的局限无法得到结果的问题便可以解决了。计算机使用自然能源作为驱动,比人脑更快速地重复图灵机所描述的逻辑过程,为人脑计算出问题的答案。
计算机并不能做比人类逻辑更多的事情,但在解决人类逻辑要找出最终结果的问题上,计算机以更快的速度和更高的可靠性弥补了人脑的生理缺陷。从这个意义上讲,计算机完美的诠释了“工具”的定义,可算是人脑最好用的工具。
当代计算机的计算能力以惊人的速度提升,但其工作方式从未改变。计算机从人类写好的程序中读取一条指令作为输入,按照内部约定的转移函数,从状态集合中的一个跳转到另一个。计算机不断重复这个过程,直到能够输出人类想要的结果。从这个意义上讲,今天超级计算机和1940年代读取打孔纸带的ENIAC没有区别。
但计算机能力的改变影响了人类使用计算机的方式。计算机的能力越强大,人类越要使用它解决更多的问题。随着计算能力的提升,计算机所要解决的问题的复杂度也越来越高。终于有一天,人们发现问题的复杂度已经高到使他们不得不研究关于计算机要解决的问题的方法论了。
面向对象思想便是这方法论的一种。面向对象的思想并非起源于计算机科学,但却在计算机科学中应用最广泛。面向对象的系统分析和程序设计,是在建立问题模型的时候,仿照了人类对物理世界本身的认知过程。
对象在哲学中被定义为“客体”,指任何可感知或可想象到的事物。以经验主义考察对象的认知:对于一个对象,人对其所能产生的任何认识,都可归结到某种“属性”。例如,我感知到一个对象A和另一个对象B,我的感官(例如眼睛)感知到它们有所不同,为了描述这种不同,我定义了一种叫做“颜色”的属性,定义对象A的“颜色”属性是“红色”,对象B的“颜色”属性是“绿色”;随着我发现更多的对象,我需要为“颜色”这个属性定义越来越多“值”来加以区分。但并不是所有对象都具有“颜色”这个属性,比如一段声音,为了描述它,我开始定义其他的属性(音量、时长等)。于是随着感官感知到越来越多的对象,我的意识中便定义了越来越多的属性和这些属性的“取值”。当意识中存在了各种不同的对象时,我会发现某些对象的属性具有共通之处,于是我抽象出了“类”的概念(其他观点并不认为类的概念由对象派生出来,而认为类是先于对象的,后面有提及)。
这就是人类对物理世界中对象的认知过程。如何把一个对象同另一对象区别开来呢?我们的意识所使用的,是而且仅仅是,在上述认知过程中所定义的属性。一个对象即使在某个属性上与其他一些对象相同(如都是红色),但是把这个对象所有的属性在放一起考虑,那么它总是独一无二的。一个对象与其他对象要么颜色不同,要么重量不同,要么空间位置不同……或者,所具备的属性不同。人类把一个对象同其他对象区别开来的方式,便是这些属性的集合。没有属性的定义,便无法描述对象。
面向对象编程里的对象概念,跟人类对物理世界对象的所产生的观念是一致的。要描述一个对象,其实便是描述对象的属性集合。对象的一切都是属性。我们平时在对象中称其为“属性”的变量自不必说,对象的“方法”是对象的一个“可以做某个动作”的属性,类方法是某些对象共同拥有的“方法”属性。“类”可以当作对象的一个叫做“类型”的属性(想想各种面向对象语言中类似“.class”的方法)。
不管在形而上学还是面向对象编程里,在关于对象的概念中,都出现了“类”这个概念。类是对拥有某些共性的对象集合的抽象。关于类的地位和类与对象的关系,形而上学和面向对象编程理论都出现了分歧,两个知识体系之中关于类的分歧极其相似,非常有趣。
罗素在描述柏拉图的理念论的时候,使用“猫”做例子:“有许多个体的动物,我们对它们都能够真确地说‘这是一只猫’。我们所说的‘猫’这个字是什么意义呢?显然那是与每一个个体的猫不同的东西。一个动物是一只猫,看来是因为它分享了一切的猫所共有的一般性质……如果‘猫’这个字有任何意义的话,那末它的意义就不是这只猫或那只猫,而是某种普遍的猫性。这种猫性既不随个体的猫出生而出生,而当个体的猫死去的时候,它也并不随之而死去……‘猫’这个字就意味着某个理想的猫,即被神所创造出来的唯一的‘猫’……”柏拉图认为,这个由神创造出的唯一的理想的猫,才是真实的猫,而其他的猫只不过是现象而已。
对上面这段描述,我相信每个有面向对象编程经验的人都会有些似曾相识。因为几乎每本面向对象编程的入门书上所举的例子,跟上面的猫的例子都十分相像。即使对柏拉图没有任何了解,我们也会自然而然地把“现象的猫”和“对象”对应起来,把“理想的猫”和“类”对应起来。
柏拉图认为共相的猫(即理想的猫),是完美且先于任何一只现象的猫存在的,因为现象的猫都只不过是共相的猫的一个不完美的副本。这和正统的基于类的面向对象语言(如Java)对类的定义是类似的:类是先于对象存在的,先有类的定义,然后从类定义中派生出对象实例。
柏拉图的理念论又称为唯实论,与之相对的理论叫做唯名论,唯名论认为共相并不存在,即只有个别的猫而没有共相的猫。唯名论和唯实论的争论是形而上学中长久以来探讨的主题。唯名论的一个偏向折衷的观点是:共相由实际存在的一个个 个体推导而来,但共相一旦建立便是存在的。
唯名论的观点把类置于对象之后,让人联想起著名的“鸭子类型”:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”一些基于对象的编程语言(如Javascript),更强调对象的功能而非类型。在Javascript中实现面向对象的特性时,类的概念并不是必需的,而可以完全基于对象间的关系来实现特性。因为把对象和类放置的地位有所不同,基于类的面向对象语言和基于对象的编程语言,在对物理世界建立模型时便需要使用不同的方式。
在对世界本质的认识上,历来有两种截然不同的观点。一种是:存在一个客观世界,人类对世界所形成的观念,是由于客观世界通过感官作用于人的意识,从而产生各种关于世界的知识;另一种截然相反:认为不存在客观的世界,因为就人意识中形成的观念而论,人的意识通过感官形成了对世界的知识,但是仅凭这些知识,是无法确定客观世界的存在的,因为能够确定的只有意识本身,没有任何其他证据,使意识确信“有一个客观世界,使感官产生了作用”。两种观点可以简单的说成唯物论和唯心论。
论证这两种观点孰对孰错,是形而上学的哲学家们的事情。对于大多数对哲学问题并不热心的人来说,采取上面两种观点的哪一种,并不对生活产生任何影响。当甲对乙说:“我想吃那个苹果”时,不管在甲的心目中“那个苹果”是个真正存在的“对象”,还是他脑中形成的一个包含“颜色、重量、口味等”这些属性的意识,他都明确表达了自己的感情;同样的,听到甲说这话的乙,不管认为“那个苹果”是真实的客体还是脑中的观念,都不妨碍他理解甲的态度。
同样在面向对象编程里,类和对象哪个是更基础的概念,以及应该把对象当作类的实例还是单纯的属性集合,这些问题不能简单回答。对于类和对象,重要的不是它们“是什么”,而是它们“如何被使用”。
最后,文章开始对计算机的描述,我想说,虽然计算机的能力被限定人类逻辑之内,但是由于计算能力的提升,越来越多原来只在“算法上”可解,但是受限于人类能达到的计算能力而无法求解的问题开始慢慢得到解决。探求其他形式的图灵机实现的成果,特别是对量子计算机研究可能产生的成果,人类所能拥有的计算能力可能会发生更加急速的跳跃。这种计算能力的爆炸式增长,即便在过去的几十年里,也已经证明了,它不仅影响着人类的生活方式,也在影响着人类对所处世界的认知。
这篇文章本来写于半年前发表在博客上,今天想拿出来增色一下,但是能力所限,始终感觉很多地方词不达意,一不小心大半夜了。大概就像那句关于debug的话说的一样:代码纠错要比新编写代码困难一倍。因为,如果你写出了最聪明的代码,按此推算,你将没有更大的智慧来debug它。