[Haskell-cafe] Combining ST with STM
Alberto G. Corona
agocorona at gmail.com
Tue Feb 9 11:29:20 UTC 2016
Why not use the state monad transformer?
atomically $ evalStateT todo initialState
Seems Ok to me
evalStateT :: Monad
m a -> s -> m a
in this case:
evalStateT :: StateT
a -> MyState -> STM a
2016-02-09 9:36 GMT+01:00 Jonas Scholl <anselm.scholl at tu-harburg.de>:
> On 02/09/2016 07:20 AM, Thomas Koster wrote:
> > On 9 February 2016 at 14:43, Thomas Koster <tkoster at gmail.com> wrote:
> >> I have an STM transaction that needs some private, temporary state.
> >> The most obvious way is to simply pass pure state as arguments, but
> >> for efficiency, I would like this state to be some kind of mutable
> >> array, like STArray.
> This sounds like optimizing before you know what is really slow,
> complicating your code for no good reason...
> >> I know, STM has TVars and TArray, but since this state is private to
> >> the transaction, I am wondering if using TVars/TArrays for private
> >> state might be overkill that will unnecessarily slow down the STM
> >> commit process. The private state is, by definition, not shared, so
> >> including it in the STM log and commit process is, as far as I can
> >> tell, pointless.
> The STM log allows you to revert a failed transaction. If you do not
> record your writes to an array, you can not revert them and they can
> leak outside an aborted transaction.
> >> ST and STArray still appear to be the most appropriate tools for the
> >> private state, because STRefs and STArrays really, really are private.
> >> So this basically means I want to interleave ST and STM in a "safe"
> >> way. That is, if the STM transaction retries, I want the ST state to
> >> be vaporised as well.
> So how should this work? Some log recording what you did would be good,
> so the runtime knows which changes you did to the array... If you
> however create the array in the same transaction, this would work by
> just throwing away the whole array.
> >> Ideally, I would love to be able to say something like this:
> >> -- | Copy the value from the shared TVar into the private STRef.
> >> load :: TVar a -> STRef a -> STSTM s ()
> >> load shared private = do
> >> value <- liftSTM (readTVar shared)
> >> liftST (writeSTRef private value)
> >> Naturally, that STRef must originate from a call to newSTRef earlier
> >> in the same transaction and is private to it, just like the real ST
> >> monad. As far as I can tell, I am not trying to weaken either ST or
> >> STM in any way here.
> >> I found the STMonadTrans package on Hackage  that claims to
> >> implement ST as a monad transformer, STT, which sounds close to what I
> >> want. While its documentation does not mention STM, it does say that
> >> some monads are unsafe to use as a base monad for STT.
> >> Is STMonadTrans safe to use with STM?
> It is not even safe to use with Maybe (for now), as it can share
> different STRefs and STArrays. I filed a bug report. After the bug is
> fixed, I see no reason, why it should not work with STM, as the complete
> ST action should be repeated if the STM transaction aborts.
> >>  https://hackage.haskell.org/package/STMonadTrans
> > On 9 February 2016 at 15:16, Ryan Yates <fryguybob at gmail.com> wrote:
> >> I also have found need for what I think you are describing but only in
> >> context of transactional arrays where there are multiple fields to
> >> initialize while I know that the array is private to the creating
> >> For now I'm adding the primitives I need as I go, but I would like to
> >> better safer story. You might be interested in how the stm-containers
> >> package uses ST to build internal nodes in transactions , .
> >> :
> >> :
> > Thank you Ryan.
> > Indeed, it is by experimenting with stm-containers that the need for
> > mixing ST and STM arose. Where the previous iteration of my program
> > used plain ST transactions serialized with an MVar, I am experimenting
> > with stm-containers with the hope that I will see improved throughput
> > for transactions that do not overlap, which, I believe, could complete
> > in parallel, at least some of the time.
> > It seems stm-containers itself uses unsafeFreezeArray from the
> > "primitive" package. One difference though is that while my private
> > array would be thawed, modified and refrozen regularly, the
> > stm-containers WordArray stays immutable (not thawed) once frozen, as
> > far as I can tell.
> So what happens if you thaw an array, write to it and then abort the
> transaction? You have to revert the writes because they could be visible
> to the transaction you just aborted. When this transaction restarts, the
> array will still contain the values written prior to it. Even if nothing
> else contains a reference to it, your array is garbage after you aborted
> a transaction only once.
> > Since I am using only a single array for the entire private state,
> > sprinkling some runST calls with unsafeThawArray/unsafeFreezeArray in
> > my STM transaction may be enough for my needs, as long as I am
> > exceptionally careful not to leak one of these arrays into or out of
> > any STM transaction demarcated by the "atomically" block. If anybody
> > knows of any reason why I should abort this idea, please speak up.
> Keep in mind that ST is only "safe IO" in a sense such that no side
> effects are visible to the outside. You lose this if you start to modify
> anything which you did not create yourself. I think this is not that
> different from using
> To be safe, you should at least copy the arrays instead of unsafely
> thawing them... but then it could be faster just to use TArrays from the
> > I noticed also that Data.Array.Unsafe in base also has unsafe freezing
> > and thawing. Is there a reason to use one over the other?
> > --
> > Thomas Koster
> > _______________________________________________
> > Haskell-Cafe mailing list
> > Haskell-Cafe at haskell.org
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe