程序是什么?
2020-05-10
周溱
不管你是不是一个码农,在这个年代都需要了解一点写代码的思维方式。中文把 program 翻译成程序,很多人都是这样理解的,就是程序就是给计算机下的指令序列,让它依次序执行。但是,这个理解仅在一个相当微观的局部是对的,而对程序的宏观理解并没有帮助。尤其是对非码农来说,宏观比微观更有用。但是程序的宏观结构如何理解呢?这就涉及学派间相当大的思维冲突了。
编程语言
程序都是用编程语言写成,而编程语言我把它们分成四类:
方便语言
所谓方便语言就是是上手快的编程语言。通常来说,每种方便语言有自己的擅长领域 (niche), 在它自己的擅长领域做事情轻松方便的多,有大量可直接调用的库,现成范例,也就不需要写很多代码就能实现所需要的功能。绝大多数人学编程都是从方便语言上手,而且大多数人也只需要学会两三种方便语言,就可以解决遇到的所有编程问题了。方便语言通常有下列几种特征:
- 解释执行,而不是编译执行
- 动态弱类型,而不是静态强类型
- 多种思维方式,而不是单一思维方式
这几个概念几句话解释不清,读者可以自行领悟。什么时候应该用方便语言呢?我总结也有三个原则:
- 在本方便语言的擅长领域内
- 代码量不超过一万行
- 主要由一个人完成
其实大多数的软件项目符合以上三条原则。过早或者过晚离开方便语言都会带来问题。
系统语言
所谓系统语言,就是用来开发底层系统,例如操作系统,虚拟机,数据库等基础应用的编程语言,在这些领域中,对空间效率和时间效率要求很高,所以,系统语言和方便语言的优化方向完全不同,效率第一,易用性,简洁性相对次要。大多数人,甚至大多数程序员其实不需要真正学会某种系统语言,能读懂,理解,简单修改某些代码片断就能完成大多数工作了。系统语言通常有下列几种特征:
- 编译执行,而不是解释执行
- 静态强类型,而不是动态弱类型
- 多种思维方式,但是每一种都受严格限制
同样,我这里先不解释。使用系统语言需要谨慎,不是大型底层系统,而且多人协作,尽量不要用系统语言。
纯粹语言
实际上,最多的代码量既不应该用方便语言,也不应该用系统语言。这是因为方便语言适用的工程代码量不大,而系统语言适用的范畴很窄。现在的电脑和几十年前有了天翻地覆的改变,空间和速度都不再是瓶颈,开发人员的效率反而是最大的瓶颈。所以对于大型一点的系统,最关键的是能统一编程人员的思维方式,才能做到可实现,可维护,可扩展的软件系统。高级工具不仅提供高级功能,更重要的是禁止你使用低级的功能做低级的事情,我前面提到的多种思维方式在这里体现了,你需要思维方式纯粹的语言。这就涉及到历史久远的一个学术争端。
算法 + 数据结构 = 程序 -- Niklaus Wirth
但是算法和数据结构,谁第一重要,谁第二重要呢?当今两大学派给出的答案是不同的。
面向对象编程 (OOP)
OOP学派认为,数据结构最重要,算法从属于数据结构。所谓对象,就是封装好的数据结构,提供各种方法来访问。除封装在对象类的方法之外,再无其他访问方式。从外界看来,你不知道对象里面是什么,你也不知道它的方法究竟是怎么实现的。你给它发消息,它自行做自己的事,返回一定的结果,仅此而已。
回到文章开始的问题,就是程序是什么?OOP学派的答案是:
程序是剧本
电脑是剧场,对象是演员,大家按照剧本互动,而程序员就是编剧。
函数编程 (FP)
FP学派认为,算法最重要,数据结构从属于算法。所谓函数,就是封装好的算法,你给它输入数据,它吐出结果数据。函数自身没有状态,在给定输入情况下,输出一定是一模一样的。数据裸露在外面,结构尽可能简单,而且不能改变,只是旧数据渐渐被遗忘,新数据源源不断产生,仅此而已。
回到文章开始的问题,就是程序是什么?FP学派的答案是:
程序是接线图
电脑是接线板,函数是各种器件,一方输出接到另一方输入,而程序员就是接线员。
学什么
纯粹的思维方式是排他的。从OOP的角度看FP是异端,反之亦然。对于绝大多数智商正常的程序员来说,学兼两家是痴心妄想,最终只能是要不是邯郸学步,两边都没学到精髓,要不是精神分裂,陷入自我否定的深渊。学好OOP或者FP,即使不使用纯粹的OOP或FP语言,而使用方便语言或系统语言开发,也能深化思想,写出更漂亮,更少bug的代码。那么学什么好呢?
两者都能实现所有事情,不存在一边可能,一边不可能的问题。当然面对不同问题,效率有高低,但解决问题的能力是一样的。
两者都有成熟的语言工具和用户社区。当然短期内有冷门热点,长期来看,不管东风还是西风,两者都会继续存在发展,自己学到的本事总不会过时。
我的一点看法是OOP更适合人机界面,前端,串行问题,FP更适合批量处理,后端,并行问题。其实更主要的因素还是个人偏好,两边都试一下,然后再选吧。