
Hello, I saw on the haskell wikibook that coroutines could be implemented by using continuations : http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style#Example:_cor..., the section is empty) Since I'm actually learning the wonders of continuations, I just wonder : how ?

On 19/06/10 10:36, Yves Parès wrote:
Hello,
I saw on the haskell wikibook that coroutines could be implemented by using continuations : http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style#Example:_cor... (unhappily, the section is empty) Since I'm actually learning the wonders of continuations, I just wonder : how ?
Coroutines depend on the ability to suspend and resume execution. A continuation acts as the "resume point" in the current function. The "callCC" function in the continuation monad takes a function that expects the continuation as an argument (which is how you get access to it). So you say something like:
yield = callCC $ \continuation -> ....
Then you would typically store the continuation somewhere and call some other previously stored continuation to switch contexts. Continuations can be used to pass data back into the continuation: you call the continuation with an argument, and that argument becomes the return value of the "callCC". In this case you probably just want to use (). You typically have a queue for continuations, so the new continuation goes on the back of the queue and then you call the head of the queue. Obvious modifications for priority, simulated time, real time or whatever else you are trying to schedule. This implies some kind of monadic state to store the queue in, so you will probably make your monad of type "ContT (State Queue)" If you want a thread to wait, say on a semaphore, then you have a queue of continuations in the semaphore data structure. Is this any help? Paul.

It helps me understand better, but would you have some simple code that
would do that ?
2010/6/19 Paul Johnson
On 19/06/10 10:36, Yves Parčs wrote:
Hello,
I saw on the haskell wikibook that coroutines could be implemented by using continuations : http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style#Example:_cor..., the section is empty) Since I'm actually learning the wonders of continuations, I just wonder : how ?
Coroutines depend on the ability to suspend and resume execution. A continuation acts as the "resume point" in the current function. The "callCC" function in the continuation monad takes a function that expects the continuation as an argument (which is how you get access to it). So you say something like:
yield = callCC $ \continuation -> ....
Then you would typically store the continuation somewhere and call some other previously stored continuation to switch contexts.
Continuations can be used to pass data back into the continuation: you call the continuation with an argument, and that argument becomes the return value of the "callCC". In this case you probably just want to use ().
You typically have a queue for continuations, so the new continuation goes on the back of the queue and then you call the head of the queue. Obvious modifications for priority, simulated time, real time or whatever else you are trying to schedule. This implies some kind of monadic state to store the queue in, so you will probably make your monad of type "ContT (State Queue)"
If you want a thread to wait, say on a semaphore, then you have a queue of continuations in the semaphore data structure.
Is this any help?
Paul. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 19/06/10 17:23, Yves Parès wrote:
It helps me understand better, but would you have some simple code that would do that ?

On 20/06/10 22:03, Paul Johnson wrote:
On 19/06/10 17:23, Yves Parès wrote:
It helps me understand better, but would you have some simple code that would do that ?
Except that the paper I'm trying to refer to seems to have fallen off the net. Its "A Poor Man's Concurrency Monad". Does anyone have a copy? Paul.

Here you go!
-deech
On Sun, Jun 20, 2010 at 5:09 PM, Paul Johnson
On 20/06/10 22:03, Paul Johnson wrote:
On 19/06/10 17:23, Yves Parès wrote:
It helps me understand better, but would you have some simple code that would do that ?
Except that the paper I'm trying to refer to seems to have fallen off the net. Its "A Poor Man's Concurrency Monad". Does anyone have a copy?
Paul. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Paul Johnson wrote:
Yves Parès wrote:
It helps me understand better, but would you have some simple code that would do that ?
You can also understand coroutines and continuations in terms of operational semantics. Here is a reimplementation of Koen Claessen's poor man's concurrency monad based on this approach: PoorMansConcurrency.hs http://projects.haskell.org/operational/examples.html Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com

Yves Parès wrote:
It helps me understand better, but would you have some simple code that would do that ?
You can look at the definition of the coroutine monad transformer in the monad-coroutine package as well: http://hackage.haskell.org/package/monad-coroutine The heart of the library is in the data type
newtype Coroutine s m r = Coroutine { resume :: m (Either (s (Coroutine s m r)) r) }
where s is an arbitrary functor (like Yield, for example), m is an arbitrary monad, and r is the coroutine's final result type. You can also read the "Trampolined Style" and "The essence of multitasking" papers: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.45.5447&rep=rep1&type=pdf http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.92.4514&rep=rep1&type=pdf
2010/6/19 Paul Johnson
mailto:paul@cogito.org.uk> On 19/06/10 10:36, Yves Parčs wrote:
Hello,
I saw on the haskell wikibook that coroutines could be implemented by using continuations : http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style#Example:_cor... (unhappily, the section is empty) Since I'm actually learning the wonders of continuations, I just wonder : how ?
Coroutines depend on the ability to suspend and resume execution. A continuation acts as the "resume point" in the current function. The "callCC" function in the continuation monad takes a function that expects the continuation as an argument (which is how you get access to it). So you say something like:
> yield = callCC $ \continuation -> ....
Then you would typically store the continuation somewhere and call some other previously stored continuation to switch contexts.
Continuations can be used to pass data back into the continuation: you call the continuation with an argument, and that argument becomes the return value of the "callCC". In this case you probably just want to use ().
You typically have a queue for continuations, so the new continuation goes on the back of the queue and then you call the head of the queue. Obvious modifications for priority, simulated time, real time or whatever else you are trying to schedule. This implies some kind of monadic state to store the queue in, so you will probably make your monad of type "ContT (State Queue)"
If you want a thread to wait, say on a semaphore, then you have a queue of continuations in the semaphore data structure.
Is this any help?
Paul. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org mailto:Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
------------------------------------------------------------------------
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Mario Blazevic mblazevic@stilo.com Stilo International This message, including any attachments, is for the sole use of the intended recipient(s) and may contain confidential and privileged information. Any unauthorized review, use, disclosure, copying, or distribution is strictly prohibited. If you are not the intended recipient(s) please contact the sender by reply email and destroy all copies of the original message and any attachments.
participants (5)
-
aditya siram
-
Heinrich Apfelmus
-
Mario Blažević
-
Paul Johnson
-
Yves Parès