[Haskell-cafe] Re: Stronger STM primitives needed? Or am I just
doing it wrong?
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
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!
More information about the Haskell-Cafe