Growing a Language - 中文翻译

写在前面

看到Guy Steele在1998年的ACM OOPSLA会议上做的演讲,主题叫”Growing a Language”,颇受启发,因为google不到此文的中文翻译,于是翻译之,以便后人学习。这几乎是我看过的有关程序语言设计的最好的演讲了。这篇文章似乎解释了我对某些程序语言的偏见和偏爱。因为是演讲稿,翻译起来有点前后文连不上,又因为讲的是语言设计,用到了好多英语单词的定义,读起来不那么易懂,见谅。断断续续总算翻译完了,问题很多,第一次翻译作业以外的东西,而且还这么多,不过总算搞定了,有什么建议或这错误请发pull request。

英文原版PDF在这里。

演讲的视频在这里。

正文

大家都知道man是什么意思。woman同man差不多,只不过有着相反的性别。(这样的演讲开头可能听起来有点奇怪,不过一会你就知道为啥了)。这样我就能定义一个person:一个women或者是一个man(年轻的或者年老的)。简便为由,当我说he的时候就是指he或者she,同理,说his的时候就指his或者her。

  • machine:一个可以独立完成任务或者通过人很少的帮助完成任务的东西叫做机器。

通常,我们在一个东西的名字后面加上“s”或者“z”音来表示有两个以上的这个东西: <noun> ::= <noun that names one thing> “s” | <noun that names one thing> “es”

这里有一些人名:Alan Turing, Alonzo Church, Charles Kay Ogden, Christo-pher Alexander, Eric Raymond, Fred Brooks, John Horton Conway, James Gosling, BillJoy, and Dick Gabriel。

  • other:意为“not the same”,词组other than:意为“not the same as”。

  • number:为0(称为nought)的数或者比另外一个数大一的数。这样,我们就有了一个没有界限的数的集合:<number> ::= 0 | 1 + <number>。 这些为0或者比另外一个数大一的数,可以用来计数。两数相加,我们不停把第一个数减一,第二个数加一,直到第二个数为0,然后第一个数就是和了: 4 + 2 = 5 + 1 = 6 + 0 = 6

  • many:“more than two in number”。

想象一台这样的机器:他追踪两个数,两数分别加一减一,然后判断有数是否为nought。

  • computer:一台至少能做到上述功能的机器叫做电脑。我们要思考:如果两个数的输入输出都没错,电脑能不能正确的输出答案(显然上面的计数机器可以)。某种意义上,所有的电脑都是一样的,这当然要归功于Alan Turing和Alonzo Church。

  • vocabulary:词的集合叫做词典。

  • language:词典和规则的组合叫做语言,该规则由听者所能理解的短句组成。

  • define:当你定义一个词,就意味着要把它加到你自己和其他听到这个词的人的词典中,然后你才能使用它。

  • program:列一个你要做的事情和要做的选择的单子,然后交给电脑做。这样的单子就叫做程序。

我们通过在动词的尾部加ing来表示动词完成的动作(一个名词)所以我们有了programming这个词: <noun> ::= <verb stem> “ing”

  • programming language:是一种我们用来告诉电脑运行一段程序的语言。

  • definition:在一段代码中定义一个新词以便其他部分的代码使用。不是所有的编程语言都可以写definition,但是大部分都可以。(那些不能的语言是给菜鸡用的)

编程语言是小型的好还是大型的好?小的语言学的快。大的语言可能一开始学的慢,不过后来用起来就方便了,因为你手上现成的或者脑中的新词汇已经能信手拈来了。如果学小的语言,一开是没啥可用的,你得先定义一堆新的词,然后才有的用。

我们通过在动词的末尾加ed或者d来表示过去时态,同样的我们在方法我们还可以定义过去分词: <verb> ::= <verb stem> “ed” | <verb stem> “d” <past participle> ::= <verb stem> “ed” | <verb stem> “d”

这里,我想展示下用小型的语言是什么样的感觉,你们已经感受到了。接下来必须再定义一些新的词。

  • example:通过展示一堆东西中的一个,来知道所有东西的共同点。

  • syllable:嘴和舌头能同时发出的声音叫做音节。每个词都由一个或一个以上的音节组成。

  • primitive:可以随意说,大家都知道意思的词。

