|
|
|
# Proposal: `NoImplicitPreludeImport`
|
|
|
|
|
|
|
|
|
|
|
|
<table><tr><th> Ticket </th>
|
|
|
|
<th>[\#144](https://gitlab.haskell.org//haskell/prime/issues/144)</th></tr>
|
|
|
|
<th> TODO
|
|
|
|
</th></tr>
|
|
|
|
<tr><th> Dependencies </th>
|
|
|
|
<th> (none)
|
|
|
|
</th></tr>
|
|
|
|
<tr><th> Related </th>
|
|
|
|
<th>[\#58](https://gitlab.haskell.org//haskell/prime/issues/58), [\#124](https://gitlab.haskell.org//haskell/prime/issues/124)</th></tr></table>
|
|
|
|
<th> (none)
|
|
|
|
</th></tr></table>
|
|
|
|
|
|
|
|
|
|
|
|
## Compiler support
|
|
|
|
|
|
|
|
|
|
|
|
<table><tr><th> GHC </th>
|
|
|
|
<th> full (`-XImplicitPrelude`)
|
|
|
|
<th> partial (`-XImplicitPrelude`) (conflates the import with overriding desugaring)
|
|
|
|
</th></tr>
|
|
|
|
<tr><th> nhc98 </th>
|
|
|
|
<th> unknown
|
| ... | ... | @@ -29,14 +34,18 @@ |
|
|
|
<th> unknown
|
|
|
|
</th></tr></table>
|
|
|
|
|
|
|
|
|
|
|
|
## Summary
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This proposal is to stop implicitly importing `Prelude` in Haskell modules.
|
|
|
|
|
|
|
|
|
|
|
|
## Description
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The `Prelude` has been largely frozen since the 1990s or earlier, when
|
|
|
|
Haskell was a much different language. For example, it exports
|
|
|
|
`sequence` and `sequence_` but not the more often used `when` and
|
| ... | ... | @@ -44,26 +53,30 @@ Haskell was a much different language. For example, it exports |
|
|
|
Similarly, it exports `scanl1`, but not `sort`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
In other cases, such as `mapM`, the `Prelude` contains one version of a
|
|
|
|
function whereas modern Haskellers would prefer a more polymorphic
|
|
|
|
definition.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
While `Prelude` could be modified to make it a better fit for modern
|
|
|
|
Haskell, the implicit import of `Prelude` by every Haskell module means
|
|
|
|
that making these changes will have a very wide impact. Furthermore,
|
|
|
|
as the language continues to evolve, future changes that we want to make
|
|
|
|
will also have the potential to break lots of code in the wild.
|
|
|
|
as the language continues to evolve, so will future changes that we
|
|
|
|
want to make.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Also, there will always be some cut-off for which functions are included
|
|
|
|
in the `Prelude` and which aren't. It would seem rather ad-hoc for some
|
|
|
|
in the `Prelude` and which aren't. It seem rather ad-hoc for some
|
|
|
|
list functions, such as `map`, to be implicitly imported via `Prelude`,
|
|
|
|
when other, less common functions, such as `scanl1`, require an
|
|
|
|
implicit `Data.List` import. It would be more consistent to always
|
|
|
|
require a `Data.List` import when using any list functions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Finally, the `Prelude` is a very broad module; for example, it includes
|
|
|
|
both pure combinators like `map`, and IO functions like `putStrLn`.
|
|
|
|
There has recently been support for breaking the base package up, and
|
| ... | ... | @@ -72,64 +85,58 @@ any other proposed package, but putting it in its own package (which |
|
|
|
every other package would then need to depend on) seems excessive.
|
|
|
|
|
|
|
|
|
|
|
|
We therefore suggest that modules no longer implicitly import `Prelude`.
|
|
|
|
|
|
|
|
We therefore suggest that modules no longer implicitly import `Prelude`.
|
|
|
|
|
|
|
|
This would make the language definition a little simpler, and remove a
|
|
|
|
bit of magic.
|
|
|
|
|
|
|
|
|
|
|
|
It would also allow computer science courses to more easily use a
|
|
|
|
This would also allow computer science courses to more easily use a
|
|
|
|
simplified, more monomorphic `Prelude` replacement for teaching (or,
|
|
|
|
when asking students to implement basic functions like `length` as
|
|
|
|
exercises, no `Prelude` at all).
|
|
|
|
|
|
|
|
|
|
|
|
More generally, this would make adoption of the alternative preludes easier,
|
|
|
|
by making a more level playing field.
|
|
|
|
|
|
|
|
|
|
|
|
It may also be beneficial to EDSL designers, who wish to reuse `Prelude`
|
|
|
|
names for different functions.
|
|
|
|
|
|
|
|
More generally, this would make the alternative preludes more attractive,
|
|
|
|
by making a more level playing field.
|
|
|
|
|
|
|
|
It is possible that this would lead to a large number of alternative
|
|
|
|
Preludes, all slightly different.
|
|
|
|
On the other hand, perhaps this has already happened
|
|
|
|
([ 1](http://hackage.haskell.org/package/basic-prelude)[ 2](http://hackage.haskell.org/package/ClassyPrelude)[ 3](http://hackage.haskell.org/package/classy-prelude)[ 4](http://hackage.haskell.org/package/custom-prelude)[ 5](http://hackage.haskell.org/package/fugue)[ 6](http://hackage.haskell.org/package/general-prelude)[ 7](http://hackage.haskell.org/package/gofer-prelude)[ 8](http://hackage.haskell.org/package/interlude)[ 9](http://hackage.haskell.org/package/modular-prelude)[ 10](http://hackage.haskell.org/package/modular-prelude-classy)[ 11](http://hackage.haskell.org/package/numeric-prelude)[ 12](http://hackage.haskell.org/package/prelude-extras)[ 13](http://hackage.haskell.org/package/prelude-generalize)[ 14](http://hackage.haskell.org/package/prelude-plus)[ 15](http://hackage.haskell.org/package/prelude-prime)[ 16](http://hackage.haskell.org/package/simpleprelude)[ 17](http://hackage.haskell.org/package/yap)), in which case lowering the barrier
|
|
|
|
to using alternative Preludes may help determine a winner. However, it seems more
|
|
|
|
likely that the vast majority of developers will continue to import modules from
|
|
|
|
`base` instead, rather than add a dependency on another library.
|
|
|
|
|
|
|
|
## Related issues
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The sections below discuss issues related to the proposal, but which are
|
|
|
|
not part of it.
|
|
|
|
|
|
|
|
|
|
|
|
### Other changes to base
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
With the` Prelude` no longer implicitly imported, there are some functions
|
|
|
|
which no longer seem to have a good home. For example, if you want to use
|
|
|
|
`(+)` then you would have to import `Prelude`, which is a bit of a peculiar
|
|
|
|
name. Having a new module `Data.Num` also export `(+)` would make more
|
|
|
|
sense. We would encourage the library maintainers to go over the `Prelude`
|
|
|
|
exports, and make new homes for `Prelude` exports that don't already have
|
|
|
|
one.
|
|
|
|
one as they think best.
|
|
|
|
|
|
|
|
|
|
|
|
### The future of the `Prelude` module
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
If we stop `Prelude` being implicitly imported, then we could just leave
|
|
|
|
the module unchanged, so it can still be explicitly imported.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The module would still export an odd selection of functions, but that could
|
|
|
|
be fixed (and once it is no longer implicitly imported by every module,
|
|
|
|
less breakage would be caused).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The other option would be to remove the module too. If, as mentioned above,
|
|
|
|
base is split into smaller packages, then this would be the ideal time at
|
|
|
|
which to remove it. After the split happens, a new base package would
|
| ... | ... | @@ -141,62 +148,41 @@ modern Haskell, and will stop being shipping with the Haskell Platform |
|
|
|
after a few releases).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
We could therefore leave a `Prelude` module in the new
|
|
|
|
base package, but not put a `Prelude` module in any of the new packages.
|
|
|
|
Code moving to the new split packages would then need to import other
|
|
|
|
modules instead. It may make sense to keep some very common things, such
|
|
|
|
as the `Show` class (which is necessary whenever you want to define a
|
|
|
|
datatype deriving `Show`) in a module with a more generic name, such as
|
|
|
|
`Core` or `Base`. The name `Prelude` could also be used for this, but
|
|
|
|
another name may sound more natural.
|
|
|
|
|
|
|
|
### Desugaring
|
|
|
|
|
|
|
|
|
|
|
|
Currently, various pieces of Haskell syntax are desugared into
|
|
|
|
expressions that reference entities in the `Prelude`. Note that it is
|
|
|
|
not required that the entities are in scope, e.g.
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
import Prelude (IO, return)
|
|
|
|
|
|
|
|
main :: IO ()
|
|
|
|
main = do return ()
|
|
|
|
return ()
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
is valid even though `(>>)` is not in scope.
|
|
|
|
modules instead.
|
|
|
|
|
|
|
|
|
|
|
|
Therefore no change is necessary if the implicit import of Prelude
|
|
|
|
is dropped. If the module is also removed, then the report will have
|
|
|
|
to refer to the entities in other locations for its desugaring.
|
|
|
|
|
|
|
|
### Backwards compatibility
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The breakup of the base package also provides an opportunity to improve
|
|
|
|
the backwards compatibility that would be introduced by this change.
|
|
|
|
|
|
|
|
|
|
|
|
If `base` will now just re-exporting things from other packages then, like
|
|
|
|
|
|
|
|
If `base` is now just re-exporting things from other packages then, like
|
|
|
|
the `haskell98` and `haskell2010` packages, we presume that it would be
|
|
|
|
hidden by default. We therefore suggest that these packages (`base`,
|
|
|
|
`haskell98` and `haskell2010`) could provide a
|
|
|
|
hidden by default. We therefore suggest that these could packages provide a
|
|
|
|
useful proxy for whether the `ImplicitPreludeImport` extension defaults to
|
|
|
|
being enabled or not: if one of these packages is exposed, then it would
|
|
|
|
be on (for backwards compatibility); otherwise it would be off.
|
|
|
|
|
|
|
|
|
|
|
|
### Interactive environments
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The `Prelude` is particularly useful in interactive environments, which
|
|
|
|
many people like to use as a calculator. We would not want users to
|
|
|
|
need to manually import several modules before they could use common
|
|
|
|
functions like `length` and `(+)`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
In the case of ghc/ghci, the interactive environment already differs
|
|
|
|
from the compiler: In the interactive environment, the
|
|
|
|
`ExtendedDefaultRules` extension is enabled by default. We recommend that
|
| ... | ... | @@ -204,10 +190,12 @@ interactive implementations should similarly import one or more modules |
|
|
|
by default. e.g. {`Prelude`} or {`Data.Function`, `Data.List`, `Data.Num`}.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This could either be built in to the compiler, or the interactive
|
|
|
|
environment could use a config file for it. For example, ghci could
|
|
|
|
create a `~/.ghci` (if none exists) containing
|
|
|
|
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
set -XExtendedDefaultRules
|
|
|
|
import Prelude
|
| ... | ... | @@ -215,4 +203,8 @@ import Prelude |
|
|
|
|
|
|
|
## Report Delta
|
|
|
|
|
|
|
|
TODO |
|
|
\ No newline at end of file |
|
|
|
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
|