Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Haskell's TChan defer messages like Erlang's message queues can?

Consider the following Erlang code:

-module(testit).
-export([testit/0]).

testit() ->
    Pid = spawn(fun testit_proc/0),
    Pid ! final,
    Pid ! one,
    Pid ! two,
    io:format("Root finished~n").

testit_proc() ->
    receive
        one     -> io:format("One~n");
        two     -> io:format("Two~n")
    end,
    receive
        one     -> io:format("One~n");
        two     -> io:format("Two~n")
    end,
    receive
        one     -> io:format("One~n");
        two     -> io:format("Two~n");
        final   -> io:format("Final~n")
    end,
    io:format("Spawn finished~n").

The output is:

Root finished
One
Two
Final
Spawn finished

The processing of the final message is essentially deferred until the last receive block by virtue of the previous receive patterns not matching that message.

How do you do this with Haskell's TChan?

like image 858
me2 Avatar asked Feb 16 '10 03:02

me2


1 Answers

You're referring to Erlang's selective receive feature. As far as I know, STM in Haskell has no parallel to it. Your choices are to either refactor your code to remove the need for it (such as by using separate queues for the different types of information that may be received), or to implement this feature in a library.

The semantics of selective receive is that in addition to the incoming message queue, you also have a deferred message list. In the receive function, you need to first scan the deferred list for any matching messages. If a message matches, then you remove it from the list and deliver it. If no deferred messages match, then you need to wait for a message on the inbox. When a message is received, you check if it matches. If it does, then you deliver it; if not, then you push it to the deferred list and repeat.

like image 127
Michael Melanson Avatar answered Sep 28 '22 10:09

Michael Melanson