Question

What are some of the criticisms leveled against exposing continuations as first class objects?

I feel that it is good to have first class continuations. It allow complete control over the execution flow of instructions. Advanced programmers can develop intuitive solutions to certain kind of problems. For instance, continuations are used to manage state on web servers. A language implementation can provide useful abstractions on top of continuations. For example, green threads.

Despite all these, are there strong arguments against first class continuations?

Was it helpful?

Solution

First up, there is more then just call/cc when it comes to continuation. I suggest starting with Mark Feelys paper: A better API for first class continuations

Next up I suggest reading about the control operators shift and reset, which is a different way of representing contunations.

OTHER TIPS

The reality is that many of the useful situations where you could use continuations are already covered by specialized language constructs: throw/catch, return, C#/Python yield. Thus, language implementers don't really have all that much incentive to provide them in a generalized form usable for roll-your-own solutions.

In some languages, generalized continuations are quite hard to implement efficiently. Stack-based languages (i.e. most languages) basically have to copy the whole stack every time you create a continuation.

Those languages can implement certain continuation-like features, those that don't break the basic stack-based model, a lot more efficiently than the general case, but implementing generalized continuations is quite a bit harder and not worth it.

Functional languages are more likely to implement continuations for a couple of reasons:

  1. They are frequently implemented in continuation passing style, which means the "call stack" is probably a linked list allocated on the heap. This makes it trivial to pass a pointer to the stack as a continuation, since you don't need to overwrite the stack context when you pop the current frame and push a new one. (I've never implemented CPS but that's my understanding of it.)
  2. They favor immutable data bindings, which make your old continuation a lot more useful because you will not have altered the contents of variables that the stack pointed to when you created it.

For these reasons, continuations are likely to remain mostly just in the domain of functional languages.

A significant objection is implementation cost. If the runtime uses a stack, then first-class continuations require a stack copy at some point. The copy cost can be controlled (see Representing Control in the Presence of First-Class Continuations for a good strategy), but it also means that mutable variables cannot be allocated on the stack. This isn't an issue for functional or mostly-functional (e.g., Scheme) languages, but this adds significant overhead for OO languages.

  1. Most programmers don't understand them. If you have code that uses them, it's harder to find replacement programmers who will be able to work with it.
  2. Continuations are hard to implement on some platforms. For example, JRuby doesn't support continuations.

First-class continuations undermine the ability to reason about code, especially in languages that allow continuations to be imperatively assigned to variables, because the insides of closures can be brought alive again in hairy ways.

Cf. Kent Pitman's complaint about continuations, about the tricky way that unwind-protect interacts with call/cc

Call/cc is the 'goto' of advanced functional programming (a la the example here).

in ruby 1.8 the implementation was extremely slow. better in 1.9, and of course most schemes have had them built in and performing well from the outset.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top