Search code examples
functional-programmingcontinuationsprocedural-programming

Understanding (sub,partial,full,one-shot) continuations (in procedural languages)


After reading almost everything I could find about continuations, I still have trouble understanding them. Maybe because all of the explanations are heavily tied with lambda calculus, which I have trouble understanding.

In general, a continuation is some representation of what to do next, after you have finished doing the current thing, i.e. the rest of the computation.

But then, it gets trickier with all the variety. Maybe some of you could help me out with my custom analogy here and point out where I have made mistakes in my understanding.

Let's say our functions are represented as objects, and for the sake of simplicity:

  1. Our interpreter has a stack of function calls.
  2. Each function call has a stack for local data and arguments.
  3. Each function call has a queue of "instructions" to be executed that operate on the local data stack and the queue itself (and, maybe on the stacks of callers too).

The analogy is meant to be similar to XY concatenative language.

So, in my understanding:

  • A continuation is the rest of the whole computation (this unfinished queue of instructions + stack of all subsequent computations: queues of callers).
  • A partial continuation is the current unfinished queue + some delimited part of the caller stack, up until some point (not the full one, for the whole program).
  • A sub-continuation is the rest of the current instruction queue for currently "active" function.
  • A one-shot continuation is such a continuation that can be executed only once, after being reified into an object.

Please correct me if I am wrong in my analogies.


Solution

  • A continuation is the rest of the whole computation (this unfinished queue of instructions + stack of all subsequent computations: queues of callers)

    Informally, your understanding is correct. However, continuation as a concept is an abstraction of the control state and the state the process should attain if the continuation is invoked. It needs not contain the entire stack explicitly, as long as the state can be attained. This is one of the classical definitions of continuation. Refer to Rhino JavaScript doc.

    A partial continuation is the current unfinished queue + some delimited part of the caller stack, up until some point (not the full one, for the whole program)

    Again, informally, your understanding is correct. It is also called delimited continuation or composable continuation. In this case, not only the process needs to attain the state represented by the delimited continuation, but it also needs to limit the invocation of the continuation to the limit specified. This is in contrast to full continuation, which starts from the point specified and continues to the end of the control flow. Delimited continuation starts from this point and ends in another identified point only. It is a partial control flow and not the full one, which is precisely why delimited continuation needs to return a value (see the Wikipedia article). The value usually represents the result of the partial execution.

    A sub-continuation is the rest of the current instruction queue for currently "active" function

    Your understanding here is slightly hazy. Once way to understand this is to consider a multi-threaded environment. If there is a main thread and a new thread is started from it at some point, then a continuation (from the context of main or child thread), what should it represent? The entire control flow of child and main threads from that point (which in most cases does not make much sense) or just the control flow of the child thread? Sub-continuation is a kind of delimited continuation, the control flow state representation from a point to another point that is part of the sub-process or a sub-process tree. Refer to this paper.

    A one-shot continuation is such a continuation that can be executed only once, after being reified into an object

    As per this paper, your understanding is correct. The paper seems not to explicitly state if this is a full/classical continuation or a delimited one; however, in next sections, the paper states that full continuations are problematic, so I would assume this type of continuation is a delimited continuation.