各种编程语言的优缺点
日期 : 2021年08月02日
正文共 :11621字
【译注】:圣经记载:在远古的时候,人类都使用一种语言,全世界的人决定一起造一座通天的塔,就是巴别塔,后来被上帝知道了,上帝就让人们使用不同的语言,这个塔就没能造起来。巴别塔不建自毁,与其说上帝的分化将人类的语言复杂化,不如说是人类自身心灵和谐不再的分崩离析。之所以后来有了翻译,不仅是为了加强人类之间的交流,更寄达了一种愿望,希望能以此消除人际的隔阂,获求来自心灵的和谐及慰藉。真正的译者,把握血脉,抚平创痕,通传天籁,开启心门。
这是我写的旋风式的编程语言简介 —— 我本来为亚马逊开发者杂志本月的期刊写的,但是发现我写的东西没法见人。
首先,我偶尔一不小心口出脏话,或者对上帝不恭的话,所以在很官方很正式的亚马逊上发表是不合适的;所以我就把它塞到我的博客里了,我的博客反正没人看的。除了你以外。是的,只有你会看,你好啊。
其次,这是一项进行中的工程,现在只是东打一耙西搞一下,还没有精加工过的。又一个把它写到博客里的很大的理由。不需要很好,或很完整。就是我今天想说的一些话。请随便!
我的旋风式简介会讲C、C++、Lisp、Java、Perl (我们在亚马逊用到的所有语言)、Ruby (我就是喜欢) 和 Python,把 Python 加进来是因为 —— 好吧,你看了就知道了,现在我可不说。
C
你必须懂C。为哈? 因为出于所有现实的理由,这个世界上你过去,现在,将来会用到的每一台计算机都是一台冯·诺曼机器,而C是一种轻量级的,很有表达力的语法,能很好的展现冯·诺曼机器的能力。
冯·诺曼架构就是你每天都用的计算机的架构的标准:一个 CPU,内存,硬盘,一条总线。多核计算机并没有带来本质上的变化。冯·诺曼机是一个很方便,很便宜,上世纪五十年代的实现图灵机的技术,图灵机是执行计算的最知名的抽象模型。
世上还有其他的计算的机器。比如,Lisp 机器,是上世纪 50 年代对 Lisp 计算模型的实现。Lisp 模型是基于 lambda 代数的一种计算语言表示法,后者是与图灵机同构的一种模型。不像图灵机,lambda 代数能被人类读和写。但是这二者是同等能力的。它们同样精确的表示了计算机能干什么。
Lisp 机现在不是很流行了,除了在跳蚤市场里。从谁更受欢迎来说,冯·诺曼机器赢了。还有一些其他的计算机,比如神经网络计算机,译者也不知道怎么翻的计算机(cellular automata),但是这些都不够大众化,至少现在是这样的。
所以你必须知道C。
还有一个你必须知道C的原因是,Unix 是用C写的。巧的是,Windows 也是。基本上所有的其他操作系统都是用C写的。因为这些操作系统都是冯·诺曼机的操作系统,你还能用别的吗? 任何跟C很不一样的东西都会跟硬件的实际能力相差太远而导致无法满足性能上的需要,至少对一个操作系统来说是这样—至少在上个世纪是这样,碰巧这些系统都是上个世纪的。
你还应该知道 Lisp。你不必用它来干实际工作,虽然它在很多 GNU 的软件里都会很用得着。尤其是,你应该学会 Scheme,Lisp 的一种小巧化的,纯洁的方言。GNU 的版本叫 Guile。
他们在麻省理工和加州伯克利教新学生一到两个学期的 Scheme,这些学生都对他们为哈要学这么奇怪的语言抓破脑袋。实话实说,作为第一门学习的语言,这是一个很烂的选择,第二门也是很烂。你应该学会它,最终,但不是作为第一门或第二门语言。
这是很难的哦。这是很大的一步。学会怎么用 Lisp 写出像C语言的程序是不够的,那没有意义。C 和 Lisp 一个就像红外线,一个就像紫外线,它们分布在光谱的最两端。它俩一个牛逼的地方刚好是另一个傻逼了的地方。
如果说,C是最靠近计算机是如何工作的语言模型,Lisp 就是最能反映计算(注意,这里没有了“机”字,计算机和计算是很不同的!译者注)是如何工作的模型。你不需要懂很多 Lisp,真的。紧咬 Scheme 就哦了,因为它是最简单最干净的。其他的 Lisp 已经发展成了很大,很复杂(很好很强大? 译者:-)的编程环境,就像 C++ 和 Java,要有很多库啊,工具啊等等之类。那些,你不需要知道。但是你应该能用 Scheme 写程序。如果你能够做出 The Little Schemer 和 The Seasoned Schemer 这两本书里的所有习题,你懂得就够多了,我认为。
但是对于你天天要做的编程工作,你应该基于以下条款选择你的语言:库,文档,工具支持,操作系统集成,资源,和一堆其他的东西。这些条款跟计算机如何工作关系很小,但是跟人类如何工作关系甚大。
人们还在用很直白的C语言写东西。很多东西。你应该懂C!
C++
C++是地球上最蠢的语言,即使是从蠢这个字的真正意义上出发。C++很无厘头。它不知道自己是什么东西。它没有自省(introspective,面向对象里的一个概念,译者注)。C也没有,但是C不是“面向对象”的,而面向对象很大程度上是关于要让你的程序知道它自己。对象就像演员。所以面向对象语言应该有运行时的自省机制,知道自己是个什么类的对象。C++不是这样的,真的,你不会那样用它。
关于C:写一个C的编译器是那么的简单,以至于你可以用C写一个关于C的工具,用起来就像是有内省机制。而 C++ 呢,基本上是不可解析的,所以如果你想写一个很牛逼的工具用来 —— 比如,告诉你你的虚函数的原型,或者帮你重构你的代码,你将不得不依赖别人的工具集,因为你自己在除非脑子进屎的情况下是根本不会去写一个 C++ 的解析器的。而市面上所有的 C++ 的解析器都很傻逼。
C++很蠢,你不能用蠢语言创造一个好系统。语言决定世界,蠢语言决定蠢世界。
所有的计算都基于抽象。你用低级的东西创造出高级的东西。但是你不能用分子创造出一个城市。尝试使用太低级别的抽象只会给你带来麻烦。
我们就惹上麻烦了 (是指亚马逊的员工,还是所有 C++ 的程序员? 我也不知道,译者注)。
理智的情况下,你用C写的最大的东东就是一个操作系统。而操作系统其实不是很大的,真的。它们看起来很大,但那是因为它们有很多应用软件,操作系统本身的内核是蛮小的。
你用 C++ 能写的最大的东东是…也是操作系统。好吧,或许稍微再大点儿。让我们说,再大三倍吧。或者 10 倍吧。但是操作系统内核最多也就,那啥,一百万行代码? 所以我说你能用 C++ 写的最大的系统大概也就是一千万行代码吧,再大的话就开始不行了,这玩意儿你没法控制了,就像恐怖片里的…
我说的一千万行是指如果你那时候还能让你的系统编译通过的话。
我们(在亚马逊,译者注)有五千万行 C++ 代码。不,现在还要更多了。我已经不知道有多少行了。上个圣诞节是五千万行,那是九个月前,而它以每季度八百万行的规模增长。增长率本身也增长,妈呀。
我们想在这个系统里干点啥好像要一万年。一个亚马逊工程师有一次这样描述我们的代码库:“一座很大的屎山,你见过的最大的山,每次你想修正一个 bug,你的工作就是爬到屎山的正中心去。”
伙计们,那哥们可是在四年前说的这话。他现在已经到更环保绿色的牧场上去了。真是太可惜了,他可是个实实在在的高手啊。
这都是 C++ 的错。别跟我争论。就是的。我们用的是世上最蠢的语言。这简直有点老板级的蠢,你说呢? (译者注,meta 在计算机术语里通常表示更高一个层次,比如,meta-language,比普通的 language 高一个层次,意思是关于语言的语言。哲学里应该会经常用到这个词。我不懂哲学,但是我觉得老板们总是比我们高一级,所以 meta-dump 我就翻译成老板级的蠢喽。:-)
说了以上这些难听的话,话得说回来了。用 C++ 写出漂亮的代码显然是可以的,我的意思是说,这样的代码应该大部分还是C,偶尔很有品味的,很有节制的用一点C++。但是这种代码几乎从来不会被写出来。C++是个很好玩的游乐场,而如果你把它玩儿得门儿清的话你会觉得自己特牛,所以你总是被诱惑把你知道的所有的东西都用上。但是那是很难做好的,因为从一开始这个语言就太狗屎了,最终,你会弄得一塌糊涂,即使你很能干。
我知道,我说的都是异端邪说,该被钉到十字架上的。随便吧。我在大学里的时候老喜欢 C++ 了,因为我那时候就只知道这一门语言。当我听到我的语言教授,Craig Chambers,绝对的厌憎C++,我想:“为啥呢? 我觉得它挺好的啊”。而当我听到 STL (标准模板库)的发明者被采访时说他恨 OOP (面向对象编程)时,我更是认为他肯定是磕药了。怎么会有人恨 OOP 呢,而这个人竟然还是 STL 的发明者?
亲不敬,熟生厌(语出圣经,译者注)。说的是在大多数情况下,跟一件事物熟悉了之后你就失去对它的膜拜尊敬了; 在计算机语言里情况不是这样的。光对一门语言熟悉不会导致你看轻这门语言。你必须成为另一门更优秀的语言的专家(才能让你明白原来那门语言有多么多的问题)。
所以如果你不喜欢我针对 C++ 大放厥词,请你去学另一门语言并成为一个专家(我推荐 Lisp),只有那时你才有足够的武器与我争论。然而,那时你将不会跟我争了。你上了我的当了。你也会跟我一样变得不喜欢 C++ 了,你或许会觉得我这个人很恶心,把你骗得不喜欢自己曾经的最爱了。所以或许你应该把我说的一切都忘了。C++挺好的其实,真的。它就是很棒棒(译者注,作者在这里用了 ducky,这是一个女性喜欢用的夸某物好的词,近来也为玻璃们喜爱)。忘了我说的话。C++不错的。
Lisp
(我打赌这一节会让你觉得惊讶,即使你已经关注我的博客有一阵了[译者注,作者也可能是说,即使你成为亚马逊的员工有一阵了])
亚马逊创业之初,我们有很多明星级的工程师。我不认识他们所有人,但是我认识几个。
比如?Shel Kaphan, 大拿。Greg Linden, 大拿。Eric Benson。即使在他加入亚马逊之前就已经有自己响亮的名气了。也是大拿。
他们写了 Obidos 服务器。是 Obidos 让亚马逊成功的。只是后来那些生产大便很拿手的工程师,网页开发者,搞前端的人 —— 这些人因为生产大便很拿手而总是能让经理们满意 —— 只是在后来这些人把 Obidos 搞糟了。(他们的大便)把整条河都堵了,打个比方说的话。但是 Obidos 是亚马逊最初的成功的一块关键的基石。
这些最早的牛人们在亚马逊神圣的代码库里只允许两种语言:C 和 Lisp。
你自己去想吧。
当然,他们所有人都使用 Emacs。靠,Eric Benson 是 XEmacs 的作者之一。这个世界上所有伟大的工程师都在用 Emacs[注1]。那种世界因你而不同级别的伟大。不是坐在你旁边的格子里的那哥们那种伟大。也不是 Fred,走廊尽头那哥们。我说的是我们这个行业里最伟大的软件开发者,那些能改变这个工业的面貌的人。像 James Gosling 们(Java 语言设计者),Donald Knuth 们(这个人没有听说过的话赶紧改行吧,别搞计算机了),Paul Graham 们[注2],Jamie Zawinski 们,Eric Benson 们。真正的工程师用 Emacs。你必须很有点聪明才能把 Emacs 用好,而如果你能成为一个 Emacs 大师的话它会给你难以置信的牛力。有机会的话你应该站到 Paul Nordstrom 的肩后看看他是怎么工作的,如果你不相信我的话。对那些一辈子都在用烂 Visual Studio 之类的集成开发环境的人来说,一定会大开眼界的。
Emacs 是那种你可以用 100 年的编辑器。
Shel, Eric, Greg,和其他像他们那样的人,我没有足够幸运能跟他们直接一起工作:他们禁止在这里使用C++,他们禁止使用 Perl(或者 Java,为完整起见)。他们是明白人。
现在我们都在用C++,Java 和 Perl 了,所有的代码都用这些语言。我们的前辈们已经到更环保的牧场上去了 (指没有大便的牧场,译者注)。
Shel 用 C 写了 Mailman,客服部的人把它用 Lisp 封装了一下。Emacs-Lisp。你不需要知道 Mailman 是什么东西。除非你是个 Amazon 的老员工,或许不是搞技术的,而且你曾经不得不让客户哈皮 (只有在这种情况下你才需要知道 Mailman,译者注)。不是间接的,因为你用 C++ 写的一个狗屎功能跑不起来了,让客户很生气,于是你不得不去搞定它以恢复客户的哈皮度。不,我是说直接的,意思是,你必须跟他们聊。我们可爱的,不识字的,呱呱其谈的,心地善良的,充满希望的,困惑的,能帮点小忙的,愤怒的,哈皮的客户们,真正的客户们,那些从咱们这里买东西的人,我们的客户们。(如果你必须跟他们打交道的话,)那你就会知道 Mailman 这个东西。
Mailman 是客服部的客户电子邮件处理软件,我们用了它有…四,五年? 反正是很长时间。它是用 Emacs 写的,所有人都爱死它了。
人们现在还很爱它。直到今天,我依旧不得不听我们一些非技术员工跟我长篇大论的叨叨他们是多么的怀念 Mailman。我可绝不是满嘴喷粪。上个圣诞节我参加了一个 Amazon 的派对,一个我不知道自己怎么会被邀请的派对,里面全是些西装笔挺的商务人士,谁都长得比我帅,比我光鲜。以及一些我在公司里曾经打过交道的人(这句不知道怎么译)。四个美女认出了我是在客服部里干的,把我包围了,跟我说了十五分钟她们是多么的怀念 Mailman 和 Emacs,而现在的亚马逊(我们用 JSP 花了好多年准备换掉 Mailman 的那一套软件)是怎么的不能满足她们,让她们觉得跟以前一样爽。
这一切都太梦幻了,我觉得她们可能是喝多了。
Shel 是个天才。Emacs 是天才。连非技术人员都爱 Emacs。我现在就是在 Emacs 里打这些文字。我绝不情愿在任何其他地方打字。这不只是关于让你的效率得到飞跃,通过那些地球上其他地方找不到的快捷键和文本编辑功能。我每分钟打一百三到一百四十个英文单词,在 Emacs 里,当我在写没有格式要求的文本的时候。我测过这个时间速度。自己写了一个测打字速度的 Emacs 应用。但我想跟你说的不只是这个。
Emacs 有的是一种你叫不出名字来的品质。
我们现在不用 Mailman 了。那是因为我们有一种叫得出名字的品质 —— 就是,烂。我们很烂。我们(当时)找不到 Emacs-Lisp 足够牛的人把 Mailman 继续搞下去。今天这应该不难了; 亚马逊现在到处都是 Emacs Lisp 的黑客。但是在那时候,客服部的人没法从别人那里得到帮助。于是他们就用他们当时手头有的资源去搞这件事。他们当时没有足够多的 Emacs-Lisp 的人。有一段时间,他们甚至找来 Bob Glickstein 当合同工,那个给 O’Reilly 写了那本 Gnu Emacs 扩展的书的家伙,坐在一个小办公室里给 Emacs 写 Mailman 的扩展。
客服应用部是 Amazon 的第一个两块比萨饼的团队(代表团队人数的增加,编者注)。这个团队是完全自立的。不管是那时还是现在。没人跟他们说话,没人帮他们。没有枪,没有炮,他们自己造。他们没有网页工程师,没有支持工程师。屁也没有。有的只是一堆骨灰级的工程师和一个能带新人的文化。这就是他们需要的一切了。
但他们最终不得不让 Mailman 光荣退休。妈哎。而我呢今天还听到人们说他们是多么的怀念它。甚至在派对上。
我想今天按人头比例来说,客服部仍然拥有比亚马逊任何其他团队更多的 Lisp 黑客。可能他们用到 Lisp 的机会不多了,但是 Eric Raymond 说过,即使你很少用 Lisp 写程序,学习 Lisp 会是意义深远的一个经历,能让你下辈子都成为一个更好的工程师。
卡尔,宗教现在已经不是大众的精神鸦片了。现在鸦片是集成开发环境了。(卡尔·马克思。这个人不知道的话应该打屁屁)。
Java
Java 是过去的 10 年中计算行业里发生过的最好的同时也是最坏的事。
一方面,Java 把你从 C++ 编程的很多枯燥易错的细节中解救出来了。没有数组越界了,没有 core dump 了。抛出来的异常能让你精确定位到出错的那一行代码,而且 99% 的时候都是正确的那一行出错了的代码。对象们在需要的时候能智能地把它们自己打印出来。等等等等。
另一方面,除了是一种语言,一个虚拟机,一个巨无霸的类库,一个安全模型,一个可移植的字节码格式,Java 还是一个宗教。邪教。所以你不能太相信对它太虔诚的人。想要招一个好的 Java 工程师是一项很有技术挑战的活。
但是总的来说,Java 是软件工程史上的一大进步。
从 C++ 到 Java 不只是语法上的改变。这是一种需要一段时间去好好体会的一种震撼性的世界观的转变。这有点像突然你被配了一个执行助理。你知道老总们为什么总是好像有时间去开会,总是知道公司现在运行的情况,总是写出很酷酷的文档吗? 老总们常常忘记其实他们不是一个人在战斗,他们都是两个全职的人,他们和他们的执行助理们。有一个执行助理把你从琐事中解救出来让你有时间去思考那些真的需要你去解决的问题; 没有的话你将不得不花一半的时间在那些无聊的世俗的事情上。切换到 Java 编程语言就把你变成了两个程序员 —— 一个处理那些你不需要关心的东西,另一个可以集中精力在问题本身上。这是一个很震人的改变,一个你应该很快就能习惯能喜欢上的改变。
就像 Jamie Zawinski (Netscape 牛人,开发 Mozilla 浏览器,好像学历是高中毕业?)在他著名的“Java 真烂(java sucks)”那篇文章里说的:“先说那些好东西:Java 没有 free() 函数。我必须一开始就承认,其他的东西都没什么了不起。(没有 free)是能让我原谅其他所有东西的特性,不管其他东西有多烂。讲完这一点后,我的文章里其他一切几乎都完全没有重要性了。”
Jamie 的文章写在 1997 年,按 Java 年来算的话是很早以前了,跟他写这篇文章时比,Java 已经有很大的改善; 一些他抱怨的东西甚至已经被 fix 了。
但是大多数还是没有被 fix。Java 作为一门语言还是有点烂。但就如 Jamie 指出的,Java“是今天为止最好的语言。我的意思是说,它是今天市面上那些烂得底儿掉地一堆语言比起来有那么一点能被我接受。”
真的,你应该读读他那篇文章。
Java 几乎每一方面都很好,除了它的语言本身,而这是 JWZ 抱怨的主要对象。但那是一个很大的抱怨。再好的库也救不了一个烂语言。相信我:你可能比我知道多得多的东西,但是我知道好兵救不了烂将。在 Geoworks 搞了五年汇编语言都会了我这个道理。
跟 C++ 比,Java 作为一个语言还过得去。好吧,别扯了,Java 要好很多。因为它有(内建)的字符串。哥们,你说一个没有内建的字符串的语言是人用的吗。
但是 Java 跟 C++ 比少了一些好东西,比如(函数调用时)传引用,栈上的对象,typedef,宏,以及运算符重载。一些时不时地会很称手的东西。
哦,还有多重继承,我现在老了,反而挺欣赏了的多重继承。如果你认为我这个观点僵硬不灵活的家伙是多态教义很好的反例的话,我倒是可以给你举几个为什么你需要多态继承的好例子,或者至少像 Ruby 那样的 mixin 或者自动的派遣。下次问问我白龙马的事情。今天我要告诉你为什么 Java 的 interface 是个烂货。
几年前 Gosling 自己都说,如果一切都能重来的话,他不会搞出个 interface 的概念。
但是那正是 Java 的问题。当 James 说出那句话的时候,人们被雷到了。我甚至能感觉到那股雷劲儿,能感觉到 Sun 公司市场部和法务部的鸟人是多么想把 James 灭口,然后告诉大家他没那么说过。
Java 的问题就是人们都被那帮人搞的广告效应蒙住了眼。C++,Perl,任何流行语言都有这个问题。这是很严重的,因为如果没有一些说大话吹牛逼的广告,一个语言是不会流行起来的。所以如果一个语言的设计者说他的语言没有被设计得很完美的话,就是赶紧用麻醉枪射击这胡说八道的家伙并关闭会议的时候了。
语言们需要放点儿卫星才能活,我只希望人们不要被卫星耀瞎了眼。
我学了面向对象编程, 我自己也对此大吹大擂。当我加入亚马逊时,我不能告诉你我有什么智慧或者经验,但我可以给你背诵出所有关于 OOP 的魔咒。多重继承是邪恶的,因为大家都这么说; 运算符重载是邪恶的,诸如此类。我甚至有点模糊地知道为什么是邪恶的,但实际上不知道。后来我明白了,这些都不邪恶,不是烂玩意儿,烂的是开发者,是我。我现在还是烂,但是希望每年都不烂一点起来。
上礼拜我碰到一个来面试的,他告诉我多继是邪恶的,因为,比如,你可以从头,胳膊,腿,躯干多重继承出一个人来。他既是对的,又是错的。那样的多继情形当然邪恶,但那都是因为他自己太邪恶了。那样继承出来的“东西”远远就能看见有多蠢,如果他还把这玩意儿弄进门来那就更邪恶了。
不良开发者,占了这世上开发者的大多数,他们能用你扔给他们随便什么语言写出不良的代码。
说了这些,还是得说回来,多继不是请客吃饭那么轻松的事儿; mixin 看起来是更好的解决方案,但是还没人完美的解决这个问题。但我还是认为 Java 比 C++ 好,即使它没有多继。因为我知道不管我的出发点是多么好,某一天我还是会被一堆不懂怎么写好代码的人包围,让他们用 Java 比用 C++ 会带来更少的伤害。
此外,Java 除了语言本身外还有老多其他的重要有用的东西。且 Java 语言本身也在进化,虽然像冰川一样慢,所以我们还是能看到希望。Java 正是我们应该在亚马逊推荐使用的语言。
你就是得小心点儿,因为和其他任何语言一样,你能很容易找出一堆人,他们很懂一门语言及其编程环境,但对品味,计算或者其他任何重要的东西却一无所知。
当你有怀疑时,还是雇那种会好几门语言的 Java 程序员,那种厌憎 J2EE/EJB 之类松松跨跨的所谓框架的,那种使用 Emacs 的。这都是一些实战经验。
Perl
Perl,怎么说呢?
Perl 是个老朋友。老老朋友。我开始写 Perl 代码的时候,可能是 1995 年。而它为我很好的服务了差不多 10 年的时间。
它就像你骑了十万二十万英里的老自行车,你心里永远有一块地方装着它,虽然现在你已经换了一辆更加现代化的只有五磅重的自行车,而且这一辆也不像老的那辆顶得你屁眼疼了。
Perl 受欢迎原因有仨:
用 Perl 你很快就能搞定你的问题。而这是最终的衡量标准。 Perl 有世上最好的市场推广。你可以写一本介绍他们市场推广有多绝的书。Sun 公司砸大笔钱给 Java 推市场,Perl 在受欢迎程度来说能跟 Java 齐头并进,但 Perl 纯粹是依靠 Larry Wall 和他那帮哥们的三寸不烂之舌做市场。哈佛商学院的人应该去研究 Perl 的市场是怎么做出来的。真的让人瞠目结舌。 直到差不多,呃,现在,Perl 没有真正的竞争者。
— THE END —