[PROPOSAL] Adding Generics-based DefaultSignature to `deepseq` package
David Feuer
david.feuer at gmail.com
Thu Oct 16 13:57:49 UTC 2014
I don't know that any existing options *are* better.
On Oct 16, 2014 9:52 AM, "Johan Tibell" <johan.tibell at gmail.com> wrote:
> Could you elaborate on this? What other existing options are better?
>
> On Thu, Oct 16, 2014 at 3:36 PM, David Feuer <david.feuer at gmail.com>
> wrote:
>
>> I'm generally opposed to DefaultSignatures as an upside-down,
>> insufficiently-general attempt to solve an important problem, and generally
>> think the less relies on them the better.
>> On Oct 16, 2014 6:40 AM, "Herbert Valerio Riedel" <hvr at gnu.org> wrote:
>>
>>>
>>> The Proposal
>>> ============
>>>
>>> I hereby propose to merge `deepseq-generics`[2] into `deepseq`[1] in
>>> order to add Generics support to the `NFData` class based on the
>>> `-XDeriveGenerics` and `-XDefaultSignature` language extensions.
>>>
>>> A concrete patch is available for bike-review at [3]
>>>
>>>
>>> Prior Proposal & What's changed
>>> ===============================
>>>
>>> About 2 years ago, I already proposed something similar[4]. Back then
>>> the major concern was avoiding a conditionally exported API as using the
>>> (back then) rather young `Generics` extension would leave the Haskell98
>>> domain.
>>>
>>> This lead to me release Generics support as a companion package[2] which
>>> turns out to have become a rather popular package (judging from the
>>> Hackage download-count stats).
>>>
>>> I only realized after the discussion was effectively finished, that
>>> having a separate `deepseq-generics` actually does have an IMO
>>> non-neglectable downside:
>>>
>>> You can't support a `DefaultSignature`-based default implementation,
>>> as those need to be backed into the `NFData` class.
>>>
>>> Missing out on `DefaultSignature` would be a shame IMO, because
>>>
>>> * There's a chance that starting with GHC 7.10 `deriving` may work for
>>> arbitrary classes[5], putting `NFData` on equal footing as built-in
>>> classes such as `Eq` or `Show`. Specifically, you would be able to
>>> write
>>>
>>> data Foo = Foo [Int] String (Bool,Char) | Bar (Maybe Char)
>>> deriving (Show, Generic, NFData)
>>>
>>> instead of having to manually write the following boilerplate
>>>
>>> instance NFData Foo where
>>> rnf (Foo x y z) = rnf x `seq` rnf y `seq` rnf z
>>> rnf (Bar x) = rnf x
>>>
>>> which gets tedious rather soon if you have many (and more complex)
>>> types and tend to refactor regularly (with a risk of failing to adapt
>>> your manual instances if you change the strictness of fields)
>>>
>>>
>>> * The current default `rnf` implementation, i.e.
>>>
>>> rnf a = a `seq` ()
>>>
>>> is rather error-prone, as it's *very* easy to end up with an
>>> incorrect instance. Especially after refactoring a type for which the
>>> NF=WHNF assumption was broken after refactoring by adding new fields,
>>> or changing the strictness of existing fields.
>>>
>>> The Generics-derived `rnf` implementation does not have such a
>>> problem.
>>>
>>>
>>> Moreover, popular packages are starting adopt (and even recommend) the
>>> use of Generics in combination with `DefaultSignature` to provide
>>> automatically derived default instances, most notably `hashable`[6],
>>> `binary`[7], or `aeson`[8] just to name a few. In addition to providing
>>> a precedence for the use of Generics, I consider those packages evidence
>>> for Generics to have proven itself to the point of replacing
>>> TemplateHaskell in these use-cases.
>>>
>>>
>>> Compatibility & Breakage Considerations
>>> =======================================
>>>
>>> * This change requires a major version bump to deepseq-1.4.0
>>>
>>> * `deepseq` needs to drop GHC 7.0.* support as GHC 7.2 is the first
>>> version to support Generics & `DefaultSignature`.
>>>
>>> * Code relying on the current `rnf` default-implementation will most
>>> likely break (unless a `Generics` instance happens to be in-place)
>>>
>>> However, it's easy to provide forward/backward-compatibility w/o any
>>> CPP, by simply explicitly defining
>>>
>>> instance NFData XYZ where rnf = seq x ()
>>>
>>>
>>>
>>> Discussion Period: 2 weeks
>>>
>>>
>>>
>>> [1]: http://hackage.haskell.org/package/deepseq
>>> [2]: http://hackage.haskell.org/package/deepseq-generics
>>> [3]: https://github.com/haskell/deepseq/pull/1
>>> [4]: http://thread.gmane.org/gmane.comp.lang.haskell.libraries/17940
>>> [5]: https://ghc.haskell.org/trac/ghc/ticket/5462
>>> [6]: http://hackage.haskell.org/package/hashable
>>> [7]: http://hackage.haskell.org/package/binary
>>> [8]: http://hackage.haskell.org/package/aeson
>>> _______________________________________________
>>> 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
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/libraries/attachments/20141016/7715f4ef/attachment.html>
More information about the Libraries
mailing list