这里,我选择那些只有一个音节的词作为primitive,并且选英语作为演讲用语言。这个演讲最重要的规则就是:要用那些由两个及两个以上音节组成的词,我得先定义它们。这样可以一下只定义一个词,你们已经见过了,也可以通过设置某个规则来一下定义一堆词,你们也见过了。这就是为啥演讲开始我要先定义woman,而且可以随意用man这个词,又用person来定义machine,用“a man or a woman”来定义person。通常,像man这种只有一个音节的词我们把它当作primitive,而woman这种有两个音节的词就需要先定义它了,在非英语的语言里,man和woman可能都只有一个音节或者都有两个以上的音节,那就需要其他法子来定义了。

真正编程的时候这种事经常发生:你以为你想的东西是primitive,结果对程序语言来说就不是,需要在每个新程序里都需要重新定义一遍。max就是一个很好的例子(用来获取两个数中更大的那一个数),我觉得它就是primitive,结果很少的程序语言把它当作primitive,每次都需要我重新定义。这种事让电脑看起来像一个只有4岁大的小孩。相比英语,所有的程序语言都是小型语言;我们写代码的时候,经常需要停下来定义一些东西以便以后重复使用。许多人发现他们的代码里真正工作的的代码只有一小段,其他的都是一堆用来定义新词的代码。

我希望大家能用心来感受这个演讲—感受怎么编程、生命(生活?)的真相以及怎么使用小型语言,而不是只是想想而已。每次做这种演讲我都得先定义一些词才能真正开始,换句话说,你要真想用一门小型语言,就得先让它大起来。

有时我们在形容词后面加er比在前面加more更加优雅。举个例子:用“smoother”代替“more smooth”,用better代替“more good” <word that change what a noun means> ::= <word that change what a noun means> “er” | “r”

事实上,单音节的词有很多,可以表达的东西也很多,比Charles Kay Ogden在1930年定义的Basic English还多。我没选Basic English作为演讲用语言,因为它有很多词是由两个或两个以上音节组成的,而且它有很少的词汇,作为小型语言,它没能给说完整英语的人以自由。

随便说明,接下来我会用because这个词来表示“for the cause that”。

如果你看看英语,再看看程序语言,他们都显得很小。同理,在某些情况下,我们可以说这个程序语言比另外一个程序语言要更小。

  • design:构建一个东西的计划叫做设计,想构建的东西可能现实中不存在,也可能好点儿,构建的是现实世界可以存在的东西。

这里我最想表达的问题就是:如果我要设计一个程序语言给程序员用,我是应该设计一个小型语言,还是大型语言呢?我坚持这个观点:既不应该设计一个小型语言,也不应该设计一个大型语言,而是应该设计一门可以成长的语言。我需要操心的只是它成长的方向,当然,要留给其他人选择的余地。这不是个新点子,我们早就知道一个庞大的程序是不可能从头开始都设计好并一下完成的,它必须的有一个成长的计划。我们现在面临的问题是:程序语言已经发展到一个庞大的体积,一个不能从一开始就设计好的庞大体积。

暂停一下,让我定义一些新的词:Twenty是2个ten。Thirty是3个ten。Forty是2个twenty。Hundred是ten乘以ten。Million是hundred乘以hundred再乘以hundred。Eleven是ten加one。Thirteen是ten加上three。Fourteen是ten加上four。Sixteen是2个eight。Seven是one加上six。Fifty是7^2加1。还有一个: ago意为“in the past, as one counts back from now.”

以前,想设计一门一劳永逸的完整语言是不会被质疑的。Fortran是一门40年前为处理数字而设计的小型语言,表现很好。PL/I在30年前看前来很庞大,不过现在再看来就很小了。Pascal 25年前被设计成一门小型的、完整的、再也不加新特性的语言。

后来他们都怎么样了呢?

Fortran不停发展,加了许多新的语法和规则,而且新特性完美融入。但是对于那些从Fortran发布就开始用的人来说,它变了,不再是那个人见人爱的Fortran了,变得奇怪了。

PL/I没怎么发展,大部分和他刚发布的时候一样,可能是用的人少导致的。不过从另一方面看,用的人少是有两个原因的,第一:PL/I从设计上就没有设计成一门可以成长的语言,而是一门完整的、给程序员从头开始写代码的语言。第二:PL/I从设计初就是一门非常庞大的语言,有人说没有人知道它的一切,跟甚者说没有人能知道它的一切。

