Continuation-passing and tail call elimination
NeXT logo by Paul Rand
Logo Morph
Apple Logo Evolution
What does KISS stand for?
Logo Design History
 
Continuation passing style in JavaScript or Callbacks
by Matthew Parke, JavaScript/Web Developer


Continuation passing style in JavaScript or Callbacks
What is the advantage of continuation passing style in JavaScript?

I'm going to base my answer off the wiki on continuation passing for the definition: http://en.wikipedia.org/wiki/Con... "a function which is meant to receive the result of the computation performed".

Starting with what a continuation is: commonly referred to as a callback in JavaScript, it is a function that allows you to execute code asynchronously. This means that you can ask a function to do something for you and have it in turn execute another function ( the callback you passed as a parameter ) only when it's finished. This allows the main program flow to continue while your function with the callback is busy doing something.

One example advantage I can give you is handling data exchange, such as getting data from an Ajax call. You know you want to execute something when your data returns, but you can't be certain when your data will return, and you also don't want to hold up the rest of your program while it waits. So you give the Ajax call a callback. As soon as your data gets back, the function executes, while the rest of your program is busy at work doing whatever else the user wanted.

Scheme's call-with-current-continuation function makes it possible to capture a computation, a state of the call stack as it were, and resume that same state at a later time. On top of such a primitive, various form of exception handling and C-like longjmp tricks can be implemented.

Another issue that you should be aware of is that, since continuation-passing functions never really return, and JavaScript implementations do not typically provide 'tail-call' optimisation, it is possible to blow the call stack when you have too many such functions calling each other without resetting the stack through setTimout or a callback. In my experience this rarely becomes a problem, but when it does you can add a strategic setTimout of zero milliseconds to reset the stack manually.

Finally, JavaScript is notoriously sluggish about function calls, and all these extra calls will not exactly make your scripts run faster. Most JavaScript programs do not take up a noticeable amount of CPU time, but for some heavy-handed scripts this extra overhead might be a problem.

So I do not recommend anyone to go ahead and convert his entire code-base to continuation-passing style. There are scripts, however, especially those making lots of requests to a server, that will benefit from such a transformation. It is never necessary to convert every function. Only those that might get 'interrupted' (or call other functions that might get interrupted) benefit from having a first-class continuation.