Beating the Average------为什么要学习Lisp[转]

出类拔萃

by Paul Graham

April 2001, rev. April 2003

(这篇文章改自2001年给Franz开发者论坛的演讲)

1995年夏天,我和我的朋友Robert Morris创办了一个公司叫Viaweb. 我们的计划是写一个在线商店的建站软件。当时这个软件的新颖之处是它在我们的服务器端运行,用网页作为用户界面。

当然,很多人当年也有同样的想法,但就我所知,Viaweb是第一款基于web的应用。我们很喜欢这个新想法,并以此为公司命名:Viaweb,因为我们的软件不是桌面软件而是通过网络来运行的。

关于这个软件,另一件特别之处就是它主要用Lisp写就。它是面向大众用户的Lisp程序的先锋,在此之前Lisp几乎都是用在大学和实验室的象牙塔里。[1]

The Secret Weapon

秘密武器

Eric Raymond写过一篇文章如何成为黑客,文中他教导黑客学前班的同学如何选择语言。他建议以PythonJava起步-因为容易学。严肃的黑客要修改Unix就得学C语言。最后,真正严肃的黑客应该考虑学习Lisp:

 “悟道时那种深刻的醍醐灌顶的感受是Lisp值得学习的一个原因;这个体验会让你在后面的岁月里成为更好的程序员-即使你  不常用Lisp写程序。

这和常听到的学习拉丁语的论调很类似。学了不会帮你找到工作(语言学教授除外),但它会训练提高你的大脑,让你在用诸如英语之类的语言写作时能够得心应手。

但是,等一下。这个比喻并不普遍适用。学习拉丁语找不着工作是因为没人说拉丁语。如果你用拉丁语写作,没人能理解你。但是Lisp是计算机语言,计算机可不挑剔程序员用什么语言。

如果像他说的,Lisp能让你成为更好的程序员,为啥不用呢?如果一个画家弄了一杆能让他下笔犹如神的画笔,在我看来,他画啥画都想用的,不是吗?我不是要取笑Eric Raymond。总的来讲,他的建议很好。他关于Lisp的说法基本是传统观点。但是这个传统观点自相矛盾:Lisp会让你成为更好的程序员,但你不会去用它。

为什么不呢?毕竟编程语言只是工具。如果Lisp写的程序更好的话,你就应该用它。如果用它写得烂,那谁还稀罕呢?

这不只是理论上的问题。软件行业竞争残酷-优胜劣汰。其他条件相同,软件写的又快又好公司会把对手挤垮。当你开始创业时,会对这一点深有体会。创业公司常处于要么盆满钵满要么一穷二白的位置。你最终要么赚翻,要么潦倒。如果你对技术押错宝了,竞争对手就会来灭掉你。

Robert和我都精于Lisp,我们没有理由不相信自己的直觉而弃用Lisp. 我们知道其他人都在用C++Perl写软件。我们也知道这没啥大不了的。如果你选择那样的技术,就要在Windows上跑。选择技术时,必须忽略其他人在用什么,只考虑什么能工作得最好。

这在创业公司里更为适用。大公司里,你可以像其他所有大公司一样做事。但是创业公司里,你不能亦步亦趋。我不认为很多人意识到这一点了(即使是创业公司里的家伙们)。

大公司每年平均增长10%。所以你要是掌管一个大公司的话,你按照大公司的通用做事方式,你也就种瓜得瓜,种豆得豆-得到10%的增长。

创业公司里的情况也一样。如果你按照大多数创业公司的方式去做事,你也就只能期望业绩达到平均水平。这里的问题在于,平均水平意味着你要关门大吉。创业公司的成活率是大大低于50%的。所以,如果你开公司,最好有点与众不同。否则,麻烦就大了。

1995年那会,我们知道一个竞争者尚未参透的秘密(现在也有好多蒙在鼓里呢):如果你的软件在服务器端运行,就可以用任何你想用的语言。要是写桌面应用,很强势的一个观点就是要用操作系统的语言写应用。十年前,写应用这意味着用C语言写。但是,对于基于Web的软件,而你又有语言和操作系统的源码时,你可以用任何想用的语言。

然而,语言选择的自由是把双刃剑。现在你可以选了,你得思考选哪一个。那些拒绝变化的鸵鸟公司危险了:它们的对手可没有把头埋进沙子。

你会选哪个语言呢?我们选择Lisp. 很重要的一点就是,这个市场上快速开发很重要。我们都白手起家,一个公司要是能比对手更早的做完新特性就很有优势。我们知道Lisp用于快速开发相当合适,而基于服务器的应用会放大这个优势-因为软件写完就可以立即发布。

