[Haskell-cafe] ANN: generic-deepseq

Maxime Henrion mhenrion at gmail.com
Mon Feb 20 00:01:27 CET 2012

On Sun, 2012-02-19 at 21:06 +0100, Bas van Dijk wrote:
> On 19 February 2012 18:11, Maxime Henrion <mhenrion at gmail.com> wrote:
> > If you're not dealing with an abstract datatype, you _shouldn't_ have an
> > explicit instance, because it would be possible to write an incorrect one,
> > while that is impossible if you just derive a generic implementation
> > (as long as the generic code is correct, of course).
> I agree. I hadn't considered this advantage yet. I guess it's the same
> argument for why it's better to automatically derive Data and Typeable
> instances using the DeriveDataTypeable extension.
> > So, knowing that it would necessarily be backwards incompatible (I
> > wasn't intending to hack on GHC :-), and also that, in the end, this is
> > not quite the same class as the NFData class from the deepseq package, I
> > thought it made more sense to create another package that would be
> > mostly compatible with deepseq, but with a different class name so as to
> > force people to reevaluate the need for their instances if they have
> > some. I'd be interested in knowing what you and others think about that.
> > Maybe I'm being overly cautious?
> I do think it's better to integrate this into the deepseq package (and
> thus removing the default implementation of rnf). Otherwise we end up
> with two ways of evaluating values to normal form.

I'm okay with that, but I was interested in knowing whether you think my
reasoning for changing the class name and thus deliberately breaking the
API slightly more was sane or not (I say "more" because removing the
default implementation of rnf already constitutes an API breakage in
that the generic replacement would be optional and depends on having
Generic instances to work).

> > I'm guilty of not having preserved the "rnf :: a -> ()"
> > function as the class function though, it's a wrapper around "deepseq"
> > in my code. I just didn't see the point of having a class function with
> > such a signature versus having a function just like "seq :: a -> b ->
> > b". In retrospect, that might have been a bad idea, and maybe I should
> > switch to have an "rnf :: a -> ()" class function to make switching even
> > easier?
> I'm not sure but maybe a method like "rnf :: a -> ()" is easier to optimize.
> Also in my experience (with generics support in aeson and cereal) it's
> a very good idea (performance-wise) to INLINE your methods like I did
> in my previous message. Of course the only way to know for sure is the
> create some (criterion) benchmarks.

Yeah, I should definitely get going on the benchmarks.

> One last issue: Say I have a type like: "data T = C !Int"
> Currently GHC Generics can't express the strictness annotation. This
> means that your deepseq will unnecessarily evaluate the Int (since it
> will always be evaluated already). It would be nice if the strictness
> information could be added to the K1 type. (José, would it be hard to
> add this to GHC.Generics?)

Assuming there is way to differentiate strict constructors in
GHC.Generics, and that I have a specific instance so as to not call seq
in that case, can you actually do such an optimization safely? Consider
this code (imports omitted for simplicity):

data T = C !Int deriving Generic

instance DeepSeq T

x :: T
x = undefined

main :: IO ()
main = print (x `deepseq` ())

I would expect this to diverge, just like it does if one uses `seq`. If
we implement the optimization you suggest, I believe that deepseq
wouldn't diverge, but I admit I'm not 100% sure either.

Maxime Henrion
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 834 bytes
Desc: This is a digitally signed message part
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120220/c265ad61/attachment.pgp>

More information about the Haskell-Cafe mailing list