
Tail-call optimization added to 6to5 compiler - insertion
https://github.com/6to5/6to5/pull/714
======
jarcane
I was literally complaining today about the fact that no-one seems to have yet
implemented that part of the ES6 standard yet[1], and yet now here it is.

As someone chiefly interested in .js for it's 'functional curious' side, the
new features in ES6 have me really excited.

~~~
yoshuaw
Which parts of es6 would you call 'functional curious'?

~~~
kaonashi
With destructuring and tco, the only thing its really missing is pattern
matching on multiple function bodies.

~~~
jarcane
This is the single biggest thing I miss from Haskell when programming in other
languages.

Pattern-matching and guards are crazy useful.

------
billburcham
Best part, from the actual commit[1]:

    
    
      Showing  24 changed files  with 182 additions and 214 deletions.
    

More lines _deleted_ than added.

[1]
[https://github.com/6to5/6to5/pull/714/files](https://github.com/6to5/6to5/pull/714/files)

------
sebastianmck
Available as of 3.5.0. Happy to answer any questions if anyone has any!

------
jabbrass
[http://jsperf.com/tco/8](http://jsperf.com/tco/8)

~~~
Silhouette
Thanks for sharing the benchmarks.

I'm not sure how 6to5, or any other transpiler, could do much better. The job
these tools exist to do necessarily means they can't do better than what
today's browsers' JS engines will support.

Presumably in due course browsers will provide ES6 natively and so be better
able to optimise code that uses tail calls in this way. Still, it's important
to realise that the 6to5 implementation is _much_ slower, and more of a
forward-compatible stepping stone if you need it than something to use
routinely if you like a functional programming style.

~~~
jabbrass
Ingvar Stepanyan, author of the original 6to5 pull request has finished
submitting a series of further optimizations via
[https://github.com/6to5/6to5/pull/736](https://github.com/6to5/6to5/pull/736).

I'm clocking a 110-215X performance boost: 1,255,700 - 2,384,556 ops/sec! (on
Chrome and Firefox alpha builds respectively) Check out the new JSPerf:
[http://jsperf.com/tco/17](http://jsperf.com/tco/17)

~~~
Silhouette
That's quite a speed-up, isn't it? It looks like the newly optimised version
of 6to5 effectively inlines the tail call, similar to the way a real compiler
would, and so avoids function call overheads altogether. Smart move. I hadn't
realised the processing done by transpilers like 6to5 was so sophisticated,
and I have even more respect for their developers now than I already did.

------
smrtinsert
I wonder if this implementation idea is general enough that it could be added
to clojure anr script.

~~~
tsmarsh
Clojure has recur, which is tail recursion that detects not being in the tail.
I prefer that to implicit tails with quiet , expensive fails like scheme.

~~~
dragonwriter
Tail _call_ optimization is more than optimized tail _recursion_.

Recur provides an explicit form of support for the latter, but not the former.

~~~
im2w1l
In practice recursion probably covers most of the cases where it matters.
Corecursion could (if awkwardly) be converted into ordinary recursion.

~~~
DanWaterworth
Corecursion doesn't mean what you think it means. You mean mutual recursion.

~~~
waterhouse
(read this with a mild trollface) Given functions f and g, it is possible to
write them as the same function M. Supply an extra argument called "mode": if
0, then the function behaves like f, and if 1, then the function behaves like
g. If you want to call f or g, call M with the "mode" argument as 0 or 1
respectively. If f and g take different numbers of arguments, let M take the
larger number of arguments, and when you intend to call the function that
takes fewer arguments, supply 0s for the extra args. This should indeed
implement mutual recursion in terms of self-recursion.

The grandparent commenter did say "Corecursion could (if awkwardly) be
converted into ordinary recursion", which I would say is technically correct,
which some say is the best kind of correct. (Perhaps he has a somewhat less
awkward scheme in mind.)

~~~
dllthomas
You seem to be talking about mutual recursion.

[http://en.wikipedia.org/wiki/Corecursion](http://en.wikipedia.org/wiki/Corecursion)

[http://en.wikipedia.org/wiki/Mutual_recursion](http://en.wikipedia.org/wiki/Mutual_recursion)

