[Haskell-cafe] STM rollback?

Joachim Durchholz jo at durchholz.org
Mon Nov 30 08:45:33 UTC 2020


 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.
> 



More information about the Haskell-Cafe mailing list