
No more tail calls in Javascript? - soundsop
http://lambda-the-ultimate.org/node/3047
======
jlouis
I am missing something here if it is considered hard to implement. It is not
that hard to TCO in Scheme or ML, so I must surely be missing some detail that
makes it hard to implement in Javascript.

I can't see why you would leave that out of the system.

~~~
raganwald
Eval is what makes TCO hard to implement in Javascript. It is extremely hard
to perform certain optimizations in an environment where any symbol can be
referenced at any time. If you had a pragma that said "this function never
calls eval or calls anything that calls eval" it would be much simpler.

~~~
febeling
This is interesting, can you expand a bit on this? Scheme has an EVAL as well,
but surely no-one would consider droping TCO there.

~~~
raganwald
I never suggested it is impossible, merely it requires some work from the
ground up. For lack of a better word, features like continuations and TCO are
global, not local rewrites. They aren't bolt-on features like some sort of
optimization stages you throw in on top of an existing implementation.

And that's the political problem here: The implementors don't want to start
with a blank sheet of paper, they want to work from what they already have and
find convenient to build.

You know the expression "Lisp is a black hole?" TCO is one of those massy
features that drags a language inside Scheme's Schwarzschild radius. They will
end up writing a Scheme implementation with JS syntax and DOM support.

They know it and obviously don't want to go there, thus the mealy-mouthed
"this feature is not necessary because we provide the all-powerful for loop
and OO programming." Meanwhile, as the OP points out, the other features they
provide can be written by programmers and supplied in libraries, so they
really are not as essential to the implementers' debate as TCO.

 _Portions of this rant may be Erik Naggum's intellectual offspring, only
misshapen and lacking his insight and biting wit_

~~~
LogicHoleFlaw
One thing I find interesting about Lua is that it has tail-call elimination,
coroutines isomorphic to one-shot continuations, proper lexical scoping, and a
"feel" similar to a (cleaned-up, better thought-out) JavaScript. The language
has an entirely intentional semantic resemblance to Scheme yet seems to orbit
that black hole rather than get sucked in, to abuse the metaphor.

I suspect that one reason it can do this successfully is that the authors are
not afraid to break backwards compatibility with each new major release of the
language. The fact that it is intended to be embedded within an application
which ships with the appropriate revision of the language helps greatly in
this regard.

------
bbb
In my opinion, that's not really such a big deal.

For example, Python does not optimize tail calls, but supports many functional
idioms anyway and is quite pleasant to use.

So, yeah, having tail call optimization be a _mandatory_ part of Javascript
would be cool from a language nerd point of view, but it would have very
little practical impact.

~~~
qwph
Yeah, but, if you can't rely on tail-call optimization, you can't really use
recursion and expect your code to handle any arbitrary amount of data that's
thrown at it. To write robust code, you're forced to use iteration instead.

The difference between O(1) and O(n) memory usage is a big deal, IMHO...

~~~
bbb
> To write robust code, you're forced to use iteration instead.

That's exactly the point. You can use nice functional idioms in Python as long
as you make the main loop(s) that crunch data iterative. Same thing in
Javascript.

Adding tail-call optimization adds little to Javascript; it's nice to have but
has no high return on investment (in terms of the effort you put into the
language vs. what becomes impossible if you omit it).

Case in point: Think of all the criticism directed at Python. The lack of
tail-call optimization is not voiced very frequently.

~~~
ardit33
that's a huge step back for computing.

The point of recursion is that it makes really hard problems simple to solve.

~~~
earthboundkid
It makes some hard problems simple to solve. Other times you end up wasting a
lot of time figuring out how to send the return value to an accumulator
without accidentally creating an infinite loop or doing things twice.

Anyway, in Python you can always fake TCO using decorators. As long as someone
invents the same thing for Javascript, no harm, no foul.

