
Hello all I recently saw a video on call/cc in Scheme, where call/cc was used inside an expression and call/cc faithfully figured out the rest of the computation. I tried the same in haskell, but was bitten badly. Then I looked at the type signature and learned that call/cc only works inside a continuation monad (if I am not mistaken). Is this correct and why is that so? Are scheme's call/cc and haskell's callCC semantically different?

Is this correct and why is that so? Are scheme's call/cc and haskell's callCC semantically different?
Yes, Haskell's `callCC` is a user defined function and Scheme's is a magical primitive. Under the hood Scheme should behave as if *every* expression lived inside the continuation monad. The Haskell equivalent would be something morally equivalent to foo :: Cont r Int foo = callCC $ \cont -> (+) <$> cont 1 <*> pure 1 Also, to do a lot of the fun games we can play with Scheme's call/cc, we need ContT r IO vs plain old Cont. For example, this program works "as expected" and returns 1 foo :: ContT r IO Int foo = do ref <- lift (newIORef undefined) result <- callCC $ \c -> lift (writeIORef ref c) >> pure False if not result then lift (readIORef ref) >>= ($ True) >> return 0 else return 1

martin
Hello all
I recently saw a video on call/cc in Scheme, where call/cc was used inside an expression and call/cc faithfully figured out the rest of the computation.
I tried the same in haskell, but was bitten badly. Then I looked at the type signature and learned that call/cc only works inside a continuation monad (if I am not mistaken).
Is this correct and why is that so? Are scheme's call/cc and haskell's callCC semantically different?
The ContT monad transformer provides "delimited continuations," aka "composable continuations" or "partial continuations." These are much easier to use and reason about than global continuations. A continuation reified by callCC can be reused as a regular monadic action; it won't disrupt the entire program's evaluation. There's an Oleg article [1] that argues against Scheme's call/cc as a "bad abstraction" for numerous reasons. I believe it's good Scheme coding practice to avoid this operator in favor of some construction for delimited continuations, such as shift & reset, though standard Scheme only specifies call/cc. Oleg says: | Undelimited continuations by themselves seem to have no practical use: | at least noone has shown me a practical application of just call/cc, | which I have been asking for a long time. To my knowledge, in all | practical programs call/cc emulates, to the extent possible, some sort | of a delimited control operation, often as simple as exceptions or | generators. Scheme seems to retain call/cc mostly by inertia. [1]: http://okmij.org/ftp/continuations/against-callcc.html
participants (3)
-
Danny Gratzer
-
martin
-
Mikael Brockman