Ticket #4879 (new feature request)
Deprecate exports
| Reported by: | basvandijk | Owned by: | |
|---|---|---|---|
| Priority: | high | Milestone: | 7.8.1 |
| Component: | Compiler | Version: | 7.0.1 |
| Keywords: | Cc: | ||
| Operating System: | Unknown/Multiple | Architecture: | Unknown/Multiple |
| Type of failure: | None/Unknown | Difficulty: | Unknown |
| Test Case: | Blocked By: | ||
| Blocking: | Related Tickets: |
Description
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, 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, 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?)
