现在的位置: 首页 > 综合 > 正文

像大师们一样思考——从“UML何时死掉”谈起

2012年08月28日 ⁄ 综合 ⁄ 共 4080字 ⁄ 字号 评论关闭

题记:
  在与Ivar的访谈之后,我一直想把这一段过程写出来。我尝试拟过许多个题目,最后都写不成文章。几乎在我要放弃的时候,BLOG读者在评论中,对我所解释的“函数式语言”的置疑提醒了我:很多时候不是问题的答案令人置疑,而是问题的思想方法令人置疑。如同我问Ivar的问题,他的答案“令人怀疑的正确”,其实是思想方法的问题。不站在Ivar的历史,以及Ivar的成就的角度上去思考,你会认为Ivar是在应付我的责难。

  事实上,那个访谈中,Ivar非常慎重地面对这个问题,并仔细地解释了他所提供的答案。可惜后来CSDN录制时,正好漏掉了这一段。非常遗憾,此回顾这些经历,既以钦佩,亦复深研。

像大师们一样思考
        ——从“UML何时死掉”谈起

  得了一个机会(1),我问Ivar:“UML什么时候才会死掉呀”。我无意用这个
透着促狭味道的问题去为难大师,实在是因为这是我一直以来思考着的问题。向
UML之父去求解,自然是最好。
  Ivar细毫没有认为我是在为难他,他诚恳的回答让我在那个会议中陷入了
深思。他说:“什么时候面向对象死掉了,UML就死掉了”。(2)
  一个问题看起来很复杂,但它的答案可能非常简单。一个答案看起来非常简
单,但它可能是最正确的。一个正确的答案,也许毫无意义,但也许,那就是大
师的答案。
  很多我们现在看起来是非常“理所当然”的事情,就曾经困扰着大师们。比
如说,我们现在都知道程序的基本逻辑是顺序、分支与循环。那么,“为什么顺
序、分支与循环是基本逻辑呢”?“作为基本逻辑,它们充备吗?”谁能回答我?
如何回答我?

  这是一个艰深的问题吗?我们知道答案,但即使知道答案,我们也答不出
“为什么”。然而,真正的大师们是论证过这个问题的。那个提出“GOTO有害”
的大师Edsgar Wybe Dijkstra(戴克斯特拉/迪杰斯特拉)就为此写了篇“札
记”。他是怎么论证的呢?他说计算机可以理解的人的思想方式,有三种。分别
是枚举、归纳与抽象。而,重要的是,Dijkstra进一步的说明,分支(if)是
计算机实现枚举的方法、循环(for)是实现归纳的方法。当他进一步的解释“抽
象”时,他说“在现阶段,我发现很难把抽象的作用说得非常清楚”。
  Dijkstra大概是做好全部的准备,来完成这篇札记。他通过数学方法来
证明了“分支如何以及为什么能实现枚举”。也就是说明分支对于“枚举”这种思
想方法来说,是否是完备的。Dijkstra在写出了大量的数学推理之后,说“上
述的笨重证明,也使我自己感到烦恼!但是,在现在,如果真的希望证明这个程
序的正确性,我确实没有更好的办法。”Dijkstra引以为佐证的是,“以前,
平面几何里的第一批定理的荒诞证明,也常常使我感到同样的愤怒,因为这些定
理所论证的事情几乎和欧几里得公理自身一样的‘明显’”。
  Oh! Dijkstra愤怒的原因,在于原本看起来是如此“显然”、“理所当然”
的事情,却需要无比笨重的过程去证明它!如同我们明明知道“1+1=2”,但证
明这一点,既无趣又令人愤恨。
  Dijkstra这样的证明过程,奠定了“程序正确性证明”这门学科的基础;
它的证明结果,是说明了程序的结构性是有限的,例如顺序、分支与循环。这个
“结构有限”的理论,开创了“结构化编程”这样的一个时代。我在《代码之美》
的序中说“我们如今仍然在这个时代之中而不知觉于这本书的深远影响”,是意
有所指的。因为所谓的“面向对象程序设计”,其根基就是“结构化程序设计 + 在
结构上更高层次的抽象”。而这“更高层次的抽象”,就是“对象”。
  Dijkstra在1970年前后就完成了这篇札记,而我们接下来这40年的时间,仍
未逃离大师最初的思想。然而,对这所有的一切,大师最初创见性的想法可以归
结于一句:“可用来理解一个程序的种种思维方法之中,我提及以下三种:
枚举法、
数学归纳法、抽象。”

 
  为什么是这三种?是不是只有这三种?能不能有更多种?大师没有解释,他
只是“提及以下三种”而已。Dijkstra一方面给我们留下了空间,一方面,他
足够完备的“论证”说明了基础逻辑必须至少具备“顺序、分支、循环”。而我们,
40年来,无有突破。
  Ivar把UML之死,归于一种抽象的失败,或其被更高的抽象所替代。实
在是无比正确的,因为UML也是建立在结构化、抽象这样一些基元的理论之上。
Dijkstra的那篇札记,被收入《结构程序设计》一书,书里的另外两篇,一
篇是“层次结构设计”,讨论的是面向对象程序设计;另一篇是“数据结构札记”,
讨论的是数据基本抽象。三部文章,三位图灵奖得主,一个跨越40年的时代,
以及程序设计语言分类中的1/2(命令式语言)都承受着这种影响。
  然而,Dijkstra仍然无法论证,或未曾说明过“三种基础逻辑的唯一性”,
