《程序员的呐喊》一一1.2巴别塔

    xiaoxiao2023-06-27  183

    本节书摘来自异步社区出版社《程序员的呐喊》一书中的第1章,第1.2节,作者:【美】Steve Yegge ,更多章节内容可以访问云栖社区“异步社区”公众号查看。

    1.2 巴别塔

    程序员的呐喊我在这篇文章里会大致谈一谈对各种语言的看法——本来是想给这个月的亚马逊开发者期刊投稿的,后来却发现改来改去都难以示人。

    一方面是因为,我时不时地就用上一些粗鲁的字眼,说出一些得罪人的话来,实在是不适合在亚马逊的官方刊物上发表。所以我还是把它贴在博客上,反正也没人会看。除了你。没错,就是你。你好!

    另一个原因是,我还没写完呢,通篇都是东一榔头西一棒子的片段,完全没有经过润色打磨。这也是把它放在博客里的又一个理由,不用去考虑漂亮和完整性的问题,可以想到哪儿就写到哪儿。爱看不看。

    这场旋风之旅涵盖了C、C++、Lisp、Java、Perl(这些是亚马逊在用的语言)、Ruby(因为我就是喜欢这门语言),还有Python(提到它是因为……唔,我还是先卖个关子吧)。

    CC是必修课。为什么?因为就一切实际用途来说,这个世界上你遇到的每一台电脑都是冯·诺伊曼结构的,而C以精悍的语法展现了冯·诺伊曼机的能力。

    今时今日,冯·诺依曼体系结构就是计算机体系结构的标准:一个CPU、RAM、一个磁盘、一套总线。多CPU其实并不影响其本质。冯诺伊曼机是一个在20世纪50年代就实现的图灵机(这是一个进行计算的抽象模型,非常有名),它很实用,性价比也很高。

    其他类型的机器也是存在的。比如Lisp机,它实现了20世纪50年代的Lisp。Lisp是一种基于lambda演算的编程语言。而lambda演算则是另一种进行计算的模型。与图灵机不同的是,人也可以理解和编写lambda演算。不过这两种模型是等价的。它们都精确地描述了计算机的能力。

    除了在跳蚤市场,Lisp机并不常见。相比之下,冯·诺伊曼机的接受程度要高得多。此外还有诸如神经网络、细胞自动机等各种类型的计算机,只不过它们都谈不上流行,至少目前还没有。

    所以你是躲不开C的。

    还有一个原因就是,Unix是用C写的。不仅如此,包括Windows等在内的几乎所有的操作系统都是用C写成的,因为它们全部属于冯·诺伊曼机操作系统。你觉得自己还有其他选择吗?至少在操作系统领域里,任何与C迥异的语言都发挥不出硬件的实际能力——至少这句话放在近一百年里都是对的,这些系统都诞生于这段时期内。

    Lisp是另一门必修课。倒不是说真正干活的时候要用到它,只不过要是了解一点的话,在遇到很多GNU的应用程序时会觉得很趁手。特别是应该学一下Scheme,它是一种短小纯正的Lisp方言。对应的GNU版本则名叫Guile。

    麻省理工和伯克利的新生都会学一到两个学期的Scheme,但是没人知道为什么要学这样一门怪异的语言。老实说,它其实并不适合作为入门语言,可能将它作为第二门语言也不是好选择。虽然是一定要学的语言,但是等一等也无妨。

    Lisp不好学,它的门槛很高。用C的思维来学习编写Lisp程序是不够的,而且也没什么意义。C和Lisp是两个极端,它们都擅长对方不在行的事情。

    假如说C最擅长的是映射计算机是如何工作的话,那么Lisp最擅长的就是映射计算是如何进行的。你真的不需要太深入Lisp,只要掌握Scheme就足够了,它最简单、简洁。其他Lisp都已经变成了像C++和Java那样复杂的编程环境,附带了一大堆库和工具,那些都是你不需要了解的东西。你要掌握的是用Scheme来写程序。如果你能做完《The Little Schemer》和《The Seasoned Schemer》后面的全部习题,那水平在我看来就已经绰绰有余了。

    在选择日常的工作语言时,标准应该是它提供的库、文档、工具支持、操作系统集成、各种资源,以及很多其他和计算机怎么工作没什么关系,但是和人怎么工作大有关系的东西。

    今时今日,C的应用依然十分广泛,它是必须掌握的语言!

    C++C++非常冷漠,可以说是地球上最糟糕的语言。

    它连自己是谁也不知道,完全缺乏自省的能力。好吧,C也做不到,但是C不是“面向对象”语言,而让程序了解自身对面向对象来说是非常重要的。对象也是参与者。所以作为一门面向对象语言,一定要有运行时反射和获取类型的能力。而C++不具备这种能力,好吧,应该说不是真的具备这种能力,至少你不会想要去用它。

    对于C来说,你可以很方便地写一个C编译器,然后在C之上构建一些工具,让它具备自省的能力。可是C++基本上是无法解析的,因此,假如你想要写个很聪明的工具,告诉你虚拟函数的签名是什么,或是帮你重构代码的话,就只能去用别人写好的工具集,因为自己解析实在太麻烦了。可是目前所有解析C++的工具集都不好用。(作者注:现在clang还算不错,不过距离我写这篇东西已经8年多了。抗战都打完了啊!)

    C++非常愚钝,用愚钝的语言是写不出聪明的系统来的。语言能塑造世界观。愚蠢的语言只能创造愚蠢的世界。

    一切计算都是以抽象为基础的。高阶必须构建在低阶之上。直接在分子的层面上搭建一个城市是不现实的。采用过于低阶的抽象纯粹是自找麻烦。

    麻烦来了。

    C能负担的最大项目应该是操作系统,老实说,操作系统并不是什么庞然大物。它们之所以看起来很恐怖,都是因为系统之上的应用程序,其实内核本身是很小的。

    而C++的最大负荷……也是操作系统。好吧,或许还能再大一点。就算3倍大好了,10 倍也行。操作系统内核最多有多少行代码?100 万行差不多了吧。那么C++可以驾驭的系统规模大概在 1000 万行代码,超过这个数字后,系统就会开始失控,就好像《异形奇花》里的那棵植物一样。“我要吃东西……”

    这还是在假设你能成功编译的情况下。

    我们拥有5000万行C++代码。不对,这个数字现在肯定更大了。我都不知道有多少了。5000万是9个月之前的数字,它还在以每个季度800万的速度增长,而且增长的速度也在加快。天哪……

    这里任何事情都进展缓慢。曾经有个亚马逊工程师把我们的代码库比作“像山一样高的排泄物,规模超过你见过的任何山脉。每当你要修复什么东西的时候,非得爬到最中间的地方才行”。

    这是4年前的事情了,伙计们。现在他已经跳槽到更好的地方了。他是非常出色的程序员,你说可惜不可惜。

    这都是C++的错。别跟我吵。就是它的错。我们用的是全世界最愚蠢的语言。你不觉得这简直蠢到家了吗?

    尽管如此,漂亮的C++代码还是可以写出来的,这样的代码绝大部分都是C,外加一些C++特性,而且用得优雅,有节制。可惜这几乎是痴人说梦。C++是个巨大无比的坑,越是了解它,优越感就越强,最后一定会忍不住要用上各种特性。可是要用得好真的非常难,这门语言实在是太糟糕了。不管你有多牛,最后肯定会弄得一团糟。

    你肯定觉得我在胡说八道吧?我也懒得解释。读大学的时候我曾经非常热爱C++,那时我也只懂C++。当我听说我的编程语言教授克雷格·钱伯斯彻底否定C++的时候,我心想:“为什么会这样?我挺喜欢的啊。”STL的发明人公开宣称他讨厌OOP的时候,我还以为他被黑了呢。怎么会有人讨厌OOP?而且还是STL的作者?

    计算机编程语言里没有所谓的“亲近生侮谩”,只有在掌握更优秀的语言的前提下,才会懂得怎么批判自己最熟悉的那门语言。

    因此,要是你不喜欢我批评C++,我建议你去了解一下更优秀的语言是什么样子的(如Lisp),然后你才有资格否定我的话。不过到那时你就不会来否定我了。我忽悠成功了。那时你不会再喜欢C++,可能会有点生我的气,忽悠你讨厌自己之前最爱的语言。所以你还是别管我说什么了。C++很出色,非常优秀。别在意我说的话。它是门很棒的语言。

    Lisp(我打赌这一节会让你大吃一惊,就算你已经了解我的风格了也不例外。)

    亚马逊初创的时候,有很多了不起的工程师。虽然我不是每个人都认识,但还是熟悉其中一些的。

    比如,谢尔·卡范,大牛。格雷格·林登,大牛。埃里克·本森,加入亚马逊之前就已经声名遐迩了,同样也是大牛。

    Web服务器Obidos就是他们写出来的。亚马逊的成功离不开Obidos。只是后来那些垃圾工程师和 Web 开发人员,绝大多数是前端工程师,为了赶进度,为了让老板满意,不惜以最快的速度制造垃圾代码,最后把Obidos给搞坏了。换句话说,就是坏了一锅粥啊。但不管怎么说,Obidos都是亚马逊创业成功的重要基石。

    亚马逊的伟大元老们只用两种语言:C和Lisp。

    奇怪吧。

    显然,他们都是Emacs的拥趸。埃里克·本森就是XEmacs的作者之一1 。全世界的伟大工程师都用Emacs。我说的是改变世界的那种工程师。不是坐在你隔壁小隔间里的漂亮女生,也不是楼下那个棒小伙弗莱德。我说的是咱们行业里最出色的软件工程师,他们改变了整个行业的面貌:詹姆斯·高斯林、高德纳、保罗·格雷厄姆 2 、杰米·扎温斯基、埃里克·本森。真正的工程师只用Emacs。要用好它是需要一点智商的,但是掌握以后它却是异常强大的工具。要是你不相信,不妨找机会去观摩一下保罗·诺德斯特龙是怎么工作的。对那些只用过.NET系IDE的人来说绝对大开眼界。

    Emacs是不朽的编辑器。

    对于谢尔、埃里克、格雷格,还有很多我未曾有幸与之合作的人来说,C++和Perl都是禁止出现的(因此Java也同属此类)。他们知道什么东西更好。

    而现在,我们写的尽是C++、Java,还有Perl。老鸟们也早就择木而栖了。

    Mailman是谢尔用C写成的,然后客服部门用Lisp把它封装起来。没错,就是Emacs-Lisp。除非待的时间够长,或是遇到必须帮客户解决问题的情况,否则非技术员工通常都不知道Mailman是什么东西。比如你写的某个垃圾功能工作不正常(因为你是用C++来写的),客户很生气,你必须马上把问题解决,不然后果很严重。这时你必须直接和他们打交道,我是说那些可爱的、大字不识几个却能说会道、善意的、满怀希望的、搞不清楚状况的、乐于助人的、愤怒并快乐着的客户,他们是真正的在我们这里买东西的客户。这时你就知道Mailman是干吗的了。

    Mailman以前是客服部门用来处理客户E-mail的应用程序……有四五年了吧?反正已经很久了。它是在Emacs里写成的,大家都很喜欢它。

    现在大家也还念着它。直到今天,我还在被迫去听非技术同事跟我长篇大论地怀念Mailman。我可没在唬你。去年圣诞的时候我参加了一个亚马逊的聚会,我压根就不知道自己会跑到这种聚会上来,满眼望去全是商务人士,比我们这些在亚马逊锅炉房里上班的人靓丽多啦。有 4 个年轻妹子知道我曾经在客服部门待过后,直接把我拉到一边,聊了整整15分钟,说她们有多怀念Mailman Emacs和Arizona(我们花了数年开发,用来替代Mailman的JSP应用)就是不好用。

    当时的情况真的很诡异,我觉得她们大概是酒喝多了吧。

    谢尔是天才,Emacs也是天才之作。即便是非技术人员也喜欢Emacs。我现在也是在用Emacs打字,可以的话我绝不会想在其他环境下打字。Emacs提供了无与伦比的输入快捷方式和文本编辑功能,能大大提高工作效率。在自由输入的情况下,我能在Emacs里每分钟无错误地输入130~140个单词。这是用我写的一个打字测试的Emacs应用程序来计时的。但Emacs的能力远不止如此。

    Emacs具备了那种难以名状的特质。

    可是我们却让Mailman退休了,因为我们具备了一种名叫愚蠢的品质。我们太差劲了。我们找不到擅长Emacs-Lisp的人,所以也就没法让Mailman继续服役。这个问题要是放到今天就好解决了。现在的亚马逊里随便一抓就是一把Emacs-Lisp高手,但在当时,谁会关心客服应用呢,他们也只能螺蛳壳里做道场了,而且当时也没太多人懂Emacs-Lisp。曾经有一段时间,他们甚至把鲍勃·格里克斯坦都请来,把他关在一间小办公室里专门给Mailman写Gnu Emacs扩展。他就是那个写长颈鹿书(奥莱利出版的《Writing Gnu Emacs Extentions》)的家伙。

    你知道吗,客服应用是亚马逊第一支“双比萨团队”(译者注:最佳团队)。无论是过去还是现在,他们都是完全自治的。没人搭理他们,也没人出手帮忙,一切都是他们自己搭建起来的。他们没有 Web 开发,也没有支持工程师,更没有什么squat(一种软件质量保证流程),他们只有水平扎实的工程师,以及传帮带的传统。这就足够了。

    可惜当时他们除了让Mailman退休外别无选择。真的很可惜。直到今天我还会听到怀念它的声音,包括在聚会上。

    我觉得客服应用团队里的Lisp高手按人均数量来算的话,可能仍然能在亚马逊里排第一。这并不是说他们用得多,而是像埃里克·雷蒙说的那样,就算不是日常语言,学习Lisp的经历也能让你受益终身。

    JavaJava可以说是过去10年来,计算机行业里出现的最好也是最坏的事物。

    一方面,Java把你从C++里无数平凡却又容易出错的细节中解放出来。再也不用担心越界,也不再有core dump文件。抛出的异常会确切地告诉你错误在哪一行,而且99%的情况下都很准。对象能很聪明地按照需要把自己打印出来。诸多优点不一而足。

    另一方面,作为一种语言,Java除了拥有虚拟机、庞大的类库、安全模型和可移植的字节码格式外,还是一种信仰。所以那些太喜欢Java的人都不值得信任。要找到优秀的Java程序员是很不容易的。

    但无论如何,Java都称得上是软件工程历史上的一大进步。

    从C++到Java,改变的不仅仅是语法。这种编程范式的转换可以说翻天覆地,不需要一点时间浸淫是不行的。这感觉就好像突然拥有自己的行政助理一样。你知道那些身居高位的副总裁们为什么看起来总是有那么多时间开会,对公司运营状况了如指掌,同时还能写出那么多漂亮的文件吗?他们往往会忘记自己其实是两个人:他们自己,还有他们的行政助理。行政助理让你有时间去思考真正需要解决的问题,而不是把宝贵的时间浪费在无聊的琐事上。同理,Java把你变成了两个程序员——一个专门负责你无须关心的东西,另一个就可以专心解决实际问题。尽管这种差异非常明显,但是很快就能让人适应。

    杰米·扎温斯基曾经写过一篇非常有名的文章来批判Java有多糟糕,但他还是这样写道:“先说好的地方:Java没有free()。我必须承认这一点,其他锦上添花而已。光这一点就足以让我忽视其他缺点了,不管它们有多糟糕。有鉴于此,本文接下来的内容都可以说无足轻重。”

    杰米的这篇文章写于1997年,那时的Java还在襁褓之中,如今Java早已今非昔比,他当时抱怨的有些东西现在都已经修复了。

    但也不是全都改好了。就语言层面,Java仍然算不上优秀。但正如杰米所言,它“依然是今天最好的语言,远远比我们在实际工作中用的那些彻头彻尾的垃圾语言要好得多”。

    说真的,你应该读一下用Java写的程序。

    除了作为语言本身不怎么样(杰米的不满主要就集中在这里)外,Java在每个层面上都表现得异常出色。当然光凭这一点,可以吐槽的地方就很多了。语言本身不给力,类库再牛也是有限的。相信我:你懂的东西可能比我多很多,但是我很清楚,再好的类库也救不了一门垃圾语言。这可是在Geoworks的汇编地狱里摸爬滚打5年得来的经验。

    Java在语言层面上和C++也就打个平手。唔,好吧,这句话我收回,Java其实要好得多,至少它有字符串。连字符串都支持不好的语言哪是人用的呀。

    不过Java也缺了一些C++的优点,比如(在栈上)传引用、typedef、宏,还有重载操作符。这些东西并非必不可少,但是需要的时候就很方便。

    对了,还有多重继承,说得我都开始怀念从前了。假如你要用我自己的“固执己见的精灵”来反对多态,那么我还可以举出更多为什么多重继承是必需的例子。至少也要像Ruby那样的mixin或自动委托。有时间我们可以讨论一下“火焰剑”或者“盗贼披风”的问题,你就会明白接口是多糟糕的东西了。 3

    几年前,高斯林自己也承认,要是有机会重来的话,绝对不会考虑接口。

    而这正是Java的问题所在。詹姆斯的言论让人大吃一惊。我能感觉到那种冲击力,也能猜到Sun的营销和法律部门肯定心急火燎地杀过去让他闭嘴,并否认他的观点。

    Java的问题就在于人们被营销攻势牵着鼻子走。C++和Perl等各种主流语言都有这个问题,当然这也是无可奈何的事情,没有造势的话,这些语言也火不起来。因此,假如语言的设计者故作天真地宣称自己的设计并不完美,你就应该给他打上一针镇静剂让他闭嘴,然后取消所有的研讨大会。

    炒作是不可避免的,我只是希望人们不要盲从罢了。

    我自己都曾经中过OOP的毒,傻乎乎地为它摇旗呐喊。刚加入亚马逊的时候,我能背诵各种代替智慧和经验出现的咒语、诗篇和巫术,比如因为大家都说多重继承不好,所以它就是不好的,运算符重载也是不好的等。我隐约明白其中的道理,却又没有真正明白。那时我才渐渐意识到其实糟糕的不是多重继承,而是程序员自己。我就曾经是其中一个,当然我现在也很弱,不过每年都会变好一点就是了。

    上星期面试的时候我就碰到一个候选人跟我聊为什么多重继承不好的问题,他举的例子是,如果允许多重继承,那么“人”就可以继承“头”、“手臂”、“腿”和“躯干”了。他只说对了一半。在这个例子里,多重继承当然是不好的,但要怪的是他自己。让他通过面试的话就是我傻了。

    不管什么语言,不合格的程序员写出来的都是烂代码。可惜整个业界里大多数都是这样的人。

    尽管多重继承的麻烦多多,而mixin似乎看起来很美,但其实谁也没能彻底解决问题。不过就算没有多重继承,我还是觉得Java要更胜C++一筹,因为我很清楚,无论出发点有多好,我的周围肯定会出现不会写代码的家伙,而Java能让他们的危害小一点。

    此外,Java所拥有的并不只是语言核心本身。哪怕它演化的速度很慢,只要它还在进步,就还有希望。这才是亚马逊应该用的语言。

    还有一点需要格外小心的就是,任何语言都一样,你很容易碰到那种对语言环境很熟悉,但是对品味以及计算本身等真正重要的东西却一无所知的人。

    若是吃不准要找什么样的Java程序员,不妨考虑一下这些条件:会玩好几门语言,讨厌J2EE和EJB那类臃肿框架,还有用Emacs编程。这些都是不错的指标。

    PerlPerl。从哪里说起呢?

    我用Perl好多年了。差不多是1995年开始写Perl的吧,10年来我们一直合作愉快。

    这就好像一辆骑了将近20万公里的老爷自行车,每每想到它的时候心里总有一种特别的感情,哪怕现在的新车只有2.5千克重,也不会骑得屁股疼。

    Perl的流行主要有3个原因。

    1.Perl代码写起来很快,能出活,这一点其实是很关键的。

    2.Perl的营销是世界一流的,专门为此写本书出来也不为过。Java是Sun用钱堆出来的,而Perl则完全依赖拉里·沃尔和他的同僚无与伦比的营销手段,流行度却不遑多让。哈佛商学院的那些人应该好好学学Perl是怎么宣传的。绝对惊人。

    3.不谦虚地讲,就算到现在,它也没遇到什么真正的对手。

    假如“更好”的定义是“不疯狂”的话,比Perl好的语言真的有好多。我随便就能举出二三十种比Perl“更好”的语言,Lisp、Smalltalk、Python、gosh,它们都不会像夏天中国台湾省的街道上爆炸的抹香鲸一样,器官喷得到处都是,汽车、摩托、行人都无法幸免。而这正是Perl的写照,同时也是它真正的魅力所在。 4

    不过Perl也有很多不可错过的特点,到今天也是独一无二的,这就足以抵消其他令人纠结的缺点了。爆炸的鲸鱼也能做出各种有用的东西来,比如香水,因此它仍然是有价值的。Perl也一样。

    其他语言(主要是Lisp和Smalltalk)全都假装不存在操作系统这种东西,而列表(Lisp)和对象(Smalltalk)才是解决一切问题的银弹,Perl的理念正好相反。

    拉里如是说:“Unix和字符串处理才是王道。”

    而大多数时候,他说得一点也没错。在Unix集成和字符串处理方面,Perl毫无疑问是王者。唯一的例外也只是最近才出现,这里我先卖个关子,后面再分解。

    可惜的是,拉里太过关注Unix集成和字符串处理,完全忘了列表和对象的存在,结果错过了正确实现它们的时机。其实他还是犯过一些错误的,特别是Perl早期的……唔,我不太想用“设计”这个词,不妨说“版本”好了。这些错误导致Perl很难正确实现列表和对象,最后(至少)在这方面,Perl逐渐演变成一台典型的哥德堡装置。 5

    拉里!列表和对象其实也是非常重要的哟!

    Perl没办法处理好列表是因为,拉里一开始就做了一个悲剧到极点的愚蠢决定,自动压扁列表。这样一来,(1,2,(3,4))就会神奇地变成(1,2,3,4)。而这有时并非你的本意。当时拉里肯定是遇到了某些特殊的问题,这种方式又正好适合。结果自此Perl的数据结构就彻底变成了爆炸鲸鱼。

    时至今日,不花三分之一的时间去研究“参考书”的话,是没有办法理解以Perl为主题的书籍、教程,或者ppt的,这无疑是一种悲哀,拉里妄图以这种哥德堡式的办法来补救扁平化列表所带来的麻烦,这根本就是越帮越忙。只不过Perl的宣传实在是一流,硬是让你觉得参考书好像是圣经一样。什么东西都查得到!多好玩呀!捧在手上还有书香呢!

    Perl没有对象则是因为拉里从来没有真正相信过它。这倒没什么,我都不敢说自己认同它。既然如此,他干嘛还要把它加进来呢?OO和Perl貌合神离,从未被社区接受过。它和字符串处理以及Unix集成完全不能相提并论。

    当然啦,Perl还有很多其他怪异的设计。随便举个例子,拉里设计了非常滑稽的多变量命名空间,然后通过所谓的前导符(sigil)来解析,结果弄出“上下文”这种可怕的副作用。他大概是从脚本语言那获得的灵感吧。根据当前“上下文”,Perl语言里的每个操作符、每个函数,以及每个运算都可以有6种不同的行为。一个特定运算在给定上下文里的行为完全没有规则或者直觉可言。除了死记硬背,没有其他办法。

    比如说?比如在标量上下文里,访问哈希会得到一个包含分数的字符串,分子是已分配的键,而分母是桶的总数。不骗你吧?真的很诡异。

    不过就像前面说的——直到最近出现了能像Perl那样干净利落的语言。

    Ruby差不多每15年左右,就会出现更优秀的语言。C++取代了C,至少对大规模应用程序开发来说是这样的,那些人追求性能却又渴望数据类型。现在C++逐渐被Java所取代,而毫无疑问Java会在7年之后被更好的语言取代——我说的是它彻底干掉C++的7年以后,显然它还没做到这一点,这主要归功于微软拖慢了Java占领桌面的进程。不过在服务器端,C++已经基本出局了。

    Perl的命运也差不多。因为有一种叫Ruby的新语言终于被翻译成英文了。没错,这是日本人的作品,这让人大跌眼镜,毕竟日本是以硬件制造而非软件开发闻名于世的。所有人都在琢磨为什么(日本不擅长软件),不过我觉得肯定和打字有关。我完全无法想象他们是怎么运用一门有超过10万字符的语言做到快速打字的。

    不过Emacs在几年前终于开始支持多字节字符,所以我估计现在他们打字应该打得很快了吧。[没错,他们的确是用Emacs——其实Mule(Emacs的多字节扩展)主要就是由日本人开发的,而且完成得非常漂亮。]

    总之,Ruby对Perl充分实行了拿来主义。Ruby的作者Matz(我没记错的话,他的本名是松本行弘,不过通常都自称“Matz”)甚至可能有点借鉴过头了,连一些不好的东西也拿了过来。好在不多,只有一点点而已。

    基本上Ruby照搬了Perl的字符串处理和Unix集成,语法完全一样,只此一点,Perl的精华就全都有了。这可以说是开了个去芜存菁的好头。

    接着Matz从Lisp那里吸收了列表处理的精华,从Smalltalk那里拿来了OO,迭代器则是取自CLU,基本上各个语言里的优点都吸收进来了。

    所有的这些东西被完美地糅合在一起,你压根注意不到斧凿的痕迹。我学Ruby比之前接触过的三四十种语言都快;我有8年的Perl经验,可我用了3天Ruby就觉得比Perl更顺手了。Ruby具备出色的一致性,一眼就能猜到它是怎么工作的,而且基本上能猜个八九不离十。它非常漂亮,充满乐趣,同时又兼具实用性。

    假如把编程语言比作自行车的话,那么Awk就是粉色小童车,前面有个白色的篮子,把手上还有些穗子,Perl则是沙滩自行车(记得它们以前有多酷吗?天哪!),Ruby则是价值7 500美元的钛架山地车。Perl到Ruby的飞跃和C++到Java是一样的,而且没有附带任何缺点,因为Ruby是Perl优点的超集,而Java去掉了一些人们想要的东西,却又没提供真正的替代方案。

    后面我还会聊到Ruby,只要有灵感。比如读一读_why先生的Ruby指南 6 ,那本书让我大开眼界。真的,推荐你也读一下,非常棒。虽然那种思维不是我能理解的,但是那本书实在太好玩、太犀利了,而且完全以Ruby为主题。好吧,也不全是,反正你读一下就明白了。

    Python说了半天,Python这门在幕布后守候多年的龙套语言又怎么样呢?Python社区一直以来都是避难所,收留那些吃下红色药丸,从Perl母体中苏醒过来的人们。 7

    其实他们和Smalltalk程序员一样,苦等取代C++的机会,结果Java一出,就彻底毁掉了他们所有的希望。今天的Ruby之于Python,扮演的正是这样的角色,而且是一夜之间。

    Python本来是有机会一统江湖的,但是它有两个致命的缺陷:一个是空白符,另一个是死脑筋。

    所谓空白符的问题就是Python的嵌套是通过缩进来完成的。它强迫你用特定的方式来缩进,这样大家的代码看起来就是一样的了。可惜,很多程序员都讨厌这个规定,感觉好像被剥夺了自由一样;他们觉得胡乱排版和编写那种精简到一行,没人看得懂的小程序是自己的权利,而Python却侵犯了这一点 8 。

    Python之父吉多· 范罗苏姆之前也出过几次昏招——虽然不如拉里那么惊世骇俗,但也真的是够小儿科的了。比如,Python原本是没有词法作用域的。可问题是它连动态作用域也没有,虽然说动态作用域也有自身的问题,但至少还勉强可以用。Python最早只有全局和局部(函数)作用域,所以虽然它拥有一个“真正的”OO系统,可是一个类却连自己的实例变量都没法访问。你只能给每个实例方法带上一个“self”参数,然后通过self来访问自己的实例数据。所以你在Python里看到的都是self,selfself,selfselfself,selfSELFselfSELFSELF,哪怕你忍了空白符,这些self也能把你给逼疯了。

    这样的问题不胜枚举。

    不过在我看来,真正压死Python的稻草其实是它的死脑筋,这才是它成为脚本语言,乃至所有语言老大的梦想的绊脚石。你看,Python可以说在各方面都远胜Tcl,可就是因为这份固执,在嵌入解释器领域,大家还是选择Tcl。

    你或许要问,所谓的死脑筋到底是怎么回事?本来我有很多坏话要讲的,不过看在Python用起来挺顺手的份上(只要你能容忍它的缺点),我觉得还是不要对Python信徒太刻薄了。所谓的“死脑筋”其实也就是他们有点……脑子不转弯罢了。为什么这么说?

    因为他们实在是听空白符的抱怨听怕了!

    我觉得这才是Python一直没有Perl那么流行的原因,当然这也只是我个人的感觉而已。

    尾声这才是我真正想写给亚马逊开发者期刊的文章,至少是我想表达的东西。不过由于某种原因,我只有在凌晨3点到6点,因为失眠而攻击性变强的时候,才能表达出自己真正的感受。好啦,睡了!睡两个小时还要起来开会呢。

    相关资源:敏捷开发V1.0.pptx
    最新回复(0)