Deprecate exports (in modules)
Since this was originally written, https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0134-deprecating-exports-proposal.rst was created and approved formalizing the feature we want. The rest of this is subsumed by that and just for historical interest.
Motivation
During the library submission process there's sometimes the desire to have the ability to deprecate an export from a module.
For example during the discussing about ticket #4422 (closed), I would have liked the ability to deprecate the exports of the String
functions: lines
, words
, unlines
and unwords
from Data.List
in favour of importing them from Data.String
. However I wasn't able to do so, so these exports remain.
Similarly, during the discussion about ticket #4865 (closed), Ian also desired to deprecate the export of catch
from System.IO.Error
but was unable to do so.
Syntax
To deprecate an export simply place a DEPRECATE
pragma for the export inside the export list, as in:
module Data.List
( ...
{-# DEPRECATE lines "Exported from Data.String instead" #-}
, lines
...
) where
...
Another design might be to have a different pragma as in:
{-# DEPRECATE_EXPORT lines "Exported from Data.String instead" #-}
But I find the former much prettier and more obvious.
Semantics
If the lines
export from Data.List
is deprecated the following should raise deprecation warnings:
- Directly importing a deprecated export:
import Data.List (lines)
- Referring to a deprecated export:
import Data.List
foo = lines
If you import the same symbol from different modules and only some of them are deprecated exports then referring to the symbol won't give a deprecation warning. For example the following should not give deprecation warnings:
import Data.List
import Data.String
foo = lines
What exports can be deprecated?
- Functions.
- Types.
- Classes.
- Constructors. Possible syntax:
module A
( {-# DEPRECATE T(C1) "The export of C1 is deprecated" #-}
T(C1, C2, C3)
) where
- Modules. Possible syntax:
module A
( {-# DEPRECATE module B "The export of module B is deprecated" #-}
module B
) where
The semantics of deprecating a module export is that you get deprecation warnings for all symbols from module B
that you refer to inside a module that imports A
. (Does that make sense?)
Trac metadata
Trac field | Value |
---|---|
Version | 7.0.1 |
Type | FeatureRequest |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |