Tail call optimization (TCO) in Node v6

Node v6 supports proper tail calls also known as tail call optimization, according to node.green.

What is a tail call?

It’s a function call that is done at the end of a function. Usually, when a function is called, it returns, so the calling function has to be memorized. However, if it’s a tail call, the function doesn’t have to return, or return to the original call in the call chain. Technically, it doesn’t consume stack for tail calls, so there’s no stack overflow.

Example in Node v6

You need to add flags, but this is how it works:

$ node --harmony --use_strict
> function f() { return f(); }
undefined
> f()

It runs forever, just like an infinite loop.

Let’s disable TCO by removing the flags, and see how it goes:

$ node
> function f() { return f(); }
undefined
> f()
RangeError: Maximum call stack size exceeded
at f (repl:1:19)
at f (repl:1:31)
at f (repl:1:31)
at f (repl:1:31)
at f (repl:1:31)
at f (repl:1:31)
at f (repl:1:31)
at f (repl:1:31)
at f (repl:1:31)
at f (repl:1:31)

You can add console.log to see more convincingly.

node --harmony --use_strict 
> function f(x) { console.log(x); return f(x + 1); }
undefined
> f(0)
1
2
3
4
5
6
7
8
9
10
11

And, it continues forever, maybe.

A note

One thing I found, which is the reason of this post, is the following.

function f(x) { console.log(x); f(x + 1); }

This code looks like a proper tail call, but it doesn’t work with Node v6. You need to explicitly add “return” to enable TCO.

Question

Is this expected in the spec?