泰勒斯,欧几里得,与结构化编程

294 阅读6分钟

在上一篇《柏拉图与面向对象编程》中,我讲到,面向对象这一编程范式,与西方哲学中的柏拉图思想不谋而合。今天我们看看另一个编程范式,同时也是第一个被广泛使用的编程范式 —— 结构化编程。

0

先说说什么是结构化编程。

结构化编程,顾名思义,得先有结构。就像建筑一样,有砌体结构,钢筋混凝土结构,钢结构等等。结构化编程里面的三大结构是顺序结构,分支结构和循环结构。顺序结构就是顺序执行的一行行代码,分支结构是指由 if/else/switch 这些关键词划分的条件分支语句,循环结构是指由 while/for 等关键词组成的循环语句。这三种结构通过不同的排列组合,可以组成任何复杂度的程序。

有的小伙伴就问了,所有程序不都是这样的吗?难道还有例外?

提出这个问题的小伙伴一定很年轻。不知道在一些上古编程语言里面,还有 goto 这个逆天的存在。

1

goto 关键词是用来做什么的呢?它能从你代码的任何一行语句,跳转到任何一行语句。它就像是一个拥有瞬移能力的超级英雄,可以从世界上任何一个地方,瞬移到另一个地方。

听起来是不是很强大?那为什么现在的编程语言都抛弃了这个关键词?它又有什么问题呢?

它会让程序的复杂度成倍地增加。试想,你正在尝试理解一段只有 10 行的程序,它执行到第三行的时候,跳转到了第七行,从第七行往下执行,到第九行的时候又往回跳到了第五行,第五行和第八行之间的 goto 调用似乎又形成了一个循环。退出循环之后才最终走到第十行……但是后面第十一行,你不知道又有什么惊喜等着你。如果你不在乎自己所剩无几的头发的话,可以把这个烧脑的游戏继续玩下去。

它破坏了结构。在使用了 goto 的程序之中,你根本无法总结出一个基本结构来。就像你正在用砖瓦盖房子,你拿起一块砖,发现这块砖竟然是个故宫?!它就像一团乱麻,没有结构,肆意疯长。

所以,区分一段程序是不是符合结构化编程的思想,就看它是不是只包含了顺序,分支,循环这三大结构,并且没有使用像 goto 这样的任意跳转的语句。

2

那么,这又跟欧几里得有什么关系呢?

这得从 Dijkstra 怎么提出的结构化编程说起。

Edsger Wybe Dijkstra 出生于荷兰,是荷兰的第一个程序员。在工作了几年之后,他得出一个结论:编程是一个难度很大,复杂度很高的活动。随着需求的发展,一段程序会包含越来越多的细节信息,如果没有工具的帮助,这些细节信息会远远超过一个程序员的认知能力范围。

Dijkstra 想到的这个『工具』就是欧几里得。他认为可以借鉴数学推导的方法,建立由公理,定理,推论,引理组成的欧几里得结构。任何数学理论都是由一些公理和由公理导出的定理进一步推导出来的。同样的,任何程序也可以由一些基本的,已经被证明正确的结构组成,并且,也可以被证明是正确的。而这些已经被证明的基本结构,就是程序世界里面的『公理』。

于是 Dijkstra 开始致力于寻找程序世界里面的『公理』,他找到了顺序结构,分支结构和循环结构,并用数学的方法证明了这些结构的正确性。在这个过程中,他也发现,goto 语句的某些用法会导致程序无法被拆分成更小的可证明单元。就像我上面说的,你在盖房子的时候,拿起一块砖,却发现它竟然是故宫。于是,goto 语句被排除在了结构化编程的大门之外。

Dijkstra 证明了这三种结构本身的正确性,后面的 Bohm 和 Jocopini 则证明了,人们可以用这三种结构构造出任何程序。

3

结构化编程解决了一个问题,就是程序的最小单位是什么,或者说,程序的本质是什么。这个本质,是在时间意义上面在先的一个本质。即先有了这些最小的结构单位,才有了后面复杂的程序。那么对于我们这个世界,时间上在先的本质是什么呢?

泰勒斯说,大地浮于水上,宇宙充满了灵魂。

泰勒斯是被公认的西方第一个哲学家,是希腊早期自然哲学学派——米利都学派的代表人物。他认为,宇宙万物的本质是水。一切都是由水演变而来,而一切,又终将归于水。对泰勒斯来说,水并不是指我们日常生活中的水,而是一个哲学概念。水的流动性,易变性,可塑性和生命原则,是化生万物的基本特征。

米利都学派的另外一位学者,阿那克西美尼,则认为,万物的本原是『气』,是生命,或者灵魂,它本真就包含着生成的动力,推动着万物周而复始,循环不已。

再到后来的赫拉克利特,他说到,『一切事物都换成火,火也换成一切事物。正像货物换成黄金,黄金换成货物一样』。在赫拉克利特那里,『火』成为了本原。

亚里士多德综合了前人的思想,得出了事物都有四种元素构成 —— 火,气,水,土。火比气重,水比火重,土比水重。这样,含土量多的事物自然在最下面,含气量多的事物在最上面,这意味着个别事物以四元素的比例多少『找到它自然的位置』。这就是万物运动的动力来源。

4

可以看到,哲学家和程序员,在一开始都是在寻找时间在先的本原。哲学家寻找宇宙万物的本原,找到了火,气,水,土这四种基本元素。程序员寻找代码的本原,找到了顺序,分支,循环这三种基本结构。后来,哲学家们开始转向,寻找逻辑在先的本原,提出了『存在』的概念。而程序员也同样如此,于是,『面向对象』就此诞生。