[Haskell-cafe] Non-strict evaluation and concurrency (STM) : conflict?

Felipe Lessa felipe.lessa at gmail.com
Tue Sep 28 09:31:35 EDT 2010


On Tue, Sep 28, 2010 at 10:06 AM, Romain Demeyer
<romain.demeyer at gmail.com> wrote:
> Let's a function "do_job", the function to execute by the threads (the
> workers) :
> do_job :: (b -> a) -> b -> Inbox a -> IO ()
> do_job f input inbox = do { value <- return (f input)
>                           ; atomically ( writeMsg inbox value ) }

First of all, note that

  do v <- return (f x)
     ...

is exactly the same as

  do let v = f x
     ...

Now, if you want to evaluate your value to WHNF (Weak Head Normal
Formal), you may use

> do_job :: (b -> a) -> b -> Inbox a -> IO ()
> do_job f input inbox = do
>   value <- evaluate (f input)
>   atomically (writeMsg inbox value)

This will work pretty well if your value is simple (eg. an Int)
but not so well if it is complex (eg. a Data.Map) because it will
evaluate only as much as 'seq'.

You may than use the 'deepseq' package:

> import Control.DeepSeq
>
> do_job :: NFData a => (b -> a) -> b -> Inbox a -> IO ()
> do_job f input inbox =
>   let value = f input
>   in value `deepseq` atomically (writeMsg inbox value)

This will fully evaluate the structure before calling 'writeMsg'.

> That's what we want, but what is the explanation of this behavior? STM is
> designed to be optimistic, not blocking. So, does it means that the "value"
> is evaluated at "commit-time"?
> Do you know some problems that are related or do you know some works that
> can be useful at this subject?

Those values are pure, so if you say

  writeMsg inbox (f x)

then internally a thunk is created referencing 'f' and 'x', and a
pointer to that thunk is atomically commited.  Just like the rest
of the program.

The value is not being evaluated by STM at all, as your STM functions
don't need the value.  In your program is evaluating when you print
the answer in the main thread, as printing requires the value of the
computation.  If you didn't print, nothing would be computed at all.
Lazy =).

HTH,

--
Felipe.


More information about the Haskell-Cafe mailing list