Pascal发展了一点点,被用来设计很多大型程序。设计初它有个很大的错误:字符串很难用,因为它是定长的。如果Pascal不改变这点的话,将永远不能用来设计真正的大型程序。但是Wirth没有打算修改,事实上,Pascal改的东西很少。

有时我们认为C语言是一个凭空产生的小型语言。但是,它却是从B语言发展而来的,并且又发展成另外一个大型语言C++。像C++这种巨大的语言是不可能传播开来的,除非一下子强加于整个世界。C语言本该很难移植的(?)。

新规则:在动词末尾加“er”来表示做那件事的人或物,举个例子,buyer是买东西的人,user是用户: <noun> ::= <verb stem> “er”

大家可能已经看出来了,我的想法和我的好友Dick Gabriel是一样的,他是家喻户晓的“Worse is better”文章的作者。那篇文章的主旨是:要想一门语言被大家使用的最好方法不是设计构建一门“适当的语言”,因为那会花很长时间。现实里满是缺点的小型语言会打败设计完美的语言,因为用户不会浪费时间等待最好的东西,而是忍受缺点去用快捷方便的语言。一旦用小的语言用爽了,再让用户转变就难了。

那么,“适当的语言”不能即小、又不难移植而且没有缺点吗?

我猜可能会实现,不过我就没那么聪明来实现了(或者说没那么好运了)。其实,我觉得不可能。25年前,用户不想用某个“完美的”语言,他还有的选,Scheme是最好的选择之一。但是现在的用户才不会抢着用那些还没Scheme或者Pascal功能多的语言呢。他们需要在屏幕上画点、线、面;需要同复印机和服务器交流;需要随时加载代码;需要代码和其他人的不可信的代码一起运行;需要代码在多个线程多个机器上同时运行;需要处理全世界不同语言的文字和语音。一门小型语言根本不够用。

那么,如果小型语言不能胜任,大型语言又要花很长时间设计发展才能真正使用,那我们就陷入只能用满是缺点的small语言的困境了吗,就因为整个世界就只有一种能设计小型语言的方法吗?这个问题曾经笼罩着我,但是后来我灵光一闪:我知道用户不会浪费时间等“适当的语言”,而去用满是缺点的新语言,但是,用户不会一直容忍缺点的。用户很快就会哭着喊着要求改缺点。小型语言终会成长,缺点终会被修复。一个人干所有的事,成长会很慢,但如果让用户来帮忙,成长就快了。如果大家齐心协力,选出那些最好的东西,很快就能加很多功能了。

APL由一人设计,一个聪明的人,我喜欢APL,但是它有一个致命的瑕疵:用户不能帮助它平滑的成长。大多数语言,都支持用户自定义看起来像primitive的新词来代替一段代码以便以后使用,这样用户就能以自己的方式构建一门满足需求的庞大语言。但是,APL里用户定义的新词一点都不像primitive。一段代码的名字是个词,但是内建的东西却是由奇怪的符号组成。要想自己定义primitive,需要一堆麻烦的工作,这样用户就不愿意帮助语言发展了。APL发展了一点点,但实际工作却是有几个有源码的人完成的。如果一个用户向APL加了东西,而且负责人觉得不错,把它加到内建的功能里,但其他用户用起来就不是一样的了,还得先变成其他的形式,因为:APL内建的代码和用户调用的代码完全不一样。

Lisp由一人设计,一个聪明的人,但我觉得Lisp并没像他设计的那样运行。Lisp里,用户定义的新词和primitive长的差不多,事实上,所有的primitive长的都像用户定义的词!换句话说,如果一个用户擅长定义新词,那么最终出现的会是一个没有接口的large语言。负责设计的人可以完全不用参考他的代码,只需要从其他人的代码中仔细挑选就可以了。Lisp比APL发展快了许多,因为许多人都尝试并提供了最好的代码供别人使用。现在Lisp已经用的不多了,不过Lisp的部分特性依然活在其他语言当中,其中最著名的就是垃圾回收机制了(garbage collection)。

所以我说,从现在开始,设计一门语言的最主要目标是一个成长、发展的计划。一门语言必须从小开始,随着用户量的增长而发展。作为一个参与Java语言设计的语言设计者,我觉得我不能再问“Java应不应该成长?”了,而是“Java应该怎么成长?”,成长的类型和方法有很多种,但是我们可以看出,如果目标是速度而不是质量,那一种成长模式可能要比有许多模式要好上很多。语言的成长有两种方式,一个是改词典,另一个是改语法。

  • library:设计加入一门程序语言中使其词典变大的词典。Libaries意为很多词典。一个真正的词典不应该改变语法,而只是加入新的词汇。(所以,我认为,C里那种做“long jump”的代码不是真正的library)。当然,很多语言都可以让用户制定libraries,但是重点是:library里新定义的词应该看起来和语言里的primitive一样。一些语言是这样的,有些不是,那些不是的语言成长要难的许多。也有很多加语法的方法,有好有坏,但不管怎样,新的设计一定要和用户定义的一样,如此,用户能贡献更多的话,我也很乐意帮助Java语言成长。

同样,成长也有两种方法,一种是由一人负责测试、评判、加入功能。另一种是把所有的源码放出去由人随意修改。相比两种方法,前者因为有人掌控进度可能很慢,后者则因为没有人负责使得把大家的工作成果加在一起变得更难。最好的两全其美的办法就是:把源码放出去让人修改,由一个人来负责迅速评判出好的、加入,并推出。你可以不用发布的东西,也不必收回自己发布的代码,这样就给大家提供了一个快速传播代码的途径。最好的例子就是Linux,一个操作系统,也是一段程序,负责追踪电脑里的其他程序并分配给他们应得的空间和时间。你应该读读Eric Raymond写的关于Linux怎么来的不得不说的故事,我会告诉你,不过我得先定义两个词。

  • cathedral:一个巨大的教堂,它可能由石头搭建,可能让让人敬畏,不过Eric Raymond认为最重要的是:它只有一个设计、只有一个可能花很长时间或者许多年的宏伟的计划。计划不随着时间的推移而改变;设计者的设计也不因教堂由很多人建造而改变。

  • bazaar:有很多商店的摊位的地方叫做集市,在集市,你可以买商人的商品。最重要的点是:卖家卖自己想卖的,买家买自己想买的,大家可以随时改变主意,没有一个特定的计划。

Eric Raymond写了一篇关于他如何构建程序的文章,名字叫做“The Cathedral and the Bazaar”。讲述了他是怎么在200多号人的帮助下写出了一个邮件接收程序的故事。他引用了Fred Brooks的名言:“More users find more bugs”,又用成功用bazaar风格构建程序的例子来证明自己的观点。有好的点子是不错,不过作为管事的人,在其他人的代码中亲眼看到要好的很多。如此,万事皆可成。Linux也以相同的方式到达了现在的高度和荣耀,不过规模要更大。(有可能有人能靠自己的热情,整天泡在打字机上,把偶然出现的好的代码合在一起,最终写出了个操作系统,不过可惜的是,要花很长的时间。)

bazaar故事的重点不是:你能和很多人一起完成一项任务,cathedral的建造者也得到了许多帮助;也不是你能在设计和建造上都能得到帮助,尽管听起来不错;而是,以bazaar风格构建程序或者设计语言,能满足用户的需求:能实时改变。这样,能确保用户不流失;如果用户知道自己的需求得到了重视、自己的辛勤工作能让设计向更好的方向发展,他们会更加愉悦的努力工作、贡献帮助。

终于到了这次演讲的重点。似乎这几年,谁要谈到设计,谁就得引用Christopher Alexander的名言。他的作品我了解一些,不过不多。这里就得谢谢我的好友Dick Gabriel,指出我得引用一段和我演讲主题密切相关的话。其实我不知道这段引用啥意思,因为Christopher Alexander用了好多有一个音节以上的单词,而且没有定义它们。不过还好我死记硬背住了,希望能给大家有所帮助。

Christopher Alexander says: Master plans have two additional unhealthy characteristics. To begin with,the existence of a master plan alienates the users . . . After all, the very exis-tence of a master plan means, by definition, that the members of the community can have little impact on the future shape of their community, because mostof the important decisions have already been made. In a sense, under a master plan people are living with a frozen future, able to affect only relatively trivial details. When people lose the sense of responsibility for the environment they live in, and realize that they are merely cogs in someone else’s machine, how can they feel any sense of identification with the community, or any sense of purpose there?

