Unable to enable tail call optimization in node v6.4.0

I will not play with tail call optimization in node / es2015, but I keep getting RangeError: Maximum call stack size exceeded . So I tried a very simple test function:

  function countTo(n, acc) { if(n === 0) { return acc; } return countTo(n - 1, acc + n); } console.log(countTo(100000 , 0)) 

and it still does not work. I tried adding 'use strict'; inside the function body and at the top of the file. I tried using --harmony and --harmony-tailcalls

The same function works as expected in a racket:

 #lang racket (define count-to (lambda (n acc) (cond ((= n 0) acc) (else (count-to (- n 1) (+ acc n)))))) (count-to 100000000 0) ; ~> 5000000050000000 

Edit:

As suggested by @MatthieuLemoine. It works in v6.5.0 + with "use strict"; and either --harmony or --harmony-tailcalls

+6
source share
2 answers

Using node v6.5.0, follow these steps:

 function countTo(n, acc) { 'use strict'; if(n === 0) { return acc; } return countTo(n - 1, acc + n); } console.log(countTo(100000 , 0)); 

Working with the --harmony-tailcalls :

 node --harmony-tailcalls tco.js 
+2
source

You can use the tco module to emulate tail call optimization even on the old node. I will add an example using your code for this answer in a minute.

By changing the code a bit, you can even run 10 million recursion levels:

 var tco = require('tco'); var countTo = tco(function (n, acc) { if (n === 0) { return [null, acc]; } return [countTo, [n - 1, acc + n]]; }); console.log(countTo(10000000, 0)); 

You can use Sweet macros to make them look bigger:

 var countTo = tco(function (n, acc) { if (n === 0) { ret acc; } ret countTo(n - 1, acc + n); }); console.log(countTo(10000000, 0)); 

Which basically changes return to ret , but currently my macros that I used before do not seem to work with the current version of Sweet.js - I have to examine it when I have time.

Disclaimer: I am the author of this module.

+2
source

All Articles