
On May 3, 2021, at 7:40 AM, Tom Smeding
wrote: But perhaps I'm being ignorant of other existing cases where this already matters, and I've been living in an idealised world until now.
Sad to say it, but order does matter here. In the very simple case, if you have {-# LANGUAGE FlexibleContexts, NoFlexibleContexts #-}, that's different from {-# LANGUAGE NoFlexibleContexts, FlexibleContexts #-} -- later extensions override earlier ones. This problem becomes more confounding when we recognize that some extensions imply others. For example {-# LANGUAGE TypeFamilies, NoMonoLocalBinds #-} means something different from {-# LANGUAGE NoMonoLocalBinds, TypeFamilies #-} because TypeFamilies implies MonoLocalBinds. Perhaps even worse, {-# LANGUAGE CUSKs, StandaloneKindSignatures #-} differs from {-# LANGUAGE StandaloneKindSignatures, CUSKs #-} because StandaloneKindSignatures implies NoCUSKs. Returning to Safe Haskell: It's true that Safe cannot be overridden locally. This is implemented by the fact that NoSafe does not exist. To me, this design makes sense, because it means that compiling with `ghc -XSafe` is guaranteed to use Safe Haskell. So we would need something like a default-safety field in Cabal, that could be overridden locally. But, still, this may be easier than the status quo. Do we think this would work? Specifically: * Introduce a new flag -fdefault-safety={safe,trustworthy,unsafe} that changes the module-level default. This default names the safety level in effect for any module that declares none of Safe, Trustworthy, or Unsafe. * If -fdefault-safety is not specified at the command line, it is as if the user wrote -fdefault-safety=unsafe. And that's it. Consequence: Safe-inference would never take place, because every module would have a declared level of Safety. The Safe-inference code could thus be removed. Further work: Introduce default-safety in Cabal, but that's not really necessary to make the changes above. What do we think? Richard