某种程度上,我觉得文章要表达的是:要给用户一个加入和帮助的机会,这样对大家都有好处。其实好多cathedral都是用bazaar模式建造的。是不是这样就意味着设计本身就没有意义呢?当然不是, 应该提供设计之法,而不是设计本身。终于可以讲你们都想听的了:

  • pattern:一个由很多组成部分的设计,而且每部分互相影响、独立;每部分都有自己的工作,它们互相帮助,也可能拉对方下水;每部分最终合在一起组成一个pattern;这个pattern可能是为了更高的目标而设计,或者是另一个更大的pattern的一部分。pattern应该给用户提示,一个关于何时何地用才能发挥最大功用的提示。而且,一个pattern应该有多余的空位,以便以后加新东西。一个好的pattern会随着时间的推移告诉大家怎么修改自己。有的变化已经作为pattern的一部分加进去了,有的变化还在等待某天被人用。这样,pattern就代表一个你能做选择的设计空间,一个成长变化的道路。

设计一样东西很好,但设计一个pattern更好,最好的就是知道什么时候用pattern。

到了定义些有关电脑的词汇的时候了。

  • datum:一组有意义的资料;data:一堆datum的合名词。

  • object:一个datum,它的组成部分的意思由一组语言规则决定,下文译作对象。在Java语言当中,语言规则使用类型来区别出一个对象的哪一部分引用了另外一个对象。对象可以分组来组成类,了解一个对象对应的类可以帮助你知晓大部分有关这个对象的操作。对象可以有字段,每个字段都可以储存一个datum,这个datum储存的值可以随着时间的变化而改变。每个字段都有一个类型,类型告诉你什么data可以在运行的时候存储在字段当中(还有,哪些不能)。

  • method:一个对象当中命名好的一段代码叫做方法,如果你能命名或者引用一个对象,那么你就能调用那个对象的方法,然后方法开始做自己应该做的事情。

java语言有对象、类、字段、方法、类型。现在我得说说java没有的东西了。

  • generic type:范型是一个从一个类型或者一堆类型到一个类型的映射,换句话说,范型是一个构建类型的pattern。人们设计的四种给java加范型支持的方法,各有各的特色。

  • operator:运算符是一个符号,比如加号,可以用在一门语言当中,就像是一个词一样,C和java如同英语一样,“and per se and”是个操作符,但是句号和引号就不是了。

  • overloaded:如果一个词有两个或两个以上的意思,听者得从上下文来判断词的意思,这就叫重载。举个例子,根据之前演讲定于的规则,“painted”可能是过去时态,也可能是过去分词,理解则取决于听者你们。另一个例子是“design”,即使一个名词也是一个动词。有些时候,一些人,称重载为多态(polymorphic),意味一个词有很多形式,但是其实它只有一个形式,只不过有很多意思罢了。一个词的定义可能多态,但是词本身不是。c++里操作符可以重载,现在java还不支持这一点,虽然方法名可以重载,我以后会改的。

以前我说过,现在也同样会说,给java加范型支持和运算符重载是件好事。用户用自定义方法应该就像用内建方法一样,用自定义操作符应该就像用内建操作符一样。而且,我喜欢那些小的类,它们的对象可以随意复制,可以放在栈里来加快速度,而不只是能放在堆里,这样的类用起来很舒服,就像用户定义的数字类型也可以有其它用途一样,详情参照James Gosling的网站。(还有其他要加的东西,比如尾递归、读写机器标志位里的浮点数,不过相比范型和运算符重载,就小巫见大巫了。)

如果我们用这几种方法来发展一门语言,那就不需要其他的众多方法了,用户会解决剩下的东西,让我来举几个例子来告诉你为啥。

complex number:复数由两个数组成,有一些规则决定了复数之间如何相加和相乘。比如(a,b)+(c,d)=(a+c,b+d),ab组合加上cd组合相当于ac、bd相加的组合。(a,b)+(c,d)=(a+c,b+d),同理ab组合乘以cd组合相当于ac、bd相乘的组合。有些程序员经常用到复数,不过大多数程序员根本用不到复数。我们应该把复数加到Java中吗?

interval:区间也由两个数组成,同样有规则(当然与复数的规则不同啦)决定了区间如何相加和相乘。(a,b)+(c,d)=(a+c,b+d),(a,b)(c,d)=(min(ac,ad,bc,bd),max(ac,ad,bc,b*d))。极少的程序员经常用到区间而且他们希望全部跟数打交道的人都用区间,但是大多数的程序员更本用不上复数。那我们应不应该把区间作为一个类型加到Java中呢?

