Skip to content

Instantly share code, notes, and snippets.

@maxbeatty
Last active December 19, 2015 23:09
Show Gist options
  • Save maxbeatty/6032959 to your computer and use it in GitHub Desktop.
Save maxbeatty/6032959 to your computer and use it in GitHub Desktop.

Literate CoffeeScript

Literate Coffeescript allows you to write code as Markdown documents and when compiled, the indented blocks are treated as code and the rest is ignored as comments.

Literate programming is a methodology that combines a programming language with a documentation language, thereby making programs more robust, more portable, more easily maintained, and arguably more fun to write than programs that are written only in a high-level language.

We have a lot of crazy logic because of always-flexible business rules. Writing in a more verbose, natural way to describe why we have an odd snippet of code would make it easier for someone else to come back to later.

Here's a quick example of how we could rewrite for loops that populate an array in a more coffee-like manner

Original:

lineItemUids = []
lineItems.forEach (li) ->
  lineItemUids.push li._data.uid

Compiles to: var lineItemUids;

lineItemUids = [];

lineItems.forEach(function(li) {
    return lineItemUids.push(li._data.uid);
});

Coffescript way:

lineItemUids = (li._data.uid for li in lineItems)

Compiles to:

var li, lineItemUids;

lineItemUids = (function() {
    var _i, _len, _results;
    _results = [];
    for (_i = 0, _len = lineItems.length; _i < _len; _i++) {
        li = lineItems[_i];
        _results.push(li._data.uid);
    }
    return _results;
})();

1/3 of the code and same result. Here are the benchmark results

$ coffee forLoopTest.litcoffee 
native for loop x 1,263,250 ops/sec ±1.14% (93 runs sampled)
coffee for loop x 2,160,374 ops/sec ±1.50% (92 runs sampled)
Fastest is coffee for loop

Pretty neat, huh? The other file in this gist has the test.

Let's benchmark the difference between a native for loop and a more coffee-like one

Benchmark = require 'benchmark'

suite = new Benchmark.Suite

lineItems = (uid: i for i in [1..10])

suite.add('native for loop', ->
  fill = []
  lineItems.forEach (li) ->
    fill.push li.uid
).add('coffee for loop', ->
  fill = (li.uid for li in lineItems)
).on('cycle', (event) ->
  console.log(String(event.target))
).on('complete', ->
  console.log('Fastest is ' + this.filter('fastest').pluck('name'))
).run({ 'async': true })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment