[Haskell-cafe] Re: Stronger STM primitives needed? Or am I just doing it wrong?

apfelmus apfelmus at quantentunnel.de
Wed Apr 23 14:49:58 EDT 2008


Ryan Ingram wrote:
> Consider the following transaction:
> 
>> intV :: TVar Int
>> boolV :: TVar Bool
>>
>> interesting = atomically $ do
>>    retryUntil intV (> 50)
>>    retryUntil boolV id
> 
> Lets say that intV contains 100 and boolV contains False.  Then this
> transaction retries.  Now, if intV changes to 101, this transaction
> doesn't need to re-run; we can see immediately that no predicate
> changed.  Using "readTVarWhen", this is less clear; the transaction
> log would hold a read on intV which would be more difficult to ignore.

I don't quite understand what you want to do but I presume it's related 
to the following: given an expression like

    readTVar intV >>= (\ -> ... readTVar boolV >>= (\_ -> ... retry))

The ... indicate branches that are there have not been taken in our 
example run, so the STM-side-effects that have been performed are

    readTVar intV
    readTVar boolV
    retry

The thread waits for either  intV  or  boolV  to change. Now, assume 
that  boolV  changes. Then, the idea for improving performance is to not 
restart the whole transaction, but only the part after the  readTVar 
boolV . In other words, only the continuation (\_ -> ... retry) will be 
executed again (and possibly yield something different from  retry ). 
I'm not sure whether this is currently implemented in Control.STM.


It seems that your scheme wants even more. You want to avoid work when 
intV  changes, because the predicate for  boolV  clearly indicates that 
no matter what  intV  is, we'll have to retry anyway. Unfortunately, I 
don't think it works: the predicate itself might depend on  intV

   interesting = atomically $
     readTVar intV >>= $ \i ->
     if i > 50 then retry else
        retryUntil boolV (even i ==)

That's the general property of  >>= , you always have to evaluate its 
right argument when the left argument changes. In essence, we have the 
same problem with parser combinators. Applicative functors to the rescue!


Regards,
apfelmus



More information about the Haskell-Cafe mailing list