John Horton Conway曾经设计了一个有关游戏的游戏,他指出有些游戏可以想象成一个数字,代表这要走几步才能赢得游戏的数字。规则决定了如何算出两个游戏的和,由此他得到了预知好几百个现实游戏当中哪个玩家会赢的方法。我觉得,知道这个东西的世界上不会超过三人。那我们应该把他当作一个类型加到Java当中吗?

vector:矢量是由相同类型的数组成的一行数,每个位置都由我们先前定义的number来命名。它提供有两种方法把两个长为三的矢量相乘,简直欢乐无限。长为三或四的矢量在绘制类似现实世界的数据的时候特别有用。我们应该把矢量作为一个类型加到Java当中吗?

matrix:矩阵是一个外型是正方形的一堆数字,当然它也有一堆规则。我们应该把矩阵作为一个类型加到Java当中吗?

这样的例子还有很多很多。对这些问题,你都可能说可以,不过,很明显,我的答案是:不行!不只是我这样认为,James Gosing和Bill Joy也是如此。 对Java语言来说,这些类型显得太多了。有些词适合大家用,有些词只是方便有些人自己。这样只是为了一些小众需求,而加重所有人学习负担的事情对大家来说是不公平的。教堂模式和平淡放纵的bazaar模式对Java来说都不行,我么需要东西更像一个购物中心,虽然选择不多但至少东西是好的。

现在,用户能为这些数字定义对象,对象里的方法也能正确运行,但是,要用这些数字的时候,代码可能看起来很奇怪。习惯用加号来把两个数字相加的人可能就会抱怨。(Java有一个叫大整数的类,提供了诸如相加、相比等方法,这里你就不能用加号来把两数相加,用到此类的程序员就会抱怨。)范型和运算符重载能让程序员写出上面这些类型,而且这些类型看起来就像内建的一样。这样用户能帮助Java语言平滑、干净的成长。不知是数字,范型也有很多其他的用途,比如对写哈希表就很有帮助。用户不必每个人都自己实现这些类来供自己用,当一门程序语言给你适当的工具,一些人可以写好这些类,然后以库(libraries)的形式提供给其他人用,或者,提供选择。并不需要把这些类型加到Java当中。

给人一条鱼,他能吃一天。

教人如何钓鱼,他能吃鱼吃一辈子。

给人以工具,他能造出鱼杆—和其它的许多工具!他可以造出一个制造鱼杆的机器,这样他就能帮其他人抓鱼了。

meta意为从自己的位置后退一步,从现在可以看出你过去的习惯,从你的行为可以看出你是什么样的人。动词变名词(?)。你以前认为是模式(pattern)的,现在要重新审视为一件放入其它模式的模式。meta foo是一个可以放进foo的foo。以前,传统的语言设计是程序的模式,现在我们需要将其meta化(go meta),我们应该把语言设计当作语言设计的一个模式,一个为了造更多工具的工具。

这就是我要讲的关键,语言设计不再是一件东西,而是一个模式,一个为了语言成长而设计的模式;一个为了模式自己成长的模式;一个为了让程序员可以定义新的模式来完成自己的工作、目标的模式。我想说的是:现今,一名优秀的程序员不应该只是写程序,还要构建可以用的字典。换句话说,一名优秀的程序员要做语言设计,不是从头开始设计一门语言,而是在另外一门基础语言上做设计。演讲开始的时候,鉴于我用使用的是small语言,我定义了十五余个新词、短语还有十六个人名、物品;又规定了六个从旧词定义新词的规则,这样,我就可以向基础语言中加东西。如果我要写一本书,而且只用一个音节的词来写,我敢肯定我得先定义几百个新词。要写一个一百万行代码的程序,不用说,大家都知道代码里有很多很多新词:一个新的语言构建在一门基础语言之上。我敢确定只有这一种可行的方法,当然,非要说的话还有另外一个方法,就是用一个数十年或数百年发展而来的巨大的、丰富的程序语言,里面有我们需要的一切,我们随着语言的发展而成长,加了很多随意加的东西。我只能说,可能几百年后出现了一门程序语言,它通过了时间的考研、能满足大部分需求而不需要改变、所有程序员都用它因为它是每个人在学校学的东西。但是,我们离那时候还远着呢。

所以说,语言设计已经不再像二十、三十年前那样了。以前,你,或者你的团队,能从头到尾设计、维护一门语言,因为它很小,你能做的改变也很小。现在,程序复杂而且程序员的需求多到爆,这么小的语言根本不够用,而且你要是想一劳永逸的设计、构建一门巨大的语言,你是会失败的,因为你会延期,最终,其它小型语言会取代你的。

最终方案就是:设计成长的计划,同时从用户那里得到帮助。你能得到帮助,同时用户能把自己的需求和语言成长结合,对你和用户来说是双赢。你也需要一些人或一些小组来负责评测、移植用户的代码,并把那些好的加到语言当中,其它用户可能会相信你加的代码,这样,他们就不用再为了自己的需求而对每段代码都评测、移植了。语言的一部分必须为了帮助语言成长而设计。一些好的类型、用户定义新类型的方法、用户加新词和新规则的方法、用户定义和使用各种模式的方法,这些都是必须的。设计者不应该做诸如在语言中定义二十种数字类型的事,可能有用户求着要用这么多的数字类型,这时语言本身就应该有让用户定义数字类型的方法,并且这些数字类型能正常工作、有加号和其他符号、有各种读写字符的方法。一开始你可以只定义一到两个数字类型,展示给用户定义数字类型的方法,剩下的交给用户就行了。有时为了发布迅速,需要在设计里加上瑕疵,并设定以后去除的目标。瑕疵何时都有,是无法避免的,但如果处理得当的话,设计的瑕疵可以在日后轻松的去除或者修复,否则,你会数年都卡在一个不在计划内的缺点上。瑕疵不是缺点,而是为日后添加优点留的空位。如果你选择日后再加优点的做法,要确保当时机成熟时,其他部分的设计不会影响添加。

讲了这么多就是希望大家能忍受现在Java语言。因为Java设计为小型语言,它迄今为止表现还好,Java不难学也不难移植,Java也成长了不少。我敢肯定,如果Java语言按照12年前而不是现在的方式来设计的话,它早就失败了,程序员会抱怨“Too Big!Too much hair!I can’t deal with all that!”但是事实上Java表现很好,用户同Java一同成长,他们一点点学习。用户因为可以发表对语言成长的意见所以对Java买账。现在Java需要变大一些,但不要太多。至少一点新规则是需要的,剩下做成libraries就好了,大多数的库是由用户写的,而不是sun公司。如果我们向Java中加了数百个新东西,是会得到一个巨大的语言,但这要花很长的时间。如果我们只加了一点东西——范型,运算符重载,和轻量级的用户自定义类型,比如矢量之类的能让他们按照自己的需求制造、加入的类型,就能发展的更快更远。我们需要给用户提供语言发展的工具。我希望我们能通过这样的方法或其他的方法设计一门不需要花大部分时间谈论一个音节的词的程序语言。

有关短的词我能想到的唯一有点就是可以做短的演讲,我这个演讲本来要一个半小时,现在不到一个小时就完了。

我想告诉你们我从设计这个演讲学到了什么。放弃用那些从小到大学到的意义丰富的长词汇,我让本该简单的演讲变得难以理解,希望你们还没发现这一点吧。但是从遵守这个规则,我思考了许多。我花了很多时间思考如何措辞。面对每个新词都有个选择:是花功夫定义它,还是就用现成的词划算。我是定义一个诸如“mirror”的新词,还是每次提到它都用“looking glass”。

小时候从,我从一些诸如Strunk and White的好书中学到了:尽可能的使用短词汇。不应该用那些复杂的长词汇来让别人觉得你知道的很多,尝试清晰的表达你的思想,如果你表达的清晰明确,人们就能客观的评价你的工作了。这个演讲中,我就前所未有的更加遵从这条规则,大部分情况下都是正确的,短词汇的确表现很好,当然只要你选的好。所以我觉得程序语言也应该像我用的语言一样,说不定就很好呢。

总的来说,如果那些控制我们生活的人——那些高层的管理国家的人、那些评价我们工作的人、那些大多数是来定制法律的人,都用一个音节的词来定义条款,一切都会变的很美好。我发现这种模式的演讲让一切变得难以维护,需要花功夫、精力、技巧来找到表达你想表达东西的正确方式,但是到最后,选择似乎不多了,实话自然就实说了。If you do not veer wide of the truth, you are forced to hit it dead on。

我劝你也来试试吧。