他只是想当然地说“我认为”而已。

 

  同样只是从“我认为”开始的,还有图灵机。如果有一个毛头小子跳出来说,
“我认为”计算机应该象一个大笨象吃意大利面条;大笨象要有肚子,面条上要
打孔。Oh,很好,这个毛头小子立即会被哄出“计算机科学”的神圣殿堂。问题
是,图灵就是这样一个毛头小子。于是他的这一构想就被称为“天才式的创想”。


  然而,真的只是这样吗?
  算盘用了几千年,谁问过“算盘为什么能算东西”?算珠、进位、栏,这些
东西,是不是基本的存储结构?用算盘的“我们”,是不是计算单元?珠算表是
不是运算规则?那些珠子表达出来的“0~9”的排列,是不是输入输出的界面?
  “我们+算盘”就是一个完整的计算系统。这个计算系统的完整性,是图灵用
了一个假想来说明的。图灵不过是用一个假想描述了一个事实,而这个事实,“看
起来”能被机器实现。于是,我们的计算机时代就开始了。


  图灵是否证明过“大笨象吃意大利面条为什么是一个完备的计算机系统”
呢?不,最初等的问题,往往难于证明。往往,他的证明过程,或应用过程,只
是触发了一个想象。
  对计算机根本问题的思考,许多会追溯到哲学思想的层面。IOPD和PDIO
的问题,“程序=算法+结构”的问题等等,就是这一类。还有一些会追溯到人类行
为学、语言学等层面,例如语言、语法、语义,以及有没有语用这样的问题。大
多数时候,真正推动了计算机发展的,不是对具体问题的推理求解,而是对问题
本身的抽象。在Dijkstra的叙述中,抽象更象是终极武器。按照Brooks的
观点,“数据的表现形式(数据结构,抽象的结果之一)是编程的根本”;按照
Dijkstra的引述,“引用未解释过的名词阐述公理或定理和作用于未解析过的
操作数的(命了名的)运算两者之间有着某种平行的相似性”。
  无论如何,我们“做一个计算机”,原始的目的不外两个。其一是“让它计算
数学”,其二是“让它像人一样思考”。注意,我的确是说“计算数学”,数学是人
类的理论学科,“怎么算”,以及算的内容等等,都是我们自己设定的。而计算
机的能力,只是计算“数学”这个它未知的对象而已。事实上,我们现在在讲的“命
令式”,以及“函数式”,或“说明式”,就只是我们为计算机设定的“最基础的运
算方式”。在这个“运算系统”中,“数学”并不是最初设定的。
  命令式如何计算,函数式如何计算……类似于此的问题了解清楚了,我们对
这类语言也就了解了。再谈什么高阶函数(higher-order function)、克
里化(Currying)、延续(Continuation),或发生-迭代器
(Generator-Iterator)之类,那已经是具体语言的表象,而非“这一类语
言”的本质了。举例来说,JavaScript 1.5还没有实现过“生成器对象
(Generator Object)”,但并没有人否认它是函数式语言。反过来说,
Generator Object原本就不是函数式语言的必备要素。
  LISP表达了函数式语言的全部“必备要素”,然而LISP七个原子运算也是
针对于“LIST”这个结构抽象来说的。对于一个“(顺序的)表”,这七个原子运
算是必须的,而对于另一个“(关系的)表”就未必如此了。所以,那这些原子
运算,也不必放在函数式的必备要素中。象LUA这样的函数式语言实现方法的
出现,也证明了这一点(3)。
  函数式还剩什么?
  真正理解函数式的秘密,是要一个语言一个语言的学习下去么?是要一种运
算法一种运算法地学习下去么?我们听完人家说“持续”,于是就开始了解持续,
而不去问持续为什么出现在函数式里面?亦或是不是函数式的必备要素?还是
函数式运算系统的自身的“问题”?我们正是迷失于种种语言和概念的表象,而
最终没能象大师一样去思考“计算机不过是大笨象吃意大利面条”这样的抽象层
面的问题。


  我们要改变的是思想,我们要增强的是能力。大多数人只是增强能力,而不
改变思想。这就是“我们”——大多数人不是大师的原因。
  感谢Ivar。并不仅仅是因为他给出了一个问题的答案,以及他的谦谨和微
笑,还感谢他告诉我们:答案并不是表面上的正误,真正的答案是答案背后的思
想。

注:
~~~~~~
(1)CSDN围绕“软件工程40年”进行的一个软件工程研讨会。相关的视频在

http://live.csdn.net/Issue519/LivePlay.aspx

但是由于录制技术上的问题,这个研讨会丢失了1/2多的内容。
(2)当然,在那个会议上,我的提问与Ivar的回复都不会如此轻率。我原始的
问题是:“既然——包括自然语言在内的——所有的语言最终都会消亡,
那么UML作为一门建模语言,它什么时候会消亡呢?以及,新的替代它的
建模语言又应该具备那些特性呢?”Ivar当时的答案是:“如果作为UML
核心思想的OOP方法没有被推翻,那么UML就不会消亡”。因此他对这个时
间的预期是:“接下来10~15年,或更长的时间,不会有更新的、标准
化的建模语言。”
(3)LISP的基础数据结构索引数组(表,LIST),LUA的基础数据结构是关
联数组(表,MAP)。 


(我与Ivar Jacobson先生,2008.07.21,CSDN软件工程研讨)

抱歉!评论已关闭.