If Kerouac wrote JavaScript (and Dr Johnson wrote CoffeeScript)

(New Book “If Hemingway wrote JavaScript” Now Available)

Last summer I introduced the concept of literary JavaScript with If Hemingway wrote JavaScript in which five well known authors wrote a JavaScript utility to generate the Fibonacci sequence. In May I presented their efforts at JSConf 2013, and to mark the occasion I asked an additional six authors (as well as the irrepressible Hemingway) to solve factorial(n) as only they could. Here’s what they sent me…

Jack Kerouac #

“All of JavaScript is a foreign country” #

/*...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

Kerouac is renowned for his spontaneous, stream-of-consciousness approach to writing, supposedly delivering some works at a single sitting. Since planning is alien to Kerouac’s process, he has no use for functions. His solution will only return the factorial of 43. If you want the factorial of another number, you’ll need to rewrite it.

Notice how comments are virtually indistinguishable from code; to Kerouac it’s all the same – one long, rhapsodic outpouring.

Samuel Johnson #

“When a man is tired of JAVA-SCRIPT, he is tired of LIFE” #

# 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

When I opened Johnson’s completed assignment, I found a short note from the good doctor, explaining why he had chosen to use CoffeeScript: “Sir, the funcktion key-word is an ALBATROSS and the curly brace is worthless FILIGREE. I desire a clean and artickulate script for the dockumenting of my varied MUSINGS”.

And indeed Johnson’s solution radiates sparse elegance, albeit liberally peppered with his own pithy witticisms: he expresses his incredulity that factorial(0) is 1, is amused that it should require an entire statement to ascertain that factorial(1) is indeed 1, and finishes with a sardonic definition of recursion lifted, presumably, from his own dictionary.

Johnson’s solution lies at the intersection of art and parody – a gentle self-mocking blended with uncluttered expression and genuine beauty. A doff of the tricorn to you, Doctor.

James Joyce #

“Writing in JavaScript is the most ingenious torture ever devised for sins committed in previous lives” #

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

OK, where do we start? Joyce is not content with merely solving the problem at hand, he is compelled to turn it into a raucous adventure on the high seas of verbal deviancy.

He continues the Joycean tradition of generating contrived yet intuitive portmanteau words (most abundantly present in Finnegans Wake). Here’s a mini glossary for the Joyce-less among us:

hacktorial–the function is a hack on factorial

integette–indicating that if you don’t use a small integer it’s all ruined

nonthings–for reasons best known to Joyce, our function begins with a declaration of falsey values

resultation–the result of the computation

strangerous–both strange and dangerous

zeroine–our heroine, value 0

caligulate–to calculate, presumably with a liberal dose of tyranny

multicapables–items capable of being multiplied

duodismal–the bleakness that is the duodecimal system (i.e. base 12)
disemvowel–to remove all vowels, or in this case all letters

By the time he’s half way through, the problem is already solved, but Joyce insists on converting the result into the currency of the time: shillings and pence. As with much of Joyce’s work, there’s a degree of method to this madness, since the factorial of every number over 3 is divisible by 12 – which also happens to be the number of pennies in a shilling.

Here’s what we get:

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"

Richard Feynman #

“I never pay attention to anything by experts. I program everything myself.” #

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

Although better known as a maverick scientist, Feynman’s work is characterized by the daring originality and eccentric brilliance that is the hallmark of the greatest authors. His factorial solution is no exception.

Feynman chooses to distance himself from conventional strategies and instead uses a little known approximation which allows him to calculate the factorial of integers and non-integers alike. His boyish delight at this discovery is evident from the playful name he assigns to the function. He also tosses in a delicious with, just to prove the pedants wrong.

Here’s a few factorial’s, Feynman style. Don’t worry about the alleged “rounding errors”, if you’re at all familiar with JavaScript, they’ll likely be a source of comfort to you.

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

Arthur Conan Doyle #

“You know my methods. Apply them” #

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

Conan Doyle is best known as the author of the Sherlock Holmes mysteries and he was clearly in full deer-stalker and magnifying glass mode when solving the case of the hidden factorial.

Or, rather, unfactorial. Because Holmes lives by deduction and his methodology is to work backwards towards the source of the deed – the well worn, predictable process of the factorial holds no mystery for him. Instead Holmes opts to trace those fiendish numbers that seed existing factorial results.

As expected, Holmes’ process is precise and meticulously ordered – clearly he was an early adopter of the imperative approach. Notice he also directs his utility to run in strict mode – he’ll tolerate no sloppiness. He starts with a dose of humility – even the master sleuth cannot be certain which number has a factorial of 1 – but he quickly gains his stride, so that by the end of the exercise he imperiously derides those who would supply false arguments as charlatans and impostors. Case closed Watson.

Jane Austen #

“A programmer, especially if she has the misfortune of knowing anything, should conceal it as well as she can” #

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’s solution demonstrates two pleasing characteristics for which she is justly famous. First there’s her attention to craft and structural integrity, reflected here in the neat packaging of her code – she invokes the module pattern, hiding away the historical data (or ledger) within the folds of the super structure. Second is her playful, even subversive, send-up of the powers that be and their ridiculous conventions.

At first glance Austen’s code appears to be submissive, yielding to every overbearing commandment and pious proclamation set forth by the more pedantic leaders in our community. Yet a closer reading reveals a rich undertone of parody. There are several clues to Austen’s real intent: checking if the argument is a number pokes fun at edge-case mania, her over-embellished commentary suitably ridicules those who insist that == is the devils work, and finally the satirical fawning over the nice Mr Crockford is used as an amusing justification for the all-too-common misuse of hasOwnProperty.

Austen is on top of her game here, simultaneously gaining approval from the purveyors of code dogma, while winking furiously at those who can see beyond the artifice and discern the subtext that ridicules those she purports to follow.

Ernest Hemingway #

“When you stop writing JavaScript for fun you may as well be dead” #

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

Enough said.

What have we learned? #

The greatness of the best novelists, poets and play-writes lies in their readiness to stake out new ground, to pioneer new techniques in writing and in doing so lay the tracks for those who follow.

All the best writers in English have been flagrant flouters of prescriptive rules
– Steven Pinker

As with the best writers, when a good developer breaks a rule, they don’t do so arbitrarily, but because a dubious constraint has formed a barrier to their means of expression. Patterns that were once viewed as dangerous and radical – immediately invoked functions, callbacks and modules – are, thanks to the risk takers, now part of the JavaScript mainstream. The message is clear: the progress of the JavaScript language depends on the willingness of its best developers to take risks, to play, and so discover new patterns and idioms that benefit the community at large.

 
1,857
Kudos
 
1,857
Kudos

Now read this

How to Read a Book

Although Ernest Hemingway’s brilliant 1927 story Hills like White Elephants is only three pages long, there are tens of thousands of pages of academic analysis telling us how to read it. The story itself is little more than tense,... Continue →