0.2.2命令编程范式 返回目录 [最后更新2021.3.12]
命令编程范式是对图灵机(Turing machine) [1]模型的演绎。命令编程范式的核心观念和观念范式:以机器的运作方式看待一切。
1.命令范式的特点
基于图灵机的命令范式,有两个基本特点:
①无限长的纸带。图灵机的基本概念是机器状态(machine state),每一个语句的执行导致计算机的内存的一个或多个区域的值发生变化,从而使机器进入了一个新的状态。 “状态变化”是命令编程范式的关键词汇,SICP指出:"广泛采用赋值的程序设计被称为命令式程序设计"。
②顺序执行。从机器语言、汇编语言到高级语言如C,命令范式的程序观以CPU对指令的读取-执行循环(fetch-and-execute cycle)为基础、完全遵循计算机硬件按顺序执行指令这一事实,秉承鲜明的物理学风格的实证主义。冯•诺伊曼体系结构(von Neumann architecture)计算机,都遵循冯•诺伊曼的“关于EDVAC的报告草案[2]” 中介绍的制造电子计算机和程序设计的思想:二进制、顺序执行和存储-程序。命令范式的程序由一系列的语句组成,将自然而然地按照各语句的书写顺序、从头到尾依次执行,这是命令式语言中的“总”趋势即总体上遵循顺序结构,一江春水向东流[3]:
statement1;
statement2;
……作为对比,函数编程范式中,一个个函数解决小问题,组合起来解决大问题。因此Scheme语言仅对一些有副作用的表达式(命令),以begin块封装一系列的表达式,并顺序执行。
(begin (display "Hello") (newline) )
既然计算机是这样运作的,程序就应该如此解读。这就是命令范式的逻辑。对于程序员而言,命令范式是最为传统和经典的编程范式,也是很多人认为自然而然和理所当然的编程范式。命令编程范式将编程过程定义为一个命令/指令序列的开发,这些指令操作数据而改变机器的状态。
2.命令编程范式Vs.面向对象范式
人的思维——编写程序和看待程序运行,与机器的运作方式的一致性,是命令编程范式的全部优点和缺点所在。如果说命令式编程范式有问题,是指视角(perspectives)的问题:为什么把程序看成指令的集合呢?通常把命令编程范式的软件开发称为机器的思路,而不是人的思路。
在其他自然科学如物理学中,人们先研究身边熟悉的事物然后再深入到宏观或微观。计算机科学或者说编程则不同,从夸克(quark)——机器语言的0和1起步,再逐步进入到高级语言。人们渴求的是接近人类熟悉尺度的事物——编程领域的原子、分子和更大颗粒度的模块/实体。想象一下,能够使用分子运动的规律来解释人是如何行走的吗?即使不是不可能的,至少也是非常困难的。所以从问题求解的角度看,指令、内存小盒子、地址对于程序员解决当前复杂的软件需求而言,不能够提供足够的帮助。
一个有趣事实,初学者(甚至小学生)能够很容易理解对象,但在有经验的命令范式程序员眼里,对象有些深奥。他们的心智模型已经与机器融合,难以接受新的范式。此时,隐喻再次显示了强大的力量,不过是负面的。很多面向对象的语言,如Smalltalk 、C++、Java仍然采用了命令式语言的一些语法、语义和技术,但是思考方式却全然不同。不要“打着面向对象的幌子,干着面向过程的勾当”。
面向对象范式的核心是构造概念/类型,而命令编程范式只有函数级别的封装机制而没有概念级别的封装机制,因此熟悉命令编程范式的程序员常常不习惯组织一系列函数来完成对概念的模拟。反过来,面向对象范式先构造概念,面向对象编程范式在形成概念/类型时,不拘泥于采用什么观点或实现。当建模Dog时,可以按照命令范式;当建模风/Wind时,可以按照函数范式。
很多人认为,命令式语言逻辑体系或者说传统的结构化编程,通过设计一系列的过程(或算法)来求解问题,其核心是“解决一个问题所需要的算法是什么?”或者说“为了解决一个问题,需要什么算法”,并将Pascal语言的设计者尼克莱斯·沃思(Niklaus Wirth)的著名书籍的书名《算法+数据结构=程序》作为其代表性口号。事实上,抛弃方法论,[0.1.2行为抽象]中已说明:结构化分解是所有编程范式都具有的特点。
3.不要迷信底层!
机器/程序运作和人的思维的一致性,通常给人踏实的感觉。学习C语言的时候,很多人(高手)会查看对应的汇编代码,这很好。但是,不要过于关注底层的实现细节,如果他学习了函数式编程语言后,就会发现机器相关的“底层知识”并不那么重要;在学习面向对象编程语言时(注意这个前提),应该明白:Java语言、Java虚拟机规范和JVM实现是3个层面的东西。不要因为关注底层的习惯为Java语言的各种现象,探寻其JVM实现上的解释!
另一方面,学习C语言的时候,应该查看对应的汇编代码么?应该。学生既要知道世界之大,也要探索命令范式的真谛——图灵机。
[1] Turing, A.M., 1936-7, "On Computable Numbers, With an Application to the Entscheidungsproblem", http://www.abelard.org/turpap2/tp2-ie.asp
[2] Neumann,《The First Draft Report on the EDVAC》,1945年
[3]这些特点在Java的方法实现中保留,因此Java是命令型的面向对象语言。
命令式编程范式的