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.
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.
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
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.
Oh, that is easy to fix. Kill EVAL. I will postulate that EVAL is a much more intrusive thing to have in a language than TCO.
And why kill EVAL? Because it makes it a lot harder to reason about programs and the future mandates we can prove properties about our programs. Better start now than later.
I can't see why you would leave that out of the system.