babel-plugin-tailcall-optimization

Tail call optimization for JavaScript!

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
babel-plugin-tailcall-optimization
19022.0.04 years ago6 years agoMinified + gzip package size for babel-plugin-tailcall-optimization in KB

Readme

babel-plugin-tailcall-optimization
JavaScript Style Guide
Tail call optimization for JavaScript!

Installation

if you use babel@6 use babel-plugin-tailcall-optimization@1 package.
npm install babel-plugin-tailcall-optimization --save-dev

and add to your .babelrc:
"plugins": ["tailcall-optimization"]

How does it work?

We rewrite functions with tail calls to ones using while loops. Original function with tail call:
function counter (n, acc = 0) {
  if (n === 0) {
    return acc
  } else {
    return counter(n - 1, acc + 1)
  }
}

gets rewritten to this:
function counter(n, acc = 0) {
  var _repeat = true;

  var _n, _acc;

  while (_repeat) {
    _repeat = false;

    if (n === 0) {
      return acc;
    } else {
      _n = n - 1
      _acc = acc + 1
      n = _n
      acc = _acc
      _repeat = true;
      continue;
    }
  }
}
Plugin does not affect functions without TCOs so it's safe to use.

Benchmarks

For Fibonacci Sequence example
benchmark.js results are:
Fibonacci Sequence without TCO x 270,170 ops/sec ±1.14% (85 runs sampled)
Fibonacci Sequence with TCO x 1,298,276 ops/sec ±1.24% (83 runs sampled)

So function after TCO optimization is almost 5 times faster.
Benchmark code

Known issues

- Currently when plugin detects function creation within tailcalled function it does not optimize it. It's related to difficulties in implementation (function scoping rules). Read more: https://phabricator.babeljs.io/T6869
- It does not work for mutual recursive functions. I guess it's not super big problem - even JVM does not do this.