Beating the Averages
Paul Graham recounts his startup Viaweb's experience to argue that programming languages vary in power and choosing a more powerful language like Lisp can provide a decisive competitive advantage for startups. He introduces the 'Blub paradox': programmers tend to think their current language is good enough and fail to appreciate more powerful ones. In Viaweb, roughly 20-25% of the editor code consisted of Lisp macros—programs that write programs—enabling features competitors couldn't match. For startups, this technical edge can be a secret weapon. The article is relevant for founders making tech choices and programmers curious about language design.


April 2001, rev. April 2003
(This article is derived from a talk given at the 2001 Franz Developer Symposium.)
In the summer of 1995, my friend Robert Morris and I started a startup called Viaweb. Our plan was to write software that would let end users build online stores. What was novel about this software, at the time, was that it ran on our server, using ordinary Web pages as the interface.
A lot of people could have been having this idea at the same time, of course, but as far as I know, Viaweb was the first Web-based application. It seemed such a novel idea to us that we named the company after it: Viaweb, because our software worked via the Web, instead of running on your desktop computer.
Another unusual thing about this software was that it was written primarily in a programming language called Lisp. It was one of the first big end-user applications to be written in Lisp, which up till then had been used mostly in universities and research labs. [1]
2001年4月,2003年4月修订
(本文源自2001年Franz开发者研讨会上的演讲。)
1995年夏天,我和朋友Robert Morris创办了一家名为Viaweb的初创公司。我们的计划是编写软件,让终端用户能够建立在线商店。这款软件在当时的新颖之处在于,它运行在我们的服务器上,并以普通网页作为界面。
当然,很多人可能同时想到了这个主意,但据我所知,Viaweb是第一个基于Web的应用。对我们来说,这个想法如此新颖,以至于我们以它命名了公司:Viaweb,因为我们的软件通过Web工作,而不是运行在你的台式电脑上。
这款软件的另一个不同寻常之处是,它主要用一种叫做Lisp的编程语言编写。它是首批用Lisp编写的大型终端用户应用之一,而在此之前Lisp大多只在大学和研究实验室中使用。[1]
The Secret Weapon
Eric Raymond has written an essay called "How to Become a Hacker," and in it, among other things, he tells would-be hackers what languages they should learn. He suggests starting with Python and Java, because they are easy to learn. The serious hacker will also want to learn C, in order to hack Unix, and Perl for system administration and cgi scripts. Finally, the truly serious hacker should consider learning Lisp:
Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.
This is the same argument you tend to hear for learning Latin. It won't get you a job, except perhaps as a classics professor, but it will improve your mind, and make you a better writer in languages you do want to use, like English.But wait a minute. This metaphor doesn't stretch that far. The reason Latin won't get you a job is that no one speaks it. If you write in Latin, no one can understand you. But Lisp is a computer language, and computers speak whatever language you, the programmer, tell them to.
So if Lisp makes you a better programmer, like he says, why wouldn't you want to use it? If a painter were offered a brush that would make him a better painter, it seems to me that he would want to use it in all his paintings, wouldn't he? I'm not trying to make fun of Eric Raymond here. On the whole, his advice is good. What he says about Lisp is pretty much the conventional wisdom. But there is a contradiction in the conventional wisdom: Lisp will make you a better programmer, and yet you won't use it.
Why not? Programming languages are just tools, after all. If Lisp really does yield better programs, you should use it. And if it doesn't, then who needs it?
This is not just a theoretical question. Software is a very competitive business, prone to natural monopolies. A company that gets software written faster and better will, all other things being equal, put its competitors out of business. And when you're starting a startup, you feel this very keenly. Startups tend to be an all or nothing proposition. You either get rich, or you get nothing. In a startup, if you bet on the wrong technology, your competitors will crush you.
Back in 1995, we knew something that I don't think our competitors understood, and few understand even now: when you're writing software that only has to run on your own servers, you can use any language you want. When you're writing desktop software, there's a strong bias toward writing applications in the same language as the operating system. Ten years ago, writing applications meant writing applications in C. But with Web-based software, especially when you have the source code of both the language and the operating system, you can use whatever language you want.
This new freedom is a double-edged sword, however. Now that you can use any language, you have to think about which one to use. Companies that try to pretend nothing has changed risk finding that their competitors do not.
秘密武器
Eric Raymond写了一篇名为《如何成为一名黑客》的文章,其中他告诉未来的黑客应该学习哪些语言。他建议从Python和Java开始,因为它们容易学习。严肃的黑客还需要学习C,以便破解Unix,以及Perl用于系统管理和CGI脚本。最后,真正严肃的黑客应该考虑学习Lisp:
Lisp值得学习,因为你最终掌握它时会获得深刻的启迪;这种经历会让你在余生中成为更好的程序员,即便你实际上并不大量使用Lisp本身。
这和你常听到的学习拉丁语的理由如出一辙。拉丁语不会给你带来工作,除非你成为古典学教授,但它能提升你的思维,让你在使用你真正想用的语言(如英语)时成为更好的写作者。但等等,这个比喻并不完全成立。拉丁语找不到工作的原因是没人说它。如果你用拉丁语写作,没人能理解你。但Lisp是一种计算机语言,计算机说任何你作为程序员告诉它们的语言。
所以,如果像他说的那样Lisp让你成为更好的程序员,为什么你不想用它呢?如果一个画家得到一支能让他画得更好的画笔,我觉得他会想在所有画作中使用它,不是吗?我不是在取笑Eric Raymond。总的来说,他的建议很好。他对Lisp的看法基本是传统智慧。但传统智慧中存在一个矛盾:Lisp会让你成为更好的程序员,然而你却不使用它。
为什么不呢?编程语言终究只是工具。如果Lisp确实能产出更好的程序,你就应该使用它。如果不能,那谁需要它呢?
这不仅仅是一个理论问题。软件是一个竞争非常激烈的行业,容易形成自然垄断。在其他条件相同的情况下,一家能更快更好地编写软件的公司会将其竞争对手挤出市场。当你创办初创公司时,你会深切地感受到这一点。初创公司往往是一场要么全有要么全无的赌局。你要么发财,要么一无所获。在初创公司中,如果你押错了技术,你的竞争对手就会碾压你。
早在1995年,我们就知道一些我认为竞争对手并不理解、甚至现在也很少有人理解的事情:当你编写只在自有服务器上运行的软件时,你可以使用任何你喜欢的语言。当你编写桌面软件时,存在一种强烈的偏好,即用与操作系统相同的语言编写应用程序。十年前,编写应用程序意味着用C编写。但对于基于Web的软件,尤其是当你同时拥有语言和操作系统的源代码时,你可以使用任何你想要的。
然而,这种新自由是一把双刃剑。既然你可以使用任何语言,你就必须思考该用哪一种。那些试图假装一切未变的公司,可能会发现竞争对手并未如此。
Robert and I both knew Lisp well, and we couldn't see any reason not to trust our instincts and go with Lisp. We knew that everyone else was writing their software in C++ or Perl. But we also knew that that didn't mean anything. If you chose technology that way, you'd be running Windows. When you choose technology, you have to ignore what other people are doing, and consider only what will work the best.
This is especially true in a startup. In a big company, you can do what all the other big companies are doing. But a startup can't do what all the other startups do. I don't think a lot of people realize this, even in startups.
The average big company grows at about ten percent a year. So if you're running a big company and you do everything the way the average big company does it, you can expect to do as well as the average big company-- that is, to grow about ten percent a year.
The same thing will happen if you're running a startup, of course. If you do everything the way the average startup does it, you should expect average performance. The problem here is, average performance means that you'll go out of business. The survival rate for startups is way less than fifty percent. So if you're running a startup, you had better be doing something odd. If not, you're in trouble.
If you can use any language, which do you use? We chose Lisp. For one thing, it was obvious that rapid development would be important in this market. We were all starting from scratch, so a company that could get new features done before its competitors would have a big advantage. We knew Lisp was a really good language for writing software quickly, and server-based applications magnify the effect of rapid development, because you can release software the minute it's done.
If other companies didn't want to use Lisp, so much the better. It might give us a technological edge, and we needed all the help we could get. When we started Viaweb, we had no experience in business. We didn't know anything about marketing, or hiring people, or raising money, or getting customers. Neither of us had ever even had what you would call a real job. The only thing we were good at was writing software. We hoped that would save us. Any advantage we could get in the software department, we would take.
So you could say that using Lisp was an experiment. Our hypothesis was that if we wrote our software in Lisp, we'd be able to get features done faster than our competitors, and also to do things in our software that they couldn't do. And because Lisp was so high-level, we wouldn't need a big development team, so our costs would be lower. If this were so, we could offer a better product for less money, and still make a profit. We would end up getting all the users, and our competitors would get none, and eventually go out of business. That was what we hoped would happen, anyway.
Robert和我都精通Lisp,我们找不到任何理由不信任自己的直觉并使用Lisp。我们知道其他人都在用C++或Perl编写软件。但我们也知道这并不意味着什么。如果你那样选择技术,你最终会运行Windows。在选择技术时,你必须忽略别人在做什么,只考虑什么是最好的。
在初创公司中尤其如此。在大公司里,你可以做其他大公司在做的事。但初创公司不能做其他初创公司在做的事。我认为很多人没有意识到这一点,即使是初创公司内部。
普通大公司每年增长约10%。所以如果你经营一家大公司,并且一切都按照普通大公司的方式去做,那么你的表现也会和普通大公司一样——也就是每年增长约10%。
当然,如果你经营一家初创公司,情况也一样。如果你按照普通初创公司的方式做所有事,你的表现也会是平均水准。问题在于,平均水准意味着你会倒闭。初创公司的存活率远低于50%。所以,如果你在经营初创公司,你最好做一些与众不同的事。否则,你就有麻烦了。
既然你可以使用任何语言,那用哪一种呢?我们选择了Lisp。首先,快速开发在这个市场中显然很重要。我们都是从零开始,所以一家能先于竞争对手完成新功能的公司将拥有巨大优势。我们知道Lisp是一种非常适合快速编写软件的语言,而基于服务器的应用会放大快速开发的效果,因为你可以在完成的瞬间发布软件。
如果其他公司不想用Lisp,那更好。这可能会给我们带来技术优势,而我们需要一切可能的帮助。当我们创办Viaweb时,我们没有任何商业经验。我们对营销、招聘、融资或获取客户一无所知。我们两人甚至从未有过所谓真正的工作。我们唯一擅长的是编写软件。我们希望这能拯救我们。任何在软件方面能获得的优势,我们都会争取。
所以可以说,使用Lisp是一个实验。我们的假设是,如果我们用Lisp编写软件,我们就能比竞争对手更快地完成功能,还能在我们的软件中实现他们做不到的事情。而且因为Lisp是高级语言,我们不需要庞大的开发团队,从而降低成本。如果真是这样,我们就可以以更低的价格提供更好的产品,同时还能盈利。最终我们将获得所有用户,而竞争对手一无所获,并最终倒闭。无论如何,这就是我们希望发生的事。
What were the results of this experiment? Somewhat surprisingly, it worked. We eventually had many competitors, on the order of twenty to thirty of them, but none of their software could compete with ours. We had a wysiwyg online store builder that ran on the server and yet felt like a desktop application. Our competitors had cgi scripts. And we were always far ahead of them in features. Sometimes, in desperation, competitors would try to introduce features that we didn't have. But with Lisp our development cycle was so fast that we could sometimes duplicate a new feature within a day or two of a competitor announcing it in a press release. By the time journalists covering the press release got round to calling us, we would have the new feature too.
It must have seemed to our competitors that we had some kind of secret weapon-- that we were decoding their Enigma traffic or something. In fact we did have a secret weapon, but it was simpler than they realized. No one was leaking news of their features to us. We were just able to develop software faster than anyone thought possible.
When I was about nine I happened to get hold of a copy of The Day of the Jackal, by Frederick Forsyth. The main character is an assassin who is hired to kill the president of France. The assassin has to get past the police to get up to an apartment that overlooks the president's route. He walks right by them, dressed up as an old man on crutches, and they never suspect him.
Our secret weapon was similar. We wrote our software in a weird AI language, with a bizarre syntax full of parentheses. For years it had annoyed me to hear Lisp described that way. But now it worked to our advantage. In business, there is nothing more valuable than a technical advantage your competitors don't understand. In business, as in war, surprise is worth as much as force.
And so, I'm a little embarrassed to say, I never said anything publicly about Lisp while we were working on Viaweb. We never mentioned it to the press, and if you searched for Lisp on our Web site, all you'd find were the titles of two books in my bio. This was no accident. A startup should give its competitors as little information as possible. If they didn't know what language our software was written in, or didn't care, I wanted to keep it that way.[2]
这个实验的结果如何?出人意料的是,它成功了。我们最终拥有许多竞争对手,大约二三十家,但他们的软件都无法与我们的竞争。我们有一个运行在服务器上却感觉像桌面应用的WYSIWYG在线商店构建器,而我们的竞争对手只有CGI脚本。在功能上我们始终遥遥领先。有时,绝望的对手会试图引入我们没有的功能。但凭借Lisp,我们的开发周期如此之快,以至于我们有时能在竞争对手发布新闻稿宣布新功能的一两天内复制出该功能。等到报道新闻稿的记者打电话给我们时,我们已经有了那个新功能。
在竞争对手看来,我们一定拥有某种秘密武器——仿佛我们在破解他们的恩尼格玛密码之类。事实上,我们确实有秘密武器,但它比他们想象的要简单。没有人向我们泄露他们的功能消息。我们只是能以超乎想象的速度开发软件。
大约九岁时,我偶然得到一本弗雷德里克·福赛斯的《豺狼的日子》。主角是一名受雇刺杀法国总统的刺客。他需要避开警察,进入一间俯瞰总统路线的公寓。他装扮成一个拄着拐杖的老人从警察身边走过,他们从未怀疑他。
我们的秘密武器与之类似。我们用一种奇怪的AI语言编写软件,语法怪异,布满括号。多年来,听到有人这样描述Lisp都让我恼火。但现在这成了我们的优势。在商业中,没有什么比竞争对手不理解的技术优势更有价值。在商业中,如同在战争中,奇袭与力量同等重要。
因此,我有点尴尬地说,在开发Viaweb期间,我从未公开谈论过Lisp。我们从未向媒体提及,如果你在我们的网站上搜索Lisp,只能找到我简介中两本书的标题。这绝非偶然。初创公司应尽可能少地向竞争对手透露信息。如果他们不知道我们的软件用什么语言编写,或者不在乎,我希望保持这种状态。[2]
The people who understood our technology best were the customers. They didn't care what language Viaweb was written in either, but they noticed that it worked really well. It let them build great looking online stores literally in minutes. And so, by word of mouth mostly, we got more and more users. By the end of 1996 we had about 70 stores online. At the end of 1997 we had 500. Six months later, when Yahoo bought us, we had 1070 users. Today, as Yahoo Store, this software continues to dominate its market. It's one of the more profitable pieces of Yahoo, and the stores built with it are the foundation of Yahoo Shopping. I left Yahoo in 1999, so I don't know exactly how many users they have now, but the last I heard there were about 20,000.
The Blub Paradox
What's so great about Lisp? And if Lisp is so great, why doesn't everyone use it? These sound like rhetorical questions, but actually they have straightforward answers. Lisp is so great not because of some magic quality visible only to devotees, but because it is simply the most powerful language available. And the reason everyone doesn't use it is that programming languages are not merely technologies, but habits of mind as well, and nothing changes slower. Of course, both these answers need explaining.
最了解我们技术的人是客户。他们也不关心Viaweb是用什么语言写的,但他们注意到它确实很好用。它让用户能在几分钟内建立漂亮的在线商店。因此,主要通过口碑,我们获得了越来越多的用户。到1996年底,我们大约有70家在线商店。1997年底有500家。六个月后,雅虎收购我们时,我们有1070个用户。如今,作为Yahoo Store,这款软件仍在主导其市场。它是雅虎最赚钱的部分之一,用其搭建的商店是Yahoo Shopping的基础。我于1999年离开雅虎,所以不知道他们现在具体有多少用户,但上次听说大约有2万。
Blub悖论
Lisp到底好在哪?如果Lisp这么好,为什么不是所有人都用它?这些问题听起来像反问,但实际上有直截了当的答案。Lisp之所以这么好,不是因为只有爱好者才能看到的某种魔力,而是因为它就是目前可用的最强大的语言。而大家不使用它的原因是,编程语言不仅仅是技术,更是思维习惯,没有什么比这变化更慢的了。当然,这两个答案都需要解释。
I'll begin with a shockingly controversial statement: programming languages vary in power.
Few would dispute, at least, that high level languages are more powerful than machine language. Most programmers today would agree that you do not, ordinarily, want to program in machine language. Instead, you should program in a high-level language, and have a compiler translate it into machine language for you. This idea is even built into the hardware now: since the 1980s, instruction sets have been designed for compilers rather than human programmers.
Everyone knows it's a mistake to write your whole program by hand in machine language. What's less often understood is that there is a more general principle here: that if you have a choice of several languages, it is, all other things being equal, a mistake to program in anything but the most powerful one. [3]
There are many exceptions to this rule. If you're writing a program that has to work very closely with a program written in a certain language, it might be a good idea to write the new program in the same language. If you're writing a program that only has to do something very simple, like number crunching or bit manipulation, you may as well use a less abstract language, especially since it may be slightly faster. And if you're writing a short, throwaway program, you may be better off just using whatever language has the best library functions for the task. But in general, for application software, you want to be using the most powerful (reasonably efficient) language you can get, and using anything else is a mistake, of exactly the same kind, though possibly in a lesser degree, as programming in machine language.
You can see that machine language is very low level. But, at least as a kind of social convention, high-level languages are often all treated as equivalent. They're not. Technically the term "high-level language" doesn't mean anything very definite. There's no dividing line with machine languages on one side and all the high-level languages on the other. Languages fall along a continuum [4] of abstractness, from the most powerful all the way down to machine languages, which themselves vary in power.
我先说一个极具争议性的声明:编程语言的能力各不相同。
至少,几乎没有人会否认高级语言比机器语言更强大。如今大多数程序员都同意,你通常不会想要用机器语言编程。相反,你应该使用高级语言,让编译器将其翻译成机器语言。这个想法甚至已经融入了硬件:自20世纪80年代以来,指令集就是为编译器而非人类程序员设计的。
每个人都知道用手写机器语言编写整个程序是个错误。但人们不太理解的是,这里有一个更普遍的法则:如果你有几种语言可选,在其他条件相同的情况下,不选择最强大的语言编程就是一个错误。[3]
这个规则有许多例外。如果你编写的程序必须与用某种语言编写的程序紧密配合,那么用同一种语言编写新程序可能是好主意。如果你编写的程序只需要做非常简单的事情,比如数值计算或位操作,那么使用不太抽象的语言也无妨,尤其因为它可能稍微快一点。如果你在写一个短小的、一次性的程序,那么使用拥有最佳库函数的语言可能更好。但总的来说,对于应用软件,你想要使用你能得到的最强大(且合理高效)的语言,而使用其他任何语言都是一个错误,其性质与用机器语言编程相同,尽管程度可能较轻。
你可以看到机器语言非常底层。但至少作为一种社会惯例,高级语言往往被视为等同。但它们并不等同。从技术上说,“高级语言”这个术语并没有很明确的含义。不存在一条把机器语言放在一边、所有高级语言放在另一边的分界线。语言沿着一个抽象度连续谱分布[4],从最强大的一直延伸到机器语言,而机器语言本身的能力也各不相同。
Consider Cobol. Cobol is a high-level language, in the sense that it gets compiled into machine language. Would anyone seriously argue that Cobol is equivalent in power to, say, Python? It's probably closer to machine language than Python.
Or how about Perl 4? Between Perl 4 and Perl 5, lexical closures got added to the language. Most Perl hackers would agree that Perl 5 is more powerful than Perl 4. But once you've admitted that, you've admitted that one high level language can be more powerful than another. And it follows inexorably that, except in special cases, you ought to use the most powerful you can get.
This idea is rarely followed to its conclusion, though. After a certain age, programmers rarely switch languages voluntarily. Whatever language people happen to be used to, they tend to consider just good enough.
Programmers get very attached to their favorite languages, and I don't want to hurt anyone's feelings, so to explain this point I'm going to use a hypothetical language called Blub. Blub falls right in the middle of the abstractness continuum. It is not the most powerful language, but it is more powerful than Cobol or machine language.
And in fact, our hypothetical Blub programmer wouldn't use either of them. Of course he wouldn't program in machine language. That's what compilers are for. And as for Cobol, he doesn't know how anyone can get anything done with it. It doesn't even have x (Blub feature of your choice).
As long as our hypothetical Blub programmer is looking down the power continuum, he knows he's looking down. Languages less powerful than Blub are obviously less powerful, because they're missing some feature he's used to. But when our hypothetical Blub programmer looks in the other direction, up the power continuum, he doesn't realize he's looking up. What he sees are merely weird languages. He probably considers them about equivalent in power to Blub, but with all this other hairy stuff thrown in as well. Blub is good enough for him, because he thinks in Blub.
When we switch to the point of view of a programmer using any of the languages higher up the power continuum, however, we find that he in turn looks down upon Blub. How can you get anything done in Blub? It doesn't even have y.
By induction, the only programmers in a position to see all the differences in power between the various languages are those who understand the most powerful one. (This is probably what Eric Raymond meant about Lisp making you a better programmer.) You can't trust the opinions of the others, because of the Blub paradox: they're satisfied with whatever language they happen to use, because it dictates the way they think about programs.
I know this from my own experience, as a high school kid writing programs in Basic. That language didn't even support recursion. It's hard to imagine writing programs without using recursion, but I didn't miss it at the time. I thought in Basic. And I was a whiz at it. Master of all I surveyed.
The five languages that Eric Raymond recommends to hackers fall at various points on the power continuum. Where they fall relative to one another is a sensitive topic. What I will say is that I think Lisp is at the top. And to support this claim I'll tell you about one of the things I find missing when I look at the other four languages. How can you get anything done in them, I think, without macros? [5]
考虑一下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思考,而且我是Basic高手,俯视一切。
Eric Raymond推荐给黑客的五种语言落在能力谱系的不同位置。它们相对于彼此的排序是一个敏感话题。我要说的是,我认为Lisp位于顶端。为了支持这一说法,我将告诉你当我看其他四种语言时,我发现缺少的东西之一:没有宏,你如何能在其中完成任何工作?[5]
Many languages have something called a macro. But Lisp macros are unique. And believe it or not, what they do is related to the parentheses. The designers of Lisp didn't put all those parentheses in the language just to be different. To the Blub programmer, Lisp code looks weird. But those parentheses are there for a reason. They are the outward evidence of a fundamental difference between Lisp and other languages.
Lisp code is made out of Lisp data objects. And not in the trivial sense that the source files contain characters, and strings are one of the data types supported by the language. Lisp code, after it's read by the parser, is made of data structures that you can traverse.
If you understand how compilers work, what's really going on is not so much that Lisp has a strange syntax as that Lisp has no syntax. You write programs in the parse trees that get generated within the compiler when other languages are parsed. But these parse trees are fully accessible to your programs. You can write programs that manipulate them. In Lisp, these programs are called macros. They are programs that write programs.
Programs that write programs? When would you ever want to do that? Not very often, if you think in Cobol. All the time, if you think in Lisp. It would be convenient here if I could give an example of a powerful macro, and say there! how about that? But if I did, it would just look like gibberish to someone who didn't know Lisp; there isn't room here to explain everything you'd need to know to understand what it meant. In Ansi Common Lisp I tried to move things along as fast as I could, and even so I didn't get to macros until page 160.
But I think I can give a kind of argument that might be convincing. The source code of the Viaweb editor was probably about 20-25% macros. Macros are harder to write than ordinary Lisp functions, and it's considered to be bad style to use them when they're not necessary. So every macro in that code is there because it has to be. What that means is that at least 20-25% of the code in this program is doing things that you can't easily do in any other language.
许多语言都有称为宏的东西,但Lisp的宏是独一无二的。信不信由你,它们的作用与括号有关。Lisp的设计者并不是为了标新立异才在语言中加入这么多括号。在Blub程序员看来,Lisp代码很奇怪。但这些括号的存在是有原因的。它们反映了Lisp与其他语言之间的根本差异。
Lisp代码由Lisp数据对象构成。这并非指源文件包含字符、字符串是语言支持的数据类型这种浅层意义。Lisp代码在被解析器读取后,由你可以遍历的数据结构组成。
如果你理解编译器的工作原理,就会发现实际情况与其说Lisp有奇怪的语法,不如说Lisp没有语法。你在其他语言解析时编译器内部生成的解析树中编写程序。但这些解析树对你的程序完全可访问。你可以编写操作它们的程序。在Lisp中,这些程序被称为宏。它们是编写程序的程序。
编写程序的程序?你什么时候会想这样做?如果用Cobol思考,那是不常有的。如果用Lisp思考,则一直如此。如果我能举一个强大宏的例子,然后说“看!怎么样?”那会很方便。但如果我这样做,对不了解Lisp的人来说它看起来就像天书;这里没有足够的篇幅来解释你理解它所需的一切。在《ANSI Common Lisp》中,我尽可能快地推进,即便如此也要到160页才讲到宏。
但我认为我可以给出一种可能令人信服的论证。Viaweb编辑器的源代码中,宏可能占了大约20-25%。宏比普通Lisp函数更难写,而且在没必要的时候使用宏被认为是不良风格。因此,那段代码中的每个宏都是因为不得已才存在的。这意味着该程序中至少有20-25%的代码在做其他语言中不容易做到的事情。
However skeptical the Blub programmer might be about my claims for the mysterious powers of Lisp, this ought to make him curious. We weren't writing this code for our own amusement. We were a tiny startup, programming as hard as we could in order to put technical barriers between us and our competitors.
A suspicious person might begin to wonder if there was some correlation here. A big chunk of our code was doing things that are very hard to do in other languages. The resulting software did things our competitors' software couldn't do. Maybe there was some kind of connection. I encourage you to follow that thread. There may be more to that old man hobbling along on his crutches than meets the eye.
无论Blub程序员对我关于Lisp神秘力量的断言多么怀疑,这都应该让他好奇。我们编写这些代码不是为了自娱自乐。我们是一家小型初创公司,竭尽全力编程,只为在我们和竞争对手之间建立技术壁垒。
一个多疑的人可能会开始怀疑这里是否存在某种关联。我们的大量代码在做其他语言中很难做到的事情。最终完成的软件做到了竞争对手的软件做不到的事。也许存在某种联系。我鼓励你顺着这条线索思考。那个拄着拐杖蹒跚而行的老人,可能并不像表面看起来那么简单。
But I don't expect to convince anyone (over 25) to go out and learn Lisp. The purpose of this article is not to change anyone's mind, but to reassure people already interested in using Lisp-- people who know that Lisp is a powerful language, but worry because it isn't widely used. In a competitive situation, that's an advantage. Lisp's power is multiplied by the fact that your competitors don't get it.
If you think of using Lisp in a startup, you shouldn't worry that it isn't widely understood. You should hope that it stays that way. And it's likely to. It's the nature of programming languages to make most people satisfied with whatever they currently use. Computer hardware changes so much faster than personal habits that programming practice is usually ten to twenty years behind the processor. At places like MIT they were writing programs in high-level languages in the early 1960s, but many companies continued to write code in machine language well into the 1980s. I bet a lot of people continued to write machine language until the processor, like a bartender eager to close up and go home, finally kicked them out by switching to a risc instruction set.
Ordinarily technology changes fast. But programming languages are different: programming languages are not just technology, but what programmers think in. They're half technology and half religion.[6] And so the median language, meaning whatever language the median programmer uses, moves as slow as an iceberg. Garbage collection, introduced by Lisp in about 1960, is now widely considered to be a good thing. Runtime typing, ditto, is growing in popularity. Lexical closures, introduced by Lisp in the early 1970s, are now, just barely, on the radar screen. Macros, introduced by Lisp in the mid 1960s, are still terra incognita.
Obviously, the median language has enormous momentum. I'm not proposing that you can fight this powerful force. What I'm proposing is exactly the opposite: that, like a practitioner of Aikido, you can use it against your opponents.
If you work for a big company, this may not be easy. You will have a hard time convincing the pointy-haired boss to let you build things in Lisp, when he has just read in the paper that some other language is poised, like Ada was twenty years ago, to take over the world. But if you work for a startup that doesn't have pointy-haired bosses yet, you can, like we did, turn the Blub paradox to your advantage: you can use technology that your competitors, glued immovably to the median language, will never be able to match.
但我不指望能说服任何人(超过25岁)去学习Lisp。本文的目的不是为了改变任何人的想法,而是为了安抚那些已经对使用Lisp感兴趣的人——他们知道Lisp是一种强大的语言,却因为没有被广泛使用而担忧。在竞争环境中,这反而是一种优势。Lisp的力量因竞争对手不理解它而加倍。
如果你考虑在初创公司中使用Lisp,你不应该担心它不被广泛理解。你应该希望它继续保持这种状态。而且很可能会这样。编程语言的本质就是让大多数人对他们当前使用的语言感到满意。计算机硬件的变化远快于个人习惯,因此编程实践通常落后处理器十到二十年。在MIT这样的地方,早在20世纪60年代初他们就用高级语言编写程序,但许多公司直到80年代还在用机器语言写代码。我打赌很多人一直用机器语言,直到处理器像急于打烊回家的酒保一样,通过切换到RISC指令集最终将他们踢了出去。
通常技术变化很快。但编程语言不同:编程语言不仅仅是技术,更是程序员用来思考的工具。它们一半是技术,一半是宗教。[6]因此,中位语言(即中位程序员使用的语言)移动得像冰山一样缓慢。垃圾回收由Lisp在1960年左右引入,现在被广泛认为是好东西。运行时类型同理,正日益流行。词法闭包由Lisp在70年代初引入,现在才刚刚进入人们的视野。宏由Lisp在60年代中期引入,至今仍是未知领域。
显然,中位语言有着巨大的惯性。我不是建议你去对抗这股强大的力量。我建议的恰恰相反:就像合气道的修炼者一样,你可以利用它来对付你的对手。
如果你在一家大公司工作,这可能不容易。当尖头发老板刚在报纸上读到某种语言(就像二十年前的Ada一样)准备接管世界时,你很难说服他让你用Lisp构建东西。但如果你在一家还没有尖头发老板的初创公司工作,你可以像我们一样,将Blub悖论转化为你的优势:你可以使用那些牢牢粘在中位语言上的竞争对手永远无法匹敌的技术。
If you ever do find yourself working for a startup, here's a handy tip for evaluating competitors. Read their job listings. Everything else on their site may be stock photos or the prose equivalent, but the job listings have to be specific about what they want, or they'll get the wrong candidates.
During the years we worked on Viaweb I read a lot of job descriptions. A new competitor seemed to emerge out of the woodwork every month or so. The first thing I would do, after checking to see if they had a live online demo, was look at their job listings. After a couple years of this I could tell which companies to worry about and which not to. The more of an IT flavor the job descriptions had, the less dangerous the company was. The safest kind were the ones that wanted Oracle experience. You never had to worry about those. You were also safe if they said they wanted C++ or Java developers. If they wanted Perl or Python programmers, that would be a bit frightening-- that's starting to sound like a company where the technical side, at least, is run by real hackers. If I had ever seen a job posting looking for Lisp hackers, I would have been really worried.
如果你真的在初创公司工作,这里有一个评估竞争对手的实用技巧:阅读他们的招聘启事。他们网站上的其他内容可能都是库存照片或类似文案,但招聘启事必须明确具体需要什么,否则会招到错误的候选人。
在Viaweb工作的那些年里,我阅读了大量职位描述。似乎每个月都会有一家新的竞争对手冒出来。我做的第一件事(在检查他们是否有在线演示之后)就是看他们的招聘启事。经过几年这样的观察,我能判断出哪些公司值得担心,哪些不必担心。职位描述的IT味道越浓,这家公司的危险性就越低。最安全的是那些要求Oracle经验的,你永远不必担心它们。如果他们说要招C++或Java开发者,你也很安全。如果他们想要Perl或Python程序员,那就有点可怕了——这听起来像一家至少技术方面由真正黑客主导的公司。如果我看到过招聘Lisp黑客的启事,那我真的会担心了。
Notes
[1] Viaweb at first had two parts: the editor, written in Lisp, which people used to build their sites, and the ordering system, written in C, which handled orders. The first version was mostly Lisp, because the ordering system was small. Later we added two more modules, an image generator written in C, and a back-office manager written mostly in Perl.
In January 2003, Yahoo released a new version of the editor written in C++ and Perl. It's hard to say whether the program is no longer written in Lisp, though, because to translate this program into C++ they literally had to write a Lisp interpreter: the source files of all the page-generating templates are still, as far as I know, Lisp code. (See Greenspun's Tenth Rule.)
[2] Robert Morris says that I didn't need to be secretive, because even if our competitors had known we were using Lisp, they wouldn't have understood why: "If they were that smart they'd already be programming in Lisp."
[3] All languages are equally powerful in the sense of being Turing equivalent, but that's not the sense of the word programmers care about. (No one wants to program a Turing machine.) The kind of power programmers care about may not be formally definable, but one way to explain it would be to say that it refers to features you could only get in the less powerful language by writing an interpreter for the more powerful language in it. If language A has an operator for removing spaces from strings and language B doesn't, that probably doesn't make A more powerful, because you can probably write a subroutine to do it in B. But if A supports, say, recursion, and B doesn't, that's not likely to be something you can fix by writing library functions.
[4] Note to nerds: or possibly a lattice, narrowing toward the top; it's not the shape that matters here but the idea that there is at least a partial order.
[5] It is a bit misleading to treat macros as a separate feature. In practice their usefulness is greatly enhanced by other Lisp features like lexical closures and rest parameters.
[6] As a result, comparisons of programming languages either take the form of religious wars or undergraduate textbooks so determinedly neutral that they're really works of anthropology. People who value their peace, or want tenure, avoid the topic. But the question is only half a religious one; there is something there worth studying, especially if you want to design new languages.
注释
[1] Viaweb最初有两部分:编辑器(用Lisp编写,用于构建网站)和订单系统(用C编写,处理订单)。第一个版本大部分是Lisp,因为订单系统很小。后来我们又添加了两个模块:一个用C编写的图像生成器,以及一个主要用Perl编写的后台管理器。
2003年1月,雅虎发布了用C++和Perl编写的新版编辑器。不过很难说这个程序不再用Lisp编写了,因为为了将其翻译成C++,他们几乎必须编写一个Lisp解释器:据我所知,所有页面生成模板的源文件仍然是Lisp代码。(参见Greenspun第十定律。)
[2] Robert Morris说我无需保密,因为即使竞争对手知道我们在用Lisp,他们也不会理解为什么:“如果他们那么聪明,早就用Lisp编程了。”
[3] 所有语言在图灵完备的意义上能力相同,但这不是程序员关心的那种能力。(没人想编程图灵机。)程序员关心的那种能力可能无法正式定义,但一种解释方式是:它指的是那些只有在较弱语言中为较强语言编写解释器才能获得的特性。如果语言A有一个去除字符串空格的运算符而语言B没有,这大概不会让A更强大,因为你很可能可以在B中写个子程序来实现。但如果A支持递归而B不支持,这就不太可能通过编写库函数来修复。
[4] 给书呆子的注释:也可能是格,向上收敛;在这里重要的不是形状,而是至少存在一个偏序这一概念。
[5] 将宏视为一个独立特性有点误导。在实践中,其他Lisp特性如词法闭包和剩余参数极大地增强了宏的实用性。
[6] 因此,编程语言的比较要么采取宗教战争的形式,要么是决心保持中立、以至于实际上是人类学著作的本科教材。重视和平或想获得终身教职的人会避开这个话题。但这个问题只有一半是宗教性的;其中有些值得研究的东西,尤其是如果你想设计新语言的话。