Arie Peterson | 3 Mar 16:40 2013
Picon
Picon

Future of MonadCatchIO

Hi all,

The function 'block' and 'unblock' (from Control.Exception) have been 
deprecated for some time, and are apparantly now being removed (in favour of 
'mask').

Generalisations of these functions are (part of) the interface of 
MonadCatchIO-transformers (the 'MonadCatchIO' class has methods 'block' and 
'unblock'). So, the interface would have to change to keep up with base.

I'm inclined to deprecate MonadCatchIO-transformers itself, in favour of 
monad-control.

I suspect that most clients do not use 'block' or 'unblock' directly, but use 
only derived functions, like 'bracket'. (I have partly confirmed this, by 
inspecting some reverse dependencies on hackage.) This allow an easy 
transition to monad-control: in many cases, only imports will need to be 
changed. In the minority of cases where 'block' and 'unblock' are used and/or 
instances of MonadCatchIO are defined, code will need to be updated.

There is a difference in functionality between MonadCatchIO and monad-control. 
In the former, 'bracket' will not perform the final action if the main action 
is an ErrorT that throws an error (in contrast with exceptions in the 
underlying IO monad). In monad-control, 'bracket' will perform the final action 
in this case. (See this discussion for background:
<http://www.haskell.org/pipermail/haskell-cafe/2010-October/084890.html>.)

Probably, in most use cases the behaviour of monad-control is preferred. This 
seems to be the case also for snap, which uses MonadCatchIO-transformers, but 
defines its own variant of 'bracket' to get the right behaviour.
(Continue reading)

Ertugrul Söylemez | 3 Mar 17:07 2013
Picon

Re: Future of MonadCatchIO

Arie Peterson <ariep <at> xs4all.nl> wrote:

> Would anyone have a problem with a deprecation of
> MonadCatchIO-transformers, and a failure to update it to work with a
> base without 'block' and 'unblock'?

Yes.  This is a simplified variant of a monad I use:

    newtype Continue f m a = Continue (m (Maybe a, f (Continue f a)))

It's related to Cofree and has a valid and very straightforward
MonadCatchIO instance.  However, it's probably impossible to write a
valid MonadTransControl/MonadBaseControl instance for it.

So I kindly ask you not to deprecate MonadCatchIO.  The reason I'm
hesitant about moving to monad-control is that it's hard to understand
and also very difficult to define for CPS monads.  It is commonly
believed to be impossible.

Also I've seen at least one article about the incorrectness of
monad-control.  That's one further reason I like to avoid it.

Greets,
Ertugrul

--

-- 
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
(Continue reading)

Ertugrul Söylemez | 3 Mar 17:19 2013
Picon

Re: Future of MonadCatchIO

Ertugrul Söylemez <es <at> ertes.de> wrote:

>     newtype Continue f m a = Continue (m (Maybe a, f (Continue f a)))

Typo:

    newtype Continue f m a = Continue (m (Maybe a, f (Continue f m a)))

Sorry.

Greets,
Ertugrul

--

-- 
Not to be or to be and (not to be or to be and (not to be or to be and
(not to be or to be and ... that is the list monad.
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Michael Snoyman | 3 Mar 17:24 2013

Re: Future of MonadCatchIO




On Sun, Mar 3, 2013 at 6:07 PM, Ertugrul Söylemez <es <at> ertes.de> wrote:
Arie Peterson <ariep <at> xs4all.nl> wrote:

> Would anyone have a problem with a deprecation of
> MonadCatchIO-transformers, and a failure to update it to work with a
> base without 'block' and 'unblock'?

Yes.  This is a simplified variant of a monad I use:

    newtype Continue f m a = Continue (m (Maybe a, f (Continue f a)))

It's related to Cofree and has a valid and very straightforward
MonadCatchIO instance.  However, it's probably impossible to write a
valid MonadTransControl/MonadBaseControl instance for it.


Perhaps there's a good reason why it's impossible to make such an instance. Are you sure that your MonadCatchIO instance is well founded? What happens if you use finally? Are you guaranteed that your cleanup function is called once, and precisely once?

These are the problems I ran into with MonadCatchIO three years ago, almost precisely. The main monad for Yesod was built around ContT, and I ended up with double-free bugs. It's true that I had to move away from ContT in order to get the desired semantics, but that has nothing to do with MonadCatchIO vs monad-control. The former just made it seem like I had working code when in fact I had a lurking bug.
 
So I kindly ask you not to deprecate MonadCatchIO.  The reason I'm
hesitant about moving to monad-control is that it's hard to understand
and also very difficult to define for CPS monads.  It is commonly
believed to be impossible.

Also I've seen at least one article about the incorrectness of
monad-control.  That's one further reason I like to avoid it.


I've seen the criticisms of monad-control (or at least I believe I have). What I've seen has been dubious at best. I'll fully agree that the implementation is hard to follow, but it's designed for efficiency. The underlying concept is simple: capture the current state and pipe it through the underlying monad. If you needed to lift a control operation for the ReaderT or StateT monads, you would likely end up with an almost exact replica of what monad-control does for you.

Michael
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Arie Peterson | 3 Mar 17:48 2013
Picon
Picon

Re: Future of MonadCatchIO

On Sunday 03 March 2013 17:07:18 Ertugrul Söylemez wrote:
> > Would anyone have a problem with a deprecation of
> > MonadCatchIO-transformers, and a failure to update it to work with a
> > base without 'block' and 'unblock'?
> 
> Yes.  This is a simplified variant of a monad I use:
> 
>     newtype Continue f m a = Continue (m (Maybe a, f (Continue f a)))
> 
> It's related to Cofree and has a valid and very straightforward
> MonadCatchIO instance.  However, it's probably impossible to write a
> valid MonadTransControl/MonadBaseControl instance for it.

Is it possibly to write the equivalent of Control.Exception.mask for it? That 
would be the first candidate for replacing block and unblock in the 
MonadCatchIO class.

Regards,

Arie
John Lato | 4 Mar 03:14 2013
Picon

Re: Future of MonadCatchIO

On Mon, Mar 4, 2013 at 12:07 AM, Ertugrul Söylemez <es <at> ertes.de> wrote:
Arie Peterson <ariep <at> xs4all.nl> wrote:

> Would anyone have a problem with a deprecation of
> MonadCatchIO-transformers, and a failure to update it to work with a
> base without 'block' and 'unblock'?

Yes.  This is a simplified variant of a monad I use:

    newtype Continue f m a = Continue (m (Maybe a, f (Continue f a)))

It's related to Cofree and has a valid and very straightforward
MonadCatchIO instance.  However, it's probably impossible to write a
valid MonadTransControl/MonadBaseControl instance for it.

So I kindly ask you not to deprecate MonadCatchIO.  The reason I'm
hesitant about moving to monad-control is that it's hard to understand
and also very difficult to define for CPS monads.  It is commonly
believed to be impossible.

You can always cast the continuation to a dynamic type and cast it back later.
Doing so would typically require additional constraints, however if you're trying to make an instance for MonadTransControl that's unfortunately not possible (you'd need a Typeable constraint on the monad parameter, but it's not in scope).  Lacking an appropriate MonadTransControlWithTypeable class, it's certainly possible to fall back to various low-level, highly-dubious constructs.  Which I of course implemented without hesitation :grin
 
Also I've seen at least one article about the incorrectness of
monad-control.  That's one further reason I like to avoid it.

I'd appreciate a link if anyone could manage to find it.  I haven't seen any criticisms of monad-control.

John L. 
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
John Lato | 4 Mar 03:25 2013
Picon

Re: Future of MonadCatchIO

Also I've seen at least one article about the incorrectness of
monad-control.  That's one further reason I like to avoid it.

I'd appreciate a link if anyone could manage to find it.  I haven't seen any criticisms of monad-control.

Oddly, I just stumbled across  http://blog.ezyang.com/2012/01/monadbasecontrol-is-unsound/ from a mostly-unrelated search.  Was this the article to which you're referring?
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Edward Z. Yang | 26 Mar 23:38 2013
Picon

Re: Future of MonadCatchIO

While block and unblock have been removed from base, they are still implementable
in modern GHC.  So another possible future is to deprecate MonadCatchIO
(which should have been done a while ago, honestly!), but manually redefine
the functions so that old code keeps working.

Edward

Excerpts from Arie Peterson's message of Sun Mar 03 07:40:06 -0800 2013:
> Hi all,
> 
> 
> The function 'block' and 'unblock' (from Control.Exception) have been 
> deprecated for some time, and are apparantly now being removed (in favour of 
> 'mask').
> 
> Generalisations of these functions are (part of) the interface of 
> MonadCatchIO-transformers (the 'MonadCatchIO' class has methods 'block' and 
> 'unblock'). So, the interface would have to change to keep up with base.
> 
> I'm inclined to deprecate MonadCatchIO-transformers itself, in favour of 
> monad-control.
> 
> I suspect that most clients do not use 'block' or 'unblock' directly, but use 
> only derived functions, like 'bracket'. (I have partly confirmed this, by 
> inspecting some reverse dependencies on hackage.) This allow an easy 
> transition to monad-control: in many cases, only imports will need to be 
> changed. In the minority of cases where 'block' and 'unblock' are used and/or 
> instances of MonadCatchIO are defined, code will need to be updated.
> 
> There is a difference in functionality between MonadCatchIO and monad-control. 
> In the former, 'bracket' will not perform the final action if the main action 
> is an ErrorT that throws an error (in contrast with exceptions in the 
> underlying IO monad). In monad-control, 'bracket' will perform the final action 
> in this case. (See this discussion for background:
> <http://www.haskell.org/pipermail/haskell-cafe/2010-October/084890.html>.)
> 
> Probably, in most use cases the behaviour of monad-control is preferred. This 
> seems to be the case also for snap, which uses MonadCatchIO-transformers, but 
> defines its own variant of 'bracket' to get the right behaviour.
> 
> 
> Would anyone have a problem with a deprecation of MonadCatchIO-transformers, 
> and a failure to update it to work with a base without 'block' and 'unblock'?
> 
> 
> Regards,
> 
> Arie
> 

Gmane