
Simon, I'm still trying to figure out if there is a sane way to support Safe Haskell's module structure in vector. I'll post my thoughts later. Here are a couple of quick questions and observations, though. Simon Marlow wrote:
Myth #1 seems to be that Safe Haskell excludes large amounts of Haskell code that people want to write. Not at all! Normally when you use an unsafe feature, the purpose is to use it to implement a safe API - if that's the case, all you have to do is add Trustworthy to your language pragma, and the API is available to use from Safe code. 99% of Hackage should be either Safe or Trustworthy. We know that 27% is already inferred Safe (see the paper), and a lot of the rest is just waiting for other libraries to add Trustworthy where necessary.
Is "inferred Safe" the same as being marked "Safe-Infered" on Hackage? It does say that for Data.Vector.Unboxed, for instance, but that module certainly contains unsafe functions.
Despite none of them having had a thorough security review. In practice Trustworthy language pragmas on top of modules to make code compile. There are 139 modules in base marked as Trustworthy. I seriously doubt that they all are.
Whether you believe those claims or not is entirely up to you. Someone who is relying on Haskell for security has to trust a lot of things - GHC itself, the RTS, not to mention the hardware. Safe Haskell just makes it a bit clearer what you have to trust, and allows GHC to automate some of the checking.
FWIW, I went looking through the libraries and GHC does indeed come with a Trustworthy unsafePerformIO out of the box (it's in Data.Binary.Builder.Internal). Now, I'm not trying to knock the binary package. I think it just shows that unsafe functions *will* slip through the net, even in code written by absolute experts, so Johan's concerns are quite warranted.
SH is much more invasive than your typical language extension. It requires maintainers of libraries who don't care about SH to change their APIs (!)
It will be very rare for this to happen. The vast majority of packages do not expose unsafe APIs, so at most all that will be needed is some Trustworthy pragmas, and in many cases no changes at all are needed. In the very few cases where there is a mixed safe/unsafe API, and we really care about Safe access to the safe parts, then the unsafe parts should be moved into a .Unsafe module.
It seems that anything array-related would have to be split up in this way, just like it was in base. FWIW, I think Debug.Trace should be split up, too, since traceIO and especially traceEventIO are perfectly safe and useful. What about floating point arithmetic? Is it safe if I turn on FP exceptions?
I don't think adding a few Trustworthy pragmas is very onerous, and arguably it's good documentation anyway.
One problem I noticed here is Haskell's treatment of instances. It just isn't always obvious what exactly your module exports. It's easy to say that a particular function is safe. It is much harder to say the same for a whole module because you might be importing and hence exporting unsafe instances without realising. I think more language support would be needed here.
Of course it's your prerogative as a library maintainer to decide whether to use Trustworthy or not. For the platform I think the bar is a little higher, and cleanly separating safe from unsafe APIs is warranted.
Independent of vector, I'm against making Safe Haskell compliance a prerequisite for anything at this point. If it proves itself and if enough people start using it and relying on it - sure. But right now, it an experimental language extension with a very small user base. Roman