simonmar / async

Run IO operations asynchronously and wait for their results
BSD 3-Clause "New" or "Revised" License
323 stars 65 forks source link

The new `Internal` module is marked as `Trustworthy`. #151

Closed phadej closed 1 year ago

phadej commented 1 year ago

Safe Haskell is meant (among other things) to help prevent module abstraction violations, in that light, .Internal module should be Unsafe.

simonmar commented 1 year ago

I'm not sure I agree. Simply renaming a module does not affect its safety - Safe Haskell is for a very narrow purpose, namely to ensure the user can trust the type system and abstraction facilities provided by the language, it doesn't encompass any broader notion of safety.

phadej commented 1 year ago

@simonmar please bring this to the table at GHC steering committee. https://www.microsoft.com/en-us/research/wp-content/uploads/2012/01/safe-haskell.pdf says in section 3.1

Subject to this, Safe Haskell provides the following guarantees for code compiled in the safe language:

...

• Module encapsulation. Haskell provides an effective module system that is used to control access to functions and data types. In the safe language these module boundaries are strictly enforced; a user of a module that contains an abstract data type is only able to access or create values through the functions exported.

which have been argued e.g. to make and keep GeneralizedNewtypeDeriving and Data.Coerce unsafe.

EDIT: the ghc issue https://gitlab.haskell.org/ghc/ghc/-/issues/8827 and https://gitlab.haskell.org/ghc/ghc/-/issues/8745

simonmar commented 1 year ago

@phadej I think you might have a different interpretation of "Module encapsulation" than the intended one. Safe Haskell only promises that the semantics of abstraction are respected, it doesn't promise that you can't see the representation of a datatype by importing it from some other module.

phadej commented 1 year ago

@phadej I think you might have a different interpretation of "Module encapsulation" than the intended one. Safe Haskell only promises that the semantics of abstraction are respected, it doesn't promise that you can't see the representation of a datatype by importing it from some other module.

Fair.

It seems that this is not 100% clear. Data.Text.Internal is unsafe (or rather not explicitly marked to be anything, its haddock says it's Safe-Inferred but that is a bug in haddock), but Data.Set.Internal are Trustworthy.

It seems we shouldn't assume that Safe Haskell code (i.e. importing only safe or trustworthy) modules cannot violate any internal invariants of data types, because there can be trustworthy way to break them.