babel-plugin-tailcall-optimization
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:
{ if n === 0 return acc else return }
gets rewritten to this:
{ 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.
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.