views:

315

answers:

7

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?

+2  A: 
  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.
Kevin Peterson
Whether programmers understand continuations or not depends on the goals of the language. Obviously this would be a bad thing for Cobol or Java. But for a language like Scheme or Haskell it isn't a factor.
Jonathan Arkell
A: 

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

Brian
Yes, but in a lot of ways, call/cc is kinda similar to the return statement. Every once in a while, people get upset by the use of return, but most people seem to be OK with it. It seems only fair to me that if you're going to complain about call/cc you should also be giving equal time to the return statement on principle.
Bob Aman
`lambda` is the goto of functional programming (example: http://www.cs.brown.edu/~sk/Publications/Talks/SwineBeforePerl/)
Eli Barzilay
That's a gross oversimplification.
Jonathan Arkell
Logically it's true that return is a type of continuation call. However, it is a very constrained and easy-to-understand use of the concept. This is what generally distinguishes such specialized language constructs from call/cc, they are constrained in their functionality enough that you have a pretty good idea of what they're doing the moment you see them. If you're using call/cc you'd better be commenting your code real carefully because it's often quite non-obvious what it's supposed to do.
Nate C-K
A: 

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.

Martin DeMello
Please note that the question is about a language feature, not the quality of its various implementations.
Vijay Mathew
+3  A: 

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.

Jonathan Arkell
+4  A: 

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.

Mike Ashley
+5  A: 

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.

Nate C-K
+1  A: 

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

Charles Stewart