Hacker News new | past | comments | ask | show | jobs | submit login
No more tail calls in Javascript? (lambda-the-ultimate.org)
35 points by soundsop on Oct 12, 2008 | hide | past | favorite | 13 comments



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.


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.


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.


...and POOF! Ruby on Rails' RJS templates rolled-up into an 11-dimensional ball and vanished...


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.


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...


> 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.


that's a huge step back for computing.

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


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.


I know you are being sincere in raising your doubts, but please keep this in mind: Even if you do not receive 100 arguments and careful essays explaining the value of TCO and comparing inductive vs. iterative algorithms, that doesn't mean that those arguments do not exist.

It's just that Language feature X is clearly unnecessary because Language Y has feature Z instead, and I'm perfectly happy programming in Y has been raised, refuted, defended, and debated so many times that the people with the most experience arguing either side of it are the ones who are least likely to consider trotting it out again productive, and the people with the least experience are most likely to find arguing it again productive and intellectually rewarding.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: