Skip to content

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
Edited by John Ericson
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information