如果讓莎士比亞、海明威編寫JavaScript程式碼

csdn發表於2013-07-12

  本文作者Angus Croll是Twitter工程師、JavaScript迷、文學迷,並且非常喜歡作家海明威。他在夢中"夢見"一些名人編寫JavaScript程式碼,不同的作家呈現出各種程式設計風格,大家不妨一起來品嚐下。

 

  下面是對原文的摘譯。

  最近,我做了一個夢,我請海明威和其他四位文學名人替我編寫JavaScript程式碼,一個函式返回一個給定長度的斐波納契數列。有趣地是,他們每個人都以不同的方式完成了這一題,並且都做的很好——只是我想說,每個解決方案工作起來都好比廣告(即使是Andre Breton的),後來我又請包括海明威在內的7名文豪用JavaScript來編寫階乘,似乎一切都那麼神奇,但他們都成功地完成了,大家不妨來看看結果吧。 

  一、實現斐波納契數列

  1.歐內斯特·海明威(Ernest Hemingway 美國作家)

  代表作:《老人與海》《太陽照樣升起》《永別了,武器》《喪鐘為誰而鳴》

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.威廉·莎士比亞(William Shakespeare 英國詩人、戲劇家

  代表作: 《哈姆雷特》《奧賽羅》《李爾王》《羅密歐與朱麗葉》等

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]
}

  大家可以看看莎士比亞是如何使用抑揚格五音步編寫註釋的。熟悉他戲劇的朋友應該對抑揚格五音步非常熟悉吧。

  3.安德烈·布勒東(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;
}

  整個解決方案的邏輯非常清晰、優雅,在galleons、brigantines、bassoons這三個之間,使用逗號操作符對它們進行同時轉移。

  4.羅貝託·波拉尼奧(Roberto Bolano 智利小說家、詩人)

  代表作:《荒野偵探》《2666》

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<l;r.push(r[i-1]+r[i-2]),i++)
  /**/
  //Here are some other mathematicians. Mostly it's just nonsense.
  rationalTheorists = ["Archimedes of Syracuse", "Pierre de Fermat (such margins, boys!)", "Srinivasa Ramanujan", "Rene Descartes", "Leonhard Euler", "Carl Gauss", "Johann Bernoulli", "Jacob Bernoulli", "Aryabhata", "Brahmagupta", "Bhaskara II", "Nilakantha Somayaji", "Omar Khayyám", "Muhammad ibn Mūsā al-Khwārizmī", "Bernhard Riemann", "Gottfried Leibniz", "Andrey Kolmogorov", "Euclid of Alexandria", "Jules Henri Poincaré", "Srinivasa Ramanujan", "Alexander Grothendieck (who could forget?)", "David Hilbert", "Alan Turing", "von Neumann", "Kurt Gödel", "Joseph-Louis Lagrange", "Georg Cantor", "William Rowan Hamilton", "Carl Jacobi", "Évariste Galois", "Nikolay Lobachevsky", "Rene Descartes", "Joseph Fourier", "Pierre-Simon Laplace", "Alonzo Church", "Nikolay Bogolyubov"]
  /**/
  //I didn't understand any of this, but here it is anyway.
  return r
  /**/
  //Nothing happens here and if it does I'd rather not talk about it.
}

  長短不齊的段落,缺少分號,使用隱式全域性變數——對每一個變數都做進一步深入的說明。

  5. 查爾斯·狄更斯(Charles Dickens 英國小說家)

  代表作:《匹克威克外傳》《霧都孤兒》《 雙城記 》等

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);
}

  從程式碼中可以看出,他沒有體會到斐波那契數列的基本理念,而是採用乘法解決。程式碼裡也有些有趣的命名,但缺乏核心地理解。

  二、實現factorial(n)階乘

  以上是這些著名的作家用JavaScript編寫斐波那契數列,下面再讓我們看看,作家們是如何用JavaScript/CoffeeScript編寫factorial(n)的。

  1. 傑克·凱魯亞克(Jack Kerouac 美國小說家)

  代表作:《在路上》《販毒者》等

/*...the only numbers for me are the mad ones, take forty-three like a
steam engine with a talky caboose at the end*/ n = 43, /*and that lanky
fellow in a cocked fedora*/ r = 1 /*then back to our number, our mad
number, mad to become one*/ while (n > 1) /*mad to descend*/ n--, /*mad
to multiply*/ r = r * n /*and at the end, you see the blue center-light
pop, and everybody goes 1.4050061177528801e+51...*/
r

  上面程式碼只能返回43的階乘,如果想要實現另一個數的階乘,你還需重寫程式碼。不過,最值得注意地是,註釋和程式碼幾乎沒有區別,無法分辨,從側面反映了Kerouac的風格,很長、狂野和狂想式的流露。

  2.塞繆爾·約翰遜(Samuel Johnson 英國作家、詩人)

  代表作:《英語大辭典》《倫敦》《人類慾望的虛幻》等

# In which various NUMBERS are summon'd by
# means of ELECTRONICK CONJURY
factorial = (n) ->
   # All argument is against it; yet all belief is for it
   return 1 unless n
   # Ingenious sophistry to prove the palp'bly OBVIOUS
   return 1 if n is 1
   # Recursion (n.)
   # a program that calls 'pon itself in the manner of
   # a dog returning unto its VOMIT
   return n * factorial n - 1

  整段程式碼比較稀疏,中間也摻雜著Johnson的精言妙語:其中,他也對factorial(0)應該為1進行了懷疑,他應該用一個完整的句子來表達factorial(1)就是1,從其字典裡進行推測,完成了一個具有諷刺定義的遞迴解除。

  Johnson的整個解決方案充滿著藝術和模仿的結合——帶有整潔表示式地溫和的自我嘲諷和真正美麗的混合。

  3.詹姆斯·喬伊斯(James Joyce 愛爾蘭作家、詩人)

  代表作:《尤利西斯》