如果其他公司不想用Lisp, 真好。这在技术上会让我们有一个优势,能帮上忙的来者不拒。当我们创立Viaweb时,我们没有商业经验,不懂得市场推广,招聘员工,融资或者吸引用户。我们几个甚至都没工作过。我们唯一玩的转的就是写软件。我们寄希望于此。软件开发方面的任何优势,我们都不会放过。

你可以说采用Lisp是一个试验。我们的算盘是这样打的:如果我们用Lisp,我们功能会开发的比对手快,也可以做一些他们做不到的事情。Lisp很高层,我们就不需要大的开发组,我们的开销就很小。如果行得通,我们就能提供物美价廉的产品,还能盈利。最终,赢得所有用户,我们的对手则失掉用户最终关门。这就是我们当时希望的过程。

试验的结果如何?居然行得通。我们最终遇见了很多竞争者,2030个吧,但没有一个能和我们针尖对麦芒。我们服务器上跑着一个所见即所得的在线商店编辑器,用起来却和桌面应用没啥差别。我们的对手们用的是CGI脚本。功能上我们总能先他们一步。有时,绝望中的对手想增加几个我们没有的功能。但是Lisp的开发周期很快,我们可以在他们发布软文宣传的一两天之内就复制一个新功能。当记者们读到他们的公关稿然后打电话给我们来问时,我们也有这个功能了。

我们的竞争对手也许觉得我们有什么秘密武器-能够读到他们脑子里的计划。实际上我们没有,比他们想的要简单。没人泄密他们的新功能,我们只是比任何人预期的开发速度更快而已。

我九岁时看过一部The Day of the Jackal, Frederick Forsyth执导主角是个刺客,要去刺杀法国总统。他必须通过警察,上到一个公寓能够俯瞰总统的行车路线。他乔装成一个跛老头,警察根本没有注意到他。

我们的秘密武器也差不多。我们用一个怪异的人工智能语言写软件,语法难看,充斥着括号。很多年以来,对Lisp的这种描述让我很不自在。现在,却成了我们的优势。商业上,拥有一项对手根本不懂的技术是无价的,正如战争一样,出其不意和厉兵秣马一样重要。

嗯,我有点窘:开发Viaweb时,公开场合我对Lisp只字未提。我们不向媒体说,如果你在网站上搜,也就只能找到我简历里提到的两本书。这是有意为之。如果他们不知道或者不关心我们用什么开发,我也乐于保持现状。[2]

理解我们技术最好的是我们的客户。他们不关心Viaweb用什么写的,但是他们注意到软件跑得很好。几分钟就能建好一个漂亮的在线商店。然后,口碑就传开了,用户越来越多。1997年底时,我们有500个用户。六个月后,Yahoo买我们时,有了1070个用户。今天,成了Yahoo StoreViaweb还统治着市场,是Yahoo产品线中很能盈利的一员。那些由Viaweb建成的商店成了Yahoo Shopping的基础。我1999年离开Yahoo,我不知道用户数量的具体数字,但是最近一次听到的是大约20000.

The Blub Paradox

Blub困境

Lisp到底强在哪儿?如果Lisp真那么棒,为啥没人用呢?听起来文绉绉的问题,实际上答案很直接。Lisp很棒不是因为某些痴迷者才能看到的品质,而是因为它就是所有语言中最强大的。没有普及的原因是选择编程语言不仅仅是个技术问题,而且是思维习惯-再没有比思维习惯改变得更慢得东西了。当然,这两个答案都需要解释。

我以一个不那么惊世骇俗的论断开始:编程语言的能力各有千秋。

高级语言比机器语言强大-这是个不争的事实。如今大多数程序员都赞成通常不要用机器语言写程序的观点。相反,你应当用高级语言,然后用编译器把程序编成机器语言。这个想法已经为硬件设计所采纳:自80年代起,指令集就专为编译器设计而不那么考虑我们程序员了。

人人都知道你的程序要是全用机器语言写就是个错误。但是另外一个原则却不为人熟知:如果你要从一堆语言里挑一个出来(其他条件都相同的情况下),要是不选择最强大的-这也是个错误。[3]

这个原则也有很多例外。如果你的程序要和另外一个用某种语言写的程序打交道,那么通常新程序采用同样的语言是个好选择。如果你的程序只是要干点简单的活,比如数据处理或者位操作之类的,你可以用稍微低级一点的语言,还能带来速度上的优势。如果你写一个试验原型,你最好找库函数能满足要求的随便什么语言。但是大体来讲,对于应用软件,你需要用最强大的(也不太慢的)语言,其他的选择都是错误-这一定程度上和用机器语言写程序是一码事。

你知道机器语言很低级。但是,至少某种社会共识认为高级语言通常被认为是一样强大的。但事实并非如此。高级语言这个技术词汇实际上没有表明任何确定的东西。并没有一个位于机器语言和高级语言之间的分水岭。所有语言都位于一个由不同抽象能力构成的谱系[4]之中:从最强大的语言到机器语言,位置反映着语言本身的能力的差别。

