Programming
javascript continuations callcc continuation-passing
Updated Sun, 29 May 2022 14:48:26 GMT

What's the difference between a continuation and a callback?


I've been browsing all over the web in search of enlightenment about continuations, and it's mind boggling how the simplest of explanations can so utterly confound a JavaScript programmer like myself. This is especially true when most articles explain continuations with code in Scheme or use monads.

Now that I finally think I've understood the essence of continuations I wanted to know whether what I do know is actually the truth. If what I think is true is not actually true, then it's ignorance and not enlightenment.

So, here's what I know:

In almost all languages functions explicitly return values (and control) to their caller. For example:

var sum = add(2, 3);

console.log(sum);

function add(x, y) {
    return x + y;
}



Solution

I believe that continuations are a special case of callbacks. A function may callback any number of functions, any number of times. For example:

var array = [1, 2, 3];

forEach(array, function (element, array, index) {
    array[index] = 2 * element;
});

console.log(array);

function forEach(array, callback) {
    var length = array.length;
    for (var i = 0; i < length; i++)
        callback(array[i], array, i);
}




Comments (5)

  • +0 – I'm so grateful words cannot describe. I finally understood at intuition level all continuation-related concepts in one sweep! I new once it clicked, it was going to be simple and i would see i used the pattern many times before unknowingly, and it was just like that. Thanks so much for the wonderful and clear explanation. — Feb 17, 2014 at 00:33  
  • +2 – Trampolines are fairly simple, yet powerful stuff. Please check Reginald Braithwaite's post about them. — Oct 31, 2015 at 04:26  
  • +1 – Thanks for the answer. I wonder if you could possibly provide more support for the statement that callcc can't be implemented in JavaScript? Possibly an explanation of what JavaScript would need to implement it? — Dec 19, 2015 at 23:17  
  • +1 – @JohnHenry - well, actually there is a call/cc implementation in JavaScript done by Matt Might (matt.might.net/articles/by-example-continuation-passing-style - go to the very last paragraph), but please don't ask me how it works nor how to use it :-) — Dec 30, 2015 at 16:28  
  • +1 – @JohnHenry JS would need first class continuations (think of them as a mechanism to capture certain states of the call stack). But it has only First Class functions and closures, thus CPS is the only way to mimic continuations. In Scheme conts are implicit and part of callcc's job is to "reify" these implicit conts, so that the consuming function has access to them. That's why callcc in Scheme expects a function as the only argument. The CPS version of callcc in JS differs, because the cont is passed as an explicit func argument. So Aadit's callcc is sufficient for a lot of applications. — Jan 21, 2016 at 19:57