function hacktorial(integette) {
  var nonthings = [undefined, null, false, 0, '', NaN];
  var resultution = 1;

  if (integette == 0) {
    //behold the strangerous zeroine!
    resultution = 1;
  } else {
    while (integette > 1)
    //caligulate by multicapables
    resultution = resultution * integette--;
  }
  with(resultution) {
    var duodismal =  Function('return this').call(toString(12));
    var disemvowel = Function("n","return n?parseInt(n,12):'0'")
    return [
      disemvowel(duodismal.slice(0,-1)),
      'shillings and',
      disemvowel(duodismal[duodismal.length-1]), 'pence'
    ].join(' ');
  }
  //klikkaklakkaklaskaklopatzklatschabattacreppycrottygraddahappluddyappladdypkonpkot!
}

  Joyce不僅僅是解決了階乘問題,前半部分程式碼已經解決了這個問題,但Joyce堅決把結果轉換為當時的貨幣:先令和便士。

  結果:

hacktorial(3) //"0 shillings and 6 pence"
hacktorial(4) //"2 shillings and 0 pence"
hacktorial(7) //"420 shillings and 0 pence"
hacktorial(21) //"4257578514309120000 shillings and 0 pence"

  4.理查德·費曼(Richard Feynman美國物理學家)

  代表作:《費曼物理學講義》《物理之美》

//using Ramanujan's approximation
function fractorail(n){
  with(Math) {
    var r = sqrt(PI)*pow(n/E,n);
    r *= pow(8*pow(n, 3) + 4*(n*n) + n + 1/30, 1/6);
    return r;
  }
}

  費曼的工作的特點是具有大膽的創意和非常古怪的才華,從它所編寫的這段程式碼中也能看出。

  結果,不要擔心一些“舍入誤差”,如果你非常熟悉JavaScript,你就應該知道:

fractorail(3); //6.00005
fractorail(1.1); //1.04671
fractorail(5.2); //169.40628

  5. 阿瑟·柯南·道爾(Arthur Conan Doyle世界著名小說家)

  代表作:《福爾摩斯探案集》《失落的世界》

"use strict";
//In solving a problem of this sort, the grand thing is to be able to reason backwards...
//some things are easier known than explained!
var caseHistory = new Object({2:2, 6:3});
function unfactorial(evidence){
    //first, humility!
    if (evidence === 1) {
      return "Watson, I am at a loss!"
    }
    //second, logical precedence!
    if(caseHistory[evidence]){
      //elementary!
      return caseHistory[evidence];
    }
    //third, eliminate the impossible!
    if(evidence === 0 || evidence % 24 !== 0) {
      return "charlatans!";
    }
    //fourth, deduction!
    var theDeduction, enumarator = evidence, denominator = 1;
    while(enumarator % denominator === 0) {
      enumarator = enumarator/denominator++;
      if (enumarator === denominator) {
        theDeduction = enumarator;
      }
    }
    theDeduction = theDeduction || "impostors";
    //What one man can invent another can discover!
    caseHistory[evidence] = theDeduction;
    //What remains, however improbable, must be the truth!
    return theDeduction;
}

  正如大家想象的那樣, 柯南道爾的設計過程是精確和認真有序的,此外,大家可能注意到,他讓其應用程式在strict模式執行——容不得半點馬虎。

  6.簡·奧斯汀(Jane Austen 英國小說家)

  代表作:《理智與情感》 《傲慢與偏見》

factorial = (function() {
  //I declare...
  var ledger = {};
  return function reckoning(quantity) {
    if (isNaN(quantity)) {
      console.log("I have not the pleasure of understanding you");
      return;
    }
    //It is a truth universally acknowledged that two values
    //can only be adjudged truly agreeable by means of ===
    if (quantity === 0) {
      return 1;
    }
    //Mr Crockford teaches that we be wary of inherited property...
    if (ledger.hasOwnProperty(quantity)) {
      return ledger[quantity];
    }
    //Pray persist until an answer is furnished
    return ledger[quantity] = quantity * reckoning(quantity - 1);
  };
})();

  Jane Austen解決方案的亮點之一是程式碼工藝和結構的完整性,主要體現在程式碼塊的整潔上,她呼叫模組模式,隱藏曆史資料(或ledger)在上層結構的資料夾裡;第二個則是體現了Jane Austen的俏皮,甚至是顛覆性的,對power的諷刺和荒謬的約定。

  7. 歐內斯特·海明威(Ernest Hemingway 美國小說家)

  代表作:《老人與海》《太陽照樣升起》等

//Economy.
function factorial(n) {
  return n < 2 ? 1: factorial(n-1)*n;
}

  程式碼足以說明一切。

  我們從中所學到的

  這些著名的小說家、詩人、戲劇家的偉大之處在於他們勇於開拓新方式,嘗試新的技術並且打破我們一直所遵循的規律。

最優秀的英語作傢俱有著對規則的蔑視。——Steven Pinker

  JavaScript作為最流行的程式語言之一,它的進步取決於開發者們地大膽創新、研究以及發現新模式,這樣才能惠及更多的人。

  各位開發者們,如果讓你們喜歡的作家來編寫JavaScript程式碼會是啥樣呢?不妨一起探討下吧。

  英文來源:Angus Croll部落格

相關文章