On Thu, 2011-10-27 at 09:12 +0100, Simon Marlow wrote:
> On 26/10/2011 21:45, David Terei wrote:
> > Hi Duncan,
> >
> > On 26 October 2011 06:05, Duncan Coutts<[email protected]>  
> > wrote:
> >> I don't understand this. Is it required that we mark Data.Trace as
> >> unsafe? Why is it not just left unmarked?
> >>
> >> My previous understanding was that Unsafe was for modules that don't
> >> break the language but rather break the encapsulation of abatract
> >> datatypes, ie for Blah.Internals modules.
> >>
> >> Data.Trace and indeed System.IO.Unsafe are not like this. They are
> >> simply not -XSafe because they use unsafePerformIO or ghc primitives.
> >
> > Yes and no. We infer safety now. So 'default' is hard to define but if
> > anything the default is actually more towards safe. The inference
> > tracks if a module imports any unsafe modules and if so marks it as
> > unsafe.

Which Debug.Trace does, it imports System.IO.Unsafe. In turn
System.IO.Unsafe can be infered to be unsafe because it imports GHC.IO.

The chain continues via GHC.Base --> GHC.Types (which defines the IO
datatype) --> GHC.Prim which defines State#, RealWorld etc.

> > We've never built into the Safe Haskell implementation any
> > specific knowledge of things like unsafePerformIO and GHC.*
> > primitives. Instead we handle these with the trust tracking mechanism.
> > So we do need to mark some of the base / root modules as Unsafe so
> > that this propagates through the rest of the module system.
> >
> > If we marked no modules at all as Unsafe (including the GHC.* ones)
> > then you'd have a lot of modules being inferred safe when they aren't.
> 
> I thought that making GHC.Prim Unsafe would do everything for us?  As a 
> result virtually everything becomes Unsafe, and we have to use explicit 
> Trustworthy pragmas to introduce safety.

Right.

For a moment I was thinking that the module that defines the IO type has
to be marked UNSAFE explicitly, because e.g. unsafeDupablePerformIO does
not use any ghc primitives:

lazy (case m realWorld# of (# _, r #) -> r)

Well, ok, it uses lazy, but that primitive isn't actually unsafe. It's
access to the IO constructor that lets the demons out.

But of course the definition of the IO type uses things from GHC.Prim,
so again we're ok.

> > In the case of Data.Trace and basically all the public modules in
> > base, we could remove the -XUnsafe flag and rely on the fact that they
> > import from GHC.* and will be inferred unsafe. I prefer explicitly
> > marking them as unsafe though. Yes this is a different story than what
> > the public facing use case of -XUnsafe is but base isn't a standard
> > package and I think its fine to require people hacking on it have some
> > understand of the implementation mechanics of Safe Haskell.

So here's where we disagree. I think marking things that are inferred as
unsafe as explicitly UNSAFE is actually a bad thing. It adds confusion,
makes people nervous about the safety inference and could mask bugs.

> If Data.Trace were not automatically inferred as Unsafe we'd be in big 
> trouble.  I agree with Duncan - marking it as Unsafe feels wrong (like 
> it could be hiding a bug).  Perhaps we want
> 
>   {-# LANGUAGE VerifyUnsafe #-}

It's not really a language feature anymore. We just want an assertion. 

It could be some other pragma. Or just a test in the testsuite that the
inferred safety of all the modules in base is what we expect them to be.
A pragma assertion would have the advantage that other packages could
use it easily too.

Duncan


_______________________________________________
Cvs-libraries mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-libraries

Reply via email to