[Haskell-cafe] STM rollback?

Jake McArthur jake.mcarthur at gmail.com
Fri Dec 4 22:38:09 UTC 2020


I made an STM implementation for work with the ability to give a "reason"
for retrying, which I have found very useful. A Haskell version might look
something like this:

data STM e a
instance Monad (STM e)

-- These also form a monad, but we'd need a newtype to define the instance.
retry :: e -> STM e a
orElse :: STM e1 a -> (e1 -> STM e2 a) -> STM e2 a

With this interface, you could define something like this:

possiblyRollback :: STM (Either e a) b -> STM e (Either a b)
possiblyRollback stm = fmap stm Right `orElse` either retry (return . Left)

With this, you can retry as normal with `retry (Left e)`, locally rollback
with `retry (Right a)`, or return as normal with `return b`.

On Mon, Nov 30, 2020 at 3:47 AM Joachim Durchholz <jo at durchholz.org> wrote:

>  From a contract design perspective, rolling back means that an
> operation failed and had to be undone. (If everything was fine, you
> wouldn't want to rollback, wouldn't you?)
>
> So if rollback is the reaction to some failure, then triggering it via
> an exception is the Right Thing To Do, actually.
> Oh, and you always want to rollback if there's an exception somewhere.
>
> Now that contract thing warrants a few more words.
> Yes, you can word your contracts so that they include failure. It's just
> that they get more complicated. Usually so much more complicated that
> it's not worth it.
> Also, you want any exception (i.e. breach of contract) to go into a
> rollback. Now in Haskell, rolling back means just abandoning the
> computation since things aren't mutable and there is no state that you
> need to restore. Technically, not even in STM - so there *is* reason to
> make the rollback non-exceptional here: One could argue that STM is
> *supposed* to include the rollback in the contract.
> In the end, it depends on your use case: Do you want the rollback in the
> contract or not?
>
> Now for STM itself, yeah using an exception to trigger a rollback is a
> bit hacky.
> OTOH it works.
> OT3H it might be a good idea to have a rollback function for STM.
> Technically it would just trigger the same exception, but it would
> indicate that the rollback is part of the contract.
> OT4H throwing Rollback is essentially an indicator of non-failure
> rollback (otherwise you'd be throwing whatever exception is appropriate,
> or get aborted by some library functionality that throws an exception).
>
> Regards,
> Jo
>
> Am 28.11.20 um 22:05 schrieb amindfv--- via Haskell-Cafe:
> > I'd like to be able to give up on an STM transaction: roll back and
> don't retry.
> > I've cooked up something with exceptions but it feels a bit icky to use
> exceptions for something like this - is there a better way?:
> >
> >      data Rollback = Rollback deriving (Show)
> >      instance Exception Rollback
> >
> >      rollback :: STM x
> >      rollback = throwSTM Rollback
> >
> >      atomicallyWithRollback :: STM x -> IO (Maybe x)
> >      atomicallyWithRollback a =
> >         (Just <$> atomically a)
> >            `catch` (\Rollback -> pure Nothing)
> >
> > The alternative I've found is something like:
> >
> >      otherWay :: STM x -> IO (Maybe x)
> >      otherWay a =
> >         atomically $ (Just <$> a) `orElse` pure Nothing
> >
> > But this turns any "retry" in "a" into a rollback, and I'd like to have
> the option to do either (retry or rollback).
> >
> > Thanks,
> > Tom
> >
> >
> > _______________________________________________
> > Haskell-Cafe mailing list
> > To (un)subscribe, modify options or view archives go to:
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > Only members subscribed via the mailman list are allowed to post.
> >
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20201204/cc9727ae/attachment.html>


More information about the Haskell-Cafe mailing list