3

I think I understand what Promises are about, and I think I understand what continuations are about, but I still fail to see what their connection is. In what ways do Promises use Continuations. They never return, which is explained by the fact that they use Continuations, but I don't see when and why they do the "jump" which is so characteristic when working with Continuations.

  • 1
    I don't feel confident enough to give an answer, but here's an idea: Continuations are a universal control flow construct like GOTO – "universal" meaning "all control flow (including but not limited to GOTO, subroutine calls, conditionals, exceptions, generators, coroutines, threads, promises, futures, tasks, spores, …) can be expressed in terms of continuations". Since most languages don't support GOTO and don't have reified stacks, Continuations are the way to implement Promises. – Jörg W Mittag Jan 28 '17 at 2:05
4

TL;DR

The code that is executed after a synchronous call to a function becomes the continuation that you pass to a promise when you call the same function asynchronously.

Detailed illustration

To give you some intuition, here is how a piece of synchronous code is transformed to a piece of asynchronous code. The whole answer is written informally, with no particular programming language in mind.

Synchronous code:

actionsBeforeCall();
x = computeSomething();
actionsAfterCall(x);

This illustrates schematically, that there is some code before your call, then the call which can return a value x, and then some other code that may depend on the result of the call through variable x. Of course there may be more than one variable (x, y, etc) or no variable at all but the actions after the call depend on some global state that has been left behind by computeSomething().

If you want to execute the call asynchronously, you can create a promise:

actionsBeforeCall();
p = promise(computeSomething);

A promise is an object that represents a computation that will complete some time in the future, so the thread that started the asynchronous computation can still have a handle to communicate with it. Now the main thread will not stop waiting for the asynchronous function to terminate, because it is running asynchronously. So we have two problems:

  1. How does the main thread tell the asynchronous computation what to do when it completes?
  2. How does the asynchronous computation return its result: it is now decoupled from the thread that called it and it cannot return any value.

A continuation solves both problems:

  1. It is a function that must be invoked when the asynchronous computation completes.
  2. The continuation takes an argument x that represents the result returned by computeSomething. Alternatively, it accesses some global variables to fetch the result produced by computeSomething.

So in the main thread you write

actionsBeforeCall();
p = promise(computeSomething);
p.onComplete(actionsAfterCall)

The last line means: when computeSomething is finished, call the function actionsAfterCall with the result. In turn, actionsAfterCall must take an input argument, so that the promise can internally do something like:

x = computeSomething()

...

actionsAfterCall(x)

An important point is that in asynchronous computations you do not return result values. Instead, you pass the result of a computation to a continuation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.