来源:周神的博客 | Rockjins Blog
原文:http://byfat.xxx/if-hemingway-wrote-javascript
在写第一行代码很久以前,我就酷爱文学。现在,我写JavaScript,不计其数。我正在写一本关于JavaScript的书。
JavaScript凭啥能吸引那么多文艺青年?说到它有限的语法所具备的表达潜能,我倒是有几点不成熟的想法,不过那是另外一个话题了。哎,如果那些大作家都喜欢上JavaScript,会咋样?你说他们会用JavaScript写出点什么东西来?作为海明威的十足拥趸,我的第一反应也是这老爷子不可能喜欢编程序(包括程序员)。话虽如此,我还是愿意相信在对它的各种非议中,其实潜藏着足以打动人心的一点:它是一门很文艺的语言,你说呢?它表面上简单粗陋、平淡无奇,而实质上却引人入胜、内涵十足。
代码审查之母
前些天,我做了一个梦。梦见我让海明威还有其他四位作家给我写点JavaScript,特别是得写一个能返回指定长度斐波纳契数列的函数。我发现这些作家解决问题的方法各有千秋,很有意思。不过确实都写得不错,至少都实现了既定的功能(连安德烈·布勒东都写出来了)。下面就是他们交给我的作业。
欧内斯特·海明威(美国作家)
function fibonacci(size) {
var first = 0, second = 1, next, count = 2, result = [first, second];
if(size < 2)
return "the request was made but it was not good"
while(count++ < size) {
next = first + second;
first = second;
second = next;
result.push(next);
}
return result;
}
毫不奇怪。海明威的代码非常凝练,没有浪费一个词一个变量。代码没什么出奇之处,甚至显得有点迂腐,可这正是海明威作品的长处。没有烦琐的逻辑,也没有花里胡哨的变量名。就那么简单直白地把活儿干了,干完完事儿。
海明威没心情跟傻瓜逗闷子,如果你想要的是一个长度小于2的数列,他根本不睬你:“我累啦,你的问题很白痴。”
威廉·莎士比亚(英国诗人、作家)
function theSeriesOfFIBONACCI(theSize) {
//a CALCKULATION in two acts.
//employ'ng the humourous logick of JAVA-SCRIPTE
//Dramatis Personae
var theResult; //an ARRAY to contain THE NUMBERS
var theCounter; //a NUMBER, serv'nt to the FOR LOOP
//ACT I: in which a ZERO is added for INITIATION
//[ENTER: theResult]
//Upon the noble list bestow a zero
var theResult = [0];
//ACT II: a LOOP in which the final TWO NUMBERS are QUEREED and SUMM'D
//[ENTER: theCounter]
//Commence at one and venture o'er the numbers
for (theCounter = 1; theCounter < theSize; theCounter++) {
//By divination set adjoining members
theResult[theCounter] = (theResult[theCounter-1]||1) + theResult[Math.max(0, theCounter-2)];
}
//'Tis done, and here's the answer.
return theResult;
//[Exuent]
}
这位文豪啰嗦了点,可也是独树一帜了。注意他的注释(不算场名和台本),典型的英文抑扬格五音步格律——共十对音节,每音步(两个音节)的重音都落在第二个音节上。在他的戏剧中,莎士比亚经常会脱离严格的抑扬格五音步格律以示强调,比如增加一个音节,或者采用交替重音。在这个编程作业中,他好像也运用了同样的技巧。码如其文。
安德烈·布勒东(Andre Breton,法国诗人和评论家,超现实主义创始人之一)
function Colette(umbrella) {
var staircase = 0, galleons = 0, brigantines = 1, armada = [galleons, brigantines], bassoon;
Array.prototype.embrace = [].push;
while(2 + staircase++ < umbrella) {
bassoon = galleons + brigantines;
armada.embrace(brigantines = (galleons = brigantines, bassoon));
}
return armada;
}
作为超现实主义运动的倡导者,布勒东主张梦想比现实更有趣,应该作为创作的出发点。他的变量命名颇具超现实主义色彩。尽管并非无可挑剔,但他的作品的确几近完美,真挚又美好。在他有意识的表达中,蕴含着一幅无意识的梦幻图景。可以把这个作业看成华美诗篇Facteur Cheval的再创作。
布勒东在这个斐波纳契函数中总是喜欢使用老相好的名字,他把结果想象成了一个史前舰队。他的方案逻辑优雅,巧妙地采用了逗号运算符在galleons、brigantines和bassoons之间同时迁移元素。向安德烈致敬!
罗贝托·波拉尼奥(Roberto Bolano,智利诗人和小说家)
function LeonardoPisanoBigollo(l) {
if(l < 0) {
return "I'd prefer not to respond. (Although several replies occur to me)"
}
/**/
//Everything is getting complicated.
for (var i=2,r=[0,1].slice(0,l);i
如果这辈子没看过波拉尼奥的著作,那你的生命是不完整的。波拉尼奥的作品忽而精于事故,忽而憨态可掬,让人叹为观止。他的叙事风格以毫无悬念的坦诚见长。人类的弱点始终存在,但温暖幽默地传达出每一个弱点,却无不令人沉醉、催人振奋。
一如既往,他的编程作业也流露出了一种不安、局促和无知。他给出的解答尽管颇显才情,可总让人觉得有几分累赘。偏执依旧,跑题依旧,他好像更愿意向我们展示似乎很有意思,但其实毫无用处的天才数学家名录。
以下几方面也是波拉尼奥的特点,比如长短段并列、忘记加分号(对应着他小说中缺失的引号),以及隐含地使用全局变量——暗示每个变量注定会在后续章节中再次现身。
查尔斯·狄更斯
function mrFibbowicksNumbers(enormity) {
var assortment = [0,1,1], tally = 3, artfulRatio = 1.61803;
while(tally++ < enormity) {
//here is an exceedingly clever device
assortment.push(Math.round(assortment[tally-2] * artfulRatio));
}
//should there be an overabundance of elements, a remedy need be applied
return assortment.slice(0, enormity);
}
我不是狄更斯的粉丝。我基本同意亨利·詹姆斯(美国著名小说家和批评家)的恶评:
“要是让我们冒险评价一下他的文学成就,可以称他为最肤浅的小说家。没错,这么说等于把它归入了他所处的文学领域的低等行列,但我们愿意承认这一点。把狄更斯先生归入最伟大的小说家之列,我们是过意不去的。因为他除了人物角色,并没有创造其他任何东西。他没有对我们理解人物角色多给任何资料。”
——亨利·詹姆斯谈查尔斯·狄更斯,评《我们共同的朋友》,1865年12月21日
他的肤浅从他的斐波纳契作业中可见一斑。没错,变量名还算中规中矩,但却是他无法把握实质性内容和内心理解不到位的表现。他没有从实质上领会斐波纳契数列的含义,倒是一心想通过乘法解决问题。哎。
最终点评
不管是老道(Crockford)的极力维护,还是干巴巴的计算机科学课,条条框框始终是JavaScript的敌人。有些开发者喜欢手册和样板,结果就是Java。JavaScript的趣味性源自它天性就不刻板,以及由此生发的无限可能。自然语言也具有相似的特点。最好的作者和最优秀的JavaScript开发者一定会对这门语言神魂颠倒,没有一天不在探索和实践它,从而塑造自己的风格、自己的习惯,还有自己的表达方式。
就这些,希望你喜欢。恐怕大都是无稽之谈。