Cobol来说,它是个高级语言-因为它能被编译成机器语言。真有人会跳出来辩护说CobolPython一样强吗?它要比Python更接近机器语言。

或者Perl4又如何呢?Perl4Perl5之间,词法闭包被加进来了。大多数Perl黑客都同意Perl5Perl4更强了。但是,一旦你同意这一点,你也就同意了一个高级语言比另一个更强大。直接的推论就是,除了特殊情况,你应当用最强大的语言。

然而现实中这个想法很少能实现它的结论。过了一定的年龄,程序员很少再会主动的更换语言了。他们手上碰巧用起来的随便什么语言,都被奉为圭臬。

程序员对于喜好的语言偏爱有加,不能自拔。我不打算伤任何人的感情,所以解释观点时,我用一个虚构的语言:BlubBlub位于抽象谱系的中间,它不是最高级的语言,但也比Cobol和机器语言强。

实际上,我们虚构的Blub程序员不会用机器码或者Cobol:当然他们不会去写机器码-那是编译器该干的事情。对于Cobol,他们纳闷那些人是怎么用这语言干活的- Cobolx功能都没有(x是一个Blub的功能)。

只要我们的Blub程序员朝下看,他就知道在朝下看-比Blub弱的语言一眼就能看出来,因为它们缺少一些Blub的功能。但是如果向上看,他不会意识到。他认为所看到的都是些怪异的语言。他也许会觉得看到的语言都和Blub差不多,只是花哨的东西太多。Blub对他就够好了-因为,他用Blub思考。

当我们切换到使用更高级的语言的程序员的视角,我们会发现他朝下会看到Blub:你怎么能用Blub干活呢?它连y功能都没有哎。

推理一下,只有理解最强大的语言的程序员才能一览众山,看到所有语言能力间的差别。(这也许就是Eric RaymondLisp能让你成为一个更好的程序员的意思。)你不能相信其他人的观点,因为Blub困境:他们对自己碰巧用上的语言很满意,因为这语言描绘了他们思考程序的方式。

我从自己的经验里知道这一点,高中时我用Basic写程序。这语言甚至都不支持递归。现在难以想象写程序不用递归。可那时,我可不稀罕。我用Basic思考,我写得很顺,我所触及皆以掌握。

Eric Raymond所推荐的5种语言位于能力谱系的不同位置。它们的相对位置如何讨论起来比较敏感。我要说的是,我认为Lisp最高。要支持我的观点,我要告诉你一样其它4种语言都没有的东西:离了宏,你咋能编程呢?[5]

很多语言都有叫做宏的东西。但是Lisp的宏独树一帜。信不信由你,宏和括号联系紧密。Lisp的设计者把那一堆括号加进来可不是为了标新立异。对于Blub程序员,Lisp看起来很怪。但是那些括号事出有因。它们是Lisp与其它语言本质区别的外在表现。

Lisp代码由Lisp数据对象构成。不是在像源码文件由字符构成或者字符串也是该语言支持的数据类型之一这样的浅显的层次上:在由解析器读进内存后,Lisp代码就由你能遍历的数据结构构成了。

如果你了解编译器的工作原理,其实解析器干的活不多:要说Lisp的语法奇怪,还不如说Lisp没有语法。你写程序实际上是在写语法树-而其它语言需要编译器生成这种内部表示。你的程序完全可以存取这些语法树。你可以写程序去操作它。在Lisp里,这些程序叫做宏。它们是写程序的程序。

写程序的程序?你哪天才能用得到啊?如果你用Cobol思考,不常用。而用Lisp思考的话,答案就是:天天都用。这里要是我能举个例子说明就好了。但是这样对于不懂Lisp的人就是在废话了;要是从头到尾讲明白这里篇幅也不够,在Ansi Common Lisp里我的进度很快,但也到160页才开始讲宏。

但我想给一点有说服力的论据。Viaweb的编辑器代码里有2025%的宏。宏比普通的Lisp程序难写,不该用的时候用就是画蛇添足。所以我们代码里的每个宏都有用。这意味着2025%的代码是其它语言没法容易做到的。然而,挑剔的Blub程序员也许会找找我所声称的Lisp的神秘力量,这一堆宏应该能让他们迷惑不已。我们写这些宏不是为了自娱自乐-我们是个小创业公司,我们必须疯狂写程序,这样才能与竞争对手之间构筑技术上的壁垒。

怀疑的人会说这有什么联系吗?我们代码里的一大块是在做其它语言很难做到的事情,发布的软件做了很多竞争对手的软件没法做到的事情。也许这其中有联系。我鼓励你顺着这条线索再走走。拄着拐杖的跛老头也许还有更多去了解。

Aikido for Startups

创业公司的合气道

