views:

1413

answers:

5

I read somewhere where rich hickey said:

"I think continuations might be neat in theory, but not in practice"

I am not familiar with clojure.
1. Does clojure have continuations?
2. If no, dont you need continuations? I have seen a lot of good examples especially from this guy. What is the alternative?
3. If yes, is there a documentation?

+5  A: 

Is continuation a necessary feature in a language?

No. Plenty of languages don't have continuations.

If no, dont you need continuations? I have seen a lot of good examples especially from this guy. What is the alternative?

A call stack

Draemon
+1 for the call stack
Dario
+10  A: 

When talking about continuations, you'll have to distinguish between two different kinds of them:

  • First-class continuations - Continuation-support that is deeply integrated in the language (Scheme or Ruby). I doubt that Clojure supports them.

  • Continuation-passing-style (CPS) - CPS is just a style of coding and any language supporting anonymous function will allow this style (which applies to Clojure too). Example:

    -- Standard function
    double :: Int -> Int
    double x = 2 * x
    
    
    -- CPS-function - We pass the continuation explicitly 
    doubleCPS :: Int -> (Int -> res) -> res
    doubleCPS x cont = cont (2 * x)
    
    
    -- Call
    print (double 2)
    
    
    -- Call CPS: Contintue execution with specified anonymous function
    double 2 (\res -> print res)
    

Read continuation on wikipedia.

I don't think that continuations are necessary for a good language but especially first-class continuations and CPS in functional languages like Haskell can be quite useful (Intelligent backtracking example)

Dario
Regarding the second of your two points, wouldn't tail-call optimisation be required to make CPS usable in the general case? Consider a standard function, which you wrap in a "while (!aborted)" block to make it repeat until aborted. Wouldn't the equivalent use of a CPS-style function be to send it itself as a continuation? Thus you get unbounded recursion and tail-call optimisation would be required. I'm just thinking out loud here, so please tell me if this makes sense :-)
harms
+8  A: 

I've written a Clojure port of cl-cont which adds continuations to Common Lisp.

http://github.com/swannodette/clj-cont/tree/master

dnolen
+2  A: 

A common use of continuations is in the implementation of control structures for: returning from a function, breaking from a loop, exception handling etc. Most languages (like Java, C++ etc) provide these features as part of the core language. Some languages don't (e.g: Scheme). Instead, these languages expose continuatiions as first class objects and let the programmer define new control structures. Thus Scheme should be looked upon as a programming language toolkit, not a complete language in itself.

In Clojure, we almost never need to use continuations directly, because almost all the control structures are provided by the language/VM combination. Still, first class continuations can be a powerful tool in the hands of the competent programmer. Especially in Scheme, continuations are better than the equivalent counterparts in other languages (like the setjmp/longjmp pair in C). This article has more details on this.

BTW, it will be interesting to know how Rich Hickey justifies his opinion about continuations. Any links for that?

Vijay Mathew
What are the features that you need to have in order for a language to be "full"?
kunjaan
It should have been "complete" not "full". When I said "complete" I did not mean Turing complete. I meant the features that people usually expect from "modern" languages. For instance, exception handling using try-catch. Scheme does not provide that, but using first-class continuations you can implement your own exception handling mechanism.
Vijay Mathew
You are now just rambling. But you still have not justified your inane statement: "Scheme should be looked upon as a..toolkit...and not a complete language".
kunjaan
Good Lispers write programs by growing the language towards the problem. In other words, you transform Lisp into a language that is best suited to solve the problem at hand. This is a big difference between Lisps and other languages. Paul Graham explains this in great detail in his book "On Lisp". I don't know who you are or what you do, but I suppose that you haven't written any significant piece of software in Lisp. Otherwise I wouldn't have to explain this. I maintain my own Scheme and use it daily to solve real world problems.
Vijay Mathew
BTW, I don't think it is a good idea to ask someone to explain his viewpoint after calling it "inane rambling".
Vijay Mathew
Re "almost all the control structures are provided by the language/VM combination", you forgot to add that nobody will ever need more than 640kb RAM.
Eli Barzilay
+3  A: 

Clojure (or rather clojure.contrib.monads) has a continuation monad; here's an article that describes its usage and motivation.

pmf