Proposal: GHC.Generics marked UNSAFE for SafeHaskell
Mon Oct 7 17:33:34 UTC 2013
Thanks Edward! That provides a real example of someone who uses both
SafeHaskell and GHC.Generics in their libraries! I'm glad to know such a
person exists but that you don't depend on handwritten Generic instances.
(I'm also glad to hear that you care about SafeHaskell in the first place!)
I totally agree that #ifdef'ing on GHC version is a pain, and all that
code would need to conditionally import GHC.Generics or GHC.Generics.Safe
to retain -XSafe status.
I'm perfectly happy with the GHC-internal fix if someone can point me to
how to do it / where it should go. I guess I'll start by greping for
Typeable in the compiler. Is this something you can do trivially Edward?
Just for reference here is a small patch to Base representing my
library-based way of making the change discussed in this thread:
Again, my use-case (closed/safe Eq & Ord instances) is a few steps removed
from this Generics business and I don't feel strongly about how it gets
done. But having *SOME* way of doing it will be a massive boon to my lab's
particular effort at maximizing the abilities of guaranteed-Safe
deterministic parallelism in Haskell. Further, I think anyone else who
tries to do something in SafeHaskell that depends on guaranteeing a
closed/controlled set of instances (SafeEq, SafeOrd but also others) based
on GHC.Generics will *also* find this change useful.
On Mon, Oct 7, 2013 at 12:44 PM, Edward Kmett <ekmett at gmail.com> wrote:
> I'd much rather have code that can compile as Safe rather than
> Trustworthy. Trustworthy code is a pain to annotate the safety of
> A one line change to GHC to ensure the safety of GHC.Generics and to
> maximize the number of operations you can use safely seems entirely
> Otherwise I have to mark perfectly Safe-by-construction code Trustworthy,
> enlarging the trusted code base considerably. Using properly constructed
> Generic instances is perfectly safe.
> That library level fix has knock-on effects across the entire ecosystem
> for anyone who cares about SafeHaskell. I tend to instantiate GHC.Generics
> for any type in most of my packages. A quick grep finds 209 modules broken
> in just the projects I have open in my working directory. That is a mixture
> of public and private repos. The majority of which are public. So, I first
> have to change a couple hundred import statements... conditionally on
> compiler version, since I maintain wide support windows. This fix would
> literally break SafeHaskell for me silently across almost everything I have
> written, forcing me to run through tons of packages trying to figure out
> what I have to change to get it back. I've done this song and dance before
> trying to get lambdabot to build, since it uses lens these days. If I don't
> get every one of them right lens builds as unsafe. There isn't a good
> debugging process for this, as the only real way I have to know it worked
> is to go through each one and make sure I didn't compromise safe haskell by
> looking at the resulting haddocks for each case.
> The code that *uses* GHC.Generics uses their internals and is safe by
> construction. It is only the instance construction that is unsafe, so lets
> mark it as such.
> On Mon, Oct 7, 2013 at 11:11 AM, Ryan Newton <rrnewton at gmail.com> wrote:
>> On Mon, Oct 7, 2013 at 10:22 AM, Edward Kmett <ekmett at gmail.com> wrote:
>>> Am I correct in understanding your issue arises from manually rolled
>>> instances of Generic, not from Generic itself?
>>> Wouldn't then perhaps the better fix be to resurrect the old rule for
>>> derived Typeable instances and apply it to Generic and Generic1 instead?
>> The new rule would be that if you hand-implemented Generic or Generic1 in
>>> your module it isn't Safe.
>> Ah... so you're proposing adding an extra rule to the GHC compiler itself?
>> Isn't it simpler to do it just with a library-level fix? I.e. my
>> proposal is that GHC.Generics is marked as Unsafe. And then if you really
>> want you can mark your module as TrustWorthy even with manual instances.
>> (And then, yes, we'd need a GHC.Generics.Safe to pull the Generic symbol
>> itself from when we just want to derive it.)
>> That would make it so that derived Generic, Generic1 would be considered
>>> Safe, and you wouldn't break literally every user of the library who care
>>> about Safe Haskell.
>> Isn't that also accomplished just by "import GHC.Generic.Safe (Generic)"?
>> And the handful of hypothetical people that are using this right now can
>> make that one-line fix. I will *personally* make that fix for all those
>> people if they would come forward and share the link to their code ;-).
>> As it stands the things are damn-near impossible to get right
>>> instantiating them by hand anyways, so I expect this would affect only 1 or
>>> 2 users rather than all of them!
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the ghc-devs