
All About Recursion and Tail Calls in JavaScript - blacksmythe
http://lucasfcosta.com/2017/05/08/All-About-Recursion-PTC-TCO-and-STC-in-JavaScript.html
======
xg15
What I don't understand with STCs is, how would I, as a developer, decide when
to use them and when not?

As program correctness is concerned, tail calls and recursive calls should
behave exactly the same (except stack use), so going by correctness alone,
either the choice doesn't matter at all or tail calls are preferable. So the
logical thing to do would be to always use tail calls.

The post goes on to list a number of disadvantages, but those seem to be
either debugging concerns or platform-specific implementation concerns.

The former doesn't seem to be something that should be solved in the code -
the document itself lists a number of solutions. The latter is not something
that I as developer could judge as I likely don't have knowledge about the
specific implementation of the platform the code is running on (if I know the
platform in advance at all)

So it seems to me, STC shifts the problem of deciding to the developer even
though the developer has no good tools to actually solve it.

~~~
ecma_horse
You absolutely should have knowledge of your target platform and whether it
does TCO (and whether it kicks in for your code).

Otherwise, you may decide to just use recursion everywhere and then your stack
overflows when your N is bigger than expected.

When in doubt, don't use recursion and don't expect that you get TCO.

~~~
xg15
> _You absolutely should have knowledge of your target platform and whether it
> does TCO_

If I write web apps, as far as I'm concerned, my platform is V8,
Whatevermonkey, Trident and every other hypothetical​ javascript engine out
there, any of which might or might not support TCO under different
circumstances.

> _When in doubt, don 't use recursion and don't expect that you get TCO._

I think _relying_ on TCO is always a bad idea, exactly because you can't be
sure your platform supports it. But STC doesn't change that. You can't expect
the platform to support tail calls because you did some magic incantations.

On the other hand, it doesn't make sense to me to _forbid_ tail calls either.
If you know your recursive code will work without TCO, it will work with TCO,
too.

------
holmberd
Until ES6 which introduces Tail Call Optimization, you can use trampolines.

Small summary code:
[http://paste.ubuntu.com/24568118/](http://paste.ubuntu.com/24568118/)

~~~
devrandomguy
Trampoline would make a nice addition to Ramda. Unless I'm missing it under an
unexpected name?

[http://ramdajs.com/](http://ramdajs.com/)

------
Kholo
What's the best way to benchmark perf optimizations in JavaScript. I see lot
of articles like this with no time and memory usage stats. I would like to
hear an answer from someone who has experience using gdb or visual studio
while studying performance. Whenever I use the chrome debugger to time
anything involving async calls and recursion I have this uncomfortable feeling
I am not getting it right. With gdb or visual studio C/C# I always feel like I
know what is going on.

~~~
fenomas
Having worked on this pretty extensively, my preferred method is: (1) make two
implementations of the function I'm trying to speed up, (2) add a wrapper so
half of that function's calls get sent to each version, and then (3) profile
in Chrome and compare the results (particularly the time spent in the two
alternate implementations, but overall as well).

I know that's not the gdb-like experience you're looking for, but as far as
I've found it's the best approach. The issue is that modern JS engines achieve
their speed by tracking what happens at runtime and dynamically re-optimizing
hot functions - so microbenchmarks are largely meaningless, and the
performance of a given function can hugely affected by code that's far away.

(The above is for everyday. For extreme deep-diving, one can use JS engine
tools to see what kind of internal representation your code has been compiled
into after it got optimized. In chrome this is done with IRHydra -
[http://mrale.ph/irhydra/2/](http://mrale.ph/irhydra/2/) .)

~~~
Kholo
Thanks for link. Didn't know this was possible. Also will try your wrapper
approach.

------
cpeterso
JavaScript TCO can't be feature detected so how do you know when tail calls
are safe to use in front end or library code that can run on a variety of
clients?

~~~
ecma_horse
You don't. Assume you don't get it. Right now, chances are you don't get it
anyway.

------
wcummings
Which js implementations currently support TCO?

~~~
olliej
Javascriptcore (so all the webkits :) )

