作者:leezy_2000
关于编程语言的争论虽然此伏彼起,但事实上很少有人真的在做编程语言的比较,同时许多无价值或错误的观点却在真实的误导着许多程序员的认识,为此我决定写这篇文章。
一、前提本文后述观点是基于这样一种前提:只关注语言特性,而忽略标准库和其他各种商业框架(虽然这些更大程度上决定着人们对语言的选择)。这必将使这篇文章的观点更具有理论意义,而非现实意义。但语言特性是编程语言的根本,无论是做语言比较,还是评论语言,都应该以此为出发点,否则将导致讨论范围的无限增大,进而导致讨论的无结果。为避免有人找碴,必须预先声明的一点是,由标准库实现的语言特性将被看作语言特性,进而列入考虑的范围。同时这里说的编程语言是指一些通用目的的高级编程语言,比如C/C++,Java,Python,Perl等。
二、80% 与 20%我学习不同的编程语言时,更多的时候是感觉到其间的共性。于是我对此进行思考,发现这种共性的存在具有必然性。
软件的根本特性是复杂性,对此Dijkstra告诉我们,“掌握复杂性的技巧早在古代就有了:divide et impera(分解和规则)”。当我们具体进行分解和设定规则时,我们要用到一些分析和设计方法。当代两大主流分析和设计方法是结构化和OO。结构化设计方法的三种基本结构是顺序,分支和选择。OO的三大基本特性是封装,继承和多态。各种设计语言通常都支持这两种分析和设计方法,其基本语言特性也必然涵盖上述六个要素。所以从这个角度看不同编程语言必然具有相当多的共性。
可为佐证的首先是《The Art of Computer Programming》这本书。这本书中的算法用低级语言描述的,但其内涵被大多掌握不同编程语言的开发人员所分享。有人评论说,当今软件开发人员所掌握的绝大多数计算机程序设计的知识都来源于此,这意味着相当多程序设计知识可以具体实现在各种编程语言中。
另一个是《设计模式》,你很难说那个设计模式是专属于那种语言的,大多的设计模式可以用各种编程语言来实现的。虽然具体的实现上会因为语言特性而做相当的调整。应该可以说不同的编程语言在某个确定的设计模式面前,体现的也是共性。
把上面的内容总结一下就是:很多的场合下,不同的语言是可以互换的。互换的基础是不同种语言间的共性,而存在这些共性的基本原因是不同的编程语言要支持的根本思想中大部分是相同的。
故老相传,学到高处,语言间切换是很容易的,很多人的经历也验证了这句话。上面说的正是这句话的所以由来。
这里没有把各种语言等同起来的意思,但编程语言的个性同共性相比反倒是较小的部分。它们往往成为关注的焦点,同时也是存在这么多编程语言的一个主要原因。
大多数人对此的体验大概来自基本语法,事实上这是让人非常懊恼的一个方面。基本语法的不同起源于什么无从考证,但根本事实是这种不同在浪费学习者的时间。我们来做个类比大家就知道这种浪费有多么不值得,UML出现前,OO表示法主流上有三种,他们表达意思差不太多,但他们不一样。学习的人,工作的人要为同一件事花近三倍的力气(要不然别人用另外的表示法写的文档你怎么看的懂),现在这些人得到了解放。但在编程语言领域这种糟糕的事仍然在继续,差不多每个人都要记住好多种if语句,虽然事实上它们可以统一。
抛却基本语法不谈,其它的方面是真的不多。即使把C++和Python这两种差别非常巨大的语言放在一起进行类比。一时间能想起的主要差别也只有:①Python内置了list及tuple等一些数据结构作为内置类型(当然还有与此相关的操作)。而C++中要用基本类型对此进行定义。②Python支持函数生成器和函数嵌套定义。而C++不支持。③Python是动态类型语言,先天具有范型能力。而C++要通过模板的概念支持范型。这不是一个完整的列表,如果愿意,这个列表确实可以变长,但另外一张反映共性的标通常会更长。
(注:我没有参考相应的书籍把两者的语言特性一一罗列,并彻底的比较其异同,仅是把平常使用时经常用到的语言特性想了一下,写了上面的东西。如果那位使用过两种以上的语言,我也建议能用这种方式来确定两种不同语言的常用部分有多大的重叠度。)
这也正是题目所说的80%和20%的根本含义。不同的语言虽然看起来差别很大,但共性要大于个性。至于是不是4:1的关系,老天知道,那位感兴趣,可以统计出一份数据来。
三、结论(事先声明,这里是从学习的角度来下这个结论,而非混饭的角度)
好多年前就有这句话:编程语言并不重要,设计思想才重要。这几年在托鼠标即是编程的大潮中,这句话逐渐被遗忘了。
在这篇文章的结尾,我想对这句话进行一些诠释。编程语言不是不重要,光有想法,基本语法都搞不清楚的人肯定什么都做不出来。但而后呢?不停的学习新的语言,接触新的语法么?从上面的分析看,如果你这样做,那意味着你在做重复劳动,并且没有实际的进步。真的程序员不该如此堕落,总要学些思想性的东西吧。总不能去研究怎么才能把一个钮拖到另一个地方的路径缩到最短吧?
学习编程语言,熟悉基本语法后,一定要关注某些语言特性背后所承载的东西。但
单知道这两样仍然是不够的,还要知道什么时候这些被承载的东西适合使用。这是远比前两者更难的东西。
为避免结论过于抽象,举个例子来描述这三重境界:比如说学习模板的时候,第一步是要把基本语法搞清楚,要能够确保写出来的模板类、模板函数没有语法错误,能够通过编译。第二步要去理解范型这种思想,去思考范型存在的根本目的是什么?第三步是能够在碰到具体问题时,来正确的取舍是否需要使用这种特性,用的话又怎么去用。
四、尾声程序员作为一个笼统的称呼,其真正的含义正在分化。Bjarne Stroustrup自称:“是的,我是一个程序员”。而一个只会拖拖鼠标,完成指定功能的新手,通常我们也称之为程序员。但事实上这同一个称呼,其内在含义是不一样的。
可视化编程和RAD的快速发展所产生的一个明显后果就是,所谓的软件蓝领离我们是如此之近。并且越来越多的人以闪电般的速度切入这个队伍。这又是怎么样一场绚丽却虚假的繁华。于是许多妖言应势而生,最为让人哭笑不得的莫过一句“程序员是吃青春饭的”。这未免太小觑程序员这个职业了,这句话成立的前提是做程序员没什么难度,不需要什么积累,主要是力气活。诚然如果程序员只是一个拖鼠标的职业,那么年富力强者具有先天的优势。但很不幸大多时候他不是,或者说不应该是。
在这里我姑且漠视许多公司对软件蓝领的呼唤,单从个人发展的角度提醒一句,实践实用主义的同时,莫要忘了什么是编程的根本,莫要忘了提升自己的境界。