Ben Gamari | 28 Sep 05:11 2012
Picon

Strictness of modify in Control.Monad.State.Strict

Is there a reason there is no `modify` operation in
Control.Monad.State.Strict (and the transformers analogue) which is
truly strict in the state? That is,

    modify' :: Monad m => (a -> a) -> StateM a m ()
    modify' f = get >>= (\x -> put $! f x)

While this is admittedly not a difficult piece of code to write, even
the suggestion in the documentation that `modify` isn't as strict as one
might think would likely save many man-hours of debugging (especially
for those who are less familiar with the language, for whom, speaking
from experience, strictness issues can pose a major hurdle to adoption)

In general it would be nice if the notion of strictness were better
addressed in the major libraries' documentation. It's a nuanced
issue which is not fully captured by a ".Lazy" or ".Strict" in the
module name.

Just a thought.

Thanks,

- Ben
Edward Kmett | 28 Sep 06:13 2012
Picon

Re: Strictness of modify in Control.Monad.State.Strict

The strictness of Control.Monad.State.Strict has to do with the strictness of the tuple constructor, not of the state per se. The dichotomy between Lazy and Strict comes from the competing desires to fake products as categorical products that don't introduce _|_'s of their own and the lifted products we have in Haskell which do. The former leads you to the .Lazy model, the latter leads you to the .Strict model. The former is nicer for certain lazy knot tying tricks. The latter is easier to reason about when you start throwing fmap _|_'s around.


However, a Strict State or Writer is not actually strict in the state or log. This is admittedly a somewhat common misconception.

My concern is that such a combinator would exacerbate this confusion and that it doesn't generalize. e.g. This trick doesn't generalize to Strict.Writer, where you can `tell'`, but then you lose than on the next bind after you lazily smash it into something that is probably just mempty.

I'm not against noting that put/modify is not the thing that we are 'Strict' in more carefully though.

-Edward

On Thu, Sep 27, 2012 at 11:11 PM, Ben Gamari <bgamari.foss <at> gmail.com> wrote:
Is there a reason there is no `modify` operation in
Control.Monad.State.Strict (and the transformers analogue) which is
truly strict in the state? That is,

    modify' :: Monad m => (a -> a) -> StateM a m ()
    modify' f = get >>= (\x -> put $! f x)

While this is admittedly not a difficult piece of code to write, even
the suggestion in the documentation that `modify` isn't as strict as one
might think would likely save many man-hours of debugging (especially
for those who are less familiar with the language, for whom, speaking
from experience, strictness issues can pose a major hurdle to adoption)

In general it would be nice if the notion of strictness were better
addressed in the major libraries' documentation. It's a nuanced
issue which is not fully captured by a ".Lazy" or ".Strict" in the
module name.

Just a thought.

Thanks,

- Ben


_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Ben Gamari | 12 Oct 19:52 2012
Picon

Re: Strictness of modify in Control.Monad.State.Strict

Edward Kmett <ekmett <at> gmail.com> writes:

> The strictness of Control.Monad.State.Strict has to do with the strictness
> of the tuple constructor, not of the state per se. The dichotomy between
> Lazy and Strict comes from the competing desires to fake products as
> categorical products that don't introduce _|_'s of their own and the lifted
> products we have in Haskell which do. The former leads you to the .Lazy
> model, the latter leads you to the .Strict model. The former is nicer for
> certain lazy knot tying tricks. The latter is easier to reason about when
> you start throwing fmap _|_'s around.
>
> However, a Strict State or Writer is not actually strict in the state or
> log. This is admittedly a somewhat common misconception.
>
> My concern is that such a combinator would exacerbate this confusion and
> that it doesn't generalize. e.g. This trick doesn't generalize to
> Strict.Writer, where you can `tell'`, but then you lose than on the next
> bind after you lazily smash it into something that is probably just mempty.
>
I understand your concern regarding the inability to generalize to
Writer. That being said, does it do any harm to include a truly strict
combinator in Strict.State?

I for one end up rewriting modify' fairly often (or when I don't, I
generally only realize after the first stack overflow). As I mentioned
earlier, I think just the presence of "modify'" in the documentation
would lead many new Haskellers to catch their mistake before even facing
the dreaded "*** Exception: stack overflow".

Regardless, it seems there is a general consensus around improving the
treatment of laziness in the documentation. Unfortunately, not having
mastered this myself, I'm not sure I'd be a terribly good candidate to
write this language. Any volunteers?

Cheers,

- Ben
Evan Laforge | 28 Sep 21:19 2012
Picon

Re: Strictness of modify in Control.Monad.State.Strict

> In general it would be nice if the notion of strictness were better
> addressed in the major libraries' documentation. It's a nuanced
> issue which is not fully captured by a ".Lazy" or ".Strict" in the
> module name.

I agree.  I too wasted a significant amount of time hunting down space
leaks with were fixed by adding a modify' function.  If it had been in
the State module along with documentation about the implications, I
could have saved time.
Ryan Newton | 29 Sep 16:43 2012
Picon

Re: Strictness of modify in Control.Monad.State.Strict

I agree. I think part of the issue is that one is in "imperative mindset" when writing this code. For me that
seems to make it easier to miss "modify" space leaks in a forM loop, than if I were writing pure code with a
fold. 

Sent from my cell phone

On Sep 28, 2012, at 3:19 PM, Evan Laforge <qdunkan <at> gmail.com> wrote:

>> In general it would be nice if the notion of strictness were better
>> addressed in the major libraries' documentation. It's a nuanced
>> issue which is not fully captured by a ".Lazy" or ".Strict" in the
>> module name.
> 
> I agree.  I too wasted a significant amount of time hunting down space
> leaks with were fixed by adding a modify' function.  If it had been in
> the State module along with documentation about the implications, I
> could have saved time.
> 
> _______________________________________________
> Libraries mailing list
> Libraries <at> haskell.org
> http://www.haskell.org/mailman/listinfo/libraries

Gmane