I wan't to play around 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 fails. I've tried adding 'use strict';
inside the function body and at the top of the file. I've tried using --harmony
and --harmony-tailcalls
The same function works as expected in 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
"use strict";
and either --harmony
or --harmony-tailcalls
Using node v6.5.0, the following works :
function countTo(n, acc) {
'use strict';
if(n === 0) {
return acc;
}
return countTo(n - 1, acc + n);
}
console.log(countTo(100000 , 0));
Running with --harmony-tailcalls
flag :
node --harmony-tailcalls tco.js
You can use the tco module to emulate a tail call optimization even on old node. I'll add an example using your code to this answer in a minute.
Slightly changing your code, you can run even 10 million levels of recursion:
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 it look more like:
var countTo = tco(function (n, acc) {
if (n === 0) {
ret acc;
}
ret countTo(n - 1, acc + n);
});
console.log(countTo(10000000, 0));
Which is basically changing return
to ret
but currently my macros that I used before don't seem to work with the current version of Sweet.js - I have to investigate it when I have some time.
Disclaimer: I'm the author of that module.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With