Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

does Babel with the `es2016` preset implement tail call optimization?

I used the following example to test tail call recursion with Babel and the es2016 preset:

'use strict';

try {
    function r(n) {
        if (n%5000===0)
            console.log(`reached a depth of ${n}`);
        r(n+1);
    }
    r(0);
} catch (e) {
    if (!(e instanceof RangeError))
        throw e;
    else
        console.log('stack blown');
}

My package.json file is:

{
    "name": "tail-call-optimization",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "build": "babel es6 --out-dir es5 --source-maps",
        "watch": "babel es6 --out-dir es5 --source-maps --watch",
        "start": "node es5/app.js"
    },
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "babel-cli": "^6.6.5",
        "babel-core": "^6.7.4",
        "babel-loader": "^6.2.4",
        "babel-polyfill": "^6.7.4",
        "babel-preset-es2016": "^6.0.10",
        "babel-runtime": "^6.6.1"
    },
    "dependencies": {
        "babel-polyfill": "^6.7.4",
        "source-map-support": "^0.4.0"
    }
}

... and the .babelrc is simply:

{
    "presets": ["es2016"]
}

Running the above with:

npm run build && npm run start

... results in the following console output:

reached a depth of 0
reached a depth of 5000
reached a depth of 10000
reached a depth of 15000
stack blown

Indeed, looking at the transpiled file in the es5 directory, there's nothing to suggest that TCO has been implemented.

Am I missing something?

My node version is 4.3.2.

like image 630
Marcus Junius Brutus Avatar asked Apr 06 '16 08:04

Marcus Junius Brutus


People also ask

Does gcc do tail call optimization?

Some C compilers, such as gcc and clang, can perform tail call optimization (TCO).

Does JavaScript have tail call optimization?

JavaScript does not (yet) support tail call optimization.

Does Clojure have tail call optimization?

Since Clojure uses the Java calling conventions, it cannot, and does not, make the same tail call optimization guarantees. Instead, it provides the recur special operator, which does constant-space recursive looping by rebinding and jumping to the nearest enclosing loop or function frame.


1 Answers

Looking at: https://babeljs.io/docs/learn-es2015/ one reads:

Temporarily Removed in Babel 6

Only explicit self referencing tail recursion was supported due to the complexity and performance impact of supporting tail calls globally. Removed due to other bugs and will be re-implemented.

So I guess it's not presently implemented.

like image 193
Marcus Junius Brutus Avatar answered Sep 19 '22 06:09

Marcus Junius Brutus