但是我不期望能让任何人(过了25岁)去学Lisp。这篇文章的目的不是要改变谁的思想,而是让那些有兴趣用Lisp的人更加确信-这些人知道Lisp很强大,但是因为它应用不广泛而有所顾虑。在竞争中,这是个优势。如果你的竞争对手不了解,Lisp的力量会加倍。

如果你想在创业公司里用Lisp,不用担心它不流行。你应当期望保持现状。事实也如此。程序设计语言的天性就是让人们乐于用它。计算机硬件的发展比个人习惯的发展快得多,程序设计的实践通常比处理器的进步落后1020年。在MIT,他们60'就开始用高级语言写程序了,但是很多公司到了80'还在用机器语言。我打赌,很多人会一直用机器语言写下去,直到有一天,处理器换成了RISC指令集-就像急着下班的酒吧服务员急着关门一样,端掉这些人的饭碗。

通常,技术进步很快。但是程序设计语言不同:它不只是技术,它是程序员思考的工具。语言是技术和信仰的混合体[6]。于是,位于中间的语言(也就是中级程序员用的那些语言)动得跟冰山一样慢。60'Lisp引入的垃圾回收功能,现在开始被接受。词法闭包,由Lisp70'引入的,现在其它语言还没有广泛采纳。60'Lisp引入的宏,现在还是处女地。

很明显,中间的语言族有着巨大的惯性。我不认为你能和这个力量对抗。相反,你要向合气道的选手学习:以彼之道,还治彼身。

如果你在大公司工作,这不太容易。你很难说你的服秃顶上司同意用Lisp写东西,他刚才才读到另一种语言新鲜出炉(就像Ada二十年前那样),正要征服世界。但是你要是为创业公司工作,没有秃顶老板干涉,你就能像我们那样化解Blub困境,转为自己的优势:你可以用那些黏糊在中间语言的竞争者不能采用的技术。

如果你为创业公司工作,这儿有个估量对手的妙招:读读他们的招聘职位列表。他们网站上其它的东西无非是些股票图片和乏味的说明,但是招聘职位却必须反映他们要找的人,否则会引来一堆无关的求职者。

Viaweb工作的时候,我读了不少职位描述。大约每个月都有一个新的竞争对手加入这个行当。检查了他们的在线Demo后,我做的第一件事就是看看他们的招聘页。过了几年,我就知道要当心哪家。工作描述里要是IT类的成分越多,这家公司就越不构成威胁。对我们最安全的就是那些要求Oracle经验的,永远都不用担心他们。他们要是招聘C++或者Java开发者,也不用担心。但是要是找的是Perl或者Python程序员,就有点威胁了-这公司至少在技术方面是由真正的黑客掌管的。要是当初我看见一家招Lisp黑客的,我一定会忧心忡忡的。

-----

注:

[1] Viaweb一开始有两块:编辑器(用Lisp写的,客户用来建站)和订单系统(用C写的,处理订单)。第一版主要是Lisp,因为订单系统很小。后来增加了两个模块:C写的图片生成器以及Perl写的结算工具。

2003年一月,Yahoo发布了新的编辑器,用C++Perl写的。也很难讲这程序就不再是用Lisp写的了:因为要把它翻译成C++,他们先得写一个Lisp解释器-页面生成模板的代码据我所知还是Lisp的。(参考Greenspun's Tenth Rule。)

[2] Robert Morris说我没必要那么保密。因为即使竞争对手知道我们用Lisp,他们也不会理解原因的:如果他们足够聪明,那他们应当已经在用Lisp了。

[3] 所有语言在图灵相等这一层上是一样强大的。但是这和程序员的意思不一样。(没人想在图灵机上写程序。)程序员在意的语言的能力也许不能形式化的定义,但一种解释就是,你想要在弱的语言里的要某种强语言的功能,就只能用弱语言去写一个解释器。如果A语言由一个操作可以把字符串里的空格移走,而B语言没有,这并不意味着B语言弱,因为你可以写个函数来完成这件事。但是要是A支持递归,而B不支持,这你就不好写个库函数来完成了。

[4] Nerd们的注解:可能是个格,顶尖;形状不重要,这里至少有个偏序关系。

[5] 把宏当作一个单独的功能有点误导。实践中,宏的作用通常由其它一些Lisp特性比如词法闭包以及rest参数大大加强。

[6] 这样,比较编程语言要么挑起信仰口水战要么就只能在绝对中立的教材里,这只能是人类学的工作了。想追求平静,保护自己的所有的人会避免这个话题。但是,这问题只是一半和信仰相关;还有值得研究的东西,特别是你要设计一个新语言时。

译注:

[1] 翻译时中英混排,完成时提取中文可以用grep: 

 

from:http://article.yeeyan.org/view/11304/49653

posted on 2010-12-13 18:29  chinese_submarine  阅读(1625)  评论(0编辑  收藏  举报