
On Wed, Apr 23, 2008 at 01:46:53PM -0700, Ryan Ingram wrote:
On 4/23/08, David Roundy
wrote: I'm confused as to how your retryUntil gains you anything. If any of the TVars used in the expensive_computation change while waiting for a retry, then the expensive_computation will need to be done again. If none of them change, then we can skip the expensive_computation.
Does the STM runtime do this?
i.e. how does your broken function using retryUntil differ from the following?
broken = atomically $ do v <- expensive_computation :: STM (TVar Int) vv <- readTVar v unless (vv > 50) retry
If the STM runtime does the optimization you suggest, it's not different at all.
I doubt it does this, but my point is that you aren't suggesting a new primitive, you're suggesting an improved runtime. Once you've got your improved runtime, this optimization is trivial, as far as I can tell. And without an improved runtime, your function is equivalent to this one.
But consider this computation:
-- non-primitive retryUntil: retryUntil v p = do x <- readVar v unless (p x) retry
broken2 = atomically $ do (v1, v2) <- expensive_computation :: STM (TVar Int, TVar Int) retryUntil v1 (> 50) x <- expensive_computation2 :: STM Int retryUntil v2 (> x)
If v1 succeeds and v2 fails, then v1 changes to some other value > 50, I am sure that the STM runtime as it stands now will re-run expensive_computation2.
I suppose it depends on how you rewrite the runtime. Rather than your very limited retryUntil + caching of results computed in the STM, why not make this caching explicit, and allow users to write their own more complicated variants of retryUntil? e.g. retryUntil2 :: TVar a -> TVar b -> (a -> b -> Bool) -> IO () A simple primitive to do this (in combination with a totally rewritten STM runtime) would be subatomically :: ReadOnlySTM a -> STM () which would run a STM computation that is guaranteed to have no side-effects (i.e. can't write to TVars) and ignore its results (and let the runtime know that the results have been ignored). Then your extra-fancy retryUntil could simply be. retryUntil v p = subatomically $ do x <- readVarRO v unless (p x) retryRO The only thing that is special about your retryUntil is that it does not allow the modification of TVars. On the other hand, I suspect the whole issue is silly. Is it ever actually wise to do an expensive calculation in the STM monad? That seems like it's guaranteed to be a performance nightmare. -- David Roundy Department of Physics Oregon State University