Difference between revisions of "Continuation"
(Changed the link to YAHT, removed references to hawiki, updated the link to "All about monads") 
m (Added link to orphan "Cont computations [...]" page) 

(8 intermediate revisions by 8 users not shown)  
Line 14:  Line 14:  
==== Functional metaphors ==== 
==== Functional metaphors ==== 

−  * Continuations represent the future of a computation, as a function from an intermediate result to the final result ([http://www.haskell.org/ 
+  * Continuations represent the future of a computation, as a function from an intermediate result to the final result ([http://www.haskell.org/haskellwiki/All_About_Monads#The_Continuation_monad] section in Jeff Newbern's All About Monads) 
−  * The idea behind CPS is to pass around as a function argument what to do next ([http:// 
+  * The idea behind CPS is to pass around as a function argument what to do next ([http://users.umiacs.umd.edu/~hal/docs/daume02yaht.pdf Yet Another Haskell Tutorial] written by Hal Daume III, 4.6 Continuation Passing Style, pp 5356. It can also be read in [http://en.wikibooks.org/wiki/Haskell/YAHT/Type_basics#Continuation_Passing_Style wikified format]). 
* Rather than return the result of a function, pass one or more [[Higher order function  Higher Order Functions]] to determine what to do with the result. Yes, direct sum like things (or in generally, case analysis, managing cases, alternatives) can be implemented in CPS by passing ''more'' continuations. 
* Rather than return the result of a function, pass one or more [[Higher order function  Higher Order Functions]] to determine what to do with the result. Yes, direct sum like things (or in generally, case analysis, managing cases, alternatives) can be implemented in CPS by passing ''more'' continuations. 

Line 97:  Line 97:  
The function <hask>Foreign.C.String.withCString</hask> converts a Haskell string to a C string. 
The function <hask>Foreign.C.String.withCString</hask> converts a Haskell string to a C string. 

−  But it does not provide it for 
+  But it does not provide it for external use but restricts the use of the C string to a subprocedure, 
because it will cleanup the C string after its use. 
because it will cleanup the C string after its use. 

It has signature <hask>withCString :: String > (CString > IO a) > IO a</hask>. 
It has signature <hask>withCString :: String > (CString > IO a) > IO a</hask>. 

Line 104:  Line 104:  
<haskell> 
<haskell> 

multiCont :: [(r > a) > a] > ([r] > a) > a 
multiCont :: [(r > a) > a] > ([r] > a) > a 

−  multiCont xs = runCont ( 
+  multiCont xs = runCont (mapM Cont xs) 
withCStringArray0 :: [String] > (Ptr CString > IO a) > IO a 
withCStringArray0 :: [String] > (Ptr CString > IO a) > IO a 

Line 112:  Line 112:  
(\rs > withArray0 nullPtr rs act) 
(\rs > withArray0 nullPtr rs act) 

</haskell> 
</haskell> 

−  However, the right associativity of <hask> 
+  However, the right associativity of <hask>mapM</hask> leads to inefficiencies here. 
See: 
See: 

Line 151:  Line 151:  
== Continuation monad == 
== Continuation monad == 

−  * Jeff Newbern's [http://haskell.org/ 
+  * Jeff Newbern's [http://www.haskell.org/haskellwiki/All_About_Monads All About Monads] contains a [http://www.haskell.org/haskellwiki/All_About_Monads#The_Continuation_monad section] on it. 
−  * [http://haskell.org/ 
+  * [http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/ControlMonadCont.html Control.Monad.Cont] is contained by Haskell Hierarchical Libraries. 
+  * [[Cont computations as questionanswering boxes<code>Cont</code> computations as questionanswering boxes]] 

== Delimited continuation == 
== Delimited continuation == 

Line 167:  Line 167:  
;[http://okmij.org/ftp/Computation/Continuations.html#zipperfs ZipperFS] 
;[http://okmij.org/ftp/Computation/Continuations.html#zipperfs ZipperFS] 

:Oleg Kiselyov's [[zipper]]based [[Libraries and tools/Operating systemfile server/OS]] where threading and exceptions are all realized via [[Library/CCdelcontdelimited continuation]]s. 
:Oleg Kiselyov's [[zipper]]based [[Libraries and tools/Operating systemfile server/OS]] where threading and exceptions are all realized via [[Library/CCdelcontdelimited continuation]]s. 

+  
+  == Blog Posts == 

+  
+  * [http://www.haskellforall.com/2012/12/thecontinuationmonad.html The Continuation Monad] by Gabriel Gonzalez. 

[[Category:Idioms]] 
[[Category:Idioms]] 
Latest revision as of 05:32, 24 April 2021
Contents
General or introductory materials
Powerful metaphors, images
Here is a collection of short descriptions, analogies or metaphors, that illustrate this difficult concept, or an aspect of it.
Imperative metaphors
 In computing, a continuation is a representation of the execution state of a program (for example, the call stack) at a certain point in time (Wikipedia's Continuation).
 At its heart,
call/cc
is something like thegoto
instruction (or rather, like a label for agoto
instruction); but a Grand High Exaltedgoto
instruction... The point aboutcall/cc
is that it is not a static (lexical)goto
instruction but a dynamic one (David Madore's A page aboutcall/cc
)
Functional metaphors
 Continuations represent the future of a computation, as a function from an intermediate result to the final result ([1] section in Jeff Newbern's All About Monads)
 The idea behind CPS is to pass around as a function argument what to do next (Yet Another Haskell Tutorial written by Hal Daume III, 4.6 Continuation Passing Style, pp 5356. It can also be read in wikified format).
 Rather than return the result of a function, pass one or more Higher Order Functions to determine what to do with the result. Yes, direct sum like things (or in generally, case analysis, managing cases, alternatives) can be implemented in CPS by passing more continuations.
External links
 The appropriate section of Haskell: Functional Programming with Types.
 Wikipedia's Continuation is a surprisingly good introductory material on this topic. See also Continuationpassing style.
 Yet Another Haskell Tutorial written by Hal Daume III contains a section on continuation passing style (4.6 Continuation Passing Style, pp 5356). It can be read also in wikified format, thanks to Eric Kow.
 David Madore's A page about
call/cc
describes the concept, and his The Unlambda Programming Language page shows how he implemented this construct in an esoteric functional programming language.  Continuations section of article Functional Programming For The Rest of Us, an introductory material to functional programming.
 Continuations and delimited control
Examples
Citing haskellized Scheme examples from Wikipedia
Quoting the Scheme examples (with their explanatory texts) from Wikipedia's Continuationpassing style article, but Scheme examples are translated to Haskell, and some straightforward modifications are made to the explanations (e.g. replacing word Scheme with Haskell, or using abbreviated name fac
instead of factorial
).
In the Haskell programming language, the simplest of directstyle functions is the identity function:
id :: a > a
id a = a
which in CPS becomes:
idCPS :: a > (a > r) > r
idCPS a ret = ret a
where ret
is the continuation argument (often also called k
). A further comparison of direct and CPS style is below.
mysqrt :: Floating a => a > a
mysqrt a = sqrt a
print (mysqrt 4) :: IO ()

mysqrtCPS :: a > (a > r) > r
mysqrtCPS a k = k (sqrt a)
mysqrtCPS 4 print :: IO ()

mysqrt 4 + 2 :: Floating a => a

mysqrtCPS 4 (+ 2) :: Floating a => a

fac :: Integral a => a > a
fac 0 = 1
fac n'@(n + 1) = n' * fac n
fac 4 + 2 :: Integral a => a

facCPS :: a > (a > r) > r
facCPS 0 k = k 1
facCPS n'@(n + 1) k = facCPS n $ \ret > k (n' * ret)
facCPS 4 (+ 2) :: Integral a => a

The translations shown above show that CPS is a global transformation; the directstyle factorial, fac
takes, as might be expected, a single argument. The CPS factorial, facCPS
takes two: the argument and a continuation. Any function calling a CPSed function must either provide a new continuation or pass its own; any calls from a CPSed function to a nonCPS function will use implicit continuations. Thus, to ensure the total absence of a function stack, the entire program must be in CPS.
As an exception, mysqrt
calls sqrt
without a continuation — here sqrt
is considered a primitive operator; that is, it is assumed that sqrt
will compute its result in finite time and without abusing the stack. Operations considered primitive for CPS tend to be arithmetic, constructors, accessors, or mutators; any O(1) operation will be considered primitive.
The quotation ends here.
Intermediate structures
The function Foreign.C.String.withCString
converts a Haskell string to a C string.
But it does not provide it for external use but restricts the use of the C string to a subprocedure,
because it will cleanup the C string after its use.
It has signature withCString :: String > (CString > IO a) > IO a
.
This looks like continuation and the functions from continuation monad can be used,
e.g. for allocation of a whole array of pointers:
multiCont :: [(r > a) > a] > ([r] > a) > a
multiCont xs = runCont (mapM Cont xs)
withCStringArray0 :: [String] > (Ptr CString > IO a) > IO a
withCStringArray0 strings act =
multiCont
(map withCString strings)
(\rs > withArray0 nullPtr rs act)
However, the right associativity of mapM
leads to inefficiencies here.
See:
 Cale Gibbard in HaskellCafe on A handy little consequence of the Cont monad
More general examples
Maybe it is confusing, that
 the type of the (noncontinuation) argument of the discussed functions (
idCPS
,mysqrtCPS
,facCPS
)  and the type of the argument of the continuations
coincide in the above examples. It is not a necessity (it does not belong to the essence of the continuation concept), so I try to figure out an example which avoids this confusing coincidence:
newSentence :: Char > Bool
newSentence = flip elem ".?!"
newSentenceCPS :: Char > (Bool > r) > r
newSentenceCPS c k = k (elem c ".?!")
but this is a rather uninteresting example. Let us see another one that uses at least recursion:
mylength :: [a] > Integer
mylength [] = 0
mylength (_ : as) = succ (mylength as)
mylengthCPS :: [a] > (Integer > r) > r
mylengthCPS [] k = k 0
mylengthCPS (_ : as) k = mylengthCPS as (k . succ)
test8 :: Integer
test8 = mylengthCPS [1..2006] id
test9 :: IO ()
test9 = mylengthCPS [1..2006] print
You can download the Haskell source code (the original examples plus the new ones): Continuation.hs.
Continuation monad
 Jeff Newbern's All About Monads contains a section on it.
 Control.Monad.Cont is contained by Haskell Hierarchical Libraries.

Cont
computations as questionanswering boxes
Delimited continuation
 Library/CCdelcont
 Generic Zipper and its applications, writing that "Zipper can be viewed as a delimited continuation reified as a data structure" (links added).
Linguistics
Chris Barker: Continuations in Natural Language
Applications
 ZipperFS
 Oleg Kiselyov's zipperbased file server/OS where threading and exceptions are all realized via delimited continuations.
Blog Posts
 The Continuation Monad by Gabriel Gonzalez.