有必要澄清两个基本概念--算法和过程的关系以及关于程序设计方法论的一些看法
概述
前些天,在一个关于面向对象和面向过程的话题, 我的一句评论"算法说白了就是过程"引起了辩论.于是我有了写这篇随笔的想法: 一位园友善意地说这个评论太业余了.我没有为业余二字生气,因为人家是善意的.但是,遗憾的是,这两个概念是最基本的程序设计理论了, 而这位园友都没有弄明白。其实没有必要说谁业余了,因为那只会助长浮躁的风气。我希望这里只有学习学习再学习.我相信一定有其他人没有弄清楚.于是这篇随笔就有必要写写了. 我同时将我在评论中说到的一些关于程序设计方法论的言论整理到这篇随笔中来.
关于算法和过程的关系
先引经据典说概念:
<<算法导论>>第二版 中文版 机械工业出版社 2006.9.1出版 I S B N : 9787111187776 南京大学潘金贵等译
第一部分(Part I) 基础(Foundations)的第一节:
所谓算法(algorithm)就是定义良好的计算过程.它取一个或者一组值作为输入, 并产生一个或一组值作为输出。亦即, 算法就是一系列的计算步骤, 用来将输入数据转换成输出结果.
以上是引用. 请注意第一句的主谓宾.主语是"算法". 谓语是"是".宾语是"过程".上述概念说明:一个算法一定是一个过程.
我想大家不用怀疑这本书的权威性, 有这本书的人可以看到长长的编审委员会人员名单.
我的上述评论"算法说白了就是过程"表达的就是同样的意思.
从下文起我就不去找权威经典了.我就将我自己的描述写到这里.
2009.11.16.增加内容
我上面只说了一半, 即算法一定是一个过程。但是所有过程都是算法吗?回答是: 不是所有过程都是算法. 符合如下五个特性的过程,才是算法。
1、有穷性: 一个算法必须保证执行有限步之后结束;
2、确切性: 算法的每一步骤必须有确切的定义;
3、输入:一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定除了初始条件;
4、输出:一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的;
5、可行性: 算法原则上能够精确地运行,而且人们用笔和纸做有限次运算后即可完成。
2009.11.16增加完毕
关于过程和面向过程编程的关系
程序语言里面的过程指的是一系列计算步骤, 计算步骤是下列三种形式的结构:顺序,条件分支和循环.
面向过程编程是一种编程的方法论. 这种方法论将程序看成数据库结构和算法.我们上面说过一个算法一定是一个过程.因此,也可以说面向过程编程将程序看成是数据结构和过程.为什么叫方法论呢,就是说它是程序设计者对世界的认识,是程序设计者的世界观.即,当程序设计者用面向过程编程的方法论来设计和编写程序的时候, 他的眼里只有数据结构和算法,而没有其他(包括类,对象等).
过程与面向过程编程是不同的概念, 进一步说, 过程与程序设计方法论也是不同的, 因为面向过程编程只是程序设计方法论的一种.
过程反映了人们数理逻辑思维的脉络. 你在用面象对象语言编程的时候,你在不自觉地用过程. 面象对象方法论告诉你哪里可以避免重复写类似地过程. 过程是所有程序语言必须的内容. 程序设计方法论再怎么变,程序设计语言始终不能离开这三个过程式的结构: 顺序,条件分支和循环结构. 离了这三个结构,就不叫程序了.
关于程序设计方法论
程序设计方法论即程序设计者的世界观. 现在有很多种程序设计方法论. 如面象对象,面向过程,命令式编程,函数化编程,标记式语言等等.面象对象,面向过程,命令式编程,函数化编程,标记式语言等都是一种程序设计方法论. (从1990年后)目前工业界用得最多的是面象对象,面向过程这两种方法论.当你用面象对象来看世界时,你只看到了对象. 当你用面向过程看世界时,你只看到了数据结构和算法, 如果用其他的, 看到的又是另外的东西了. 无论是面象对象、面向过程、函数化编程还是标记式语言,写出来的代码无不体现出程序设计者对真实世界的认识。面象对象是一种世界观,面向过程也是,函数化编程同样也是。只不过在我们表述这个认识的时候用的是不同的方式。
这些程序设计方法论之间没有什么优劣之分.只有根据实际需要采取最合适的方法论或者方法论的组合. 关于如何选取程序设计方法论,我目前还没有仔细看这个话题.就不写这个话题了. 有兴趣的朋友可以去找找看. 不过请朋友们记住: 当某大师向你说某个方法论总是(或者说任何时候都)比其他方法论好的时候,你可要警惕了. 道理很简单, 拿治病来说, 因为从来就没有万灵的药物, 只有在某种情况下最合适的药物. 病万变,药亦须万变.
现在面向对象的强势, 以致于我们好多从业人员连想都不想就会选择面向对象. 因为目前我们很多开发工具都是国外生产的.国外说面向对象我们就只能跟着念. 国外计算技术的发展是多样的,丰富的。当面向过程强势时,面向对象的方法论也在酝酿和进化中,后来面向对象取代面向过程成为工业界的主流, 现今面象对象强势时,他们又有其他的方法论被提出,或者拿出多年前的方法论再改进. 这反应出国外的计算技术水平较高. 希望不久的将来,我国的计算技术水平也能稍领风骚. 中国, 加油!
关于未来程序语言的猜想
这是我在前面发评论时想到的, 不当真. 大家就当笑谈吧. 当我们的人工智能等学科发展, 将来的程序表现形式可能既不是面向过程的, 也不是面向对象的. 而是更象自然语言. 从微观看, 它还是有过程的特征; 从宏观看, 它是不确定的, 动态的, 经过规划的,评估过的体系. 简单说是一个可进化的智能专家系统的语言. 它对于一个问题的求解象人类的认识过程似的, 有进化上升的特征, 所以不同时期它的求解可能得出不同的答案.
还不知道这个真的能实现否. 但是梦想是可以的.
2008.12.5. 将评论里面的观点整理出来
一个园友发表不同意见觉得上文中的这句明显有问题: "程序设计语言始终不能离开这三个过程式的结构: 顺序,条件分支和循环结构. 离了这三个结构,就不叫程序了". 并拿lisp语言来做证明. 他说:"比如LISP就没有过程,用递归的". 那么好吧,我们就来看看一个实际的lisp程序是否有这三个结构.
下面的lisp程序来源于: http://www.dynamiclearningcenter.com/samples/htout/htout.lisp , 是我到网上找的.
我们可以看到lisp有"if", "loop"等. 在lisp里面它们被称为函数, 但是这些函数就是实现我所说的分支结构和循环结构. lisp里面的运作是完全函数化,
对函数的调用是一层嵌套一层,先调用一个函数再调用一个, 是用递归实现这么多函数的调用.我们可以注意到lisp的先调用一个函数再调用另一个函数
就是我所说的顺序结构. 可见lisp虽称为非过程语言. 它实际上是一样是有我说的过程.
不仅lisp, 稍微记得程序语言发展史的人, 一定记得c++也是被学者们划入非过程语言范踌的. 不少人学过c++, 一定知道c++也是有我说的过程.
这个事实就是, 不管是过程语言(如c),还是非过程语言(如lisp,c++)都有过程.
过程表达的是人们自然的逻辑思考,先干什么后干什么, 如果..., 就..., 否则就...,
要有先后的次序就必须有顺序结构, 要有逻辑就必须有条件分支, 要重复做某事就必须有循环. 到具体程序语言上, 只是其表现形式不一样而已.
结论就是这位园友引用的那句: "程序设计语言始终不能离开这三个过程式的结构: 顺序,条件分支和循环结构. 离了这三个结构,就不叫程序了".
程序语言的一个倾向--只要告诉计算机做什么而不要告诉计算机怎么做
这是由lisp想起的话题. 程序语言设计者们开始倾向于设计这样的程序语言: 只要告诉计算机做什么而不需要告诉计算机怎么做.
lisp应该是他们在这个方向上的一个努力. 但是, "只要告诉计算机做什么而不要告诉计算机怎么做" 只是相对的. 计算机不可能预先知道天下所有的事情.
所以这方面的努力还只是很初步的. lisp仍然需要人们在很多地方告诉计算机怎么做.
这个话题说起来似乎微不足道, 有些人没有注意到这些概念也照样在写程序. 有些人甚至觉得无聊之极, 还在下面写上构思比较巧妙的评论.
我只好付之一笑了,也好啊, 娱乐娱乐. 对于这样的评论, 我要说的是: 你不经意的地方 有 你没有注意的事实.
2009.11.16: 此处应该说是:不识庐山真面目,只缘身在此山中。
至于重要不重要嘛,你用你自己的智慧来判断吧