Proposal: NoImplicitPreludeImport

Ben Franksen ben.franksen at online.de
Wed May 29 01:02:14 CEST 2013


Bryan O'Sullivan wrote:
> On Tue, May 28, 2013 at 8:23 AM, Ian Lynagh 
<ian at well-typed.com> wrote:
> 
>> I have made a wiki page describing a new proposal,
>> NoImplicitPreludeImport, which I intend to propose for Haskell 2014:
>>
>> http://hackage.haskell.org/trac/haskell-
prime/wiki/NoImplicitPreludeImport
>>
>> What do you think?
>>
> 
> This is a truly terrible idea.
> 
> It purports to be a step towards fixing the backwards compatibility
> problem, but of course it breaks every module ever written along the way,
> and it means that packages that try to be compatible across multiple
> versions of GHC will need mandatory CPP #ifdefs for years to come.

I think it need not necessarily come to that. If we do this right, then 
adding a line

  extensions: ImplicitPrelude

to a project's cabal file should be enough to get all existing code to 
compile, as a first step. The question is what comes after that?

Suppose you start adapting a package to the new standard. You delete the 
above extensions line in the cabal file and add

  import Prelude

to all modules that need it (most will). This should still be compatible 
with old compiler/language versions.

Now, occasionally, you will find that what you actually need to import is in 
just one or two of these new modules, so you replace some

  import Prelude

with

  import Data.Num -- etc

and at this point the code no longer compiles with old compiler/language 
versions. This is bad. #ifdef is not a nice solution, but there is better 
one:

We add a *compatibility package* (named e.g. "prelude") that contains all 
the new modules that are needed (in addition to already existing ones in 
base) to fully replace the Prelude. We also add some extra cabal magic that 
"knows" which version of prelude the old versions of base need to make them 
compatible with new packages that use the Prelude-replacement modules. The 
rules can be hard-coded into cabal and will be retained forever (at least 
for a long time).

This means that all you have to do if you have an old ghc installation is to

  cabal install cabal cabal-install

and then you can

  cabal install foo

even if foo is already converted to the new Prelude-less style, because the 
new cabal will add a silent dependency of (an old) base on the prelude 
package.

I think in order for this to actually work, the compatibility package would 
in turn have to depend on the installed version of base and the Prelude-
replacement modules inside it would have to actually re-export everything 
from the (old, installed) Prelude. It probably makes sense to create several 
versions of the prelude package, one for every supported version of base 
(ideally with the same version number to avoid confusion, adding a 5th 
number for bug-fixes). For instance base versions that appear in past 
Haskell Platforms could be supported in this way.

The circular dependency base-4.0.0.2 -> prelude-4.0.0.2.* -> base-4.0.0.2 -> 
etc must of course be handled specially by the new cabal. Or, instead of 
adding an implicit base-4.0.0.2 -> prelude-4.0.0.2.* dependency, cabal would 
-- depending on the installed version of base -- add a global constraint 
that adds the correct prelude package to all builds.

BTW, I think this could be a general method to "backward fix" compatibility 
problems when re-organising core libraries.

And one last caveat: Cabal itself would need to exercise some restraint 
w.r.t. using new language or library features, since it must be buildable on 
all supported language/compiler versions for this idea to work.

Cheers
-- 
Ben Franksen
()  ascii ribbon campaign - against html e-mail 
/\  www.asciiribbon.org   - against proprietary attachm€nts




More information about the Haskell-prime mailing list