Issue 1895 create a customised monad for Darcs to do IO in

Title create a customised monad for Darcs to do IO in
Priority feature Status needs-implementation
Milestone Resolved in
Superseder Nosy List dagit, dmitry.kurochkin, ganesh
Assigned To
Topics Core, Library

Created on 2010-07-20.22:31:24 by ganesh, last changed 2010-07-21.21:25:59 by ganesh.

msg11805 (view) Author: ganesh Date: 2010-07-20.22:31:21
We should replace direct use of the IO monad in Darcs with a customised 
monad that abstracts away various things. This is important to make the 
Darcs library properly usable.

 - The use of global IORefs (use ReaderT instead? - still with IORefs, 
but not ones defined using the global variables hack)
 - The use of exit/exitWith and atexit handlers (replace with a custom 
exception type and finally blocks?)
 - (perhaps) things like progress reports
 - The mechanism for working with directories (see issue1774 and related 
 - output to stdout/stderr
 - (perhaps) all the other IO Darcs does

A good starting point would be to newtype wrap the IO monad, and 
implement MonadIO. The downside is that this would involve putting 
liftIO in all over the place, which would be quite ugly, but the 
advantage is that it would be essentially mechanical.

Once that's in place we could gradually move things into the monad.

One thing to keep a close eye at each step on would be performance.
msg11806 (view) Author: ganesh Date: 2010-07-21.05:07:29
Another thing it should wrap up is handling interactive prompts. 

Also eventually SelectChanges might be redesigned around a data structure 
that provides a higher-level programmatic interface, for example allowing 
graphical UIs to present more information at once.
msg11809 (view) Author: dagit Date: 2010-07-21.05:32:25
One thing we can do to make this easier, is to write wrapper libraries around 
the IO primitives to make them work for any MonadIO.  As a proof of concept, 
and a library to contribute to, see the monadIO package on hackage:

See for example,
  newIORef :: MonadIO io => a -> io (IORef a)

Then we should be able to create a MonadIO instance for any wrapper monad that 
we choose and use these primitives instead of the standard haskell ones.
msg11811 (view) Author: ganesh Date: 2010-07-21.07:19:20
In the long-term, I would prefer that the monad not implement MonadIO, 
so that there's no "escape hatch" and we have to properly abstract out 
all the IO that darcs needs to do.

As a transitional measure, the monadIO package (or if necessary our own 
variant of it) looks like a good plan.
msg11814 (view) Author: ganesh Date: 2010-07-21.21:25:58
Some discussion between me and Petr of this proposal here: 
Date User Action Args
2010-07-20 22:31:24ganeshcreate
2010-07-20 22:31:48ganeshsetpriority: feature
2010-07-21 05:07:30ganeshsetmessages: + msg11806
2010-07-21 05:32:26dagitsetnosy: + dagit
messages: + msg11809
2010-07-21 07:19:20ganeshsetmessages: + msg11811
2010-07-21 21:25:59ganeshsetmessages: + msg11814