超越平均数
想创业吗? 由 Y Combinator 提供资金。
2001年4月,修订于2003年4月
(本文源自2001年Franz开发者研讨会上的演讲。)
1995年夏天,我和我的朋友罗伯特·莫里斯创办了一家名为Viaweb的创业公司。我们的计划是编写软件,让最终用户能够构建在线商店。当时这款软件的新颖之处在于,它运行在我们的服务器上,并使用普通网页作为界面。
当然,很多人可能同时有这个想法,但据我所知,Viaweb是第一个基于Web的应用。这对我们来说似乎太新颖了,以至于我们用它的名字给公司命名:Viaweb,因为我们的软件通过Web运行,而不是在您的台式电脑上运行。
这款软件的另一个不寻常之处在于,它主要用一种叫做Lisp的编程语言编写。它是首批用Lisp编写的大型终端用户应用之一,而Lisp在之前主要用于大学和研究实验室。[1]
秘密武器
埃里克·雷蒙德写过一篇名为《如何成为一名黑客》的文章,在文中,他除了其他内容外,还告诉那些想成为黑客的人应该学习哪些语言。他建议从Python和Java开始,因为它们容易学习。严肃的黑客还会想学C语言,以便黑客Unix,以及Perl用于系统管理和cgi脚本。最后,真正严肃的黑客应该考虑学习Lisp:
Lisp值得学习,因为当你最终掌握它时,会获得深刻的启蒙体验;这种体验会让你在余下的编程生涯中成为一个更好的程序员,即使你实际上不会大量使用Lisp本身。
这就像你常听到的学习拉丁语的理由。它不会让你找到工作,也许除了当古典学教授,但能提升你的思维,让你在你想使用的语言(如英语)中成为更好的作家。
但是等一下。这个比喻不能无限延伸。拉丁语不能让你找到工作的原因是没人说它。如果你用拉丁语写作,没人能理解你。但Lisp是一种计算机语言,计算机说任何你(程序员)告诉它们的语言。
所以,如果Lisp让你成为更好的程序员,就像他说的那样,你为什么不想使用它呢?如果给一位画家一支能让他画得更好的画笔,在我看来,他应该会在所有画作中使用它,不是吗?我在这里并不是想取笑埃里克·雷蒙德。总的来说,他的建议很好。他关于Lisp的说法几乎就是传统观点。但传统观点中存在一个矛盾:Lisp会让你成为更好的程序员,但你却不会使用它。
为什么不用呢?毕竟,编程语言只是工具。如果Lisp真的能产生更好的程序,你应该使用它。如果不行,那谁需要它呢?
这不仅仅是理论问题。软件是一个竞争非常激烈的行业,容易出现自然垄断。一家能更快更好地编写软件的公司,在其他条件相同的情况下,会把竞争对手挤出市场。当你创业时,你会强烈感受到这一点。创业往往是一场要么全有要么全无的赌博。你要么致富,要么一无所有。在创业中,如果你押错了技术,竞争对手就会压垮你。
罗伯特和我都精通Lisp,我们看不出有什么理由不信任自己的直觉并选择Lisp。我们知道其他人都在用C++或Perl编写他们的软件。但我们也知道这并不意味着什么。如果你这样选择技术,你会使用Windows。当你选择技术时,你必须忽略别人在做什么,只考虑什么最有效。
这在创业中尤其如此。在大公司,你可以效仿其他大公司。但创业公司不能效仿其他创业公司。我认为很多人没有意识到这一点,即使在创业公司中也是如此。
普通大公司每年大约增长百分之十。所以如果你经营一家大公司,并且做所有事情都像普通大公司那样,你可以预期表现与普通大公司相当——也就是大约每年增长百分之十。
如果你经营一家创业公司,当然也会发生同样的事情。如果你做所有事情都像普通创业公司那样,你应该预期平均表现。但问题在于,平均表现意味着你会倒闭。创业公司的存活率远低于百分之五十。所以如果你经营一家创业公司,你最好做一些不同寻常的事情。如果不是这样,你就有麻烦了。
回到1995年,我们知道一些我认为竞争对手当时不理解,即使现在也少有人理解的事情:当你编写的软件只运行在自己的服务器上时,你可以使用任何你想要的编程语言。当你在编写桌面软件时,强烈倾向于用与操作系统相同的语言编写应用。十年前,编写应用意味着用C语言编写。但对于基于Web的软件,尤其是当你拥有语言和操作系统的源代码时,你可以使用任何你想要的编程语言。
然而,这种新的自由是一把双刃剑。既然你可以使用任何语言,你就必须考虑使用哪一种。那些试图假装一切照旧的公司,可能会发现他们的竞争对手并非如此。
如果你可以使用任何语言,你会用哪一种?我们选择了Lisp。一方面,很明显在这个市场上快速开发将非常重要。我们都是从零开始,所以一家能在竞争对手之前完成新功能的公司会有很大优势。我们知道Lisp是一种非常适合快速编写软件的语言,而基于服务器的应用会放大快速开发的效果,因为你可以一完成软件就立即发布。
如果其他公司不想用Lisp,那更好。这可能给我们带来技术优势,而我们正需要所有能得到的帮助。当我们创办Viaweb时,我们没有任何商业经验。我们不懂营销,不知道如何招聘人员,不会融资,也不知道如何获得客户。我们俩甚至从未有过你所谓的真正工作。我们唯一擅长的是编写软件。我们希望这能拯救我们。我们会在软件方面获得任何优势,都会抓住。
所以你可以说使用Lisp是一个实验。我们的假设是,如果我们用Lisp编写软件,我们就能比竞争对手更快地完成功能,还能在我们的软件中实现他们做不到的事情。而且因为Lisp是这么高级的语言,我们不需要庞大的开发团队,所以成本会更低。如果真是这样,我们可以提供更好的产品,价格更低,还能盈利。我们最终会获得所有用户,而竞争对手则一无所获,最终倒闭。这至少是我们希望发生的。
这个实验的结果是什么?有点出人意料,它成功了。我们最终有很多竞争对手,大约有二三十个,但他们的软件都无法与我们的竞争。我们有一个在服务器上运行但感觉像桌面应用的所见即所得在线商店构建器。我们的竞争对手只有cgi脚本。而且我们在功能上总是遥遥领先。有时,绝望的竞争对手会尝试推出我们没有的功能。但使用Lisp,我们的开发周期非常快,以至于有时我们能在竞争对手在新闻稿中宣布新功能的一两天内复制出一个新功能。等报道新闻稿的记者打电话给我们时,我们也会有这个新功能了。
在竞争对手看来,我们一定有什么秘密武器——像是我们破解了他们的Enigma流量什么的。事实上,我们确实有秘密武器,但它比他们意识到的要简单。没有人泄露他们的功能给我们。我们只是能比任何人想象的速度更快地开发软件。
在我大约九岁的时候,我碰巧弄到了一本弗雷德里克·福赛斯的《豺狼的日子》。主角是一名受雇刺杀法国总统的刺客。刺客必须绕过警察才能到达一个俯瞰总统路线的公寓。他拄着拐杖扮成老人,直接从他们身边走过,他们从未怀疑他。
我们的秘密武器也类似。我们用一种古怪的AI语言编写软件,这种语言有奇怪的括号语法。多年来,听到Lisp被这样描述让我很恼火。但现在它对我们有利。在商业中,没有什么比竞争对手不理解的技术优势更有价值。在商业中,就像在战争中一样,出其不意和力量一样重要。
因此,我有点尴尬地说,在开发Viaweb期间,我从未公开谈论过Lisp。我们从未向媒体提及过它,如果你在我们的网站上搜索Lisp,你只会找到我简介中的两本书的标题。这并非偶然。创业公司应该尽可能少地向竞争对手提供信息。如果他们不知道我们的软件是用什么语言写的,或者不关心,我想保持这种状态。[2]
最了解我们技术的人是客户。他们也不关心Viaweb是用什么语言写的,但他们注意到它运行得非常好。它让客户能在几分钟内构建外观漂亮的在线商店。因此,大部分通过口碑传播,我们获得了越来越多的用户。到1996年底,我们大约有70家在线商店。到1997年底,我们有500家。六个月后,当雅虎收购我们时,我们有1070名用户。今天,作为雅虎商店,这款软件继续主导其市场。它是雅虎更赚钱的部分之一,用它构建的商店是雅虎购物的基础。我于1999年离开雅虎,所以我不确切知道他们现在有多少用户,但我上次听说大约有20000个。
Blub悖论
Lisp有什么了不起的?如果Lisp这么好,为什么没人用它?这些听起来像反问句,但实际上它们有直接的回答。Lisp之所以伟大,并不是因为只有爱好者才能看到的某种神奇品质,而是因为它只是现有最强大的语言。每个人都不使用它的原因是,编程语言不仅仅是技术,也是一种思维习惯,没有什么比思维习惯改变得更慢。当然,这两个回答都需要解释。
我将从一个令人震惊且有争议的声明开始:编程语言在力量上是不同的。
很少有人会否认,至少高级语言比机器语言更强大。如今大多数程序员会同意,你通常不希望用机器语言编程。相反,你应该用高级语言编程,并让编译器将其翻译成机器语言。这个想法甚至现在已经内置到硬件中:自1980年代以来,指令集是为编译器而不是人类程序员设计的。
每个人都知道用机器语言手写整个程序是错误的。但较少被理解的是,这里有一个更普遍的原则:如果你有几种语言可供选择,在其他条件相同的情况下,不使用最强大的语言编程是个错误。[3]
这个规则有很多例外。如果你编写的程序需要与用某种语言写的程序紧密配合,那么用同样的语言来写新程序可能是个好主意。如果你的程序只需要做非常简单的事情,比如数值计算或位操作,那你大可使用不那么抽象的语言,尤其是因为这样可能稍微快一些。而且,如果你是在编写一个简短的一次性程序,那么最好就用那个拥有最适合此任务库函数的语言。但总的来说,对于应用软件,你会希望使用你能够获得的最强大(且合理高效)的语言,而使用其他任何语言都是一个错误,这正如用机器语言编程一样,只是程度可能较轻。
你可以看到机器语言是非常低级的。但是,至少作为一种社会惯例,高级语言往往被视为等价。它们并非等价。从技术上讲,“高级语言”这个术语并没有非常明确的定义。并不存在一条分界线,一端是机器语言,另一端是所有高级语言。语言沿着抽象程度的连续谱系分布,从最强大的一直到机器语言,而机器语言本身在威力上也有所不同。
以Cobol为例。Cobol是一种高级语言,从某种意义上说,它会被编译成机器语言。会有人认真地认为Cobol在威力上等同于Python吗?它可能比Python更接近机器语言。
那Perl 4呢?在Perl 4和Perl 5之间,语言中加入了词法闭包。大多数Perl黑客会同意Perl 5比Perl 4更强大。但一旦你承认了这一点,你就承认了一种高级语言可能比另一种更强大。而且不可避免地,除非在特殊情况下,你应该使用你能得到的最强大的语言。
然而,这个观点很少被贯彻到底。到了一定年龄后,程序员很少会自愿更换语言。人们无论习惯使用何种语言,往往都会认为它已经足够好了。
程序员非常依恋他们喜欢的语言,我不想伤害任何人的感情,所以为了解释这一点,我将使用一种假想的语言,叫Blub。Blub正好处于抽象度连续谱的中间位置。它不是最强大的语言,但比Cobol或机器语言更强大。
事实上,我们假想的Blub程序员不会使用其中任何一种。他当然不会用机器语言编程,那是编译器干的事。至于Cobol,他不知道为什么有人能用它完成任何事情。它甚至没有x(你选择的Blub特性)。
只要我们的假想Blub程序员往下看威力连续谱,他知道自己是在向下看。比Blub威力小的语言显然威力更小,因为它们缺少了他习惯的某些特性。但当我们的假想Blub程序员往另一个方向看,即向上看威力连续谱时,他并没有意识到自己是在向上看。他所看到的只是些奇怪的。他可能认为它们在威力上与Blub大致相当,只是还附加了其他乱七八糟的东西。Blub对他已经足够好了,因为他就是用Blub思考的。
然而,当我们转换到使用威力连续谱上更高级语言的任何程序员的视角时,我们会发现他反过来也看不起Blub。在Blub里怎么能完成任何事情呢?它甚至没有y。
通过归纳,唯一能够看到各种语言之间所有威力差异的程序员,是那些理解最强大语言的人。(这大概就是Eric Raymond所说的Lisp会让你成为更好的程序员的意思吧。)你不能相信其他人的意见,因为有Blub悖论:他们对自己碰巧使用的任何语言都感到满意,因为这种语言决定了他们思考程序的方式。
这一点我深有体会,我高中时用Basic编写程序。那种语言甚至不支持递归。很难想象不用递归怎么写程序,但当时我并没有觉得缺少什么。我用Basic思考。而且我是这方面的奇才。我是我所见到的一切的主人。
Eric Raymond向黑客推荐的五种语言在威力连续谱上处于不同位置。它们之间的相对位置是一个敏感话题。我要说的是,我认为Lisp在顶端。为了支持这一说法,我会告诉你我在看其他四种语言时发现缺少的东西。没有宏,你怎么能用它们完成任何事情呢?
许多语言都有所谓宏的东西。但Lisp的宏是独一无二的。而且信不信由你,它们的功能与那些括号有关。Lisp的设计者并不是为了标新立异才在语言中加入所有这些括号。在Blub程序员看来,Lisp代码看起来很古怪。但那些括号存在是有原因的。它们是Lisp与其他语言之间根本差异的外在表现。
Lisp代码是由Lisp数据对象构成的。这并不是说源文件包含字符,而字符串是语言支持的数据类型之一这种琐碎意义。Lisp代码在被解析器读取后,是由你可以遍历的数据结构组成的。
如果你了解编译器的工作原理,那么真正发生的情况与其说是Lisp有奇怪的语法,不如说是Lisp没有语法。你在解析树中编写程序,而这些解析树是在其他语言被解析时在编译器内部生成的。但这些解析树对你的程序完全可访问。你可以编写操作它们的程序。在Lisp中,这些程序被称为宏。它们是编写程序的程序。
编写程序的程序?你什么时候会想要那样做?如果你用Cobol思考,那不会很频繁。如果你用Lisp思考,那是时时刻刻。如果我能在这里给出一个强大宏的例子,然后说“看!怎么样?”那会很方便。但如果我这样做,对于不懂Lisp的人来说那看起来就像乱码;这里没有足够的空间来解释理解它所需要的所有背景知识。在《Ansi Common Lisp》中,我尽量加快进度,即便如此,我也是到第160页才讲到宏。
但我认为我可以给出一种可能具有说服力的论证。Viaweb编辑器的源代码大概有20%-25%是宏。宏比普通的Lisp函数更难写,而且在不必要的情况下使用它们被认为是不良风格。所以那段代码中的每个宏都是有存在理由的。这意味着这个程序中至少有20%-25%的代码在做着用任何其他语言都不容易做到的事情。无论Blub程序员对我关于Lisp神秘力量的断言多么怀疑,这应该都会让他感到好奇。我们编写这些代码不是为了自娱自乐。我们是一家小创业公司,竭尽全力地编程,以便在我们和竞争对手之间设置技术壁垒。
一个多疑的人可能开始琢磨这两者之间是否存在某种关联。我们的很大一部分代码在做的事情在其他语言中是很难实现的。最终做出来的软件能完成我们竞争对手的软件做不到的事情。也许这之间有某种联系。我鼓励你顺着这条线去思考。那个拄着拐杖蹒跚而行的老人,可能并不像表面上看起来那么简单。
创业公司的合气道
但我不期望能说服任何人(超过25岁?)去学习Lisp。这篇文章的目的不是要改变任何人的想法,而是要让那些已经对使用Lisp感兴趣的人放心——那些知道Lisp是一种强大语言,但又因为它没有被广泛使用而担心的人。在竞争环境中,那是一个优势。Lisp的威力因为你的竞争对手不懂它而被放大了。
如果你考虑在创业公司中使用Lisp,你不应该担心它没有被广泛理解。你应该希望它保持这种状态。而且很可能如此。编程语言的本质就是让大多数人对他们当前使用的任何东西都感到满意。计算机硬件的变化比个人习惯快得多,以至于编程实践通常比处理器落后十到二十年。在MIT这样的地方,他们在20世纪60年代早期就用高级语言编写程序,但许多公司一直到80年代还在用机器语言编写代码。我敢打赌,很多人一直坚持用机器语言编程,直到处理器——就像急于打烊回家的酒保——终于通过切换到RISC指令集把他们赶了出去。
通常技术变化很快。但编程语言是不同的:编程语言不仅仅是技术,还是程序员思考的工具。它们一半是技术,一半是宗教。因此,中位语言——即中位程序员所使用的语言——移动得慢如冰山。垃圾回收,由Lisp在1960年左右引入,现在被广泛认为是个好东西。运行时类型,也是如此,正越来越流行。词法闭包,由Lisp在20世纪70年代早期引入,现在才刚刚进入人们的视野。宏,由Lisp在20世纪60年代中期引入,至今仍是未知领域。
显然,中位语言有着巨大的惯性。我不是提议你能对抗这股强大的力量。我提议的恰恰相反:就像合气道的练习者一样,你可以用它来对付你的对手。
如果你在一家大公司工作,这可能不容易。当你试图说服那个尖头发的老板让你用Lisp构建东西时,他会很为难,因为他刚刚在报纸上读到某种其他语言——就像二十年前的Ada一样——正准备统治世界。但如果你在一家还没有尖头发老板的创业公司工作,你就可以像我们那样,把Blub悖论转化为你的优势:你可以使用你的竞争对手永远无法匹敌的技术,因为他们被牢牢地粘在了中位语言上。
如果你真的发现自己在一家创业公司工作,这里有一个评估竞争对手的实用技巧。阅读他们的招聘信息。他们网站上的其他所有内容可能都是库存照片或文字堆砌,但招聘信息必须具体说明他们想要什么,否则他们会招到错误的候选人。
在我们开发Viaweb的那些年里,我读了很多职位描述。似乎每个月都有新的竞争对手冒出来。我做的第一件事,在查看他们是否有在线演示之后,就是看他们的招聘信息。经过两三年的观察,我能分辨出哪些公司需要担心,哪些不需要。职位描述中的IT味道越浓,这家公司的危险性就越低。最安全的是那些要求有Oracle经验的公司。你永远不用担心那些公司。如果他们说想要C++或Java开发人员,你也是安全的。如果他们想要Perl或Python程序员,那会有点吓人——这开始听起来像是一家技术方面(至少)由真正的黑客运营的公司。如果我曾经看到过招聘Lisp黑客的帖子,我真的会非常担心。
注释
[1] Viaweb最初有两个部分:编辑器,用Lisp编写,人们用它来构建他们的网站;以及订单系统,用C编写,处理订单。第一个版本大部分是Lisp,因为订单系统很小。后来我们又增加了两个模块,一个用C编写的图像生成器,和一个主要用Perl编写的后台管理器。
2003年1月,雅虎发布了一个用C++和Perl编写的新版编辑器。不过,很难说这个程序是否不再用Lisp编写,因为要将其翻译成C++,他们实际上不得不编写一个Lisp解释器:据我所知,所有页面生成模板的源文件仍然是Lisp代码。(参见格林斯潘第十定律。)
[2] 罗伯特·莫里斯说,我无需保密,因为即使我们的竞争对手知道我们在使用Lisp,他们也不会理解为什么:“如果他们那么聪明,他们早就用Lisp编程了。”
[3] 所有语言在“图灵等价”的意义上是同样强大的,但这并不是程序员关心的那种“强大”。(没有人想编程一台图灵机。)程序员关心的那种强大可能无法正式定义,但一种解释方式是:它指的是那些在较弱语言中,只有通过为较强语言编写解释器才能获得的特性。如果语言A有一个移除字符串空格的运算符,而语言B没有,这未必使A更强大,因为你可能能在B中写一个子程序来实现。但如果A支持递归,而B不支持,这就不太可能通过编写库函数来解决。
[4] 给极客的提示:或者可能是一个格,向顶部收窄;这里重要的不是形状,而是至少有部分顺序的概念。
[5] 将宏视为一个单独的特性有点误导。在实践中,它的实用性被其他Lisp特性如词法闭包和剩余参数大大增强了。
[6] 因此,编程语言的比较要么采取宗教战争的形式,要么采取本科生教科书的形式,这些教科书如此坚决地保持中立,以至于它们实际上是人类学的作品。那些重视和平或想要终身教职的人避开这个话题。但这个问题只有一半是宗教性的;这里有值得研究的东西,尤其是如果你想设计新语言。