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
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe